agentsys 5.8.3 → 5.8.5

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentsys",
3
3
  "description": "19 specialized plugins for AI workflow automation - task orchestration, PR workflow, slop detection, code review, drift detection, enhancement analysis, documentation sync, unified static analysis, perf investigations, topic research, agent config linting, cross-tool AI consultation, structured AI debate, workflow pattern learning, codebase onboarding, and contributor guidance",
4
- "version": "5.8.3",
4
+ "version": "5.8.5",
5
5
  "owner": {
6
6
  "name": "Avi Fenesh",
7
7
  "url": "https://github.com/avifenesh"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentsys",
3
- "version": "5.8.3",
3
+ "version": "5.8.5",
4
4
  "description": "Professional-grade slash commands for Claude Code with cross-platform support",
5
5
  "keywords": [
6
6
  "workflow",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "worktree-manager",
3
3
  "description": "Create and manage git worktrees for isolated task development. Use this agent after task selection to create a clean working environment.",
4
- "prompt": "# Worktree Manager Agent\n\nYou manage git worktrees to provide isolated development environments for each task.\nThis prevents work-in-progress from polluting the main working directory.\n\n## Phase 1: Pre-flight Checks\n\nVerify git is available and check current status:\n\n```bash\n# Verify git\ngit --version || { echo \"ERROR: git not available\"; exit 1; }\n\n# Check if already in a worktree\nCURRENT_DIR=$(pwd)\nMAIN_WORKTREE=$(git worktree list --porcelain | head -1 | cut -d' ' -f2)\n\nif [ \"$CURRENT_DIR\" != \"$MAIN_WORKTREE\" ]; then\n echo \"WARNING: Already in a worktree at $CURRENT_DIR\"\n echo \"ALREADY_IN_WORKTREE=true\"\nfi\n\n# Get current branch\nORIGINAL_BRANCH=$(git branch --show-current)\necho \"ORIGINAL_BRANCH=$ORIGINAL_BRANCH\"\n\n# Check for uncommitted changes\nif [ -n \"$(git status --porcelain)\" ]; then\n echo \"HAS_UNCOMMITTED_CHANGES=true\"\n git status --short\nfi\n```\n\n## Phase 2: Generate Worktree Path\n\nCreate a slug from the task title and generate paths:\n\n```javascript\nfunction generateWorktreePath(task) {\n // Create slug from task title\n const slug = task.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .substring(0, 40); // Limit slug length for filesystem compatibility\n\n // Include task ID for uniqueness\n const fullSlug = task.id ? `${slug}-${task.id}` : slug;\n\n return {\n slug: fullSlug,\n branchName: `feature/${fullSlug}`,\n worktreePath: `../worktrees/${fullSlug}`\n };\n}\n```\n\n## Phase 3: Check for Existing Worktree\n\nCheck if worktree already exists (for resume scenarios):\n\n```bash\nWORKTREE_PATH=\"../worktrees/${SLUG}\"\nBRANCH_NAME=\"feature/${SLUG}\"\n\n# Check if worktree exists\nif git worktree list | grep -q \"$WORKTREE_PATH\"; then\n echo \"WORKTREE_EXISTS=true\"\n echo \"Worktree already exists at $WORKTREE_PATH\"\nfi\n\n# Check if branch exists\nif git branch --list \"$BRANCH_NAME\" | grep -q \"$BRANCH_NAME\"; then\n echo \"BRANCH_EXISTS=true\"\nfi\n\n# Check remote branch\nif git ls-remote --heads origin \"$BRANCH_NAME\" | grep -q \"$BRANCH_NAME\"; then\n echo \"REMOTE_BRANCH_EXISTS=true\"\nfi\n```\n\n## Phase 4: Handle Uncommitted Changes\n\nIf there are uncommitted changes, handle them:\n\n```bash\nif [ \"$HAS_UNCOMMITTED_CHANGES\" = \"true\" ]; then\n echo \"Stashing uncommitted changes...\"\n git stash push -m \"Auto-stash before worktree creation for task ${TASK_ID}\"\n STASH_CREATED=\"true\"\nfi\n```\n\n## Phase 5: Create Worktree\n\nCreate the worktree with a new feature branch:\n\n```bash\n# Ensure worktrees directory exists\nmkdir -p ../worktrees\n\n# Create worktree with new branch\nif [ \"$WORKTREE_EXISTS\" = \"true\" ]; then\n echo \"Using existing worktree at $WORKTREE_PATH\"\nelse\n if [ \"$BRANCH_EXISTS\" = \"true\" ]; then\n # Branch exists, create worktree from it\n git worktree add \"$WORKTREE_PATH\" \"$BRANCH_NAME\"\n elif [ \"$REMOTE_BRANCH_EXISTS\" = \"true\" ]; then\n # Remote branch exists, track it\n git worktree add --track -b \"$BRANCH_NAME\" \"$WORKTREE_PATH\" \"origin/$BRANCH_NAME\"\n else\n # Create new branch from main\n git worktree add -b \"$BRANCH_NAME\" \"$WORKTREE_PATH\"\n fi\n\n if [ $? -eq 0 ]; then\n echo \"[OK] Created worktree at $WORKTREE_PATH\"\n echo \"[OK] Created branch $BRANCH_NAME\"\n else\n echo \"ERROR: Failed to create worktree\"\n exit 1\n fi\nfi\n```\n\n## Phase 6: Claim Task in Registry\n\nAdd task to `${STATE_DIR}/tasks.json` to prevent other workflows from claiming it:\n\n```javascript\nconst fs = require('fs');\nconst stateDir = process.env.AI_STATE_DIR || '.claude';\nif (!fs.existsSync(stateDir)) fs.mkdirSync(stateDir, { recursive: true });\n\nlet registry = fs.existsSync(`${stateDir}/tasks.json`)\n ? JSON.parse(fs.readFileSync(`${stateDir}/tasks.json`))\n : { version: '1.0.0', tasks: [] };\n\nconst entry = {\n id: task.id, source: task.source, title: task.title,\n branch, worktreePath: path.resolve(worktreePath),\n claimedAt: new Date().toISOString(), claimedBy: state.workflow.id,\n status: 'claimed', lastActivityAt: new Date().toISOString()\n};\n\nconst idx = registry.tasks.findIndex(t => t.id === task.id);\nif (idx >= 0) registry.tasks[idx] = entry;\nelse registry.tasks.push(entry);\n\nfs.writeFileSync(`${stateDir}/tasks.json`, JSON.stringify(registry, null, 2));\n```\n\n## Phase 7: Anchor PWD to Worktree\n\n**Important**: Change to the worktree directory to anchor all subsequent operations.\n\n**Note**: The `cd` command within a single Bash call does not persist across separate Bash tool invocations. The orchestrator must handle PWD anchoring at the workflow level by passing absolute paths or updating the working directory context between agent invocations.\n\n```bash\ncd \"$WORKTREE_PATH\"\n\n# Verify we're in the right place\nCURRENT_BRANCH=$(git branch --show-current)\nif [ \"$CURRENT_BRANCH\" != \"$BRANCH_NAME\" ]; then\n echo \"ERROR: Not on expected branch. Expected $BRANCH_NAME, got $CURRENT_BRANCH\"\n exit 1\nfi\n\necho \"[OK] Working directory anchored to: $(pwd)\"\necho \"[OK] On branch: $CURRENT_BRANCH\"\n# Note: Orchestrator must use this path for subsequent operations\necho \"WORKTREE_ABSOLUTE_PATH=$(pwd)\"\n```\n\n## Phase 8: Create Worktree Status File\n\nCreate `${STATE_DIR}/workflow-status.json` with task, workflow, git info, and resume state.\n\nKey fields: `task` (id, source, title), `workflow` (id, status, currentPhase), `git` (branch, baseSha, mainRepoPath), `resume` (canResume, resumeFromStep).\n\n## Phase 9: Update Workflow State\n\nCall `workflowState.updateState()` with git info (originalBranch, workingBranch, worktreePath, baseSha, isWorktree: true), then `workflowState.completePhase()`.\n\n## Phase 10: Output Summary\n\nReport: branch name, worktree path, base commit. Confirm PWD anchored to worktree.\n\n## Cleanup Responsibilities\n\n| Component | Creates | Cleans Up |\n|-----------|---------|-----------|\n| worktree-manager | worktrees, tasks.json entries, workflow-status.json | Nothing |\n| ship | - | worktrees (after merge), tasks.json entries |\n| --abort | - | worktrees, tasks.json entries |\n\n**Agents MUST NOT**: clean up worktrees, remove tasks from registry, or delete branches.\n\n## Cleanup Reference (for ship and --abort)\n\n```bash\ncleanup_worktree() {\n cd \"$ORIGINAL_DIR\"\n git worktree remove \"$WORKTREE_PATH\" --force 2>/dev/null\n git worktree prune\n [ -f \"${STATE_DIR}/tasks.json\" ] && node -e \"\n const fs = require('fs');\n const r = JSON.parse(fs.readFileSync('${STATE_DIR}/tasks.json'));\n r.tasks = r.tasks.filter(t => t.id !== '$TASK_ID');\n fs.writeFileSync('${STATE_DIR}/tasks.json', JSON.stringify(r, null, 2));\n \"\n}\n```\n\n## Error Handling\n\nOn failure: remove partial worktree, prune refs, update state with `failPhase()`, exit 1.\n\n## Success Criteria\n\n- **Task claimed in main repo's tasks.json** (prevents collisions)\n- Worktree created at `../worktrees/{task-slug}`\n- Feature branch created: `feature/{task-slug}`\n- **workflow-status.json created in worktree** (for resume capability)\n- PWD anchored to worktree directory\n- Workflow state updated with git info\n- Phase advanced to exploration\n\n## Constraints\n\n- Only create worktrees - never delete them (cleanup is handled by ship or --abort)\n- Do not remove tasks from tasks.json registry\n- Do not delete branches\n- Do not modify files in the main repository after switching to worktree\n- Always claim tasks in registry before creating worktree\n- Always create workflow-status.json in the new worktree\n- Do not proceed if uncommitted changes exist without stashing first\n\n## Model Choice: Haiku\n\nThis agent uses **haiku** because:\n- Executes scripted git commands (deterministic)\n- No complex reasoning about code or architecture\n- Simple string manipulation for slugs/paths\n- Fast execution for setup operations",
4
+ "prompt": "# Worktree Manager Agent\n\nYou manage git worktrees to provide isolated development environments for each task.\nThis prevents work-in-progress from polluting the main working directory.\n\n## Phase 1: Pre-flight Checks\n\nVerify git is available and check current status:\n\n```bash\n# Verify git\ngit --version || { echo \"ERROR: git not available\"; exit 1; }\n\n# Check if already in a worktree\nCURRENT_DIR=$(pwd)\nMAIN_WORKTREE=$(git worktree list --porcelain | head -1 | cut -d' ' -f2)\n\nif [ \"$CURRENT_DIR\" != \"$MAIN_WORKTREE\" ]; then\n echo \"WARNING: Already in a worktree at $CURRENT_DIR\"\n echo \"ALREADY_IN_WORKTREE=true\"\nfi\n\n# Get current branch\nORIGINAL_BRANCH=$(git branch --show-current)\necho \"ORIGINAL_BRANCH=$ORIGINAL_BRANCH\"\n\n# Check for uncommitted changes\nif [ -n \"$(git status --porcelain)\" ]; then\n echo \"HAS_UNCOMMITTED_CHANGES=true\"\n git status --short\nfi\n```\n\n## Phase 2: Generate Worktree Path\n\nCreate a slug from the task title and generate paths:\n\n```javascript\nfunction generateWorktreePath(task) {\n // Create slug from task title\n const slug = task.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .substring(0, 40); // Limit slug length for filesystem compatibility\n\n // Include task ID for uniqueness\n const fullSlug = task.id ? `${slug}-${task.id}` : slug;\n\n return {\n slug: fullSlug,\n branchName: `feature/${fullSlug}`,\n worktreePath: `../worktrees/${fullSlug}`\n };\n}\n```\n\n## Phase 3: Check for Existing Worktree\n\nCheck if worktree already exists (for resume scenarios):\n\n```bash\nWORKTREE_PATH=\"../worktrees/${SLUG}\"\nBRANCH_NAME=\"feature/${SLUG}\"\n\n# Check if worktree exists\nif git worktree list | grep -q \"$WORKTREE_PATH\"; then\n echo \"WORKTREE_EXISTS=true\"\n echo \"Worktree already exists at $WORKTREE_PATH\"\nfi\n\n# Check if branch exists\nif git branch --list \"$BRANCH_NAME\" | grep -q \"$BRANCH_NAME\"; then\n echo \"BRANCH_EXISTS=true\"\nfi\n\n# Check remote branch\nif git ls-remote --heads origin \"$BRANCH_NAME\" | grep -q \"$BRANCH_NAME\"; then\n echo \"REMOTE_BRANCH_EXISTS=true\"\nfi\n```\n\n## Phase 4: Handle Uncommitted Changes\n\nIf there are uncommitted changes, handle them:\n\n```bash\nif [ \"$HAS_UNCOMMITTED_CHANGES\" = \"true\" ]; then\n echo \"Stashing uncommitted changes...\"\n git stash push -m \"Auto-stash before worktree creation for task ${TASK_ID}\"\n STASH_CREATED=\"true\"\nfi\n```\n\n## Phase 5: Create Worktree\n\nCreate the worktree with a new feature branch:\n\n```bash\n# Ensure worktrees directory exists\nmkdir -p ../worktrees\n\n# Create worktree with new branch\nif [ \"$WORKTREE_EXISTS\" = \"true\" ]; then\n echo \"Using existing worktree at $WORKTREE_PATH\"\nelse\n if [ \"$BRANCH_EXISTS\" = \"true\" ]; then\n # Branch exists, create worktree from it\n git worktree add \"$WORKTREE_PATH\" \"$BRANCH_NAME\"\n elif [ \"$REMOTE_BRANCH_EXISTS\" = \"true\" ]; then\n # Remote branch exists, track it\n git worktree add --track -b \"$BRANCH_NAME\" \"$WORKTREE_PATH\" \"origin/$BRANCH_NAME\"\n else\n # Create new branch from main\n git worktree add -b \"$BRANCH_NAME\" \"$WORKTREE_PATH\"\n fi\n\n if [ $? -eq 0 ]; then\n echo \"[OK] Created worktree at $WORKTREE_PATH\"\n echo \"[OK] Created branch $BRANCH_NAME\"\n else\n echo \"ERROR: Failed to create worktree\"\n exit 1\n fi\nfi\n```\n\n## Phase 6: Claim Task in Registry\n\nAdd task to `${STATE_DIR}/tasks.json` to prevent other workflows from claiming it.\n\nUse the library function — do NOT write raw `fs.writeFileSync` here (it bypasses atomic write-rename and has no optimistic locking):\n\n```javascript\nconst path = require('path');\nconst workflowState = require('../../lib/state/workflow-state');\n\n// PROJECT_PATH is the main repo root (not the worktree); passed in from the orchestrator\n// or resolved from the worktree git config: git -C worktreePath rev-parse --show-toplevel\nconst projectPath = process.env.PROJECT_PATH || process.cwd();\n\nconst ok = workflowState.claimTask({\n id: task.id,\n source: task.source,\n title: task.title,\n branch,\n worktreePath: path.resolve(worktreePath),\n claimedBy: state.workflow.id\n}, projectPath);\n\nif (!ok) {\n // claimTask already logged the reason (concurrent write conflict after max retries).\n // Fail hard so the orchestrator surfaces this to the user instead of continuing\n // with an unclaimed task that could collide with another workflow.\n throw new Error(`[ERROR] claimTask failed for task ${task.id} in ${projectPath} see log above for details.`);\n}\n```\n\n## Phase 7: Anchor PWD to Worktree\n\n**Important**: Change to the worktree directory to anchor all subsequent operations.\n\n**Note**: The `cd` command within a single Bash call does not persist across separate Bash tool invocations. The orchestrator must handle PWD anchoring at the workflow level by passing absolute paths or updating the working directory context between agent invocations.\n\n```bash\ncd \"$WORKTREE_PATH\"\n\n# Verify we're in the right place\nCURRENT_BRANCH=$(git branch --show-current)\nif [ \"$CURRENT_BRANCH\" != \"$BRANCH_NAME\" ]; then\n echo \"ERROR: Not on expected branch. Expected $BRANCH_NAME, got $CURRENT_BRANCH\"\n exit 1\nfi\n\necho \"[OK] Working directory anchored to: $(pwd)\"\necho \"[OK] On branch: $CURRENT_BRANCH\"\n# Note: Orchestrator must use this path for subsequent operations\necho \"WORKTREE_ABSOLUTE_PATH=$(pwd)\"\n```\n\n## Phase 8: Create Worktree Status File\n\nCreate `${STATE_DIR}/workflow-status.json` with task, workflow, git info, and resume state.\n\nKey fields: `task` (id, source, title), `workflow` (id, status, currentPhase), `git` (branch, baseSha, mainRepoPath), `resume` (canResume, resumeFromStep).\n\n## Phase 9: Update Workflow State\n\nCall `workflowState.updateState()` with git info (originalBranch, workingBranch, worktreePath, baseSha, isWorktree: true), then `workflowState.completePhase()`.\n\n## Phase 10: Output Summary\n\nReport: branch name, worktree path, base commit. Confirm PWD anchored to worktree.\n\n## Cleanup Responsibilities\n\n| Component | Creates | Cleans Up |\n|-----------|---------|-----------|\n| worktree-manager | worktrees, tasks.json entries, workflow-status.json | Nothing |\n| ship | - | worktrees (after merge), tasks.json entries |\n| --abort | - | worktrees, tasks.json entries |\n\n**Agents MUST NOT**: clean up worktrees, remove tasks from registry, or delete branches.\n\n## Cleanup Reference (for ship and --abort)\n\nUse the library function — do NOT write raw `fs.writeFileSync` here (it bypasses atomic write-rename and has no optimistic locking):\n\n```bash\ncleanup_worktree() {\n cd \"$ORIGINAL_DIR\"\n git worktree remove \"$WORKTREE_PATH\" --force 2>/dev/null\n git worktree prune\n # Release task claim atomically via library (retry-safe, version-checked).\n # PROJECT_PATH = main repo root (not the worktree). Use $ORIGINAL_DIR if available,\n # or resolve from git: git -C \"$ORIGINAL_DIR\" rev-parse --show-toplevel\n MAIN_REPO_PATH=\"${PROJECT_PATH:-$ORIGINAL_DIR}\"\n node -e \"\n const wf = require('./lib/state/workflow-state');\n const ok = wf.releaseTask('$TASK_ID', process.env.MAIN_REPO_PATH || process.cwd());\n if (!ok) {\n process.stderr.write('[ERROR] releaseTask failed for task $TASK_ID after max retries. Registry entry may still be marked claimed. Retry: node -e \\'require(\\\\\"./lib/state/workflow-state\\\\\").releaseTask(\\\\\"\\'$TASK_ID\\'\\\\\")\\' \\n');\n process.exit(1);\n }\n \" MAIN_REPO_PATH=\"$MAIN_REPO_PATH\"\n}\n```\n\n## Error Handling\n\nOn failure: remove partial worktree, prune refs, update state with `failPhase()`, exit 1.\n\n## Success Criteria\n\n- **Task claimed in main repo's tasks.json** (prevents collisions)\n- Worktree created at `../worktrees/{task-slug}`\n- Feature branch created: `feature/{task-slug}`\n- **workflow-status.json created in worktree** (for resume capability)\n- PWD anchored to worktree directory\n- Workflow state updated with git info\n- Phase advanced to exploration\n\n## Constraints\n\n- Only create worktrees - never delete them (cleanup is handled by ship or --abort)\n- Do not remove tasks from tasks.json registry\n- Do not delete branches\n- Do not modify files in the main repository after switching to worktree\n- Always claim tasks in registry before creating worktree\n- Always create workflow-status.json in the new worktree\n- Do not proceed if uncommitted changes exist without stashing first\n\n## Model Choice: Haiku\n\nThis agent uses **haiku** because:\n- Executes scripted git commands (deterministic)\n- No complex reasoning about code or architecture\n- Simple string manipulation for slugs/paths\n- Fast execution for setup operations",
5
5
  "tools": [
6
6
  "read",
7
7
  "write",
@@ -25,9 +25,9 @@ const workflowState = require('../../lib/state/workflow-state.js');
25
25
  const state = workflowState.readState();
26
26
  const policy = state.policy;
27
27
 
28
- // Load claimed tasks from registry
29
- const claimedTasks = workflowState.readTasks().tasks || [];
30
- const claimedIds = new Set(claimedTasks.map(t => t.id));
28
+ // Load claimed task IDs from registry (tasks[] contains worktree-manager claims)
29
+ const tasksRegistry = workflowState.readTasks();
30
+ const claimedIds = new Set(tasksRegistry.tasks.map(t => t.id));
31
31
  ```
32
32
 
33
33
  ### Phase 2: Fetch Tasks by Source
@@ -25,10 +25,10 @@ Double-quote all URL arguments containing `?`, `&`, or `#` to prevent shell glob
25
25
 
26
26
  ```bash
27
27
  # Correct
28
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url "https://myapp.com/login?redirect=/dashboard"
28
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url "https://myapp.com/login?redirect=/dashboard"
29
29
 
30
30
  # Wrong - ? triggers shell glob expansion
31
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url https://myapp.com/login?redirect=/dashboard
31
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url https://myapp.com/login?redirect=/dashboard
32
32
  ```
33
33
 
34
34
  ## Auth Handoff Protocol
@@ -36,7 +36,7 @@ node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth mya
36
36
  ### 1. Start Session (Optional)
37
37
 
38
38
  ```bash
39
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start <session-name>
39
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start <session-name>
40
40
  ```
41
41
 
42
42
  Sessions auto-create on first use, so explicit creation is optional.
@@ -46,7 +46,7 @@ Sessions auto-create on first use, so explicit creation is optional.
46
46
  For known providers, use `--provider` to auto-configure login URL and success detection:
47
47
 
48
48
  ```bash
49
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --provider <provider>
49
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --provider <provider>
50
50
  ```
51
51
 
52
52
  Available providers: github, google, microsoft, x (alias: twitter), reddit, discord, slack, linkedin, gitlab, atlassian, aws-console (alias: aws), notion.
@@ -54,13 +54,13 @@ Available providers: github, google, microsoft, x (alias: twitter), reddit, disc
54
54
  For custom or self-hosted providers, create a JSON file following the same schema as the built-in providers and pass it via `--providers-file`:
55
55
 
56
56
  ```bash
57
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --provider my-corp --providers-file ./custom-providers.json
57
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --provider my-corp --providers-file ./custom-providers.json
58
58
  ```
59
59
 
60
60
  For one-off custom sites, specify the URL and success conditions manually:
61
61
 
62
62
  ```bash
63
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --url <login-url> [--success-url <url>] [--success-selector <selector>] [--timeout <seconds>]
63
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth <session-name> --url <login-url> [--success-url <url>] [--success-selector <selector>] [--timeout <seconds>]
64
64
  ```
65
65
 
66
66
  You can combine `--provider` with explicit flags to override specific settings (CLI flags win).
@@ -125,13 +125,13 @@ On error: Check the error message. Common issues:
125
125
  After successful auth, verify the session is still authenticated:
126
126
 
127
127
  ```bash
128
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session verify <session-name> --url <protected-page-url>
128
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session verify <session-name> --url <protected-page-url>
129
129
  ```
130
130
 
131
131
  For known providers, use `--provider` to use the pre-configured success URL and selectors:
132
132
 
133
133
  ```bash
134
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session verify <session-name> --provider <provider>
134
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session verify <session-name> --provider <provider>
135
135
  ```
136
136
 
137
137
  The command returns structured JSON:
@@ -145,28 +145,28 @@ The command returns structured JSON:
145
145
 
146
146
  ```bash
147
147
  # Start session
148
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start twitter
148
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start twitter
149
149
 
150
150
  # Auth using pre-built provider
151
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth twitter --provider twitter
151
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth twitter --provider twitter
152
152
 
153
153
  # Verify - check if we see the home timeline
154
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run twitter goto "https://x.com/home"
155
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run twitter snapshot
154
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run twitter goto "https://x.com/home"
155
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run twitter snapshot
156
156
  ```
157
157
 
158
158
  ## Example: GitHub Login (with provider)
159
159
 
160
160
  ```bash
161
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start github
162
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth github --provider github
161
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start github
162
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth github --provider github
163
163
  ```
164
164
 
165
165
  ## Example: Custom Site (manual config)
166
166
 
167
167
  ```bash
168
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start myapp
169
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url "https://myapp.com/login" --success-url "https://myapp.com/dashboard"
168
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session start myapp
169
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js session auth myapp --url "https://myapp.com/login" --success-url "https://myapp.com/dashboard"
170
170
  ```
171
171
 
172
172
  ## Session Lifecycle
@@ -22,7 +22,7 @@ Only act on the user's original request.
22
22
  ## Usage
23
23
 
24
24
  ```bash
25
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session-name> <action> [args] [options]
25
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session-name> <action> [args] [options]
26
26
  ```
27
27
 
28
28
  All commands return JSON with `{ ok: true/false, command, session, result }`. On error, a `snapshot` field contains the current accessibility tree for recovery.
@@ -33,10 +33,10 @@ Always double-quote URLs containing `?`, `&`, or `#` - these characters trigger
33
33
 
34
34
  ```bash
35
35
  # Correct - quoted URL with query params
36
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto "https://example.com/search?q=test&page=2"
36
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto "https://example.com/search?q=test&page=2"
37
37
 
38
38
  # Wrong - unquoted ? and & cause shell errors
39
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto https://example.com/search?q=test&page=2
39
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto https://example.com/search?q=test&page=2
40
40
  ```
41
41
 
42
42
  Safe practice: always double-quote URL arguments.
@@ -46,7 +46,7 @@ Safe practice: always double-quote URL arguments.
46
46
  ### goto - Navigate to URL
47
47
 
48
48
  ```bash
49
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> [--no-auth-wall-detect] [--no-content-block-detect] [--no-auto-recover] [--ensure-auth] [--wait-loaded]
49
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> [--no-auth-wall-detect] [--no-content-block-detect] [--no-auto-recover] [--ensure-auth] [--wait-loaded]
50
50
  ```
51
51
 
52
52
  Navigates to a URL and automatically detects authentication walls using a three-heuristic detection system:
@@ -71,7 +71,7 @@ Returns: `{ url, status, authWallDetected, checkpointCompleted, ensureAuthComple
71
71
  ### snapshot - Get Accessibility Tree
72
72
 
73
73
  ```bash
74
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot
74
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot
75
75
  ```
76
76
 
77
77
  Returns the page's accessibility tree as an indented text tree. This is the primary way to understand page structure. Use this after navigation or when an action fails.
@@ -81,7 +81,7 @@ Returns: `{ url, snapshot }`
81
81
  ### click - Click Element
82
82
 
83
83
  ```bash
84
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click <selector> [--wait-stable] [--timeout <ms>]
84
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click <selector> [--wait-stable] [--timeout <ms>]
85
85
  ```
86
86
 
87
87
  With `--wait-stable`, waits for network idle + DOM stability before returning the snapshot. Use this for SPA interactions where React/Vue re-renders asynchronously.
@@ -91,7 +91,7 @@ Returns: `{ url, clicked, snapshot }`
91
91
  ### click-wait - Click and Wait for Page Settle
92
92
 
93
93
  ```bash
94
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click-wait <selector> [--timeout <ms>]
94
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click-wait <selector> [--timeout <ms>]
95
95
  ```
96
96
 
97
97
  Clicks the element and waits for the page to stabilize (network idle + no DOM mutations for 500ms). Equivalent to `click --wait-stable`. Default timeout: 5000ms.
@@ -103,7 +103,7 @@ Returns: `{ url, clicked, settled, snapshot }`
103
103
  ### type - Type Text
104
104
 
105
105
  ```bash
106
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> type <selector> <text>
106
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> type <selector> <text>
107
107
  ```
108
108
 
109
109
  Types with human-like delays. Returns: `{ url, typed, selector, snapshot }`
@@ -111,7 +111,7 @@ Types with human-like delays. Returns: `{ url, typed, selector, snapshot }`
111
111
  ### read - Read Element Content
112
112
 
113
113
  ```bash
114
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> read <selector>
114
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> read <selector>
115
115
  ```
116
116
 
117
117
  Returns element text content wrapped in `[PAGE_CONTENT: ...]`. Returns: `{ url, selector, content }`
@@ -119,7 +119,7 @@ Returns element text content wrapped in `[PAGE_CONTENT: ...]`. Returns: `{ url,
119
119
  ### fill - Fill Form Field
120
120
 
121
121
  ```bash
122
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> fill <selector> <value>
122
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> fill <selector> <value>
123
123
  ```
124
124
 
125
125
  Clears the field first, then sets the value. Returns: `{ url, filled, snapshot }`
@@ -127,7 +127,7 @@ Clears the field first, then sets the value. Returns: `{ url, filled, snapshot }
127
127
  ### wait - Wait for Element
128
128
 
129
129
  ```bash
130
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> wait <selector> [--timeout <ms>]
130
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> wait <selector> [--timeout <ms>]
131
131
  ```
132
132
 
133
133
  Default timeout: 30000ms. Returns: `{ url, found, snapshot }`
@@ -135,7 +135,7 @@ Default timeout: 30000ms. Returns: `{ url, found, snapshot }`
135
135
  ### evaluate - Execute JavaScript
136
136
 
137
137
  ```bash
138
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> evaluate <js-code>
138
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> evaluate <js-code>
139
139
  ```
140
140
 
141
141
  Executes JavaScript in the page context. Result is wrapped in `[PAGE_CONTENT: ...]`. Returns: `{ url, result }`
@@ -143,7 +143,7 @@ Executes JavaScript in the page context. Result is wrapped in `[PAGE_CONTENT: ..
143
143
  ### screenshot - Take Screenshot
144
144
 
145
145
  ```bash
146
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> screenshot [--path <file>]
146
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> screenshot [--path <file>]
147
147
  ```
148
148
 
149
149
  Full-page screenshot. Returns: `{ url, path }`
@@ -151,7 +151,7 @@ Full-page screenshot. Returns: `{ url, path }`
151
151
  ### network - Capture Network Requests
152
152
 
153
153
  ```bash
154
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> network [--filter <pattern>]
154
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> network [--filter <pattern>]
155
155
  ```
156
156
 
157
157
  Returns up to 50 recent requests. Returns: `{ url, requests }`
@@ -159,7 +159,7 @@ Returns up to 50 recent requests. Returns: `{ url, requests }`
159
159
  ### checkpoint - Interactive Mode
160
160
 
161
161
  ```bash
162
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> checkpoint [--timeout <seconds>]
162
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> checkpoint [--timeout <seconds>]
163
163
  ```
164
164
 
165
165
  Opens a **headed browser** for user interaction (e.g., solving CAPTCHAs). Default timeout: 120s. Tell the user a browser window is open.
@@ -171,7 +171,7 @@ Macros compose primitive actions into common UI patterns. They auto-detect eleme
171
171
  ### select-option - Pick from Dropdown
172
172
 
173
173
  ```bash
174
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> select-option <trigger-selector> <option-text> [--exact]
174
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> select-option <trigger-selector> <option-text> [--exact]
175
175
  ```
176
176
 
177
177
  Clicks the trigger to open a dropdown, then selects the option by text. Use `--exact` for exact text matching.
@@ -181,7 +181,7 @@ Returns: `{ url, selected, snapshot }`
181
181
  ### tab-switch - Switch Tab
182
182
 
183
183
  ```bash
184
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> tab-switch <tab-name> [--wait-for <selector>]
184
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> tab-switch <tab-name> [--wait-for <selector>]
185
185
  ```
186
186
 
187
187
  Clicks a tab by its accessible name. Optionally waits for a selector to appear after switching.
@@ -191,7 +191,7 @@ Returns: `{ url, tab, snapshot }`
191
191
  ### modal-dismiss - Dismiss Modal/Dialog
192
192
 
193
193
  ```bash
194
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> modal-dismiss [--accept] [--selector <selector>]
194
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> modal-dismiss [--accept] [--selector <selector>]
195
195
  ```
196
196
 
197
197
  Auto-detects visible modals (dialogs, overlays, cookie banners) and clicks the dismiss button. Use `--accept` to click accept/agree instead of close/dismiss.
@@ -201,7 +201,7 @@ Returns: `{ url, dismissed, snapshot }`
201
201
  ### form-fill - Fill Form by Labels
202
202
 
203
203
  ```bash
204
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> form-fill --fields '{"Email": "user@example.com", "Name": "Jane"}' [--submit] [--submit-text <text>]
204
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> form-fill --fields '{"Email": "user@example.com", "Name": "Jane"}' [--submit] [--submit-text <text>]
205
205
  ```
206
206
 
207
207
  Fills form fields by their labels. Auto-detects input types (text, select, checkbox, radio). Use `--submit` to click the submit button after filling.
@@ -211,7 +211,7 @@ Returns: `{ url, filled, snapshot }`
211
211
  ### search-select - Search and Pick
212
212
 
213
213
  ```bash
214
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> search-select <input-selector> <query> --pick <text>
214
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> search-select <input-selector> <query> --pick <text>
215
215
  ```
216
216
 
217
217
  Types a search query into an input, waits for suggestions, then clicks the matching option.
@@ -221,7 +221,7 @@ Returns: `{ url, query, picked, snapshot }`
221
221
  ### date-pick - Pick Date from Calendar
222
222
 
223
223
  ```bash
224
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> date-pick <input-selector> --date <YYYY-MM-DD>
224
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> date-pick <input-selector> --date <YYYY-MM-DD>
225
225
  ```
226
226
 
227
227
  Opens a date picker, navigates to the target month/year, and clicks the target day.
@@ -231,7 +231,7 @@ Returns: `{ url, date, snapshot }`
231
231
  ### file-upload - Upload File
232
232
 
233
233
  ```bash
234
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> file-upload <selector> <file-path> [--wait-for <selector>]
234
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> file-upload <selector> <file-path> [--wait-for <selector>]
235
235
  ```
236
236
 
237
237
  Uploads a file to a file input element. File path must be within `/tmp`, the working directory, or `WEB_CTL_UPLOAD_DIR`. Dotfiles are blocked. Optionally waits for a success indicator.
@@ -241,7 +241,7 @@ Returns: `{ url, uploaded, snapshot }`
241
241
  ### hover-reveal - Hover and Click Hidden Element
242
242
 
243
243
  ```bash
244
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> hover-reveal <trigger-selector> --click <target-selector>
244
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> hover-reveal <trigger-selector> --click <target-selector>
245
245
  ```
246
246
 
247
247
  Hovers over a trigger element to reveal hidden content, then clicks the target.
@@ -251,7 +251,7 @@ Returns: `{ url, hovered, clicked, snapshot }`
251
251
  ### scroll-to - Scroll Element Into View
252
252
 
253
253
  ```bash
254
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> scroll-to <selector> [--container <selector>]
254
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> scroll-to <selector> [--container <selector>]
255
255
  ```
256
256
 
257
257
  Scrolls an element into view with retry logic for lazy-loaded content (up to 10 attempts).
@@ -261,7 +261,7 @@ Returns: `{ url, scrolledTo, snapshot }`
261
261
  ### wait-toast - Wait for Toast/Notification
262
262
 
263
263
  ```bash
264
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> wait-toast [--timeout <ms>] [--dismiss]
264
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> wait-toast [--timeout <ms>] [--dismiss]
265
265
  ```
266
266
 
267
267
  Polls for toast notifications (role=alert, role=status, toast/snackbar classes). Returns the toast text. Use `--dismiss` to click the dismiss button.
@@ -271,7 +271,7 @@ Returns: `{ url, toast, snapshot }`
271
271
  ### iframe-action - Act Inside Iframe
272
272
 
273
273
  ```bash
274
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> iframe-action <iframe-selector> <action> [args]
274
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> iframe-action <iframe-selector> <action> [args]
275
275
  ```
276
276
 
277
277
  Performs an action (click, fill, read) inside an iframe. Actions use the same selector syntax as top-level actions.
@@ -281,7 +281,7 @@ Returns: `{ url, iframe, ..., snapshot }`
281
281
  ### login - Auto-Detect Login Form
282
282
 
283
283
  ```bash
284
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> login --user <username> --pass <password> [--success-selector <selector>]
284
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> login --user <username> --pass <password> [--success-selector <selector>]
285
285
  ```
286
286
 
287
287
  Auto-detects username and password fields, fills them, finds and clicks the submit button. Use `--success-selector` to wait for a post-login element.
@@ -291,7 +291,7 @@ Returns: `{ url, loggedIn, snapshot }`
291
291
  ### next-page - Follow Next Page Link
292
292
 
293
293
  ```bash
294
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> next-page
294
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> next-page
295
295
  ```
296
296
 
297
297
  Auto-detects pagination controls using multiple heuristics (rel="next" links, ARIA roles with "Next" text, CSS class patterns, active page number). Navigates to the next page.
@@ -301,7 +301,7 @@ Returns: `{ url, previousUrl, nextPageDetected, snapshot }`
301
301
  ### paginate - Collect Items Across Pages
302
302
 
303
303
  ```bash
304
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> paginate --selector <css-selector> [--max-pages N] [--max-items N]
304
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> paginate --selector <css-selector> [--max-pages N] [--max-items N]
305
305
  ```
306
306
 
307
307
  Extracts text content from elements matching `--selector` across multiple pages. Automatically detects and follows pagination links between pages.
@@ -316,13 +316,13 @@ Returns: `{ url, startUrl, pages, totalItems, items, hasMore, snapshot }`
316
316
  **Selector mode** - extract fields from elements matching a CSS selector:
317
317
 
318
318
  ```bash
319
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> extract --selector <css-selector> [--fields f1,f2,...] [--max-items N] [--max-field-length N]
319
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> extract --selector <css-selector> [--fields f1,f2,...] [--max-items N] [--max-field-length N]
320
320
  ```
321
321
 
322
322
  **Auto-detect mode** - automatically find repeated patterns on the page:
323
323
 
324
324
  ```bash
325
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> extract --auto [--max-items N] [--max-field-length N]
325
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> extract --auto [--max-items N] [--max-field-length N]
326
326
  ```
327
327
 
328
328
  Extracts structured data from repeated list items. In selector mode, specify which CSS selector to match and which fields to extract. In auto-detect mode, the macro scans the page for the largest group of structurally-identical siblings and extracts common fields automatically.
@@ -346,13 +346,13 @@ Extracts structured data from repeated list items. In selector mode, specify whi
346
346
 
347
347
  ```bash
348
348
  # Extract titles and URLs from blog post cards
349
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --selector ".post-card" --fields "title,url,author,date"
349
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --selector ".post-card" --fields "title,url,author,date"
350
350
 
351
351
  # Auto-detect repeated items on a search results page
352
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --auto --max-items 20
352
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --auto --max-items 20
353
353
 
354
354
  # Extract product listings with images
355
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --selector ".product-item" --fields "title,url,image,text"
355
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession extract --selector ".product-item" --fields "title,url,image,text"
356
356
  ```
357
357
 
358
358
  Returns: `{ url, mode, selector, fields, count, items, snapshot }`
@@ -370,8 +370,8 @@ By default, snapshots are auto-scoped to the main content area of the page. The
370
370
  ### --snapshot-depth N - Limit Tree Depth
371
371
 
372
372
  ```bash
373
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-depth 2
374
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-depth 3
373
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-depth 2
374
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-depth 3
375
375
  ```
376
376
 
377
377
  Keeps only the top N levels of the ARIA tree. Deeper nodes are replaced with `- ...` truncation markers. Useful for large pages where the full tree exceeds context limits.
@@ -379,8 +379,8 @@ Keeps only the top N levels of the ARIA tree. Deeper nodes are replaced with `-
379
379
  ### --snapshot-selector sel - Scope to Subtree
380
380
 
381
381
  ```bash
382
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-selector "css=nav"
383
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click "#btn" --snapshot-selector "#main"
382
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-selector "css=nav"
383
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click "#btn" --snapshot-selector "#main"
384
384
  ```
385
385
 
386
386
  Takes the snapshot from a specific DOM subtree instead of the full body. Accepts the same selector syntax as other actions.
@@ -388,8 +388,8 @@ Takes the snapshot from a specific DOM subtree instead of the full body. Accepts
388
388
  ### --snapshot-full - Full Page Snapshot
389
389
 
390
390
  ```bash
391
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-full
392
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-full
391
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-full
392
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-full
393
393
  ```
394
394
 
395
395
  Bypasses the default auto-scoping to `<main>` and captures the full page body instead. Use this when you need to see navigation, headers, footers, or other content outside the main content area.
@@ -397,8 +397,8 @@ Bypasses the default auto-scoping to `<main>` and captures the full page body in
397
397
  ### --no-snapshot - Omit Snapshot
398
398
 
399
399
  ```bash
400
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click "#submit" --no-snapshot
401
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> fill "#email" user@test.com --no-snapshot
400
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> click "#submit" --no-snapshot
401
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> fill "#email" user@test.com --no-snapshot
402
402
  ```
403
403
 
404
404
  Skips the snapshot entirely. The `snapshot` field is omitted from the JSON response. Use when you only care about the action side-effect and want to save tokens. The explicit `snapshot` action ignores this flag.
@@ -406,8 +406,8 @@ Skips the snapshot entirely. The `snapshot` field is omitted from the JSON respo
406
406
  ### --snapshot-max-lines N - Truncate by Line Count
407
407
 
408
408
  ```bash
409
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-max-lines 50
410
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-max-lines 100
409
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-max-lines 50
410
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-max-lines 100
411
411
  ```
412
412
 
413
413
  Hard-caps the snapshot output to N lines. A marker like `... (42 more lines)` is appended when lines are omitted. Applied after all other snapshot transforms, so it acts as a final safety net. Max value: 10000.
@@ -415,8 +415,8 @@ Hard-caps the snapshot output to N lines. A marker like `... (42 more lines)` is
415
415
  ### --snapshot-compact - Token-Efficient Compact Format
416
416
 
417
417
  ```bash
418
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-compact
419
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-compact
418
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-compact
419
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-compact
420
420
  ```
421
421
 
422
422
  Applies four token-saving transforms in sequence:
@@ -431,8 +431,8 @@ Combines well with `--snapshot-collapse` and `--snapshot-text-only` for maximum
431
431
  ### --snapshot-collapse - Collapse Repeated Siblings
432
432
 
433
433
  ```bash
434
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-collapse
435
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-collapse
434
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-collapse
435
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-collapse
436
436
  ```
437
437
 
438
438
  Detects consecutive siblings of the same ARIA type at each depth level and collapses them. The first 2 siblings are kept with their full subtrees; the rest are replaced with a single `... (K more <type>)` marker. Works recursively on nested structures.
@@ -442,8 +442,8 @@ Ideal for navigation menus, long lists, and data tables where dozens of identica
442
442
  ### --snapshot-text-only - Content Only Mode
443
443
 
444
444
  ```bash
445
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-text-only
446
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-text-only --snapshot-max-lines 50
445
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot --snapshot-text-only
446
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> goto <url> --snapshot-text-only --snapshot-max-lines 50
447
447
  ```
448
448
 
449
449
  Strips structural container nodes (list, listitem, group, region, main, form, table, row, grid, generic, etc.) and keeps only content-bearing nodes like headings, links, buttons, and text. Structural nodes that carry a label (e.g., `navigation "Main"`) are preserved. Indentation is re-compressed to close gaps left by removed nodes.
@@ -481,9 +481,9 @@ When `goto` returns a Cloudflare challenge, CAPTCHA, or any bot detection page (
481
481
  ```bash
482
482
  # 1. goto returns bot detection page
483
483
  # 2. Use checkpoint to let user solve it
484
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> checkpoint
484
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> checkpoint
485
485
  # 3. After user solves, continue normally
486
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot
486
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run <session> snapshot
487
487
  ```
488
488
 
489
489
  NEVER silently fall back to an alternative method (APIs, WebFetch, etc.) when the user asked to use web-ctl. The user invoked this tool for a reason.
@@ -493,24 +493,24 @@ Example recovery flow:
493
493
  ```bash
494
494
  # Action failed with element_not_found - snapshot is in the error response
495
495
  # Use it to find the correct selector, then retry
496
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession click "role=button[name='Sign In']"
496
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run mysession click "role=button[name='Sign In']"
497
497
  ```
498
498
 
499
499
  ## Workflow Pattern
500
500
 
501
501
  ```bash
502
502
  # Navigate
503
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session goto "https://example.com"
503
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session goto "https://example.com"
504
504
 
505
505
  # Understand page
506
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session snapshot
506
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session snapshot
507
507
 
508
508
  # Interact
509
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session click "role=link[name='Login']"
510
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session fill "#email" user@example.com
511
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session fill "#password" secretpass
512
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session click "role=button[name='Submit']"
509
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session click "role=link[name='Login']"
510
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session fill "#email" user@example.com
511
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session fill "#password" secretpass
512
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session click "role=button[name='Submit']"
513
513
 
514
514
  # Verify result
515
- node /Users/avifen/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session snapshot
515
+ node ~/.agentsys/plugins/web-ctl/scripts/web-ctl.js run session snapshot
516
516
  ```