@vforsh/argus 0.1.18 → 0.1.19

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.
Files changed (84) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/argus.js +2802 -564
  3. package/dist/cli/plugins/pluginHost.d.ts.map +1 -1
  4. package/dist/cli/plugins/pluginHost.js +1 -0
  5. package/dist/cli/plugins/pluginHost.js.map +1 -1
  6. package/dist/cli/register/extensionCommands.d.ts.map +1 -1
  7. package/dist/cli/register/extensionCommands.js +103 -3
  8. package/dist/cli/register/extensionCommands.js.map +1 -1
  9. package/dist/cli/register/index.d.ts.map +1 -1
  10. package/dist/cli/register/index.js +6 -0
  11. package/dist/cli/register/index.js.map +1 -1
  12. package/dist/cli/register/recordCommands.d.ts +3 -0
  13. package/dist/cli/register/recordCommands.d.ts.map +1 -0
  14. package/dist/cli/register/recordCommands.js +90 -0
  15. package/dist/cli/register/recordCommands.js.map +1 -0
  16. package/dist/cli/register/skillCommands.d.ts +3 -0
  17. package/dist/cli/register/skillCommands.d.ts.map +1 -0
  18. package/dist/cli/register/skillCommands.js +13 -0
  19. package/dist/cli/register/skillCommands.js.map +1 -0
  20. package/dist/commands/domDrag.d.ts +21 -0
  21. package/dist/commands/domDrag.d.ts.map +1 -0
  22. package/dist/commands/domDrag.js +179 -0
  23. package/dist/commands/domDrag.js.map +1 -0
  24. package/dist/commands/extension/attach.d.ts +2 -0
  25. package/dist/commands/extension/attach.d.ts.map +1 -1
  26. package/dist/commands/extension/attach.js +31 -6
  27. package/dist/commands/extension/attach.js.map +1 -1
  28. package/dist/commands/extension/doctor.d.ts +6 -0
  29. package/dist/commands/extension/doctor.d.ts.map +1 -0
  30. package/dist/commands/extension/doctor.js +185 -0
  31. package/dist/commands/extension/doctor.js.map +1 -0
  32. package/dist/commands/extension/select.d.ts +7 -0
  33. package/dist/commands/extension/select.d.ts.map +1 -0
  34. package/dist/commands/extension/select.js +73 -0
  35. package/dist/commands/extension/select.js.map +1 -0
  36. package/dist/commands/extension/show.d.ts +4 -0
  37. package/dist/commands/extension/show.d.ts.map +1 -1
  38. package/dist/commands/extension/show.js +12 -88
  39. package/dist/commands/extension/show.js.map +1 -1
  40. package/dist/commands/extension/tabAttach.d.ts +28 -0
  41. package/dist/commands/extension/tabAttach.d.ts.map +1 -0
  42. package/dist/commands/extension/tabAttach.js +106 -0
  43. package/dist/commands/extension/tabAttach.js.map +1 -0
  44. package/dist/commands/extension/tabWatcher.d.ts +22 -0
  45. package/dist/commands/extension/tabWatcher.d.ts.map +1 -0
  46. package/dist/commands/extension/tabWatcher.js +89 -0
  47. package/dist/commands/extension/tabWatcher.js.map +1 -0
  48. package/dist/commands/extension/targetSelection.d.ts +62 -0
  49. package/dist/commands/extension/targetSelection.d.ts.map +1 -0
  50. package/dist/commands/extension/targetSelection.js +210 -0
  51. package/dist/commands/extension/targetSelection.js.map +1 -0
  52. package/dist/commands/extension/targets.d.ts +7 -0
  53. package/dist/commands/extension/targets.d.ts.map +1 -0
  54. package/dist/commands/extension/targets.js +73 -0
  55. package/dist/commands/extension/targets.js.map +1 -0
  56. package/dist/commands/extension/use.d.ts +13 -0
  57. package/dist/commands/extension/use.d.ts.map +1 -0
  58. package/dist/commands/extension/use.js +66 -0
  59. package/dist/commands/extension/use.js.map +1 -0
  60. package/dist/commands/record.d.ts +35 -0
  61. package/dist/commands/record.d.ts.map +1 -0
  62. package/dist/commands/record.js +210 -0
  63. package/dist/commands/record.js.map +1 -0
  64. package/dist/commands/skill.d.ts +6 -0
  65. package/dist/commands/skill.d.ts.map +1 -0
  66. package/dist/commands/skill.js +42 -0
  67. package/dist/commands/skill.js.map +1 -0
  68. package/dist/commands/watcherNativeHost.js +48 -1
  69. package/dist/commands/watcherNativeHost.js.map +1 -1
  70. package/dist/skill/argus/SKILL.md +200 -0
  71. package/dist/skill/argus/reference/CAPTURE.md +77 -0
  72. package/dist/skill/argus/reference/DIALOG.md +31 -0
  73. package/dist/skill/argus/reference/EVAL.md +137 -0
  74. package/dist/skill/argus/reference/EXTENSION.md +38 -0
  75. package/dist/skill/argus/reference/EXTENSION_IFRAME_EVAL.md +58 -0
  76. package/dist/skill/argus/reference/IFRAMES.md +46 -0
  77. package/dist/skill/argus/reference/INJECT.md +145 -0
  78. package/dist/skill/argus/reference/INSPECT.md +175 -0
  79. package/dist/skill/argus/reference/NET.md +108 -0
  80. package/dist/skill/argus/reference/PLUGINS.md +172 -0
  81. package/dist/skill/argus/reference/RUNTIME_CODE.md +42 -0
  82. package/dist/skill/argus/reference/START.md +120 -0
  83. package/dist/skill/argus/start-watcher.ts +108 -0
  84. package/package.json +2 -2
