Commit Graph

1359 Commits

Author SHA1 Message Date
Asen's Agent 55e5f6421f chore: version packages (cli v1.3.1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
actionbook-cli-v1.3.1
2026-04-11 17:10:33 +08:00
asensagent 4b46acf99c fix: handle extension mode in browser list-tabs (#501) 2026-04-11 17:09:02 +08:00
Asen's Agent 13a203935f style: fix cargo fmt formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 17:07:26 +08:00
Asen's Agent 1a0dc73ef0 fix: use extension-specific attach for discovered tabs + add test
Extension mode now uses register_extension_tab instead of
Target.attachToTarget for newly discovered tabs. Adds a focused
regression test verifying Extension.listTabs is called and no
Target.attachToTarget is sent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 17:04:04 +08:00
Asen's Agent e6c91d189b fix: use Extension.listTabs as live source in extension mode
Instead of returning stale registry data, extension mode now calls
Extension.listTabs for real-time tab enumeration, then reconciles
with the registry the same way local/cloud mode does.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 16:47:24 +08:00
Asen's Agent 1fc8713a6b fix: handle extension mode in browser list-tabs
Extension mode connects via a Chrome extension bridge that only has
page-level debugging access. Target.getTargets is a browser-level CDP
method not available in this mode, causing CDP_CONNECTION_FAILED.

For extension mode, return tabs from the registry instead of querying
CDP. The registry already tracks all tabs registered during session
startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 16:31:11 +08:00
github-actions[bot] b5d699687a chore: version packages (#500)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
actionbook-cli-v1.3.0
2026-04-11 16:28:13 +08:00
sen 3092c612dc feat(cli): restore skills install step and --target quick mode in setup (#499)
* feat(cli): restore skills install step and --target quick mode in setup

- Add setup/skills.rs porting the `npx skills add actionbook/actionbook`
  integration from the previous actionbook-rs CLI. Defines SetupTarget
  enum, SkillsResult, and both wizard-flow and quick-mode install paths.
- Wire Step 5 "Install Skills" into the setup wizard (TOTAL_STEPS 4 -> 5),
  running after Save. Non-interactive / JSON mode auto-installs with -y;
  interactive mode prompts Install / Skip.
- Add quick mode: `actionbook setup --target <agent>` skips the full
  wizard and only runs skills install for the specified target. Restores
  the CI / one-shot bootstrap path. Standalone target is special-cased
  to skip entirely (no agent integration needed).
- Change --target flag from Option<String> to Option<SetupTarget> (clap
  ValueEnum, kebab-case values: claude, codex, cursor, windsurf,
  antigravity, opencode, standalone, all). Unknown values rejected at
  parse time.
- Propagate skills install failure as CliError so CI / non-interactive
  callers see a non-zero exit.

Scope: only packages/cli/src/setup/ plus the cli.rs test block. No
changes to browser, daemon, config, error types, or Cargo.toml.

* feat(cli): show API key input and guide extension install to CWS / GitHub Releases

- API key prompt switches from `Password` to `Input` so typed characters
  echo by default. Users reported the hidden-by-default behavior felt
  broken when pasting. `allow_empty` + the validation loop are unchanged.

- Extension mode now guides the user to install the Chrome extension:
  - Primary: Chrome Web Store (recommended, one-click).
  - Fallback: manual install from GitHub Releases when CWS is
    unavailable (region-blocked, offline, corporate policy). 5-step
    Load-unpacked flow covers download -> unzip -> chrome://extensions
    -> Developer mode -> Load unpacked.
  - Interactive flow asks "Installed from CWS?" -> if no, shows the
    GitHub Releases path and asks "Loaded the unpacked extension?"
    -> if no, errors with both URLs listed for out-of-band install.
  - Non-interactive (`--browser extension`) text output lists both
    URLs; JSON payload gains `recommended_install_source`,
    `web_store_url`, `fallback_install_source`, `github_releases_url`.

- The GitHub Releases URL uses a tag-search query
  `?q=%22Chrome+Extension%22&expanded=true` so users land directly on
  extension releases (the repo mixes `actionbook-cli-v*`,
  `actionbook-extension-v*`, and `actionbook-dify-plugin-v*` in the
  same feed — a plain /releases URL buries the extension zip).

Tests: 292 lib passed. New: `test_chrome_web_store_url_is_canonical`,
`test_github_releases_url_is_extension_filtered`,
`test_apply_extension_mode_records_web_store_hint_in_json`.

* fix(cli): address Codex P1 review feedback on setup skills step

Two P1 issues flagged by Codex automated review on PR #499:

1. setup/skills.rs: JSON mode deadlock risk when `npx skills add`
   output exceeds the OS pipe buffer (~16KB on macOS). The code used
   `Stdio::piped()` for child stdout/stderr but then called `.status()`
   instead of `.output()`, which does not drain the pipes. A verbose
   skills install (common on first run) would fill the buffer and block
   the child on write, hanging setup indefinitely in CI. Switch to
   `Stdio::null()` in JSON mode to discard subprocess output entirely —
   we already emit our own JSON status event, so the subprocess output
   has no consumer anyway. Also close stdin in JSON mode (`Stdio::null`)
   so a stray read attempt can't hang either.

2. setup/mod.rs: quick mode (`setup --target <agent>`) silently exited
   with status 0 when npx was not available. `install_skills_for_target`
   returns `SkillsAction::Prompted` in that case, but `run_target_only`
   only mapped `SkillsAction::Failed` to an error. CI bootstrap relying
   on `--target` would silently pass broken runs. Extract a pure helper
   `target_only_exit_status` that maps every non-`Installed` outcome to
   `CliError::Internal` with a target-specific message; in the `Prompted`
   branch the message points at the Node.js install docs and the exact
   `npx` command to retry manually. The full-wizard Skills step is
   unchanged — there `Prompted` is still a soft prompt because the user
   can finish setup without skills.

Add 4 unit tests on `target_only_exit_status` covering all four
`SkillsAction` variants, including a regression guard for the P1 #2
silent-success case.

Tests: 296 lib passed (71 in setup::, 4 new).

* fix(cli): tighten setup target quick mode semantics

* fix(cli): install setup target all for all agents

* style(cli): format setup quick mode tests and JSON output

* chore(cli): add changeset for setup improvements
2026-04-11 16:22:45 +08:00
asensagent 32035a7a91 docs: update OpenClaw integration guide (#498)
* docs: update OpenClaw integration guide

- Install section: npm only, removed InstallTabs snippet
- Step 2: removed smoke test (actionbook search)
- Step 3: removed "search -> get -> operate" workflow reference
- Next Steps: updated card description

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: revert steps 2-3 changes, keep only npm install update

Only the installation section should change per updated request.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: update InstallTabs snippet to npm-only install

Update the shared install-tabs.mdx snippet to only show npm install
method. Reverts inline change to openclaw.mdx — keeps the import.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 12:57:07 +08:00
mcfn 95bb3066e4 Merge branch 'main' of github.com:actionbook/actionbook 2026-04-11 01:32:00 +08:00
Junliang Feng 4ad9c3530e fix(browser): include request ID in text output and deduplicate redirect chains (ACT-882)
Address Codex review findings on PR #492:
- P1: Text-mode network request listing now includes request_id so
  users can drill into browser network request <id> without --json
- P2: record_request_will_be_sent updates in-place when the same
  requestId appears again (redirect chains), preventing duplicate
  entries and ensuring detail lookup returns the correct final hop
2026-04-11 01:21:05 +08:00
Junliang Feng f119e54565 feat(browser): add network requests commands (ACT-882)
Add `browser network requests` and `browser network request <id>` commands.

- Per-tab ring buffer (500 cap) stores TrackedRequest with URL, method,
  resource type, status, headers (normalized HashMap), post data, timestamps
- CDP event handlers for Network.requestWillBeSent / Network.responseReceived
- Filters: --filter (URL substring), --type, --method, --status (exact/class/range)
- Response body fetched on-demand via Network.getResponseBody
- Chrome internal URLs filtered from tracking
- 9 unit tests + 5 e2e tests

Closes ACT-882
2026-04-11 01:09:53 +08:00
Junliang Feng 479828d1ea fix(browser): await Promise in eval command via awaitPromise CDP flag
## Summary
- Add `awaitPromise: true` to the `Runtime.evaluate` CDP call in the `eval` command
- Without this flag, evaluating a Promise expression returns the Promise object itself, which serializes to `{}` (no enumerable properties)
- With `awaitPromise: true`, CDP waits for the Promise to resolve and returns the actual value — matching Playwright's behavior
- Add e2e regression test covering `Promise.resolve(42)` and delayed Promise resolution

Cherry-picked from #490 (closed — had stale click.rs/output.rs conflicts with main).

## Test plan
- [x] `eval_json_promise` e2e: `Promise.resolve(42)` returns 42
- [x] `eval_json_promise` e2e: delayed Promise via setTimeout resolves correctly
- [x] `eval_json_number` e2e: sync expressions still work
- [x] CI lint + unit tests green
2026-04-10 17:40:34 +08:00
Junliang Feng 673d21dc81 fix(browser): fix wait-navigation timeout for fast/delayed redirects (ACT-873)
## Summary
- Fix `browser wait navigation` timing out when navigation completes before
  the wait command starts (fast-redirect scenario, ACT-873).
- Add CDP `Page.frameNavigated` event subscription alongside polling for
  reliable in-watch navigation detection.
- Use registry `prev_url` as baseline to detect navigation that occurred
  between commands.
- Add time-based URL stability (300ms) to distinguish final destinations
  from intermediate redirect pages.
- Add 5 unit tests for NavigationDetector and 3 e2e tests covering
  fast-redirect, delayed-redirect, and no-navigation timeout scenarios.

Closes ACT-873
2026-04-10 17:15:22 +08:00
Junliang Feng 4deeda4a7b perf: reduce click latency from ~2s to ~75ms for DOM-only interactions (#475)
* [packages/cli]feat: add batch click support and optimize wait_for_navigation

- Support multiple selectors in click command: click @e1 @e2 @e3
- Execute clicks sequentially with fail-fast on first error
- Batch response includes all results with url_changed/focus_changed per click
- Optimize wait_for_navigation: return immediately on URL change detection, avoid polling for DOM-only interactions
- Format text output for batch clicks (clicks count + target list)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]perf: reduce Runtime.evaluate calls per click from 5 to 2

Merged pre-click (url+focus) and post-click (url+title+focus) state reads
each into a single JS evaluate, eliminating 3 serial main-thread round-trips
per click. Also removed wait_for_navigation's fixed 2s wait — now exits
immediately when URL hasn't changed (DOM-only interactions like card expand).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]perf: return immediately on DOM-only clicks (no navigation)

After first evaluate, if URL is unchanged the click was a DOM-only
interaction — return immediately instead of polling for 2s. Only
continue polling when URL actually changed (real navigation).

Result: DOM-only clicks drop from ~2050ms to ~75ms.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [root]docs: update target branch to main in cli-devflow

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [root]docs: untrack .docs/cli-devflow.md

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]feat: support single-package local distribution via bundled binary

Add fallback in bin/actionbook.js to check for co-located actionbook-native
binary before looking up the platform-specific optional dependency package.
Enables local npm install -g from a single .tgz without separate platform packages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]chore: bump version to 1.0.2-alpha.1

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]feat: add batch-click command for bulk DOM interactions

Adds `browser batch-click` as an agent-friendly command for clicking
multiple elements sequentially. Simplified interface (no --new-tab,
--button, --count) that delegates to click::execute internally.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]perf: batch-click bypasses JS main thread entirely

