重开仓库内容:改推五个技能(browser-harness / humanizer / humanizer-zh / product-planning / session-mechanism)

按授权清空原有内容后重新提交(原 oil-ui-pro 一并移出,可从历史恢复)。
browser-harness 剔除 .venv 等运行环境;根 .gitignore 补记 .venv/ 与 node_modules/。
This commit is contained in:
admin committed 2026-10-07 16:06:02 +08:00
1 parent 9a152a1952
commit 777f7fe5d0
240 files changed
+52518 -4409

No files matched your search

@@ -0,0 +1,185 @@
# AgentList Discovery
`https://agentlist.com` — public directory of skills, agents, MCPs, configs, and paid services. Field-tested with browser-harness on 2026-05-03.
## Do This First
Use the public API for read-only discovery. It is faster and returns full listing content without browser UI parsing.
```python
import json
listings = json.loads(http_get("https://agentlist.com/api/listings?category=skill&q=github&limit=10"))
for item in listings:
print(item["title"], item["id"], item["vote_count"])
```
The web UI is useful for visual verification, voting, signing in with passkeys, and submitting listings.
## Public API
All read endpoints below worked without authentication.
```python
import json
# Search everything
items = json.loads(http_get("https://agentlist.com/api/listings?q=github&limit=10"))
# Filter by category
skills = json.loads(http_get("https://agentlist.com/api/listings?category=skill&q=browser&limit=10"))
agents = json.loads(http_get("https://agentlist.com/api/listings?category=agent&limit=10"))
mcps = json.loads(http_get("https://agentlist.com/api/listings?category=mcp&limit=10"))
configs = json.loads(http_get("https://agentlist.com/api/listings?category=config&limit=10"))
paid = json.loads(http_get("https://agentlist.com/api/listings?category=paid&limit=10"))
# Sort and paginate
new_items = json.loads(http_get("https://agentlist.com/api/listings?sort=new&skip=0&limit=20"))
top_items = json.loads(http_get("https://agentlist.com/api/listings?sort=top&limit=20"))
trending_items = json.loads(http_get("https://agentlist.com/api/listings?sort=trending&limit=20"))
# Fetch one listing
listing = json.loads(http_get("https://agentlist.com/api/listings/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2"))
```
Useful fields seen on listing objects:
- `id`, `category`, `title`, `description`, `content`
- `author_pubkey`, `vote_count`, `fetch_count`, `viewer_has_voted`
- `created_at`, `updated_at`, `reviewed_at`, `reviewed_by`
- MCP/config/paid-specific fields may be present: `repo_url`, `api_spec_url`, `transport`, `package`, `tools`, `target_tool`, `config_format`, `filename_hint`, `api_base_url`, `pricing_info`, `payment_method`
## Raw Skill Content
Use `/raw/{id}` when you only need the agent-readable content, not metadata.
```python
skill_md = http_get("https://agentlist.com/raw/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2")
```
For skill-folder loaders, the hosted `skills.agentlist.com` path also works:
```python
skill_md = http_get("https://skills.agentlist.com/skill/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2/SKILL.md")
```
Detail pages display a "Load in your local or cloud based agent" box with the folder URL:
```text
https://skills.agentlist.com/skill/{id}/
```
## Browser Navigation
```python
new_tab("https://agentlist.com")
wait_for_load()
wait(1)
print(page_info())
```
The homepage is server-rendered enough to read immediately after load. It contains:
- Category buttons: `Skills`, `Agents`, `MCPs`, `Configs`, `Paid For`
- Sort controls: `Top`, `New`, `Trending`
- Search input: `input[type=search]`
- Main listing table with headers `#`, `Title`, `Author`, `Date`, `Votes`
Extract visible rows:
```python
import json
rows = json.loads(js(r"""
JSON.stringify(Array.from(document.querySelectorAll("table:first-of-type tbody tr")).map(tr => {
const cells = Array.from(tr.children).map(td => td.innerText.trim());
return {
rank: cells[0],
title_description: cells[1],
author: cells[2],
date: cells[3],
votes: cells[4]
};
}))
"""))
```
Listing title links use `/listing/{uuid}`:
```python
links = json.loads(js(r"""
JSON.stringify(Array.from(document.querySelectorAll('a[href^="/listing/"], a[href*="/listing/"]')).map(a => ({
text: a.innerText.trim(),
href: a.href
})))
"""))
```
## UI Search Gotcha
`fill_input("input[type=search]", "github")` double-entered characters during testing (`github` became `ggiitthhuubb`). Prefer direct JS value assignment plus an `input` event, or use the API.
```python
js("""
const input = document.querySelector('input[type=search]');
input.value = 'github';
input.dispatchEvent(new Event('input', {bubbles: true}));
""")
wait(1)
print(page_info()) # URL becomes https://agentlist.com/?q=github
```
## Listing Detail Pages
Detail URL pattern:
```text
https://agentlist.com/listing/{id}
```
On skill detail pages, the rendered content includes raw code blocks, API notes, discussion, and a load URL. Detail pages also keep the homepage table lower on the page, so use scoped selectors when extracting the detail body.
```python
new_tab("https://agentlist.com/listing/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2")
wait_for_load()
wait(1)
data = json.loads(js(r"""
JSON.stringify({
title: document.querySelector(".listing-title, h2")?.innerText || null,
load_urls: Array.from(document.querySelectorAll("code")).map(e => e.innerText.trim()).filter(t => t.includes("skills.agentlist.com/skill/")),
code_blocks: Array.from(document.querySelectorAll("pre, code")).map(e => e.innerText.slice(0, 300)).slice(0, 20)
})
"""))
```
The top-right user pill and `Sign out` button can appear when already authenticated. Do not assume a logged-out session.
## Submit Page
Submit URL:
```text
https://agentlist.com/submit
```
Observed fields:
- `#title` — title input
- `#description` — short description input
- `input[type=url]` — GitHub import URL
- first `textarea` — Markdown content
- `#scripts_index_html` — optional JavaScript skill payload
Observed category buttons:
```python
buttons = json.loads(js(r"""
JSON.stringify(Array.from(document.querySelectorAll("button.category-btn")).map(b => ({
text: b.innerText.trim(),
selected: b.classList.contains("selected")
})))
"""))
```
The GitHub import button is `button.btn.btn-secondary` with text `Import`. The final submit button has text `Submit listing`. Submissions are signed with the user's Nostr identity; do not submit or vote unless the user explicitly asked for that exact action.