Commit Graph

8 Commits

Author SHA1 Message Date
mcfn.feng 05ebd77973 [root]docs: add git branch naming convention to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:19:22 +08:00
mcfn.feng 125043373a [root]docs: update CLAUDE.md 2026-03-27 22:37:30 +08:00
Junliang Feng de43e3edbf [packages/actionbook-rs]test: E2E tests — full command coverage (61 tests) (#260)
* [packages/actionbook-rs]test: full E2E test suite — 83 tests across 9 modules

Add 8 E2E test modules covering all browser commands from api-reference.md:

- browser_lifecycle.rs (9): start, list-sessions, status, close, restart
- browser_tab.rs (7): list-tabs, new-tab/open, close-tab
- browser_navigation.rs (5): goto, back, forward, reload
- browser_observation.rs (26): snapshot, screenshot, pdf, title, url,
  viewport, eval, html, text, value, attr, attrs, box, styles, query,
  describe, state, inspect-point, logs console/errors
- browser_interaction.rs (17): click, type, fill, select, hover, focus,
  press, drag, upload, mouse-move, cursor-position, scroll
- browser_waiting.rs (5): wait element, navigation, network-idle, condition
- browser_data.rs (7): cookies CRUD, local-storage, session-storage
- browser_errors.rs (6): error path coverage

Scene coverage: S1T1, S1T2 (tab isolation), SEQ (sequential operations)

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

* [packages/actionbook-rs]fix: address codex review — 13 E2E test fixes

Observation:
- Compare snapshot content only, not full JSON envelope (s1t2/seq tests)
- Add obs_query_nth test for query nth mode
- Strengthen obs_query_count assertion with numeric parsing

Interaction:
- Fix drag: positional args, not --from/--to flags
- Fix mouse-move: single "x,y" arg, not two positional
- Fix scroll: "scroll down 500", not "--amount 500"
- Add int_scroll_into_view test

Waiting:
- Fix wait_nav assertion: compare URL before/after, not vacuous check

Data:
- Fix S1T2 tests: create second tab before using t1
- Add local-storage clear step
- Add storage_session_list_delete_clear test
- Meaningful assertion in storage_s1t2_isolation

Errors:
- All 6 tests now check error message content, not just exit code

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

* [packages/actionbook-rs]fix: address codex round 2 — snapshot content, storage clear/isolation

- Snapshot content extraction: use JSON pointer /data/content for true content comparison
- Storage clear tests: verify store is empty after clear (list + assert not contains)
- Storage s1t2 isolation: assert same-origin tabs share localStorage ("crossval" visible)

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

* [packages/actionbook-rs]fix: address PR review — 3 P1 issues

1. Restrict browser-intent detection to subcommand position (args[1])
   instead of scanning all argv — prevents misrouting "actionbook search b"

2. Daemon stop: send SIGTERM via PID file instead of just deleting socket.
   Old approach left orphaned daemon process running.

3. Add #[cfg(unix)] gate to daemon module in lib.rs, commands/mod.rs,
   and main.rs — restores cross-platform compilation.

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

* [packages/actionbook-rs]docs: enhance CLI documentation and add API reference

- Added a new section on Product Principles to CLAUDE.md, outlining key design philosophies for the CLI and daemon architecture.
- Introduced a comprehensive API reference document for Actionbook CLI, detailing design goals, principles, command definitions, and error protocols.

This update aims to improve clarity and usability for developers interacting with the Actionbook CLI.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:32:25 +08:00
Junliang Feng b2fcaead44 [packages/actionbook-rs]feat: daemon_v2 — unified session+daemon architecture (Phase 1+2) (#258)
* [packages/actionbook-rs]feat: add daemon_v2 module — Phase 1 session+daemon architecture rewrite

Implement the v1.0.0 daemon architecture based on root cause analysis and
approved design doc. This is Phase 1 (Local mode) of the Strangler Fig migration.

Key design decisions:
- Thick Daemon: all browser logic in daemon, CLI is ~500 line RPC client
- Per-Session Async Task: session间并行, session内串行 (bounded(32) channel)
- BrowserBackend trait (Factory + Session handle): unified local/extension/cloud
- 3-layer protocol: CLI Action (~50 variants) / BackendOp (CDP primitives) / Wire
- Typed errors with recovery hints (Retryable/UserAction/Fatal)

New modules (daemon_v2/):
- types.rs: SessionId/TabId/WindowId newtypes, Mode enum
- action.rs: ~22 Action variants (Phase 1 subset)
- action_result.rs: ActionResult with hint on every error variant
- backend_op.rs: 15 CDP-level primitive operations
- wire.rs: length-prefix framing (4 bytes LE + JSON)
- backend/: BrowserBackendFactory + BackendSession traits, LocalBackend impl
- registry.rs: in-memory session registry with monotonic IDs
- session_actor.rs: per-session tokio task, delegates to action_handler
- action_handler.rs: Action -> BackendOp compilation (14 commands)
- router.rs: request routing (global/session/tab level dispatch)
- server.rs: UDS listener with 0o600 permissions, multi-request connections
- daemon_main.rs: daemon entry point with persistence + recovery
- persistence.rs: atomic state file write (temp+fsync+rename)
- recovery.rs: crash recovery planning per backend type
- cli_v2.rs: thin CLI client with 3-level parameter validation
- client.rs: DaemonClient RPC with 30s timeout
- formatter.rs: ActionResult terminal formatting

Tests: 166 (158 unit + 8 E2E, 2 Chrome-only ignored)

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

* [packages/actionbook-rs]fix: address Codex adversarial review — 5 critical fixes

1. CRITICAL: CDP target routing — LocalBackendSession now tracks
   target_id -> sessionId via Target.attachToTarget { flatten: true }.
   Page-scoped commands include sessionId in CDP JSON.

2. HIGH: StartSession implemented in Router — creates backend via
   factory, spawns SessionActor, registers in registry. Enforces
   1-profile-1-session constraint for Local mode.

3. HIGH: Session Close lifecycle — actor calls backend.shutdown(),
   breaks run loop, router removes session from registry.

4. HIGH: Persistence wired up — save_state() called after
   StartSession/CloseSession, periodic 30s save, save on shutdown.

5. MEDIUM: Wire protocol timeouts — 5 min connection idle timeout,
   30s read timeout on length prefix (slow-loris protection).

Tests: 162 daemon_v2 tests pass.

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

* [packages/actionbook-rs]feat: Phase 2 — ExtensionBackend + CloudBackend + multi-factory router

Add Extension and Cloud browser backends, completing the unified 3-mode
architecture. All sessions now route through the same daemon core
regardless of browser mode.

ExtensionBackend (WS + Token hybrid):
- Daemon-internal WS server (ExtensionBridge) on random localhost port
- One-time token auth via native messaging (Chrome-verified channel)
- Token: 32 random bytes, constant-time comparison, invalidated after use
- BridgeRequest/BridgeResponse protocol for CDP command forwarding
- 1 extension = 1 session constraint enforced in router

CloudBackend (WSS + TLS + auth headers):
- tokio-tungstenite with TLS for remote wss:// endpoints
- Custom auth headers on WS upgrade handshake
- Reconnection with exponential backoff (1s-30s, 5 attempts)
- Health check via separate WSS connection (avoids stream interleaving)
- Single-connection aware (cloud endpoints may reject parallel WS)

Router multi-factory:
- HashMap<Mode, Arc<dyn BrowserBackendFactory>> replaces single factory
- StartSession dispatches to correct factory by mode
- Local: factory.start(), Extension: factory.attach(), Cloud: factory.attach()
- Cloud validates --cdp-endpoint required
- Extension enforces 1-session limit

CLI updates:
- --cdp-endpoint flag on browser start
- Cloud mode validation at CLI level (before daemon round-trip)

Tests: 208 unit + 13 E2E (221 total), zero regressions

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

* [packages/actionbook-rs]feat: Phase 3 — complete all ~60 Action handlers

Add all remaining observation, interaction, waiting, and data actions
to achieve full PRD command coverage.

Observation (15 new): Pdf, Title, Url, Value, Attr, Attrs, Describe,
State, Box, Styles, Viewport, Query, InspectPoint, LogsConsole, LogsErrors

Interaction (9 new): Select, Hover, Focus, Press (modifier-aware chord
parsing), Drag (4-step mouse sequence), Upload (DOM.setFileInputFiles),
Scroll (JS scrollBy), MouseMove, CursorPosition

Waiting (3 new): WaitNavigation (URL change + readyState poll),
WaitNetworkIdle (Performance API poll), WaitCondition (JS expression poll)

Data (10 new): CookiesList/Get/Set/Delete/Clear (CDP Network.*),
StorageList/Get/Set/Delete/Clear (JS localStorage/sessionStorage)

Session (1 new): RestartSession (close + re-start same profile/mode)

All 3 backends updated (local/extension/cloud) with new CDP translations.
CLI clap definitions added for all new commands.

Action coverage: 22 -> 60 variants (exceeds design doc target of ~50)
Tests: 208+ pass, cargo check clean

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

* [packages/actionbook-rs]feat: route browser commands through daemon_v2

Switch `actionbook browser *` commands to route through daemon_v2
by default. Non-browser commands (search, config, setup, etc.)
continue using v0.x path.

- main.rs: try CliV2::try_parse() first for browser commands
- cli_v2.rs: daemon auto-start (fork + poll socket readiness)
- cli.rs: --v1 hidden flag for v0.x escape hatch
- daemon serve-v2: foreground daemon command for debugging

Routing: browser commands -> daemon_v2, everything else -> v0.x
Escape hatch: --v1 forces old path during transition

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

* [packages/actionbook-rs]chore: daemon_v2 cleanup — clippy, codex review fixes, test fixes

- Fix all clippy warnings in daemon_v2/ (unnecessary_unwrap, needless_lifetimes,
  map_entry, collapsible_if, redundant_closure, io_other_error, etc.)
- Replace 3 production unwrap() with safe if-let patterns
- Fix build_state_snapshot hardcoded Local checkpoint (now per-mode)
- Fix health() false positive on JSON parse failure (local.rs)
- Log open_url navigation errors instead of swallowing (local.rs)
- Add doc comments to public Registries methods and OpResult constructors
- Fix E2E test assertion for updated router error code
- Zero clippy warnings, zero dead_code warnings, 208 tests pass
- Chrome E2E tests also pass (2 previously ignored tests now green)

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

* [packages/actionbook-rs]fix: address Codex quality review — 6 fixes

1. router.rs: build_state_snapshot now produces mode-specific checkpoint
   (Local/Extension/Cloud) instead of hardcoding Local for all sessions
2. extension.rs: replace production unwrap() on WS rejection with fallback
3. router.rs: replace production unwrap() on cdp_endpoint with match+fatal
4. router.rs+action.rs: pass ws_headers through to Cloud backend AttachSpec
5. local.rs: log open_url navigation errors instead of swallowing
6. local.rs: health() returns connected=false on JSON parse failure

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

* [packages/actionbook-rs]refactor: clean break — delete v0.x, rename daemon_v2 to daemon

Remove all v0.x code that daemon_v2 replaces. No backward compat,
no --v1 escape hatch. daemon is the only path.

Deleted (-20,946 lines):
- src/daemon/ (old v1 daemon)
- src/browser/session.rs (old 5,846-line SessionManager)
- src/browser/router.rs (old BrowserDriver)
- src/browser/extension_backend.rs
- src/commands/browser.rs (old 6,709-line command handler)
- src/commands/app.rs (Electron, depended on SessionManager)
- src/commands/batch.rs (depended on BrowserDriver)
- tests/app_command_test.rs

Renamed: daemon_v2/ -> daemon/ (all import paths updated)

Cleaned:
- main.rs: daemon CLI is the only browser path, no v1/v2 routing
- cli.rs: removed all browser-only flags and enums
- browser/mod.rs: removed session, router, extension_backend
- commands/daemon.rs: uses new daemon module directly

Tests: 311 unit + 167 integration pass. Zero errors.

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

* [packages/cli]docs: enhance Actionbook CLI architecture and Rust engineering guidelines

Added detailed documentation on the architecture of the Actionbook CLI, emphasizing the three-layer decoupling of the CLI, Daemon, and Browser layers. Included Rust engineering constraints such as the use of mature crates, feature flags for compilation, and guidelines for error handling and output formatting. Also outlined security measures, output/error handling, and best practices for maintaining a minimal binary size. This documentation aims to improve code quality and maintainability across the project.

* [packages/actionbook-rs]chore: add .gitignore to exclude docs directory

Created a new .gitignore file in the actionbook-rs package to prevent the inclusion of the 'docs/' directory in version control.

* [packages/actionbook-rs]fix: address PR #258 Codex review — 4 fixes

P1-1: server.rs — move timeout inside loop (per-read idle timeout,
not per-connection lifetime). Active connections no longer killed.

P1-2: cli_v2.rs — screenshot path now passed through Action, base64
decoded and written to disk after daemon returns.

P1-3: cloud.rs — health probe false positive fixed. Now checks inner
Result with is_ok_and(|r| r.is_ok()) instead of just is_ok().

P2-1: router.rs — TOCTOU race on StartSession fixed. Single atomic
lock: check + allocate ID + insert placeholder. Backend start happens
outside lock. Concurrent requests see Starting placeholder and fail.

Tests: 357 pass.

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

* [packages/actionbook-rs]fix: merge release/1.0.0 + update E2E tests for daemon v2 CLI

- Merge release/1.0.0 (picks up E2E framework from PR #254, CI from PR #257)
- Remove stale daemon_v2/ that came back from merge (replaced by daemon/)
- Update E2E harness: remove --headless --no-daemon global flags (deleted in clean break)
- Update browser_basic test: use v2 CLI format (browser start --mode local --headless,
  browser goto -s s0 -t t0, browser snapshot -s s0 -t t0, browser close -s s0)

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

* [packages/actionbook-rs]fix: add --json and --profile global flags to CliV2

CliV2::try_parse() failed when `actionbook --json browser snapshot ...`
was invoked because --json wasn't a recognized flag. This caused fallthrough
to the old CLI which no longer has `browser` subcommand.

Add --json and --profile as global flags on CliV2 struct so the daemon
CLI parser accepts them. Fixes CI E2E test failure.

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

* [packages/actionbook-rs]chore: remove docs/ from tracked files

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

* [packages/actionbook-rs]fix: show daemon CLI errors for browser commands, not legacy fallback

When `actionbook browser open url` fails to parse (e.g. missing --session),
the CliV2 try_parse error was silently swallowed and the legacy CLI would
report "unrecognized subcommand 'browser'" — completely misleading.

Now: if args contain "browser", always show the daemon CLI error message
(e.g. "the following required arguments were not provided: --session").
Only fall through to legacy CLI for non-browser commands.

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:39:04 +08:00
s1mba 67b8b3122b [root]docs: add release workflow section to CLAUDE.md (#161)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:37:48 +08:00
Adcent b55ccf2709 [root]docs: update CLAUDE.md for new project structure
- Update module structure to reflect current packages
- Remove references to removed directories
- Simplify technology stack and design decisions
- Update published packages table

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:57:08 +08:00
4bmis 36124332a0 feat: add shared browser-profile package and improve selector stability
## Changes

### New: services/common/browser-profile
- Extract BrowserProfileManager to shared package (@actionbookdev/browser-profile)
- Support persistent browser context with anti-detection args
- Add stale lock cleanup for crashed sessions

### Database (services/db)
- Add @neondatabase/serverless support
- Auto-detect local vs Vercel environment for driver selection

### Selector Optimization (services/action-builder)
- Add data-* attributes to selector priority (after data-testid)
- Add hash-based CSS class detection (CSS Modules, styled-components, Emotion)
- Filter state-related data attributes (data-state, data-checked, etc.)
- Prevent duplicate selectors in extraction

### Knowledge Builder (services/knowledge-builder)
- Add `pnpm run login` script for manual browser login
- Integrate shared browser-profile package
- Show warning when profile not found

### Docs
- Add services/common to CLAUDE.md and GEMINI.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 02:15:28 +08:00
Adcent f11ebef1cc [root]docs: add AI coding guidelines
- Add Claude Code instructions (CLAUDE.md)
- Add Gemini instructions (GEMINI.md)
- Add multi-agent guidelines (AGENTS.md)
2025-12-28 15:11:35 +08:00