@@ -0,0 +1,145 @@
1
+ # Script Injection on Watcher Attach
2
+
3
+ Inject custom JavaScript when the watcher attaches to a target. Runs immediately on attach and on every page navigation/reload.
4
+
5
+ ## Config
6
+
7
+ ```json
8
+ {
9
+ "watcher": {
10
+ "start": {
11
+ "id": "app",
12
+ "url": "localhost:3000",
13
+ "inject": {
14
+ "file": "./scripts/debug-helpers.js",
15
+ "exposeArgus": true
16
+ }
17
+ }
18
+ }
19
+ }
20
+ ```
21
+
22
+ | Field | Required | Description |
23
+ | ------------- | -------- | ------------------------------------------------------------------ |
24
+ | `file` | Yes | Path to JavaScript file (resolved relative to config file) |
25
+ | `exposeArgus` | No | Set `window.__ARGUS__` metadata before script runs (default: true) |
26
+
27
+ ## Timing
28
+
29
+ 1. **On attach**: Script runs immediately via `Runtime.evaluate`
30
+ 2. **On navigation**: Script runs at document start via `Page.addScriptToEvaluateOnNewDocument`
31
+
32
+ This ensures the script is active both when attaching to an existing page and after any reload/navigation.
33
+
34
+ ## window.**ARGUS**
35
+
36
+ When `exposeArgus: true` (default), `window.__ARGUS__` is set before your script runs:
37
+
38
+ ```typescript
39
+ window.__ARGUS__ = {
40
+ watcherId: string // e.g., "app"
41
+ watcherHost: string // e.g., "127.0.0.1"
42
+ watcherPort: number // e.g., 52341
43
+ watcherPid: number // Node.js process ID
44
+ attachedAt: number // Unix timestamp (ms)
45
+ target: {
46
+ title: string | null
47
+ url: string | null
48
+ type: string // "page" | "iframe" | ...
49
+ parentId: string | null
50
+ }
51
+ }
52
+ ```
53
+
54
+ Use this to conditionally enable features or communicate with the watcher.
55
+
56
+ ## Use Cases
57
+
58
+ ### Debug Helpers
59
+
60
+ ```js
61
+ // scripts/debug-helpers.js
62
+ window.dumpState = () => console.log(JSON.stringify(window.appState, null, 2))
63
+ window.toggleDebug = () => {
64
+ window.DEBUG = !window.DEBUG
65
+ }
66
+ ```
67
+
68
+ ### Error Monitoring
69
+
70
+ ```js
71
+ // Wrap errors with extra context
72
+ window.onerror = (msg, src, line, col, err) => {
73
+ console.error('[ARGUS-INJECTED]', { msg, src, line, col, stack: err?.stack })
74
+ }
75
+ ```
76
+
77
+ ### Global Mocks
78
+
79
+ ```js
80
+ // Mock Date for deterministic testing
81
+ const fakeNow = new Date('2025-01-01T00:00:00Z').getTime()
82
+ Date.now = () => fakeNow
83
+ ```
84
+
85
+ ### Performance Markers
86
+
87
+ ```js
88
+ // Auto-add performance marks
89
+ const origFetch = window.fetch
90
+ window.fetch = async (...args) => {
91
+ const id = Math.random().toString(36).slice(2, 8)
92
+ performance.mark(`fetch-start-${id}`)
93
+ const res = await origFetch(...args)
94
+ performance.mark(`fetch-end-${id}`)
95
+ return res
96
+ }
97
+ ```
98
+
99
+ ### Conditional Debug Mode
100
+
101
+ ```js
102
+ // Enable verbose logging only when Argus is attached
103
+ if (window.__ARGUS__) {
104
+ window.DEBUG = true
105
+ console.log(`[DEBUG] Watcher ${window.__ARGUS__.watcherId} attached`)
106
+ }
107
+ ```
108
+
109
+ ## CLI Usage
110
+
111
+ ```bash
112
+ # Via CLI flag
113
+ argus watcher start --id app --url localhost:3000 --inject ./scripts/debug-helpers.js
114
+
115
+ # Via config file (inject.file resolved relative to config)
116
+ argus watcher start --id app --url localhost:3000
117
+ ```
118
+
119
+ ## Limitations
120
+
121
+ - Script file must be readable at watcher start
122
+ - Empty scripts are skipped with a warning
123
+ - Script errors are caught and logged but don't prevent watcher attachment
124
+ - Cross-origin iframe scripts need separate injection (see [IFRAMES.md](./IFRAMES.md))
125
+
126
+ ## Programmatic API
127
+
128
+ When using `@vforsh/argus-watcher` directly, pass script text (not file path):
129
+
130
+ ```js
131
+ import { startWatcher } from '@vforsh/argus-watcher'
132
+ import fs from 'node:fs'
133
+
134
+ const script = fs.readFileSync('./scripts/debug.js', 'utf8')
135
+
136
+ await startWatcher({
137
+ id: 'app',
138
+ match: { url: 'localhost:3000' },
139
+ chrome: { host: '127.0.0.1', port: 9222 },
140
+ inject: {
141
+ script,
142
+ exposeArgus: true,
143
+ },
144
+ })
145
+ ```
@@ -0,0 +1,175 @@
1
+ ## Inspect Commands
2
+
3
+ Use this as the command catalog after a watcher is attached. For eval-specific flags, polling, file scripts, and args, see [EVAL.md](./EVAL.md). For network capture, filtering, bodies, export, and mocks, see [NET.md](./NET.md).
4
+
5
+ ## Logs
6
+
7
+ ```bash
8
+ argus logs app --since 10m
9
+ argus logs app --levels error,warning
10
+ argus logs app --match "Error|Exception" --ignore-case
11
+ argus logs app --source console
12
+ argus logs app --json
13
+ argus logs app --json-full
14
+ argus logs tail app
15
+ argus logs tail app --levels error --json
16
+ ```
17
+
18
+ ## Eval / Wait
19
+
20
+ ```bash
21
+ argus js app "location.href"
22
+ argus eval app "await fetch('/ping').then(r => r.status)"
23
+ argus eval app "document.title" --json
24
+ argus eval app "window.store.getState()" --inject ./debug-hooks.js
25
+ argus eval-until app "document.querySelector('#loaded')"
26
+ argus eval-until app "window.APP_READY" --interval 500 --total-timeout 30s
27
+ argus wait app --file ./ready.js --arg level=10 --total-timeout 20s
28
+ ```
29
+
30
+ `js` is the short alias for `eval`; `wait` is the short alias for `eval-until`.
31
+
32
+ ## Screenshots / Recording
33
+
34
+ ```bash
35
+ argus screenshot app --out shot.png
36
+ argus screenshot app --selector "canvas" --out canvas.png
37
+ argus record app --duration 5s --out demo.mp4
38
+ argus record app --duration 3s --selector "canvas" --out canvas.mp4
39
+ ```
40
+
41
+ See [CAPTURE.md](./CAPTURE.md) for crop semantics, iframe behavior, recording start/stop, `ffmpeg`, and troubleshooting.
42
+
43
+ ## DOM / Snapshot / Locate
44
+
45
+ ```bash
46
+ argus dom tree app --selector "body"
47
+ argus dom tree app --testid "main-content"
48
+ argus dom tree app --selector "div" --all --depth 3
49
+ argus dom info app --selector "#root"
50
+ argus dom info app --ref e3
51
+ argus snapshot app
52
+ argus snapshot app --interactive
53
+ argus snapshot app --selector "form" --depth 3
54
+ argus locate role app button --name "Submit"
55
+ argus locate text app "Continue"
56
+ argus locate label app "Email" --action fill --value "me@example.com"
57
+ ```
58
+
59
+ `--testid <id>` is shorthand for `--selector "[data-testid='<id>']"`. `snapshot` and `locate` emit stable watcher-local refs such as `e5`, which ref-aware commands can reuse.
60
+
61
+ ## Interaction
62
+
63
+ ```bash
64
+ argus click app --selector "button.submit"
65
+ argus click app --testid "submit-btn"
66
+ argus click app --ref e5
67
+ argus click app --selector ".delayed-btn" --wait 5s
68
+ argus click app --pos 100,200
69
+ argus drag app --selector "#piece" --by 120,0
70
+ argus drag app --selector "canvas" --pos 320,240 --by 80,-30
71
+ argus drag app --pos 200,300 --to 500,300
72
+ argus hover app --selector ".menu-item"
73
+ argus fill app --selector "#username" "Bob"
74
+ argus fill app --selector "#desc" --value-file ./description.txt
75
+ echo "hello" | argus fill app --selector "#input" --value-stdin
76
+ argus keydown app --key Enter
77
+ argus keydown app --key a --selector "#input"
78
+ argus keydown app --key a --modifiers shift,ctrl
79
+ argus scroll-to app --selector "#footer"
80
+ argus scroll-to app --to 0,1000
81
+ argus scroll-to app --selector ".panel" --by 0,500
82
+ ```
83
+
84
+ `drag` uses real Chrome mouse input (`mousePressed` → `mouseMoved` → `mouseReleased`), which works for canvas/WebGL game interactions. With `--selector`/`--ref`, `--pos` is an offset from the element top-left; without an element target, `--pos` is the viewport start.
85
+
86
+ `--wait <duration>` on click/fill/drag polls for the selector before acting. Duration examples: `5s`, `500ms`, `2m`.
87
+
88
+ ## Dialogs
89
+
90
+ ```bash
91
+ argus dialog status app
92
+ argus dialog accept app
93
+ argus dialog dismiss app
94
+ argus dialog prompt app --text "updated value"
95
+ argus dialog status app --json
96
+ ```
97
+
98
+ Browser JavaScript dialogs include `alert`, `confirm`, `prompt`, and `beforeunload`.
99
+
100
+ ## DOM Helpers
101
+
102
+ ```bash
103
+ argus dom focus app --selector "#input"
104
+ argus dom focus app --testid "search-box"
105
+ argus dom focus app --ref e5
106
+ argus dom set-file app --selector "input[type=file]" --file ./build.zip
107
+ argus dom upload app --selector "input[type=file]" --file ~/Downloads/test.zip
108
+ argus dom scroll app --by 0,300
109
+ argus dom wheel app --selector "input[type=number]" --by 0,-120
110
+ argus dom scroll app --selector ".panel" --by 0,200
111
+ argus dom scroll app --pos 400,300 --by 0,200
112
+ ```
113
+
114
+ `dom scroll` dispatches real wheel input via CDP. `dom set-file` / `dom upload` set file inputs.
115
+
116
+ ## Storage
117
+
118
+ ```bash
119
+ argus storage local get app theme
120
+ argus storage local set app theme dark
121
+ argus storage local remove app theme
122
+ argus storage local ls app
123
+ argus storage local clear app
124
+ argus storage session get app draftId
125
+ argus storage session set app draftId abc123
126
+ argus storage session remove app draftId
127
+ argus storage session ls app
128
+ argus storage session clear app
129
+ ```
130
+
131
+ ## Auth
132
+
133
+ ```bash
134
+ argus auth cookies list app
135
+ argus auth cookies list app --show-values --json
136
+ argus auth cookies ls app --for-origin --exclude-tracking
137
+ argus auth cookies get app session --domain .example.com --path /
138
+ argus auth cookies set app session token123 --domain .example.com --path / --secure --http-only
139
+ argus auth cookies delete app session --domain .example.com --path /
140
+ argus auth cookies clear app --for-origin
141
+ argus auth cookies clear app --site --auth-only
142
+ argus auth export-cookies app --format netscape
143
+ argus auth export-state app --out auth.json
144
+ argus auth load-state app --in auth.json
145
+ argus auth clone extension-2 --to app
146
+ argus chrome start --auth-state auth.json
147
+ argus start --id app --auth-from extension-2
148
+ ```
149
+
150
+ `auth export-state` writes cookies, `localStorage`, `sessionStorage`, and metadata. `auth load-state` rehydrates into the current watcher tab. `auth clone` copies auth state directly between watchers.
151
+
152
+ ## Trace
153
+
154
+ ```bash
155
+ argus trace app --duration 3s --out trace.json
156
+ argus trace start app --categories "devtools.timeline"
157
+ argus trace stop app --out trace.json
158
+ ```
159
+
160
+ ## Emulation / Visibility / Throttle
161
+
162
+ ```bash
163
+ argus page emulation set app --device iphone-14
164
+ argus page emulation set app --width 1600 --height 900
165
+ argus page emulation clear app
166
+ argus page emulation status app --json
167
+ argus page show app
168
+ argus ext show --url localhost
169
+ argus page hide app
170
+ argus throttle set app 4
171
+ argus throttle clear app
172
+ argus throttle status app
173
+ ```
174
+
175
+ `page show` / `ext show` keeps a page shown and focused so timers and `requestAnimationFrame` do not throttle while debugging.
@@ -0,0 +1,108 @@
1
+ ## Network Commands
2
+
3
+ Use this after a watcher is attached and you need request summaries, fresh capture windows, request/response bodies, WebSockets, SSE, HAR export, or network mocking.
4
+
5
+ For iframe-active extension watchers, choose scope deliberately:
6
+
7
+ - `--scope selected` / `--frame selected` means traffic for the selected iframe target.
8
+ - page/tab scope means traffic for the top page.
9
+ - reload-driven `net watch`, `net export`, and `net inspect` reject selected-frame scope because reloading an iframe target is ambiguous.
10
+
11
+ ## Quick Read
12
+
13
+ ```bash
14
+ argus net app --since 5m
15
+ argus net app --grep api
16
+ argus net app --json
17
+ argus net tail app --grep api --json
18
+ argus net summary app
19
+ argus net clear app
20
+ ```
21
+
22
+ `net clear` resets the watcher buffer so the next inspection starts clean.
23
+
24
+ ## Fresh Capture
25
+
26
+ ```bash
27
+ argus net watch app --reload --settle 3s
28
+ argus net watch app --reload --settle-after "window.appReady" --settle 2s
29
+ argus net watch app --reload --settle 3s --ignore-pattern /poll
30
+ argus net watch app --reload --settle 3s --max-timeout 30s
31
+ ```
32
+
33
+ `net watch` tails matching requests until no new matches arrive for `--settle`. `--settle-after "<expr>"` polls the page first, then starts the quiet-window countdown only after the expression becomes truthy.
34
+
35
+ ## Inspect One Endpoint
36
+
37
+ ```bash
38
+ argus net inspect /api/init app --reload
39
+ argus net inspect /api/post app --settle-after "window.appReady" --settle 400ms
40
+ argus net inspect /api/init app --reload --request --response
41
+ ```
42
+
43
+ `net inspect` captures a fresh window, picks the newest URL match, prints a compact request summary, and can include request/response bodies.
44
+
45
+ ## Filters
46
+
47
+ ```bash
48
+ argus net extension --scope selected --host game-frame-host.example --resource-type Fetch
49
+ argus net extension --first-party --slow-over 500ms --status 4xx
50
+ argus net extension --large-over 100kb --mime application/json
51
+ argus net app --method POST --host api.example.com
52
+ argus net app --failed-only
53
+ argus net app --domain example.com
54
+ ```
55
+
56
+ Common filters: host, domain, method, status/status class (`2xx`), resource type, MIME prefix, first-party/third-party, failed-only, slow-over, large-over, and scope/frame.
57
+
58
+ ## Show And Bodies
59
+
60
+ ```bash
61
+ argus net show 42 app
62
+ argus net show 90829.507 extension --json
63
+ argus net body 42 app
64
+ argus net body 42 app --request
65
+ ```
66
+
67
+ `net show` drills into one buffered request by Argus id or raw CDP request id, including redacted headers, initiator, redirect chain, cache/service-worker flags, timing phases, and body availability. `net body` lazily fetches response body by default; add `--request` for request body.
68
+
69
+ ## Export / WebSockets / SSE
70
+
71
+ ```bash
72
+ argus net export app --out boot.har
73
+ argus net export app --reload --settle 3s --out boot.har
74
+ argus net ws app
75
+ argus net ws show 1 app
76
+ argus net sse app
77
+ ```
78
+
79
+ `net export --format har` writes the current buffer or a fresh reload capture as HAR. `net ws show` prints WebSocket handshake headers plus bounded recent frame previews. `net sse` lists EventSource/text-event-stream requests at request level; CDP does not reliably expose SSE event payloads.
80
+
81
+ ## Network Mocking
82
+
83
+ Intercept live requests via CDP Fetch: block, fail with a real network error, stub responses, inject latency, or rewrite requests.
84
+
85
+ ```bash
86
+ argus net mock add app --url "*/analytics/*" --block
87
+ argus net mock add app --url "*/api/save" --fail ConnectionRefused
88
+ argus net mock add app --url "*/api/init" --fail TimedOut --times 1
89
+ argus net mock add app --url "*/api/config" --status 200 --body-file ./fixtures/config.json
90
+ argus net mock add app --url "*/api/config" --status 500 --body '{"error":"maintenance"}'
91
+ echo '{"flags":{"newShop":true}}' | argus net mock add app --url "*/api/flags" --body -
92
+ argus net mock add app --url "*/api/*" --delay 2s --method POST
93
+ argus net mock add app --url "*/api/*" --set-header "x-debug: 1"
94
+ argus net mock add app --url "cdn.prod.com" --rewrite-host localhost:3000
95
+ argus net mock ls app
96
+ argus net mock rm 2 app
97
+ argus net mock clear app
98
+ ```
99
+
100
+ Rules persist across reloads and reattach until removed. First matching rule wins. `--url` is a case-insensitive wildcard pattern over the full request URL; `*` matches anything, and no `*` means substring match. Use `--times N` for one-shot failures.
101
+
102
+ Exactly one primary action per rule:
103
+
104
+ - `--block` aborts as `BlockedByClient`.
105
+ - `--fail <reason>` aborts with a CDP network error such as `TimedOut` or `ConnectionRefused`.
106
+ - `--status` with `--body`, `--body-file`, and optional headers stubs a response.
107
+
108
+ Without a primary action, rules pass requests through with optional latency, request-header changes, or host/origin rewrites.
@@ -0,0 +1,172 @@
1
+ # CLI Plugins
2
+
3
+ Argus plugins are normal ESM modules loaded before Commander parses the CLI command. They can register extra top-level commands and use stable host helpers from `@vforsh/argus-plugin-api`.
4
+
5
+ ## Load Sources
6
+
7
+ ```bash
8
+ # Global config: persistent for every workspace
9
+ argus plugin add --global foo=~/dev/foo-plugin/dist/index.js
10
+ argus foo ...
11
+
12
+ # Workspace config: persistent for this workspace
13
+ argus plugin list
14
+
15
+ # Env: useful for shells/scripts
16
+ ARGUS_PLUGINS=foo argus plugin list
17
+
18
+ # Dynamic: one invocation only
19
+ argus --plugin foo plugin list
20
+
21
+ # Config mutation
22
+ argus plugin add gsheets
23
+ argus plugin add --global foo=./plugins/foo.js
24
+ argus plugin add foo=./plugins/foo.js
25
+ argus plugin remove google-sheets
26
+ ```
27
+
28
+ Load order:
29
+
30
+ 1. `plugins` from per-user config at `ARGUS_HOME/config.json` (default `~/.argus/config.json`)
31
+ 2. `plugins` from repo-local Argus config
32
+ 3. `ARGUS_PLUGINS` comma-separated entries
33
+ 4. `--plugin <module-or-path-or-alias>` entries
34
+
35
+ Duplicate specifiers are loaded once, preserving first occurrence.
36
+
37
+ ## Inspect
38
+
39
+ ```bash
40
+ argus plugin list
41
+ argus plugin list --json
42
+ argus --plugin ./plugins/foo.js plugin list --json
43
+ ```
44
+
45
+ `plugin list` reports the config path, cwd, and one entry per discovered plugin:
46
+
47
+ ```json
48
+ {
49
+ "entries": [
50
+ {
51
+ "source": "cli",
52
+ "spec": "foo",
53
+ "resolvedSpec": "./plugins/foo.js",
54
+ "alias": "foo",
55
+ "status": "loaded",
56
+ "name": "foo",
57
+ "version": "1.2.3",
58
+ "description": "Foo commands for Argus",
59
+ "commands": ["foo"],
60
+ "homepage": null,
61
+ "minArgusVersion": null,
62
+ "url": "file:///repo/plugins/foo.js"
63
+ }
64
+ ]
65
+ }
66
+ ```
67
+
68
+ Failures are non-fatal: Argus prints a warning and keeps registering the rest.
69
+
70
+ ## Manage Config
71
+
72
+ ```bash
73
+ argus plugin add <module-or-path-or-alias>
74
+ argus plugin add <alias>=<module-or-path>
75
+ argus plugin add --global <alias>=<module-or-path>
76
+ argus plugin remove <specifier-or-name>
77
+ argus plugin remove --global <specifier-or-name>
78
+ argus plugin add ./plugins/foo.js --path argus.config.json
79
+ ```
80
+
81
+ `plugin add` creates `.argus/config.json` when no workspace config exists, appends the specifier once, and preserves the rest of the config. `--global` writes `ARGUS_HOME/config.json`, so the plugin command is available from any directory without passing `--plugin`. `plugin add foo=./plugins/foo.js` writes both `plugins: ["foo"]` and `pluginAliases.foo`. `plugin remove` accepts the full specifier, alias, or package shorthand (`google-sheets` removes `gsheets` / `@vforsh/argus-plugin-google-sheets`).
82
+
83
+ ## Resolution
84
+
85
+ - Built-in aliases resolve first: `gsheets` and `gs` point at `@vforsh/argus-plugin-google-sheets`.
86
+ - Config aliases in `pluginAliases` override built-ins.
87
+ - `file:` URLs load directly.
88
+ - `~`, relative, and absolute paths resolve from the owning config directory first, then other discovered config directories, then cwd.
89
+ - Package specifiers resolve next to Argus first, then from config directory / cwd.
90
+
91
+ Use dynamic loading for local development:
92
+
93
+ ```bash
94
+ npm run build --workspace @vforsh/argus-plugin-google-sheets
95
+ argus --plugin ./packages/argus-plugin-google-sheets/dist/index.js sheets read extension-3 --range A1:C5
96
+ argus --plugin gs sheets read extension-3 --range A1:C5
97
+ ```
98
+
99
+ ## Plugin Contract
100
+
101
+ ```ts
102
+ import { ARGUS_PLUGIN_API_VERSION, type ArgusPluginV1 } from '@vforsh/argus-plugin-api'
103
+
104
+ const plugin: ArgusPluginV1 = {
105
+ apiVersion: ARGUS_PLUGIN_API_VERSION,
106
+ name: 'my-plugin',
107
+ version: '1.0.0',
108
+ description: 'Short human description.',
109
+ commands: ['mycmd'],
110
+ register(ctx) {
111
+ ctx.program.command('mycmd').action(() => {})
112
+ },
113
+ }
114
+
115
+ export default plugin
116
+ ```
117
+
118
+ Plugins may also export the plugin as `argusPlugin`.
119
+
120
+ ## Host Helpers
121
+
122
+ `ctx.host` exposes stable helpers:
123
+
124
+ - `createOutput(options)` for Argus stdout/stderr conventions
125
+ - `requestWatcherJson(input)` for watcher HTTP calls
126
+ - `writeRequestError(result, output)` for standard watcher errors
127
+ - `runChromeOpen(options)` for opening tabs through Argus Chrome resolution
128
+ - `defineWatcherCommand(spec)` for stable watcher-backed command runners with JSON/human formatting
129
+ - `argus.eval`, `argus.dom.click/drag/info/keydown`, and `argus.screenshot` for common watcher calls without raw paths
130
+
131
+ Minimal watcher command:
132
+
133
+ ```ts
134
+ ctx.program
135
+ .command('title [id]')
136
+ .option('--json')
137
+ .action(
138
+ ctx.host.defineWatcherCommand({
139
+ build: () => ({ path: '/eval', method: 'POST', body: { expression: 'document.title', returnByValue: true } }),
140
+ formatHuman: (response: { ok: true; result: unknown }, { output }) => output.writeHuman(String(response.result ?? '')),
141
+ }),
142
+ )
143
+ ```
144
+
145
+ ## Google Sheets Plugin
146
+
147
+ ```bash
148
+ argus --plugin ./packages/argus-plugin-google-sheets/dist/index.js plugin list
149
+ argus sheets list extension-3
150
+ argus sheets list extension-3 --with-gid
151
+ argus sheets info extension-3
152
+ argus sheets switch extension-3 "Sheet 2"
153
+ argus sheets open extension-3 2
154
+ argus sheets add extension-3
155
+ argus sheets rename extension-3 "Sheet 2" "Archive"
156
+ argus sheets move extension-3 "Archive" 1
157
+ argus sheets remove extension-3 "Sheet 3" --force
158
+ argus sheets rows add extension-3 5 --count 2 --before
159
+ argus sheets rows remove extension-3 5 --count 2 --force
160
+ argus sheets columns add extension-3 3 --after
161
+ argus sheets columns remove extension-3 3 --force
162
+ argus sheets read extension-3 --range A1:C5
163
+ argus sheets export extension-3 --range A1:C5 --format tsv
164
+ argus sheets find extension-3 "needle" --column ru --ignore-case
165
+ argus sheets write extension-3 B12 --value "Новое значение"
166
+ ```
167
+
168
+ `sheets`/`gs` works against an attached Google Sheets tab. `list` reports visible sheet tabs; `--with-gid` briefly switches through them and restores the original sheet. `switch`/`open`, `rename`, `move`, and `remove` accept a visible sheet name, 1-based visible index, or gid. `add` creates a sheet through the live UI; `remove` requires `--force`. `rows add/remove` and `columns add/remove` mutate the active sheet by 1-based index; add commands require `--before` or `--after`, and remove commands require `--force`. Reads use authenticated CSV export from inside the tab; writes select a range in the live UI and paste TSV.
169
+
170
+ ## No Unload
171
+
172
+ Argus is a short-lived CLI. To unload a plugin, remove it from config/env or stop passing `--plugin` on the next invocation.
@@ -0,0 +1,42 @@
1
+ # Runtime Code Inspection
2
+
3
+ Argus can inspect runtime JS/CSS resources exposed through CDP.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ argus code ls app
9
+ argus code ls app --pattern inline
10
+ argus code read http://127.0.0.1:3333/ --id app
11
+ argus code read inline://42 --id app --offset 20 --limit 80
12
+ argus code grep '/featureFlag/' --id app
13
+ argus code grep 'argusRuntimeProbe' --id app --url inline
14
+ argus code grep showLogsByHost --id app --pretty
15
+ argus code deminify http://127.0.0.1:3333/app.js --id app
16
+ argus code edit http://127.0.0.1:3333/app.js --id app --search "DEBUG=false" --replace "DEBUG=true"
17
+ argus code edit http://127.0.0.1:3333/app.js --id app --search '/logLevel\s*=\s*"info"/' --replace 'logLevel = "debug"' --all
18
+ argus code edit http://127.0.0.1:3333/app.js --id app --file ./patched.js
19
+ cat patched.css | argus code edit inline-css://1 --id app
20
+ argus code strings app --url app.js
21
+ argus code strings app --url app.js --kind url,identifier --match '/admin\\/api/'
22
+ ```
23
+
24
+ ## What It Does
25
+
26
+ - `code ls`: list runtime scripts/stylesheets discovered via CDP
27
+ - `code read`: return line-numbered source for one resource
28
+ - `code grep`: search sources with a plain string or `/regex/flags`
29
+ - `code grep --pretty`: render clipped context around each match, which is much nicer on minified bundles
30
+ - `code deminify`: pretty-print a runtime resource for quick inspection
31
+ - `code edit`: live-patch a runtime stylesheet via CDP (`CSS.setStyleSheetText`)
32
+ - `code strings`: extract high-signal string literals such as URLs, keys, and camelCase identifiers, with ranking tuned for reverse-engineering
33
+
34
+ ## Behavior Notes
35
+
36
+ - Resource URLs can be real URLs or synthetic inline IDs like `inline://42` and `inline-css://style-sheet-1`.
37
+ - `code deminify` falls back to the original source if formatting fails.
38
+ - `code edit` supports three input modes: `--search/--replace` for surgical text replacement (with optional `--all`), `--file` for full source replacement from disk, and piped stdin. Search patterns use the same plain-string or `/regex/flags` format as `code grep`. JS script editing is not supported on Chrome 145+ (V8 removed `Debugger.setScriptSource`); use `argus eval` for runtime JS modifications instead.
39
+ - `code strings` favors signal over completeness by default. Use `--all` to include low-signal literals too.
40
+ - `code strings --kind` accepts a comma-separated subset of `url,key,identifier,message,other`.
41
+ - `code strings --match` reuses the same plain-string or `/regex/flags` pattern format as `code grep`.
42
+ - `code grep` skips stale stylesheet handles, emits a warning on stderr, and still returns matches from healthy resources.