publishport-opencli 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -61
- package/README.zh-CN.md +68 -68
- package/cli-manifest.json +502 -59
- package/clis/1688/shared.js +2 -2
- package/clis/36kr/news.js +1 -1
- package/clis/_atlassian/shared.js +1 -1
- package/clis/_shared/article/auth.js +1 -1
- package/clis/_shared/article/publish.js +1 -1
- package/clis/_shared/content-guard.js +1 -1
- package/clis/_shared/self-hosted-sites.js +2 -0
- package/clis/_shared/site-auth.js +1 -1
- package/clis/_shared/token-auth.js +2 -2
- package/clis/_shared/video-publish.js +1 -1
- package/clis/aibase/news.js +1 -1
- package/clis/amazon/shared.js +2 -2
- package/clis/antigravity/SKILL.md +12 -12
- package/clis/antigravity/storage.js +1 -1
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/archive/item.js +1 -1
- package/clis/archive/search.js +1 -1
- package/clis/archive/snapshots.js +1 -1
- package/clis/archive/wayback.js +1 -1
- package/clis/arxiv/author.js +1 -1
- package/clis/baijiahao/publish.js +1 -1
- package/clis/bbc/utils.js +1 -1
- package/clis/bloomberg/businessweek.js +1 -1
- package/clis/bloomberg/utils.js +1 -1
- package/clis/booking/search.js +1 -1
- package/clis/boss/utils.js +1 -1
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/detail.js +1 -1
- package/clis/chatgpt/history.js +1 -1
- package/clis/chatgpt/project-file-add.js +1 -1
- package/clis/chatgpt/project-list.js +1 -1
- package/clis/chatgpt/utils.js +2 -2
- package/clis/chess/utils.js +1 -1
- package/clis/claude/ask.js +1 -1
- package/clis/claude/history.js +1 -1
- package/clis/claude/utils.js +1 -1
- package/clis/codex/extract-diff.js +1 -1
- package/clis/coingecko/coin.js +1 -1
- package/clis/crates/utils.js +1 -1
- package/clis/csdn/stats.js +1 -1
- package/clis/dblp/utils.js +1 -1
- package/clis/defillama/utils.js +1 -1
- package/clis/devto/publish.js +1 -1
- package/clis/discord-app/utils.js +1 -1
- package/clis/dockerhub/utils.js +1 -1
- package/clis/douban/utils.js +1 -1
- package/clis/douyin/_shared/tos-upload.js +1 -1
- package/clis/douyin/hashtag.js +1 -1
- package/clis/douyin/publish-image.js +1 -1
- package/clis/douyin/publish.js +1 -1
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/endoflife/utils.js +1 -1
- package/clis/flathub/utils.js +1 -1
- package/clis/gemini/detail.js +1 -1
- package/clis/gemini/read.js +1 -1
- package/clis/geogebra/add-circle.js +1 -1
- package/clis/geogebra/add-line.js +1 -1
- package/clis/geogebra/add-point.js +1 -1
- package/clis/geogebra/add-polygon.js +1 -1
- package/clis/geogebra/eval.js +1 -1
- package/clis/geogebra/hexagon.js +1 -1
- package/clis/geogebra/info.js +1 -1
- package/clis/geogebra/triangle.js +1 -1
- package/clis/ghost/login.js +1 -0
- package/clis/ghost/publish.js +1 -1
- package/clis/ghost/shared.js +24 -1
- package/clis/ghost/sites.js +1 -0
- package/clis/ghost/whoami.js +1 -1
- package/clis/gitee/user.js +2 -2
- package/clis/github-trending/repos.js +1 -1
- package/clis/goproxy/utils.js +1 -1
- package/clis/grok/export-all.js +1 -1
- package/clis/grok/export.js +1 -1
- package/clis/hashnode/publish.js +1 -1
- package/clis/hf/datasets.js +1 -1
- package/clis/hf/models.js +1 -1
- package/clis/hf/paper.js +1 -1
- package/clis/hf/spaces.js +1 -1
- package/clis/homebrew/utils.js +1 -1
- package/clis/instagram/note.js +1 -1
- package/clis/jimeng/generate.js +1 -1
- package/clis/juejin/utils.js +1 -1
- package/clis/kuaishou/publish.js +1 -1
- package/clis/lesswrong/tag.js +1 -1
- package/clis/lichess/utils.js +1 -1
- package/clis/linkedin/search.js +2 -2
- package/clis/linux-do/feed.js +2 -2
- package/clis/lobsters/domain.js +1 -1
- package/clis/mastodon/login.js +1 -0
- package/clis/mastodon/post.js +1 -1
- package/clis/mastodon/shared.js +10 -10
- package/clis/mastodon/sites.js +1 -0
- package/clis/mastodon/whoami.js +1 -1
- package/clis/maven/utils.js +1 -1
- package/clis/mdn/search.js +1 -1
- package/clis/medium/tag.js +1 -1
- package/clis/notebooklm/current.js +1 -1
- package/clis/notebooklm/get.js +1 -1
- package/clis/notebooklm/history.js +1 -1
- package/clis/notebooklm/note-list.js +1 -1
- package/clis/notebooklm/notes-get.js +1 -1
- package/clis/notebooklm/open.js +1 -1
- package/clis/notebooklm/source-fulltext.js +1 -1
- package/clis/notebooklm/source-get.js +1 -1
- package/clis/notebooklm/source-guide.js +1 -1
- package/clis/notebooklm/source-list.js +1 -1
- package/clis/notebooklm/summary.js +1 -1
- package/clis/notebooklm/utils.js +1 -1
- package/clis/npm/utils.js +1 -1
- package/clis/nuget/utils.js +1 -1
- package/clis/nvd/cve.js +1 -1
- package/clis/oeis/utils.js +1 -1
- package/clis/ones/common.js +2 -2
- package/clis/ones/me.js +1 -1
- package/clis/ones/tasks.js +1 -1
- package/clis/ones/token-info.js +1 -1
- package/clis/ones/worklog.js +1 -1
- package/clis/openalex/utils.js +1 -1
- package/clis/oschina/stats.js +1 -1
- package/clis/osv/utils.js +1 -1
- package/clis/packagist/utils.js +1 -1
- package/clis/pixiv/detail.js +1 -1
- package/clis/pixiv/user.js +1 -1
- package/clis/producthunt/utils.js +1 -1
- package/clis/pypi/utils.js +1 -1
- package/clis/qiita/gql.js +2 -2
- package/clis/rest-countries/utils.js +1 -1
- package/clis/rfc/utils.js +1 -1
- package/clis/rubygems/utils.js +1 -1
- package/clis/semanticscholar/utils.js +1 -1
- package/clis/slock/errors.js +1 -1
- package/clis/spotify/spotify.js +1 -1
- package/clis/spotify/utils.js +1 -1
- package/clis/stackoverflow/utils.js +1 -1
- package/clis/steam/utils.js +1 -1
- package/clis/substack/auth.js +2 -2
- package/clis/suno/generate.js +2 -2
- package/clis/suno/list.js +3 -3
- package/clis/telegram/send.js +1 -1
- package/clis/tiktok/creator-videos.js +1 -1
- package/clis/tiktok/publish.js +1 -1
- package/clis/tiktok/utils.js +1 -1
- package/clis/trae-cn/activity.js +1 -1
- package/clis/trae-cn/approve.js +1 -1
- package/clis/trae-cn/ask.js +1 -1
- package/clis/trae-cn/dump.js +1 -1
- package/clis/trae-cn/export.js +1 -1
- package/clis/trae-cn/model.js +1 -1
- package/clis/trae-cn/new.js +1 -1
- package/clis/trae-cn/read.js +1 -1
- package/clis/trae-cn/screenshot.js +1 -1
- package/clis/trae-cn/select-model.js +1 -1
- package/clis/trae-cn/send.js +1 -1
- package/clis/trae-cn/setup.js +1 -1
- package/clis/trae-cn/status.js +1 -1
- package/clis/trae-cn/targets.js +1 -1
- package/clis/trae-cn/watch.js +1 -1
- package/clis/trae-solo/state-fs.js +1 -1
- package/clis/tumblr/publish.js +1 -1
- package/clis/tvmaze/utils.js +1 -1
- package/clis/twitter/bookmark-folder.js +1 -1
- package/clis/twitter/download.js +1 -1
- package/clis/twitter/followers.js +2 -2
- package/clis/twitter/following.js +2 -2
- package/clis/twitter/likes.js +1 -1
- package/clis/twitter/list-add-batch.js +1 -1
- package/clis/twitter/list-add-core.js +1 -1
- package/clis/twitter/list-add.js +1 -1
- package/clis/twitter/list-create.js +1 -1
- package/clis/twitter/list-delete.js +3 -3
- package/clis/twitter/list-remove-batch.js +1 -1
- package/clis/twitter/list-remove.js +1 -1
- package/clis/twitter/list-tweets.js +1 -1
- package/clis/twitter/profile.js +1 -1
- package/clis/twitter/search.js +1 -1
- package/clis/twitter/shared.js +1 -1
- package/clis/twitter/tweets.js +1 -1
- package/clis/uisdc/news.js +1 -1
- package/clis/v2ex/daily.js +2 -2
- package/clis/v2ex/me.js +2 -2
- package/clis/v2ex/notifications.js +1 -1
- package/clis/wikidata/utils.js +1 -1
- package/clis/wikipedia/page.js +2 -2
- package/clis/wikipedia/summary.js +1 -1
- package/clis/wikipedia/utils.js +1 -1
- package/clis/wordpress/login.js +1 -1
- package/clis/wordpress/publish.js +1 -1
- package/clis/wordpress/shared.js +3 -3
- package/clis/wordpress/sites.js +1 -0
- package/clis/wordpress/whoami.js +1 -1
- package/clis/woshipm/stats.js +1 -1
- package/clis/xiaoe/content.js +1 -1
- package/clis/xiaohongshu/draft-delete.js +1 -1
- package/clis/xiaohongshu/draft-open.js +1 -1
- package/clis/xiaohongshu/draft-utils.js +2 -2
- package/clis/xiaohongshu/publish-video.js +1 -1
- package/clis/xiaohongshu/publish.js +1 -1
- package/clis/xiaoyuzhou/auth.js +1 -1
- package/clis/xiaoyuzhou/transcript.js +1 -1
- package/clis/yollomi/background.js +1 -1
- package/clis/yollomi/edit.js +1 -1
- package/clis/yollomi/generate.js +1 -1
- package/clis/yollomi/try-on.js +1 -1
- package/clis/youtube/publish.js +1 -1
- package/clis/zhihu/answer-comments.js +1 -1
- package/clis/zhihu/answer-detail.js +1 -1
- package/clis/zhihu/collection.js +2 -2
- package/clis/zhihu/collections.js +1 -1
- package/clis/zhihu/question.js +1 -1
- package/clis/zhihu/search.js +1 -1
- package/clis/zhihu/target.js +1 -1
- package/clis/zhihu/user-arg.js +1 -1
- package/dist/src/adapter-shadow.js +1 -1
- package/dist/src/browser/analyze.js +1 -1
- package/dist/src/browser/article-extract.d.ts +1 -1
- package/dist/src/browser/base-page.js +3 -3
- package/dist/src/browser/cdp.js +1 -1
- package/dist/src/browser/daemon-client.d.ts +1 -1
- package/dist/src/browser/daemon-lifecycle.js +6 -6
- package/dist/src/browser/daemon-version.js +1 -1
- package/dist/src/browser/dom-snapshot.d.ts +1 -1
- package/dist/src/browser/dom-snapshot.js +2 -2
- package/dist/src/browser/errors.js +2 -2
- package/dist/src/browser/network-cache.js +1 -1
- package/dist/src/browser/profile.js +1 -1
- package/dist/src/browser/target-resolver.js +4 -4
- package/dist/src/browser/verify-fixture.js +1 -1
- package/dist/src/browser-session-lock.js +1 -1
- package/dist/src/build-manifest.d.ts +1 -1
- package/dist/src/build-manifest.js +1 -1
- package/dist/src/cli-argv-preprocess.d.ts +4 -4
- package/dist/src/cli-argv-preprocess.js +1 -1
- package/dist/src/cli.d.ts +1 -1
- package/dist/src/cli.js +19 -19
- package/dist/src/commanderAdapter.js +1 -1
- package/dist/src/commands/auth.js +2 -2
- package/dist/src/commands/daemon.d.ts +4 -4
- package/dist/src/commands/daemon.js +1 -1
- package/dist/src/completion-shared.js +12 -12
- package/dist/src/completion.d.ts +2 -2
- package/dist/src/constants.d.ts +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/daemon-utils.d.ts +1 -1
- package/dist/src/daemon-utils.js +1 -1
- package/dist/src/daemon.d.ts +2 -2
- package/dist/src/daemon.js +1 -1
- package/dist/src/discovery.d.ts +7 -7
- package/dist/src/discovery.js +2 -2
- package/dist/src/doctor.d.ts +1 -1
- package/dist/src/doctor.js +6 -6
- package/dist/src/electron-apps.d.ts +1 -1
- package/dist/src/electron-apps.js +1 -1
- package/dist/src/errors.d.ts +2 -2
- package/dist/src/errors.js +1 -1
- package/dist/src/execution.js +1 -1
- package/dist/src/external.d.ts +1 -1
- package/dist/src/external.js +1 -1
- package/dist/src/help.d.ts +1 -1
- package/dist/src/help.js +3 -3
- package/dist/src/hooks.d.ts +1 -1
- package/dist/src/launcher.js +2 -2
- package/dist/src/logger.d.ts +1 -1
- package/dist/src/main.d.ts +1 -1
- package/dist/src/main.js +1 -1
- package/dist/src/observation/artifact.js +2 -2
- package/dist/src/package-paths.js +1 -1
- package/dist/src/package-paths.test.d.ts +1 -0
- package/dist/src/plugin-manifest.d.ts +12 -3
- package/dist/src/plugin-manifest.js +1 -1
- package/dist/src/plugin-scaffold.d.ts +2 -2
- package/dist/src/plugin-scaffold.js +9 -9
- package/dist/src/plugin.d.ts +4 -4
- package/dist/src/plugin.js +10 -10
- package/dist/src/rate-limit.js +1 -1
- package/dist/src/registry-api.d.ts +1 -1
- package/dist/src/runtime-detect.d.ts +1 -1
- package/dist/src/serialization.js +1 -1
- package/dist/src/skills.js +6 -6
- package/dist/src/user-runtime.d.ts +8 -0
- package/dist/src/user-runtime.js +1 -0
- package/dist/src/user-runtime.test.d.ts +1 -0
- package/dist/src/validate.js +1 -1
- package/dist/src/validate.test.d.ts +1 -1
- package/docs/guide/browser-bridge.md +23 -23
- package/docs/guide/electron-app-cli.md +3 -3
- package/docs/guide/exit-codes.md +3 -3
- package/docs/guide/extending-opencli.md +37 -37
- package/docs/guide/getting-started.md +19 -19
- package/docs/guide/installation.md +6 -6
- package/docs/guide/plugins.md +32 -32
- package/docs/guide/remote-orchestration.md +5 -5
- package/docs/guide/troubleshooting.md +9 -9
- package/package.json +3 -2
- package/scripts/fetch-adapters.js +6 -6
- package/scripts/postinstall.js +14 -14
- package/skills/opencli-adapter-author/SKILL.md +24 -24
- package/skills/opencli-adapter-author/references/adapter-template.md +13 -13
- package/skills/opencli-adapter-author/references/api-discovery.md +25 -25
- package/skills/opencli-adapter-author/references/coverage-matrix.md +3 -3
- package/skills/opencli-adapter-author/references/field-decode-playbook.md +10 -10
- package/skills/opencli-adapter-author/references/jsdom-fixture-pattern.md +2 -2
- package/skills/opencli-adapter-author/references/site-memory.md +11 -11
- package/skills/opencli-adapter-author/references/site-recon.md +7 -7
- package/skills/opencli-adapter-author/references/strategy-selection.md +3 -3
- package/skills/opencli-adapter-author/references/success-rate-pitfalls.md +4 -4
- package/skills/opencli-adapter-author/references/typed-errors.md +2 -2
- package/skills/opencli-autofix/SKILL.md +29 -29
- package/skills/opencli-browser/SKILL.md +55 -55
- package/skills/opencli-browser-sitemap/SKILL.md +7 -7
- package/skills/opencli-sitemap-author/SKILL.md +11 -11
- package/skills/opencli-sitemap-author/references/sitemap-schema.md +19 -19
- package/skills/opencli-usage/SKILL.md +43 -43
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opencli-browser
|
|
3
|
-
description: Use when an agent needs to drive a real Chrome window via
|
|
4
|
-
allowed-tools: Bash(
|
|
3
|
+
description: Use when an agent needs to drive a real Chrome window via ppcli — inspect a page, fill forms, click through logged-in flows, or extract data ad-hoc. Covers the selector-first target contract, compound form fields, stale-ref handling, network capture, and the agent-native envelopes the CLI returns. Not for writing adapters — see opencli-adapter-author for that.
|
|
4
|
+
allowed-tools: Bash(ppcli:*), Read, Edit, Write
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# opencli-browser
|
|
8
8
|
|
|
9
9
|
The first reader of this CLI is an agent, not a human. Every subcommand returns a structured envelope that tells you exactly what matched, how confident the match is, and what to do if it didn't. Lean on those envelopes — do not guess.
|
|
10
10
|
|
|
11
|
-
This skill is for **driving a live browser** to accomplish an agent task. If you are building a reusable adapter under `~/.
|
|
11
|
+
This skill is for **driving a live browser** to accomplish an agent task. If you are building a reusable adapter under `~/.ppcli/clis/<site>/` use `opencli-adapter-author` instead.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Prerequisites
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
18
|
+
ppcli doctor
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Until `doctor` is green, nothing else will work. Typical failures: Chrome not running, extension not installed, debug port blocked by 1Password / other extensions. The doctor output tells you which.
|
|
@@ -24,27 +24,27 @@ Until `doctor` is green, nothing else will work. Typical failures: Chrome not ru
|
|
|
24
24
|
|
|
25
25
|
## Session lifecycle
|
|
26
26
|
|
|
27
|
-
- `
|
|
28
|
-
- Use a stable session name for any multi-command or human-paced browser workflow. Example: `
|
|
29
|
-
- Owned browser sessions keep a tab lease alive between calls. Release it with `
|
|
30
|
-
- `
|
|
31
|
-
- `--window foreground|background` (or `OPENCLI_WINDOW=foreground|background`) chooses whether
|
|
27
|
+
- `ppcli browser *` commands require a `<session>` positional immediately after `browser`. Use the same session name for a multi-step flow; use a different name to isolate parallel browser work.
|
|
28
|
+
- Use a stable session name for any multi-command or human-paced browser workflow. Example: `ppcli browser fb-yaya-warmup open https://example.com`, then reuse `ppcli browser fb-yaya-warmup state`, `extract`, `click`, etc.
|
|
29
|
+
- Owned browser sessions keep a tab lease alive between calls. Release it with `ppcli browser <session> close` or let the idle timeout expire.
|
|
30
|
+
- `ppcli browser <session> bind` binds the Chrome tab you already have open to that session. Use this for logged-in pages, SSO flows, or pages you manually positioned before handing control to the agent.
|
|
31
|
+
- `--window foreground|background` (or `OPENCLI_WINDOW=foreground|background`) chooses whether ppcli creates/focuses a foreground browser window or uses a background browser window for owned sessions.
|
|
32
32
|
|
|
33
33
|
### Bind Tab
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
ppcli browser gmail bind
|
|
37
|
+
ppcli browser gmail state
|
|
38
|
+
ppcli browser gmail click "Search"
|
|
39
|
+
ppcli browser gmail network
|
|
40
|
+
ppcli browser gmail unbind
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Binding never owns the user window and never closes the user tab. It fails closed if the tab is closed or becomes non-debuggable. Re-run `
|
|
43
|
+
Binding never owns the user window and never closes the user tab. It fails closed if the tab is closed or becomes non-debuggable. Re-run `ppcli browser <session> bind` when you switch to a different real tab.
|
|
44
44
|
|
|
45
|
-
Navigation is allowed on bound sessions because the session now represents explicit agent ownership of that tab. Tab mutation (`tab new`, `tab select`, `tab close`) is still blocked for bound sessions. Use an owned session when you want
|
|
45
|
+
Navigation is allowed on bound sessions because the session now represents explicit agent ownership of that tab. Tab mutation (`tab new`, `tab select`, `tab close`) is still blocked for bound sessions. Use an owned session when you want ppcli to manage tab lifecycle.
|
|
46
46
|
|
|
47
|
-
Bound sessions have no
|
|
47
|
+
Bound sessions have no ppcli idle-close timer; the binding lasts until `unbind`, tab close, window close, or daemon restart.
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
@@ -60,7 +60,7 @@ Bound sessions have no OpenCLI idle-close timer; the binding lasts until `unbind
|
|
|
60
60
|
## Critical rules
|
|
61
61
|
|
|
62
62
|
1. **Always inspect before you act.** Run `state` or `find` first. Never hard-code a ref or selector from memory across sessions — indices are per-snapshot.
|
|
63
|
-
2. **Prefer site adapters before raw browser driving.** If `
|
|
63
|
+
2. **Prefer site adapters before raw browser driving.** If `ppcli <site> <command>` already covers the task, use that adapter command first (`ppcli facebook notifications`, `ppcli reddit read`, etc.). Use `ppcli browser ...` only for gaps, debugging, or one-off UI flows the adapter does not expose.
|
|
64
64
|
3. **Prefer numeric ref over CSS once you have it.** Numeric refs survive mild DOM shifts because the CLI fingerprints each tagged element. A CSS selector written by hand will break the first time the site re-renders.
|
|
65
65
|
4. **Read `match_level` after every write.** `exact` = all good. `stable` = the element is the same but some soft attrs drifted — your action still applied. `reidentified` = the original ref was gone and the CLI found a unique replacement; double-check you hit the right element.
|
|
66
66
|
5. **Use the `compound` field for form controls.** Do not regex-guess a date format, do not `state` twice to get the full `<select>` options list. The compound envelope has the format string, full option list up to 50, `options_total` for overflow, and `accept`/`multiple` for `<input type=file>`.
|
|
@@ -187,9 +187,9 @@ Error envelope always includes `error.code` and `error.message`. Target errors (
|
|
|
187
187
|
4. 看回读的 `after`:验证码消失 / URL 跳转 = 成功;仍在且 prompt 变了 = 认错刷新了要重来;仍在且 prompt 没变 = 可能漏点,补点。
|
|
188
188
|
|
|
189
189
|
```bash
|
|
190
|
-
|
|
190
|
+
ppcli browser pub captcha --scale 4 # 存 crop 裁剪图 + 返回 prompt
|
|
191
191
|
# —— 你读 crop 图:prompt="铃却挂"(另有干扰字别点),读出三个字在图里的比例 ——
|
|
192
|
-
|
|
192
|
+
ppcli browser pub captcha-click --crop --in ".js-mocaptcha-img" "0.24,0.17 0.69,0.38 0.82,0.36"
|
|
193
193
|
```
|
|
194
194
|
|
|
195
195
|
提醒:验证码识别靠视觉,扭曲字**可能认错**(尤其岩石/云等低对比背景、生僻复杂字)——背景太乱认不清就点刷新按钮换一张(`.js-mocaptcha-refresh` 之类,刷新不提交、无害,多数会换到干净背景)。别短时间反复猛试同一账号(会抬高风控/被判异常),一两次不过就退回让用户手动点。
|
|
@@ -213,7 +213,7 @@ state, elapsedMs}` on success and a JSON error envelope on timeout/failure.
|
|
|
213
213
|
|
|
214
214
|
### Extract
|
|
215
215
|
|
|
216
|
-
- **`web read --url <url>`** — One-shot Markdown reader for arbitrary pages. It expands relevant same-origin iframes by default, so old iframe-shell sites work better than with a top-document-only scrape. Use `--frames all-same-origin` when completeness matters more than Markdown noise. For AJAX shell pages use `
|
|
216
|
+
- **`web read --url <url>`** — One-shot Markdown reader for arbitrary pages. It expands relevant same-origin iframes by default, so old iframe-shell sites work better than with a top-document-only scrape. Use `--frames all-same-origin` when completeness matters more than Markdown noise. For AJAX shell pages use `ppcli web read --url <url> --wait-for "<selector>" --wait-until networkidle --diagnose`; diagnostics show frame URLs, empty containers, and API-like XHRs. If the value you need is table/API data, switch to `browser network` or a dedicated adapter instead of relying on Markdown.
|
|
217
217
|
- **`browser eval <js> [--frame N]`** — Run an expression in the page (or in a cross-origin frame via `--frame`). Wrap in an IIFE and return JSON. Read-only: no `document.forms[0].submit()`, no clicks, no navigations. If the result is a string, stdout is the raw string; otherwise it's JSON.
|
|
218
218
|
- **`browser extract [--selector <css>] [--chunk-size N] [--start N]`** — Markdown extraction of long-form content with a continuation cursor. Returns `{url, title, selector, total_chars, chunk_size, start, end, next_start_char, content}`. Loop on `next_start_char` until it is `null`. Auto-scopes to `<main>`/`<article>`/`<body>` if you don't pass `--selector`.
|
|
219
219
|
|
|
@@ -228,7 +228,7 @@ browser network --raw # full bodies inline — large; use spari
|
|
|
228
228
|
browser network --ttl <ms> # cache TTL (default 24h)
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
List entries look like `{key, method, status, url, ct, size, shape, body_truncated?}`. Detail envelope is `{key, url, method, status, ct, size, shape, body, body_truncated?, body_full_size?, body_truncation_reason}`. Cache lives in `~/.
|
|
231
|
+
List entries look like `{key, method, status, url, ct, size, shape, body_truncated?}`. Detail envelope is `{key, url, method, status, ct, size, shape, body, body_truncated?, body_full_size?, body_truncation_reason}`. Cache lives in `~/.ppcli/cache/browser-network/` so you can re-inspect without re-triggering the request.
|
|
232
232
|
|
|
233
233
|
Default output keeps JSON/XML/plain-text and JS-like API responses, then drops obvious static assets and telemetry by URL. If an expected endpoint is missing, run `browser network --all` once and check whether an unusual content type or URL filter hid it.
|
|
234
234
|
|
|
@@ -331,9 +331,9 @@ Rule of thumb: **one `state` per page transition, one `find` per follow-up query
|
|
|
331
331
|
**Good — one shell, live session:**
|
|
332
332
|
|
|
333
333
|
```bash
|
|
334
|
-
|
|
335
|
-
&&
|
|
336
|
-
&&
|
|
334
|
+
ppcli browser hn open "https://news.ycombinator.com" \
|
|
335
|
+
&& ppcli browser hn state \
|
|
336
|
+
&& ppcli browser hn click 3
|
|
337
337
|
```
|
|
338
338
|
|
|
339
339
|
**Bad — each line is a fresh shell, refs from call 1 are already forgotten when call 2 runs.** (Only a problem if you rely on shell-scoped state; browser refs themselves persist in-page, but interleaving unrelated shells invites races.) Prefer `&&` when the steps are meant to be atomic.
|
|
@@ -347,24 +347,24 @@ opencli browser hn open "https://news.ycombinator.com" \
|
|
|
347
347
|
### Fill a login form
|
|
348
348
|
|
|
349
349
|
```bash
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
350
|
+
ppcli browser login open "https://example.com/login"
|
|
351
|
+
ppcli browser login state # find [N] for email, password, submit
|
|
352
|
+
ppcli browser login type 4 "me@example.com"
|
|
353
|
+
ppcli browser login type 5 "hunter2"
|
|
354
|
+
ppcli browser login get value 4 # verify (autocomplete can eat chars)
|
|
355
|
+
ppcli browser login click 6 # submit
|
|
356
|
+
ppcli browser login wait selector "[data-testid=account-menu]" --timeout 15000
|
|
357
|
+
ppcli browser login state # fresh refs on the logged-in page
|
|
358
358
|
```
|
|
359
359
|
|
|
360
360
|
### Pick from a long dropdown
|
|
361
361
|
|
|
362
362
|
```bash
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
ppcli browser form state # sidebar shows [12] <select name=country>
|
|
364
|
+
ppcli browser form find --css "select[name=country]"
|
|
365
365
|
# the compound.options_total is 137, but compound.current is "" — unselected.
|
|
366
|
-
|
|
367
|
-
|
|
366
|
+
ppcli browser form select 12 "Uruguay"
|
|
367
|
+
ppcli browser form get value 12 # { value: "uy", match_level: "exact" }
|
|
368
368
|
```
|
|
369
369
|
|
|
370
370
|
### Pick from a custom React dropdown
|
|
@@ -373,13 +373,13 @@ Use this for Radix, shadcn, Material UI, Mercury-style category fields, and
|
|
|
373
373
|
other controls that are not native `<select>`.
|
|
374
374
|
|
|
375
375
|
```bash
|
|
376
|
-
|
|
376
|
+
ppcli browser mercury state # find category trigger ref
|
|
377
377
|
# If the trigger/option is not clear, use AX:
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
378
|
+
ppcli browser mercury state --source ax # look for combobox/button/listbox/option names
|
|
379
|
+
ppcli browser mercury click 7 # click category trigger
|
|
380
|
+
ppcli browser mercury state --source ax # fresh refs after the portal/listbox opens
|
|
381
|
+
ppcli browser mercury click 12 # click option
|
|
382
|
+
ppcli browser mercury get text 7 # verify visible selected label
|
|
383
383
|
```
|
|
384
384
|
|
|
385
385
|
Do not use `browser select` on these widgets. `browser select` is only for
|
|
@@ -392,7 +392,7 @@ When deciding whether AX refs are better for a page, collect metrics without
|
|
|
392
392
|
sharing page contents:
|
|
393
393
|
|
|
394
394
|
```bash
|
|
395
|
-
|
|
395
|
+
ppcli browser compare state --compare-sources
|
|
396
396
|
```
|
|
397
397
|
|
|
398
398
|
Report `sources.dom.refs`, `sources.ax.refs`, `frame_sections`,
|
|
@@ -402,28 +402,28 @@ arguing that AX should become the default on a site.
|
|
|
402
402
|
### Scrape a list via network instead of DOM
|
|
403
403
|
|
|
404
404
|
```bash
|
|
405
|
-
|
|
406
|
-
|
|
405
|
+
ppcli browser hn open "https://news.ycombinator.com"
|
|
406
|
+
ppcli browser hn network --filter "title,score"
|
|
407
407
|
# -> find the /topstories entry, note its key
|
|
408
|
-
|
|
408
|
+
ppcli browser hn network --detail topstories-a1b2
|
|
409
409
|
```
|
|
410
410
|
|
|
411
411
|
### Read a long article in chunks
|
|
412
412
|
|
|
413
413
|
```bash
|
|
414
|
-
|
|
415
|
-
|
|
414
|
+
ppcli browser article open "https://blog.example.com/long-post"
|
|
415
|
+
ppcli browser article extract --chunk-size 8000
|
|
416
416
|
# -> content + next_start_char: 8000
|
|
417
|
-
|
|
417
|
+
ppcli browser article extract --start 8000 --chunk-size 8000
|
|
418
418
|
# ...until next_start_char is null
|
|
419
419
|
```
|
|
420
420
|
|
|
421
421
|
### Cross-origin iframe
|
|
422
422
|
|
|
423
423
|
```bash
|
|
424
|
-
|
|
424
|
+
ppcli browser checkout frames
|
|
425
425
|
# -> [{"index": 0, "url": "https://checkout.stripe.com/...", ...}]
|
|
426
|
-
|
|
426
|
+
ppcli browser checkout eval "(() => document.querySelector('input[name=cardnumber]')?.value)()" --frame 0
|
|
427
427
|
```
|
|
428
428
|
|
|
429
429
|
`browser state --source ax` may omit cross-origin iframe contents or fail to
|
|
@@ -449,20 +449,20 @@ normal DOM `state`, or navigate/bind directly to the iframe URL when possible.
|
|
|
449
449
|
|
|
450
450
|
| symptom | fix |
|
|
451
451
|
|---------|-----|
|
|
452
|
-
| `
|
|
452
|
+
| `ppcli doctor` red: "Browser not connected" | Start Chrome with `--remote-debugging-port=9222`, or install the extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/opencli/ildkmabpimmkaediidaifkhjpohdnifk). |
|
|
453
453
|
| `attach failed: chrome-extension://...` | Disable 1Password / other CDP-hungry extensions temporarily. |
|
|
454
454
|
| `selector_not_found` right after `state` | Page mutated. `wait selector "..."` then retry. |
|
|
455
455
|
| `stale_ref` across every command | You are reusing refs from a prior page. Re-`state`. |
|
|
456
456
|
| `click` succeeds but nothing happens | The element is probably a decorative wrapper stealing clicks from the real target. `find --css "..."` with a narrower selector and retry on the inner element. |
|
|
457
457
|
| `type` appears to finish but value is wrong | Autocomplete, masked input, or React controlled re-render. Verify with `get value`. Add `keys Enter` or re-type. |
|
|
458
458
|
| Giant `get html` output | Pass `--selector` + `--as json --depth 3 --children-max 20 --text-max 200`. |
|
|
459
|
-
| Network cache seems stale | Bump `--ttl` down, or let it expire. The cache lives at `~/.
|
|
459
|
+
| Network cache seems stale | Bump `--ttl` down, or let it expire. The cache lives at `~/.ppcli/cache/browser-network/`. |
|
|
460
460
|
|
|
461
461
|
---
|
|
462
462
|
|
|
463
463
|
## See also
|
|
464
464
|
|
|
465
|
-
- `opencli-adapter-author` — turning what you just figured out into a reusable `~/.
|
|
465
|
+
- `opencli-adapter-author` — turning what you just figured out into a reusable `~/.ppcli/clis/<site>/<command>.js`.
|
|
466
466
|
- `opencli-browser-sitemap` — consuming site sitemap context while driving a browser task.
|
|
467
467
|
- `opencli-sitemap-author` — creating or updating sitemap knowledge when you discover a durable path or stale entry.
|
|
468
468
|
- `opencli-autofix` — when an existing adapter breaks, this skill walks you through `--trace retain-on-failure` evidence and filing a fix.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opencli-browser-sitemap
|
|
3
|
-
description: Use when driving a website with
|
|
4
|
-
allowed-tools: Bash(
|
|
3
|
+
description: Use when driving a website with ppcli browser and sitemap context is available, requested, or needed to avoid blind navigation. Guides agents to consume site sitemap files lazily, choose adapter/browser fallback paths, resume from state signatures, and mark stale sitemap entries without trusting them over live browser state.
|
|
4
|
+
allowed-tools: Bash(ppcli:*), Read, Edit, Write, Grep
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# opencli-browser-sitemap
|
|
8
8
|
|
|
9
|
-
Use this skill when `
|
|
9
|
+
Use this skill when `ppcli browser open` or `ppcli browser analyze` reports `sitemap.available: true`, or when the user asks you to use a site's sitemap.
|
|
10
10
|
|
|
11
11
|
The sitemap is **prior knowledge**, not ground truth. It should reduce blind clicking, but it must never override the live browser state.
|
|
12
12
|
|
|
@@ -14,13 +14,13 @@ The sitemap is **prior knowledge**, not ground truth. It should reduce blind cli
|
|
|
14
14
|
|
|
15
15
|
## Consumption Loop
|
|
16
16
|
|
|
17
|
-
1. Run or reuse `
|
|
17
|
+
1. Run or reuse `ppcli browser <session> state` to know the current page.
|
|
18
18
|
2. Read only the smallest relevant sitemap files:
|
|
19
19
|
- `SITE.md` for site-level orientation.
|
|
20
20
|
- One matching `pages/<page-id>.md` for current state.
|
|
21
21
|
- One matching `workflows/<task-id>.md` for the user goal.
|
|
22
22
|
- `pitfalls.md` only when blocked or warned by the workflow.
|
|
23
|
-
3. Prefer the workflow's **Best path**. If it names an adapter such as `
|
|
23
|
+
3. Prefer the workflow's **Best path**. If it names an adapter such as `ppcli twitter post`, use that before raw browser actions.
|
|
24
24
|
4. If the adapter is unavailable or fails, use the **Fallback path** browser workflow.
|
|
25
25
|
5. After each navigation or state-changing action, refresh `state` and compare the workflow's `state_signature`.
|
|
26
26
|
6. If reality disagrees, trust reality, continue probing, and write a local stale note or draft patch.
|
|
@@ -33,7 +33,7 @@ The sitemap is **prior knowledge**, not ground truth. It should reduce blind cli
|
|
|
33
33
|
Read local overlay first, then global seed:
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
~/.
|
|
36
|
+
~/.ppcli/sites/<site>/sitemap/ # local overlay
|
|
37
37
|
sitemaps/<site>/ # repo seed (top-level)
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -75,7 +75,7 @@ Do not edit global seed files unless the task is explicitly a sitemap-authoring
|
|
|
75
75
|
|
|
76
76
|
When an adapter fails and the sitemap action or workflow tells you to update adapter health:
|
|
77
77
|
|
|
78
|
-
1. Find the local workflow file under `~/.
|
|
78
|
+
1. Find the local workflow file under `~/.ppcli/sites/<site>/sitemap/workflows/` whose `Best path` references the adapter command.
|
|
79
79
|
2. If no local workflow exists, copy the matching global workflow into the local overlay first; never edit the global seed directly during browser task execution.
|
|
80
80
|
3. Set `adapter_health: suspect` or `broken` as directed.
|
|
81
81
|
4. Add a short stale note with observed error, current URL, and timestamp.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: opencli-sitemap-author
|
|
3
|
-
description: Use when creating or maintaining
|
|
4
|
-
allowed-tools: Bash(
|
|
3
|
+
description: Use when creating or maintaining ppcli site sitemaps: agent-facing navigation, page-state, action, workflow, API-reference, pitfall, and fallback knowledge for a website. Use after browser exploration discovers durable site context, when a sitemap is stale, or when promoting local site knowledge into the repo.
|
|
4
|
+
allowed-tools: Bash(ppcli:*), Read, Edit, Write, Grep
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# opencli-sitemap-author
|
|
8
8
|
|
|
9
|
-
You are authoring a **task execution graph for agents**, not an SEO sitemap. The artifact should help an agent using `
|
|
9
|
+
You are authoring a **task execution graph for agents**, not an SEO sitemap. The artifact should help an agent using `ppcli browser` decide where it is, what path to take next, which ppcli adapter to prefer, and how to recover when the page disagrees with memory.
|
|
10
10
|
|
|
11
11
|
Keep the sitemap small and verified. Do not crawl a whole site. Capture only task-relevant paths that you actually observed.
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ Keep the sitemap small and verified. Do not crawl a whole site. Capture only tas
|
|
|
17
17
|
Two layers:
|
|
18
18
|
|
|
19
19
|
- **Global seed**: `sitemaps/<site>/` (top-level)
|
|
20
|
-
- **Local overlay**: `~/.
|
|
20
|
+
- **Local overlay**: `~/.ppcli/sites/<site>/sitemap/`
|
|
21
21
|
|
|
22
22
|
Local overlay wins by stable id. Write new discoveries to local first. Promote to global only after review.
|
|
23
23
|
|
|
@@ -51,10 +51,10 @@ Phase 2 cron audit 按 token count 不按 byte count(CJK 中文 token-per-char
|
|
|
51
51
|
## Authoring Loop
|
|
52
52
|
|
|
53
53
|
1. **Load existing memory**: read local overlay first, then global seed if present.
|
|
54
|
-
2. **Verify reality**: use `
|
|
54
|
+
2. **Verify reality**: use `ppcli browser <session> state`, `find`, `network`, and `analyze`; browser state is truth. If you just completed an `opencli-adapter-author` session for this site, start from the retained browse trace under `~/.ppcli/sites/<site>/traces/` as seed evidence instead of re-discovering the path from zero.
|
|
55
55
|
3. **Record only durable structure**: page purpose, stable anchors, state signature, actions, workflows, API references, pitfalls.
|
|
56
56
|
4. **Use stable ids**: page/action/workflow ids should survive URL params, locale text drift, and minor layout changes.
|
|
57
|
-
5. **Write local draft**: update `~/.
|
|
57
|
+
5. **Write local draft**: update `~/.ppcli/sites/<site>/sitemap/...` unless explicitly promoting to repo.
|
|
58
58
|
6. **Mark stale on conflict**: if existing sitemap disagrees with current browser state, trust browser state and mark the item stale rather than forcing the old path.
|
|
59
59
|
|
|
60
60
|
---
|
|
@@ -70,7 +70,7 @@ do: <agent action, adapter command, or semantic browser command>
|
|
|
70
70
|
post: <URL / state / output that proves success>
|
|
71
71
|
fail: <failure signal 1> | <signal 2>
|
|
72
72
|
recover: <fallback instruction>; adapter_health_update: <adapter> -> suspect
|
|
73
|
-
evidence:
|
|
73
|
+
evidence: ppcli browser <cmd> or trace:<path>
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Use this compact form by default. Use the longer Markdown form from `references/sitemap-schema.md` only when an action genuinely needs long explanation. `verified_at` and `source` are inherited from file frontmatter; do not repeat them per action.
|
|
@@ -106,7 +106,7 @@ Each workflow should answer:
|
|
|
106
106
|
|
|
107
107
|
- **Goal**: user-facing task this workflow solves.
|
|
108
108
|
- **State signature**: minimal observable checkpoint for resume after sleep/compaction.
|
|
109
|
-
- **Best path**: prefer existing `
|
|
109
|
+
- **Best path**: prefer existing `ppcli <site> <command>` adapter if it covers the goal.
|
|
110
110
|
- **Fallback path**: browser workflow if the adapter is missing or failing.
|
|
111
111
|
- **Avoid**: tempting paths that waste turns, trigger modals, or rely on unstable selectors.
|
|
112
112
|
- **Stale markers**: last verified date and known layout/API drift signals.
|
|
@@ -119,8 +119,8 @@ Fallback path 第一行声明触发条件 + adapter_health_update directive,
|
|
|
119
119
|
|
|
120
120
|
```yaml
|
|
121
121
|
on_adapter_fail:
|
|
122
|
-
- adapter_health_update:
|
|
123
|
-
-
|
|
122
|
+
- adapter_health_update: ppcli twitter post -> suspect
|
|
123
|
+
- ppcli browser state (verify current page)
|
|
124
124
|
- if not on /home: goto /home
|
|
125
125
|
- action:open_compose in pages/home.md
|
|
126
126
|
- ...
|
|
@@ -152,7 +152,7 @@ on_adapter_fail:
|
|
|
152
152
|
- Do not document bypasses for CAPTCHA, WAF, access control, rate limits, or paid gates.
|
|
153
153
|
- Do not store brittle snapshot indices like `[17]` as durable targets. Store semantic anchors and recovery instructions.
|
|
154
154
|
- Do not describe unverified paths as facts. Use `draft` or `stale` labels.
|
|
155
|
-
- Drafts go inside `sitemap/draft-<topic>.md`, not `~/.
|
|
155
|
+
- Drafts go inside `sitemap/draft-<topic>.md`, not `~/.ppcli/sites/<site>/sitemap.draft.md` at the parent level — the latter is invisible to `ppcli browser` sitemap availability detection.
|
|
156
156
|
|
|
157
157
|
---
|
|
158
158
|
|
|
@@ -215,7 +215,7 @@ Create a new public post on this site with text content.
|
|
|
215
215
|
- success: post visible on author's timeline within 5s
|
|
216
216
|
|
|
217
217
|
## Best path
|
|
218
|
-
adapter:
|
|
218
|
+
adapter: ppcli twitter post
|
|
219
219
|
adapter_health: healthy # healthy | suspect | broken
|
|
220
220
|
preconditions:
|
|
221
221
|
- logged_in
|
|
@@ -297,7 +297,7 @@ source: local
|
|
|
297
297
|
```
|
|
298
298
|
|
|
299
299
|
**Required per entry**:
|
|
300
|
-
- `endpoint_id` — 必须存在于同站 `~/.
|
|
300
|
+
- `endpoint_id` — 必须存在于同站 `~/.ppcli/sites/<site>/endpoints.json`
|
|
301
301
|
- `triggers_on_pages` — array of `page_id`
|
|
302
302
|
- `triggered_by_actions` — array of `action:<stable-id>`
|
|
303
303
|
- `contract_strength` — `stable | visible-ui | internal-unstable`,定义见 `strategy-selection.md`
|
|
@@ -350,7 +350,7 @@ verified_at: 2026-06-01
|
|
|
350
350
|
|
|
351
351
|
#### Scope(避免 sitemap 变杂物间)
|
|
352
352
|
|
|
353
|
-
`pitfalls.md` 只放 **task-executor 级**坑 — 跑命令 / 操作页面会撞到的坑。**adapter-internal 实现坑**(queryId 解析 / envelope unwrap / bigint id / 字段 silent rename)放在 `~/.
|
|
353
|
+
`pitfalls.md` 只放 **task-executor 级**坑 — 跑命令 / 操作页面会撞到的坑。**adapter-internal 实现坑**(queryId 解析 / envelope unwrap / bigint id / 字段 silent rename)放在 `~/.ppcli/sites/<site>/notes.md`,不进 sitemap。
|
|
354
354
|
|
|
355
355
|
判断标准:
|
|
356
356
|
|
|
@@ -407,7 +407,7 @@ State signature: # OPTIONAL — for multi-step internal
|
|
|
407
407
|
dom_anchor: <a11y role+name OR semantic selector>
|
|
408
408
|
|
|
409
409
|
Evidence:
|
|
410
|
-
- observed_with:
|
|
410
|
+
- observed_with: ppcli browser <session> <command>
|
|
411
411
|
- trace: <path to trace artifact, optional>
|
|
412
412
|
```
|
|
413
413
|
|
|
@@ -420,7 +420,7 @@ do: <agent action, adapter or semantic browser command>
|
|
|
420
420
|
post: <URL / state / output that proves success>
|
|
421
421
|
fail: <failure signal 1> | <signal 2> | <signal 3>
|
|
422
422
|
recover: <fallback instruction>; adapter_health_update: <adapter> -> suspect
|
|
423
|
-
evidence:
|
|
423
|
+
evidence: ppcli browser <cmd>
|
|
424
424
|
```
|
|
425
425
|
|
|
426
426
|
字段分隔符约定(避免 ambiguity):
|
|
@@ -428,8 +428,8 @@ evidence: opencli browser <cmd>
|
|
|
428
428
|
| 符号 | 用途 | 例 |
|
|
429
429
|
|---|---|---|
|
|
430
430
|
| `\|` | 多 failure signal 平级枚举("任一发生即视为失败")| `fail: button_not_found \| /flow/login redirect` |
|
|
431
|
-
| `\|\|` | 多 do path / recovery path **fallback priority**("前者失败试后者")| `do:
|
|
432
|
-
| `;` | 多 recovery 指令 **sequential**("逐条执行")| `recover: adapter_health_update:
|
|
431
|
+
| `\|\|` | 多 do path / recovery path **fallback priority**("前者失败试后者")| `do: ppcli twitter like <url> \|\| click [data-testid="like"]` |
|
|
432
|
+
| `;` | 多 recovery 指令 **sequential**("逐条执行")| `recover: adapter_health_update: ppcli twitter like -> suspect; dom_click within card scope` |
|
|
433
433
|
|
|
434
434
|
字段语义完全等价 Form A,**推荐 Form B**,密集站避免 verbose markdown 把 page 撑爆。
|
|
435
435
|
|
|
@@ -445,8 +445,8 @@ evidence: opencli browser <cmd>
|
|
|
445
445
|
- 一般是 page state("on /home")+ auth state("logged_in")+ UI state("compose dialog not yet open")
|
|
446
446
|
|
|
447
447
|
**Do**:实际操作。优先级:
|
|
448
|
-
1. 已有 adapter 命令(`
|
|
449
|
-
2. semantic browser command(`
|
|
448
|
+
1. 已有 adapter 命令(`ppcli twitter post`)
|
|
449
|
+
2. semantic browser command(`ppcli browser click "Post" button`)
|
|
450
450
|
3. 显式 selector(最后选项,写 stable anchor 不是裸 CSS)
|
|
451
451
|
|
|
452
452
|
**Postconditions**:成功观察信号。必须具体 — "page changed" 不算,"URL is /compose AND textarea is focused" 才算。
|
|
@@ -486,11 +486,11 @@ evidence: opencli browser <cmd>
|
|
|
486
486
|
```yaml
|
|
487
487
|
### action:like_tweet
|
|
488
488
|
pre: card visible AND (tweet_url known OR card permalink anchor extractable)
|
|
489
|
-
do:
|
|
489
|
+
do: ppcli twitter like <tweet-url> || click [data-testid="like"] (within card scope)
|
|
490
490
|
post: testid 翻转 like -> unlike,icon 红色
|
|
491
491
|
fail: testid 不变 | 弹 login modal
|
|
492
|
-
recover: adapter_health_update:
|
|
493
|
-
evidence:
|
|
492
|
+
recover: adapter_health_update: ppcli twitter like -> suspect; dom_click within card scope
|
|
493
|
+
evidence: ppcli twitter like + ppcli browser click
|
|
494
494
|
```
|
|
495
495
|
|
|
496
496
|
两层 routing 不冲突:
|
|
@@ -561,11 +561,11 @@ sitemap 内部多文件互相引用。引用格式:
|
|
|
561
561
|
|
|
562
562
|
agent 发现新路径 / stale 修正 / 半成品流程时写 draft。**draft 必须放在 `sitemap/` 目录内**,命名为 `sitemap/draft-<topic>.md` 或 `sitemap/pages/<page>.draft.md`。
|
|
563
563
|
|
|
564
|
-
**❌ 不要**放在父目录(如 `~/.
|
|
564
|
+
**❌ 不要**放在父目录(如 `~/.ppcli/sites/<site>/sitemap.draft.md`) — `ppcli browser open` 的 sitemap availability 检测只看 `sitemap/` 目录是否存在。draft 放父目录 → 检测不到 → agent 不会被提醒"有 sitemap" → 你的发现没人用。
|
|
565
565
|
|
|
566
566
|
正确:
|
|
567
567
|
```
|
|
568
|
-
~/.
|
|
568
|
+
~/.ppcli/sites/twitter/sitemap/
|
|
569
569
|
├── SITE.md
|
|
570
570
|
├── pages/home.md
|
|
571
571
|
└── draft-search-filter.md ← OK,会被检测到
|
|
@@ -573,7 +573,7 @@ agent 发现新路径 / stale 修正 / 半成品流程时写 draft。**draft 必
|
|
|
573
573
|
|
|
574
574
|
错误:
|
|
575
575
|
```
|
|
576
|
-
~/.
|
|
576
|
+
~/.ppcli/sites/twitter/
|
|
577
577
|
├── sitemap.draft.md ← 检测不到,不会触发 availability
|
|
578
578
|
└── sitemap/ ← 空 dir → 检测到但内容空
|
|
579
579
|
└── (empty)
|
|
@@ -581,7 +581,7 @@ agent 发现新路径 / stale 修正 / 半成品流程时写 draft。**draft 必
|
|
|
581
581
|
|
|
582
582
|
### 5.2 `site-alias.json`(optional, Phase 2)
|
|
583
583
|
|
|
584
|
-
`
|
|
584
|
+
`ppcli browser open` 用 adapter registry 把 hostname → site 映射(如 `news.ycombinator.com → hackernews`)。如果 sitemap 先于 adapter 存在(即一个站还没人写 adapter 但有人写了 sitemap),registry 没数据,sitemap dir 检测不到。
|
|
585
585
|
|
|
586
586
|
future fix:sitemap dir 内放 `site-alias.json` 声明它服务的 hostname:
|
|
587
587
|
|
|
@@ -633,7 +633,7 @@ sitemap 是 hint,browser state 是 truth。当冲突时:
|
|
|
633
633
|
|
|
634
634
|
### 7.3 Reality check
|
|
635
635
|
|
|
636
|
-
- action `Postconditions` 里的 `url_pattern` / `dom_anchor` → 用 `
|
|
636
|
+
- action `Postconditions` 里的 `url_pattern` / `dom_anchor` → 用 `ppcli browser` 实跑一遍,验证 anchor 仍可 resolve
|
|
637
637
|
- workflow `State signature.url_pattern` → 同上
|
|
638
638
|
|
|
639
639
|
失败 → 自动倒 `last_verified` 30 天前。
|
|
@@ -649,7 +649,7 @@ sitemap 是 hint,browser state 是 truth。当冲突时:
|
|
|
649
649
|
|
|
650
650
|
- [`../../opencli-adapter-author/references/strategy-selection.md`](../../opencli-adapter-author/references/strategy-selection.md) — `contract_strength` 和 `auth_strategy` 取值定义
|
|
651
651
|
- [`../../opencli-adapter-author/references/api-discovery.md`](../../opencli-adapter-author/references/api-discovery.md) — `endpoint_id` 怎么发现
|
|
652
|
-
- `~/.
|
|
652
|
+
- `~/.ppcli/sites/<site>/endpoints.json` — endpoint 的真实 URL/method/params/response
|
|
653
653
|
|
|
654
654
|
---
|
|
655
655
|
|
|
@@ -657,4 +657,4 @@ sitemap 是 hint,browser state 是 truth。当冲突时:
|
|
|
657
657
|
|
|
658
658
|
1. **`state_signature` 用什么 DSL**:现在写 `url_pattern: <regex>` + `dom_anchor: <semantic>`,未来可能需要更结构化(如 JSON path / xpath / a11y tree path)。等 PoC 实践后定
|
|
659
659
|
2. **多语言站 anchor**:现在建议 a11y role + name;不同 locale name 不同。是否一个 anchor 列表多 locale,还是一个 sitemap per locale?PoC 后决
|
|
660
|
-
3. **Validation cron 实现位置**:作为
|
|
660
|
+
3. **Validation cron 实现位置**:作为 ppcli 内置命令 `ppcli sitemap audit`?还是独立 GitHub Action?Phase 2 决
|