batch-click now uses resolve_center_no_scroll (DOM.getBoxModel only)
and skips pre/post state detection. All CDP calls stay on the DOM engine
thread, avoiding the JS main thread bottleneck.

Result: 5 clicks 413ms, 10 clicks 756ms (~75ms/click vs ~5000ms before).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]fix: restore scrollIntoView in batch-click fast path

Keep scrollIntoView so off-screen elements are scrolled into view
before clicking. The perf gain comes from skipping pre/post state
detection (Runtime.evaluate), not from skipping scroll.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* [packages/cli]feat: add batch-new-tab command for opening multiple tabs at once

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [packages/cli]chore: bump version to 1.0.3-alpha.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(browser): add batch-snapshot command (#479)

Implements browser batch-snapshot (tasks #14, #15):
- Cmd struct with --session, --tabs (1+), and all shared snapshot flags
- execute() loops over tabs, reuses snapshot logic per tab, collects
  results with partial success (SESSION_NOT_FOUND bubbles as Fatal,
  all other per-tab errors become inline error entries)
- Registers in mod.rs, action.rs, cli.rs (BrowserCommands), router.rs

Co-authored-by: cli-roger-test <cli-roger-test@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(browser): add batch snapshot e2e coverage

* feat(browser): add batch-snapshot command

Implements browser batch-snapshot (tasks #14, #15):
- Cmd struct with --session, --tabs (1+), and all shared snapshot flags
- execute() loops over tabs, reuses snapshot logic per tab, collects
  results with partial success (SESSION_NOT_FOUND bubbles as Fatal,
  all other per-tab errors become inline error entries)
- Registers in mod.rs, action.rs, cli.rs (BrowserCommands), router.rs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(browser): add batch snapshot e2e coverage

---------

Co-authored-by: cli-roger-test <cli-roger-test@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(browser): add batch-new-tab to text output action list

batch-new-tab was missing from the is_action match in format_text,
so "ok browser batch-new-tab" was never emitted. Also add its
format_data_fields arm and partial failure handling.

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: cli-roger-test <cli-roger-test@local>
2026-04-10 15:35:53 +08:00
mcfn 2238c15e64 Merge branch 'main' of github.com:actionbook/actionbook 2026-04-10 14:55:15 +08:00
github-actions[bot] 805bb8f171 chore: version packages (#487)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
actionbook-cli-v1.2.0
2026-04-09 20:43:41 +08:00
sen 86905ebe11 feat(cli): restore extension browser mode with bridge relay (#486)
* [packages/cli]feat: restore extension browser mode with bridge relay

Add a WebSocket bridge server inside the daemon that transparently
relays CDP messages between the Chrome extension and CdpSession.
Extension mode was removed in v1.0.0; this restores it with minimal
changes by reusing the existing cloud-mode CDP connection flow.

- daemon/bridge.rs: WS bridge on port 19222, hello handshake with
  extension origin validation, bidirectional CDP message relay
- daemon/server.rs: spawn bridge as tokio task (non-fatal on bind fail)
- daemon/registry.rs: store SharedBridgeState for session start access
- browser/session/start.rs: execute_extension() reusing cloud CDP flow
- setup: unblock extension mode in wizard and --browser flag
- CdpSession: zero changes
- Extension side: zero changes

* [packages/cli]fix: use Extension API for tab discovery in extension mode

Extension bridge requires Extension.attachTab before any CDP command
can be relayed. Replaced Target.getTargets + Target.attachToTarget
with Extension.createTab / Extension.attachActiveTab flow. Added
CdpSession.register_extension_tab() to register tabs without CDP
flat-session handshake. Local and cloud modes are unaffected.

* [packages/cli]fix: close tabs and detach debugger in extension mode

Session close and close-tab now use Extension.closeTab / Extension.detachTab
in extension mode instead of Target.closeTarget which the bridge doesn't
support. Added Extension.closeTab to the extension that detaches the
debugger and removes the tab via chrome.tabs.remove. Local and cloud
modes are unaffected.

* [packages/cli]fix: revert extension JS change, use detachTab for close

Extension is loaded from CWS — local JS changes don't take effect.
Reverted Extension.closeTab addition to background.js. Session close
and close-tab now use Extension.detachTab to release the debugger in
extension mode. Tabs are left open since CLI doesn't own the browser.

* [packages/cli]fix: read default browser mode from config instead of hardcoding Local

When --mode is not specified, browser start now reads browser.mode from
config.toml (e.g. mode = "extension") instead of always falling back to
Local mode. This allows users with extension mode configured to connect
to their existing browser without explicitly passing --mode extension.

* [packages/cli]fix: build.rs track branch ref for accurate BUILD_VERSION in worktrees

build.rs only watched .git/HEAD which doesn't change on new commits in a
worktree (it stays as ref: refs/heads/branch-name). This caused stale
BUILD_VERSION, preventing daemon version-mismatch detection when the
npm-installed binary shared the same cached hash.

Now also watches the actual ref file and packed-refs via --git-common-dir
so BUILD_VERSION updates on every new commit.

Also adds a guard in start.rs Local mode section to reject non-Local
modes explicitly instead of silently launching a local Chrome.

* [packages/cli]fix: clippy/fmt fixes and reject concurrent CDP clients in bridge

- Fix rustfmt formatting (collapsed if chains, import order, line width)
- Fix clippy collapsible-if warnings
- Reject concurrent CDP clients in bridge relay to prevent response
  channel hijacking between sessions

* [packages/cli]fix: suppress result_large_err for accept_hdr_async callback

The closure signature is dictated by tokio-tungstenite's API and cannot
use Box<Err>. Allow the lint on this specific closure.

* [root]chore: add changeset for CLI v1.2.0 (extension mode restore)
2026-04-09 20:01:37 +08:00
mcfn 9a0cd4058e fix(browser): add batch-new-tab to text output action list
batch-new-tab was missing from the is_action match in format_text,
so "ok browser batch-new-tab" was never emitted. Also add its
format_data_fields arm and partial failure handling.
2026-04-09 14:59:33 +08:00
mcfn 6da55f0d94 Merge branch 'main' into feat/multi-click
Resolve version conflicts (take main's 1.1.0), apply cargo fmt.
2026-04-09 13:38:32 +08:00
github-actions[bot] c59638d50a chore: version packages (#484)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
actionbook-cli-v1.1.0
2026-04-07 23:20:31 +08:00
s1mba 4d46f8d38f [packages/cli]release: release 1.1.0 changeset for CLI (#483)
Add CLI 1.1.0 changeset
2026-04-07 22:20:22 +08:00
s1mba 2e9ee9c245 [packages/cli]fix: batch new-tab session-loss failures (#482)
Fix skipped batch new-tab failures
2026-04-07 21:21:07 +08:00
s1mba f05fd69c57 Support multi-URL browser new-tab 2026-04-07 17:12:00 +08:00
4bmis f8c3be406b Fix e2e test helper import 2026-04-07 17:10:49 +08:00
4bmis b3498b9625 Support multi-URL browser new-tab 2026-04-07 17:03:12 +08:00
Adcent 6b4a2e9a10 Update README.md 2026-04-03 16:45:10 +08:00
Junliang Feng 90accb0213 test(browser): add batch snapshot e2e coverage
* feat(browser): add batch-snapshot command

Implements browser batch-snapshot (tasks #14, #15):
- Cmd struct with --session, --tabs (1+), and all shared snapshot flags
- execute() loops over tabs, reuses snapshot logic per tab, collects
  results with partial success (SESSION_NOT_FOUND bubbles as Fatal,
  all other per-tab errors become inline error entries)
- Registers in mod.rs, action.rs, cli.rs (BrowserCommands), router.rs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(browser): add batch snapshot e2e coverage

---------

Co-authored-by: cli-roger-test <cli-roger-test@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 16:12:04 +08:00
Adcent 8e186207ee Update README.md 2026-04-03 15:33:30 +08:00
Junliang Feng ff494fc2dc feat(browser): add batch-snapshot command (#479)
Implements browser batch-snapshot (tasks #14, #15):
- Cmd struct with --session, --tabs (1+), and all shared snapshot flags
- execute() loops over tabs, reuses snapshot logic per tab, collects
  results with partial success (SESSION_NOT_FOUND bubbles as Fatal,
  all other per-tab errors become inline error entries)
- Registers in mod.rs, action.rs, cli.rs (BrowserCommands), router.rs

Co-authored-by: cli-roger-test <cli-roger-test@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 15:31:51 +08:00
mcfn cff4ea5268 [packages/cli]chore: bump version to 1.0.3-alpha.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:28:16 +08:00
mcfn 0352417e90 Merge branch 'main' of github.com:actionbook/actionbook into feat/multi-click
# Conflicts:
#	packages/cli-darwin-arm64/package.json
#	packages/cli/Cargo.lock
#	packages/cli/Cargo.toml
#	packages/cli/package.json
2026-04-03 15:18:15 +08:00
mcfn 7bc8644ce7 [packages/cli]feat: add batch-new-tab command for opening multiple tabs at once
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:14:09 +08:00
Junliang Feng 0711c870e7 feat(browser): save snapshot as Playwright-style YAML (#477)
* test(browser): add render_yaml unit tests

* test(browser): extend render_yaml edge coverage

* feat(browser): save snapshot as Playwright-style YAML

Add render_yaml() to snapshot_transform.rs that converts a flat AXNode
list into a nested Playwright-style YAML DSL string. Format rules:
- Container nodes (children or URL): `- role "name" [ref=eN]:`
- Leaf with ref: `- role "name" [ref=eN]`
- Leaf with value (no ref): `- role "name": value`
- Leaf with name only (no ref): `- role: name`
- URL rendered as child: `- /url: <url>`
- [cursor=pointer] added when cursor_info has cursor:pointer hint

Switch build_output() to call render_yaml() instead of render_content(),
and change snapshot file extension from .txt to .yaml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(browser): escape name and value in render_yaml leaf nodes

- Use escaped_name (not node.name) in the inline leaf branch
- Escape node.value with the same rules to prevent injection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(browser): render value inline even when ref is present in render_yaml

Textbox/combobox nodes are interactive and typically have both a ref and
a value. Previously, the ref branch dropped the value entirely. Now the
value is appended inline: `- textbox "Label" [ref=eN]: value`.

Also moves escaped_value computation to the top of the loop so it can be
shared across both the ref and no-ref branches.

Adds unit test for the ref+value path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(browser): update snapshot e2e for yaml artifacts

- assert data.path ends with .yaml
- snapshot_content() validates .yaml extension before reading
- rename assert_content_has_refs to assert_content_is_yaml_snapshot
- add assertions: no legacy `url=` format, at least one YAML container line

Co-Authored-By: cli-roger-test <cli-roger-test@local>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: fix rustfmt formatting in render_yaml tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: rustfmt formatting and update link URL test for YAML format

Apply rustfmt-required formatting:
- Expand format!() call with 3+ args to multi-line
- Expand assert!(cond, msg) to multi-line
- Expand assert_eq! with long string to multi-line

Update test_build_output_renders_link_urls_from_ax_properties:
- Old format: `url=https://...` inline
- New YAML format: `- link "Docs" [ref=e1]:` + child `- /url: https://...`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: fix final rustfmt issue in link URL test assertion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: replace map_or(false) with is_some_and per clippy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: cli-roger-test <cli-roger-test@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 15:10:56 +08:00
Adcent 0760503b17 Update README.md 2026-04-03 15:09:16 +08:00
asensagent 1136f2d9ac Update hero tagline to parallel browser CLI (#478)
[root]docs: update hero tagline to parallel browser CLI

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 14:56:01 +08:00
Junliang Feng 7336c1e11f fix(cli): native-ish stealth + OOPIF iframe click offset (#465) 2026-04-03 14:51:37 +08:00
mcfn 42090975fb [packages/cli]fix: restore scrollIntoView in batch-click fast path
Keep scrollIntoView so off-screen elements are scrolled into view
before clicking. The perf gain comes from skipping pre/post state
detection (Runtime.evaluate), not from skipping scroll.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 14:44:17 +08:00
Asen's Agent 350f4fa8db chore: version packages (cli v1.0.2)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
actionbook-cli-v1.0.2
2026-04-03 14:32:01 +08:00
asensagent 4ee5e44703 docs: remove search and get from help and skills (#476)
docs: remove search and get commands from help and skills

Search and get commands are being removed from the CLI. This removes
all references from help output, SKILL.md, and command-reference.md.
The workflow now starts directly with browser automation via snapshot.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 14:29:42 +08:00
mcfn 026cc36614 [packages/cli]perf: batch-click bypasses JS main thread entirely
batch-click now uses resolve_center_no_scroll (DOM.getBoxModel only)
and skips pre/post state detection. All CDP calls stay on the DOM engine
thread, avoiding the JS main thread bottleneck.

Result: 5 clicks 413ms, 10 clicks 756ms (~75ms/click vs ~5000ms before).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 14:28:49 +08:00
mcfn 40b4bf7962 [packages/cli]feat: add batch-click command for bulk DOM interactions
Adds `browser batch-click` as an agent-friendly command for clicking
multiple elements sequentially. Simplified interface (no --new-tab,
--button, --count) that delegates to click::execute internally.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 14:21:38 +08:00
mcfn 78da0963b9 [packages/cli]chore: bump version to 1.0.2-alpha.1
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 12:43:58 +08:00
mcfn 7e1acd795f [packages/cli]feat: support single-package local distribution via bundled binary
Add fallback in bin/actionbook.js to check for co-located actionbook-native
binary before looking up the platform-specific optional dependency package.
Enables local npm install -g from a single .tgz without separate platform packages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 12:43:53 +08:00
mcfn c77aa9e64f [root]docs: untrack .docs/cli-devflow.md
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 12:41:52 +08:00
mcfn 0ec70dd032 [root]docs: update target branch to main in cli-devflow
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 12:41:22 +08:00
mcfn a6c2110a0c [packages/cli]perf: return immediately on DOM-only clicks (no navigation)
After first evaluate, if URL is unchanged the click was a DOM-only
interaction — return immediately instead of polling for 2s. Only
continue polling when URL actually changed (real navigation).

Result: DOM-only clicks drop from ~2050ms to ~75ms.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 10:43:38 +08:00
mcfn 0a25f2cace [packages/cli]perf: reduce Runtime.evaluate calls per click from 5 to 2
Merged pre-click (url+focus) and post-click (url+title+focus) state reads
each into a single JS evaluate, eliminating 3 serial main-thread round-trips
per click. Also removed wait_for_navigation's fixed 2s wait — now exits
immediately when URL hasn't changed (DOM-only interactions like card expand).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 10:35:42 +08:00
mcfn a3b3385f3f [packages/cli]feat: add batch click support and optimize wait_for_navigation
- Support multiple selectors in click command: click @e1 @e2 @e3
- Execute clicks sequentially with fail-fast on first error
- Batch response includes all results with url_changed/focus_changed per click
- Optimize wait_for_navigation: return immediately on URL change detection, avoid polling for DOM-only interactions
- Format text output for batch clicks (clicks count + target list)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-03 09:57:50 +08:00
Junliang Feng 8f7fe769fc docs: restore deleted evaluate-api.mdx (#473) 2026-04-03 08:48:17 +08:00