mirror of
https://github.com/software-mansion/argent.git
synced 2026-09-14 19:27:14 +08:00
stack/721-base-legacy
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d4a712c401 |
refactor(gesture): rename the momentum-free flag to momentum (#732)
`settle: true` collided with the runner's other `settle` — waiting for the tree to quiesce — which is the very thing a swipe step does after every dispatch, whichever way the flag is set. One sentence of the flow skill used both senses at once. This names the physics instead: `momentum: false` is the momentum-free gesture, and the natural fling is the default the prose already described. ### Renamed | surface | before | after | | --- | --- | --- | | `swipe` flow directive | `settle: true` | `momentum: false` | | `gesture-swipe` param | `settle` | `momentum` | | `gesture-drag` param | `settle` | `momentum` | The directive passes the flag straight through to the tools, so all three move together. `momentum: true` is the default and normalizes to absent, mirroring what `settle: false` did — parse/serialize stay exact inverses. ### Also - Recording summary label `(settle)` → `(momentum-free)` - Internal constants → `MOMENTUM_FREE_EASE_EXPONENT`, `MOMENTUM_FREE_MIN_STEPS` - `flow-run` tool description and `argent-create-flow` skill updated ### Testing `tsc -b`, eslint (`--max-warnings 0`) and prettier clean; `test/flows` + `test/tools` pass 671/671, including a new case covering the legacy-spelling rejection. |
||
|
|
b232114422 |
docs: audit every comment in src against the code it describes (#931)
Audits every comment in `src/` and `scripts/` against the code it
describes.
**462 files, 57 commits, net −8,194 lines.** Comment text only — the
whole branch is code-identical to `main`.
## Method
One subagent per file, strictly sequential. Scope was `src/` +
`scripts/` (459 files); three more files were added at the end because
they carried dead references of the same kind — two test headers citing
design docs that do not exist, and `publish-npm.yml` citing a retired
workflow. Each agent verified every comment — line, block, JSDoc, file
header, trailing — against the surrounding code and the rest of the
repo, following identifiers, paths, tool ids, config keys, env vars and
issue links to see whether they still exist and still behave as
described. Rules:
- **A false or misleading comment is deleted, not reworded.** If a claim
could not be confirmed by reading the source, it went. That is why the
deletion count is so much larger than the rewrite count.
- Survivors are cut to the shortest form carrying something the code
does not already say. Restatement, preamble, hedging, changelog prose
and ASCII banners are gone; the non-obvious *why* stays.
- Preserved byte-identical: license headers, pragmas and directives
(`@ts-*`, `eslint-disable`, shebangs, `/// <reference>`), JSDoc tag
tokens, everything inside a string or template literal, and the sole
comment inside an otherwise empty block (ESLint `no-empty` counts a
comment-bearing block as non-empty).
## Verification
Every file passed two independent gates before being recorded as done:
1. `comments-only` — the required check.
2. A second comment-stripping comparator with a proper mode stack,
written for this pass because `comments-only`'s flat scanner desyncs on
nested template literals and quote-bearing regex literals and then
reports comment lines as code changes. Two files hit that false FAIL
(`utils/android-profiler/pipeline/index.ts`,
`scripts/extract-tools.mjs`); in both the "changed code" it printed was
literally `//` lines, and the second checker confirmed the code was
byte-identical.
After the last file, all 462 changed files were re-checked against
`main` with the same comparator, rather than trusting any agent's
self-report. **459 code-identical; 2 are non-code (`.svg`, `.md`); 1
intentional.**
The intentional one is `packages/argent/scripts/bundle-tools.cjs`: the
changed template literal *is* the comment header of the file it
generates, `packages/native-devtools-android/src/bundled-meta.ts`.
Fixing only the generated file would have been reverted by the next
build, so the generator changed too — and it has been verified to
reproduce the committed generated file byte-for-byte.
## Representative false claims removed
Not wording nits — statements a reader would have acted on:
- **Reversed directions.** `proxyStart`'s JSDoc had the tunnel backwards
(it is a reverse tunnel: the host binds first and the simulator dials
in). A `paste()` doc had the pasteboard copy direction reversed.
- **Contradicted by the code below it.** A timeout budget multiplied by
three where the probes run concurrently — the same comment said so six
lines later. A "warn once" that warns on every call. A "binary search"
that is a linear scan.
- **Named things that do not exist.** A `vega-fast-cli` binary, a
`finish-recording.ts`, a `publish-next.yml` workflow, two
`profiler-react19-*.md` design docs, a `DebuggerTarget.ts`, a commit
hash git does not know, two tool ids, an `ensureEnv` cycle.
- **Wrong by construction.** "Welford accumulators" across four files
where the code keeps naive `n`/`sum`/`sumSq`; `sum`/`sumSq` documented
over `actualDuration` when reduce sums `selfDuration`; a strict-mode
halving written `n/2` where the code ceils; field docs listing enum
values the producers never emit.
- **Guarantees the code does not make.** A validation matrix claiming to
cover "EVERY tool" that skips flagless ones; a Pareto cutoff that
`slice(0, 20)` makes inert; an idempotence claim where the real rule is
at-or-ahead; a capability note describing a clean 400 the shape-based
device resolver can never produce.
- **Unverifiable assertions** about prebuilt binaries, external CLIs and
the cloud SDK — deleted rather than kept as folklore, since nothing in
the repo can confirm them.
- **Stale numbers**: invented Android tool versions, hard-coded tool
counts and description lengths that had drifted.
## Review
A Fable agent reviewed both halves adversarially for over-deletion,
misread code, `no-empty` hazards and byte-identity violations.
Second-half verdict: **SHIP**, with two one-line restores, both applied
in the final commit — the `npm view ""` rationale behind a blank-token
guard, and the note that `argent-mcp` keeps a copy of
`SECRET_PLACEHOLDER_MARKER` it cannot import.
## Code issues surfaced but deliberately not fixed
This pass changes comments only. Eight genuine findings are logged for a
follow-up:
1. `telemetry/src/consent.ts` — a non-ENOENT read error returns null and
falls through to the default-on path, so file errors *can* silently flip
telemetry on.
2. `chromium-server/navigation.ts` — `navigate()` is reachable from
`POST /api/navigate` with only a `typeof === "string"` check; open-url's
schema is a bare `z.string()`, so the "already validated by zod" premise
never held.
3. `http.ts` — `constantTimeEqual` returns early on a length mismatch,
so the auth token's length is observable.
4. `describe/index.ts:~114` — the ios-remote branch passes `{ isTvOs:
false }` unconditionally, so a remote tvOS simulator takes the iOS
ax-service path, though `isRemoteTvOsSimulator` exists and shake/paste
do use it.
5. `devices/boot-device.ts` — `-crash-report-mode never` is passed
unconditionally *and* appended again by the feature-detecting path, so
every emulator spawn passes it twice.
6. `react-profiler/pipeline/04-rank.ts` — `PARETO_THRESHOLD_PCT` is
dead: `slice(0, 20)` always wins.
7. `reaped-sessions.ts` — a user-facing hint string tells the agent that
`react-profiler-start { force: true }` disposes the debugger and
profiler session; it does not. Left byte-identical because it is a
string literal, not a comment.
8. `utils/simctl-backend.ts` — `localSimctl` is exported with no
importers anywhere.
## Docs
No documentation change is needed: this pass touches only source
comments, and no user-facing capability, tool, CLI flag, config key or
flow-file behaviour changed.
---------
Co-authored-by: filip131311 <f.kaminski2000@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
3fff176a32 |
fix(cli): let a boolean flag take the value you typed (#699)
Fixes #586. ## The bug `--includeChildren false` left the flag **true** and silently dropped the word, so the tool ran with the opposite of what was asked. The reporter spent a while chasing a filter bug that did not exist — the output was simply the unfiltered kind. Reproduced on 0.18.1, device-free, with a discriminator that shows the flag's value directly: ``` $ argent run screenshot-diff --udid U --baselinePath A.png --currentPath B.png --captureCurrent=false { "summary": "Screenshot diff summary … pixel_mismatch: 1.79% …" <-- false, diff runs $ argent run screenshot-diff --udid U --baselinePath A.png --currentPath B.png --captureCurrent false [Tool:screenshot-diff] Provide either currentPath or captureCurrent, not both. <-- stayed TRUE ``` That message is the whole problem in one line: the user typed `false`, and the tool refuses on the grounds that they asked to capture. ## Why the old behaviour existed, and why it does not need to The parser deliberately declined to look ahead: > `// Bare boolean flag: true. Don't consume next argv to avoid surprising behavior when a positional follows.` That protects a case which does not exist. `parseFlags` has exactly one caller, and **`positional` is never read anywhere in the repo** — every bare token is collected and dropped, for booleans and for every other type. There is no positional to steal. The module header had documented the space form as legal all along: ``` // --name value (string / number / integer / boolean-with-value) ``` This matters because several tool booleans **default to true**, so `false` is the only way to say what you mean: `screenshot.includeImageInContext`, `network-request.includeBody`, `debugger-component-tree.onScreenOnly`, `debugger-inspect-element.resolveSourceMaps`. ## What changed A boolean flag consumes a following token when it is exactly the word `true`/`false`, case-insensitively. `1`/`0` and everything else are left alone — a bare number after a switch is more likely an unrelated argument than a value, and guessing at an ambiguous token is what caused this bug. `--flag -- false` still keeps the word positional. Three consequences are handled here rather than left to bite later: - **`argent run` now reports arguments it ignored.** This is what stops `--flag 0` and `--flag yes` being the same silent inversion, in a syntax users are now being taught works. stderr, so `--json` stays parseable. - **`--no-flag true` / `--no-flag false` now name the positive form** instead of quietly meaning false. One is a contradiction, the other a double negative. - **`--flag=True` used to throw** while `--flag True` would now work — the inline coercion was case-sensitive and did not trim. Both paths now share one helper, so a single word cannot get two answers one function apart. The **flow** and **lens** parsers take switches that accept no value at all, and would have silently ignored the syntax their users just learned elsewhere. They now refuse it — in the flow parser that also stops `false` being swallowed as the flow name, since its first bare token is the flow to run. `--help` gains **one legend line** for tools with a boolean field, rather than widening the flag column on every field of every tool: ``` Booleans: --flag or --flag true sets true; --flag false, --flag=false, or --no-flag sets false. ``` It deliberately does not begin with `--`. `scripts/e2e-full/lib/discover-tools.sh` reads any such line in the `Flags:` section as a flag row and takes the first `--token` as its name, so a legend starting with a flag would inject a phantom flag into every tool model it builds. **There is a test pinning that shape**, verified live: running the harness's awk over the new help output yields exactly the real flags and no legend row. ## Verified live ``` --captureCurrent false -> diff runs (was: "Provide either currentPath or captureCurrent, not both.") --captureCurrent=false -> unchanged --captureCurrent 0 -> "Note: ignoring unused argument(s): 0. Pass values as --flag <value> or --flag=<value>." screenshot --help -> legend present; harness awk parses only the real flags ``` 25 new tests; 8 confirmed to fail before and pass after. The rest pin what deliberately did *not* change: bare flag still true, a following flag or non-boolean word left alone, `1`/`0` still positional in the space form, `--` escape, string and unknown fields untouched, `--no-flag` semantics, boolean arrays, last-write-wins. The parser had **zero** boolean coverage before — which is why this survived. Full CLI suite 298 passing; lint, prettier and `typecheck:tests` clean. ## Scope and neighbours Only `flag-parser.ts` (the schema-driven parser for `argent run`) changes semantics. The other CLI parsers take fixed, default-off switches where `false` has no coherent meaning; three of them already reject a stray token outright, and the two that did not now do. `flow.ts`'s deliberate rejection of `--flag=value` is untouched. **#648** also edits `flag-parser.ts` (rewrites `renderFlagName`, inserts helpers at the same anchor). Behaviourally compatible — it keeps boolean → bare `--name` — so this is a textual conflict only, and either order works. ## Found while here, not fixed `scripts/e2e-full/lib/discover-tools.sh:60-64` detects flag kinds with `\bboolean\b` in awk, where `\b` is **backspace**, not a word boundary — so it never matches and every non-enum flag is typed `unknown`. That makes the `bad-type` validation case downstream unreachable. Pre-existing and unrelated to this fix; filing separately. --- > **Stacked on #648** (`filip/run-cli-validation-messages`). Both rewrite the same region of `packages/argent-cli/src/flag-parser.ts` — #648 factors out `flagNameFor`/`isJsonField` and rewrites `renderFlagName`, this one adds `booleanWord` beside them and a boolean legend to `formatSchemaUsage`. Merging them independently conflicts; this branch is rebased on #648, so review only the top commit. GitHub retargets it to `main` when #648 merges. --------- Co-authored-by: Filip131311 <f.kaminski2000@gmail.com> |
||
|
|
d08c3a3cfc |
fix(cli): name the missing flag instead of printing a Zod dump (#648)
Fixes #645. ## Before ``` $ argent run gesture-tap [ { "expected": "string", "code": "invalid_type", "path": ["udid"], "message": "Invalid input: expected string, received undefined" }, ... two more ] ``` ## After ``` $ argent run gesture-tap Error: missing required flags --udid, --x, --y argent run gesture-tap [flags] ...full per-flag help... ``` ## Scope The issue names the missing-flag case. Reproducing it showed the same raw dump has a second trigger: any constraint the tool itself rejects, which the CLI cannot know in advance. | invocation | before | after | |---|---|---| | `gesture-tap` (no flags) | raw issue array | `missing required flags --udid, --x, --y` | | `screenshot --scale 99` | raw issue array | `--scale Too big: expected number to be <=1` | | `gesture-scroll --udid X --x .5 --y .5` (zero deltas) | raw issue array | `Pass a non-zero deltaX and/or deltaY …` | | `run-sequence --udid X` | raw issue array | `missing required flag --steps-json` | | `gesture-tap --x abc` | already good | unchanged | | runtime failure | plain message, exit 1 | unchanged | Fixing only the first row would have left the CLI's error voice less predictable than before, so both go through the same renderer. ## How it works Two sources, one output. Missing flags are found locally from the tool's published schema — a **presence** check only, never a type or range judgement, which stays exclusively the server's. That is sound because the schema generator excludes defaulted fields from `required` (`debugger-connect` requires `device_id`, not `port`), so it cannot reject a call the server would have accepted. Everything else is read off the rejection the tool-server already returns. Both produce one report rendered by one function and reported through one call site, so the wording, the output channel and the exit code cannot drift between them. Recognition of a rejection is **structural** — the shape of the issue list plus the tool's own schema — never the wording of a message, which is not ours to depend on and changes between Zod releases. Four gates must all hold, and any failure leaves the existing handling untouched. Details worth a reviewer's attention: - **A rule spanning the whole payload reports no field.** `gesture-scroll` and `gesture-rotate` validate at the object level, and `screenshot-diff` is `.strict()`. Treating those as field-scoped would print `Error: --undefined …`; they are stated on their own instead. - **A rule firing on an *optional* field is not called a missing required flag.** `await-ui-element` refines on `expectedText`, which it does not require — reporting that as missing would contradict the help block printed directly underneath, where the field carries no `(required)` marker. - **The check runs after `--args` is merged**, so `argent run gesture-tap --args '{...}'` is not falsely reported as missing everything. Verified live: it reaches the device and taps. - Presence uses own-key semantics, so a required field named e.g. `constructor` is not treated as supplied by the prototype chain. ## Behaviour changes a reviewer should weigh - **A tool-rejected value now exits 2 instead of 1.** `run.ts` already uses 2 for bad input and 1 for a failed run; a Zod 400 means the tool never ran. No in-repo consumer tests for a specific code — `scripts/e2e-full` only checks zero/non-zero. Note this does **not** make 2 universal: an unknown tool name still exits 1, which is untouched here. - **`--json` gains a defined failure shape** (it had none — the blob printed regardless). One object on stderr, nothing on stdout, so `--json | jq` on a failed run reads an empty stream and a non-zero status: ```json { "error": "missing required flags --udid, --x, --y", "missing": ["--udid", "--x", "--y"], "issues": [] } ``` `issues` carries the tool's list verbatim, which is the raw data the issue asked to keep. - **One adjacent fix**, called out because it is not the reported bug: the global-option parse ran *outside* the error handler, so `argent run screenshot --out` printed a raw stack trace. Same bad-input-to-ugly-output defect, one line above the fix. ## Not done - The unknown-flag hole (`argent run gesture-tap --bogusflag 1` is silently accepted and the tool runs). The pass-through is deliberate — see the comment in `flag-parser.ts` — and belongs with #586, the same CLI-argument family. - `argent flow` builds its own payload and has its own required check; it cannot reach this path. - The server still returns the issue list verbatim, so MCP and other clients are unaffected. All prettifying is CLI-side. ## Verification Live against the built CLI for every row of the table above, plus: `debugger-connect` asks only for `--device_id` and never `--port`; `--args '{...}'` reaches the device and taps; a thrown runtime error still prints its bare message with no `Error:` prefix, no help block, exit 1. 43 new tests. `run-telemetry.test.ts` passes **unedited** — it already asserted the non-Zod passthrough, which makes it the regression guard for the untouched path. Full CLI suite 320 passed, registry 87 passed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- > **#699 is stacked on this branch** — it conflicts with this one in `flag-parser.ts`, so it was rebased on top rather than left to collide at merge time. Merge this first. |
||
|
|
c5bab2a83d |
fix(cli): let a tool's own --args field win over the whole-payload flag (#458)
## Bug
`argent run flow-add-step` declares its own `args` field — a JSON string
holding the recorded step's tool arguments. But the CLI flag parser
hardcoded `--args` as a whole-payload escape hatch, so `--args` shadowed
the tool's own `args` field. The documented per-flag form
```
argent run flow-add-step --command gesture-tap --args '{"udid":"...","x":0.5,"y":0.5}'
```
silently dropped the step arguments: the `--args` JSON was consumed as
the whole payload and the tool's `args` field stayed `undefined`,
producing a misleading downstream validation error. Only the nested
full-payload form worked.
## Fix
Make `--args` schema-aware in `parseFlags()`:
- When the tool's schema declares a property named `args`
(`schema.properties.args`), `--args <value>` is routed through the
normal per-field handling and coerced by its declared type (a `string`
for flow-add-step, so the raw JSON string passes straight into the
`args` field). Both `--args value` and `--args=value` forms are
supported.
- When the schema does NOT declare `args`, the existing whole-payload
behavior is preserved exactly, including the `--args -` stdin sentinel.
`printToolHelp()` no longer prints the global whole-payload `--args
<json>` / `--args -` lines for tools that declare their own `args`
field, so the help stops contradicting the per-field `--args` shown in
the schema flags.
The change is general: any tool with an `args` field benefits, with no
special-casing by tool name.
## Verification
- `npm run build` (root tsc) — clean.
- `npm test -w @argent/cli` — 172 passed, including 6 new `parseFlags`
cases covering schema-with-`args` (space-separated + inline forms, plus
sibling fields) and schema-without-`args` (whole-payload preserved,
`--args -` sentinel, no-schema fallback).
- Prettier + ESLint (`--max-warnings 0`) clean on the touched files.
Full CLI end-to-end (running `flow-add-step` against a live tool-server
with an active flow recording) was not exercised here; the added unit
tests prove the parser behavior.
Fixes #452
---
### CLI end-to-end verification
Ran the documented per-flag form against a live tool-server with an
active flow recording:
- **Before (global argent 0.13.0):** `argent run flow-add-step --command
gesture-tap --args '{"udid":"...","x":0.5,"y":0.35}'` → `Invalid params
for tool "gesture-tap": udid expected string, received undefined ...`
(args dropped).
- **After (this branch):** same command → `{ "message": "Step added to
\"colltest\" flow", "toolResult": { "tapped": true } }`, and the
recorded YAML contains the step **with** its args (`udid`/`x`/`y`). The
per-flag form now works as documented.
|
||
|
|
8483fe23f9 |
feat: add telemetry (#274)
## Summary Adds anonymous, opt-out telemetry for Argent installer, update/uninstall flows, CLI telemetry controls, tool-server lifecycle, and tool invocation health signals. ## What Changed - Added a new private `@argent/telemetry` package - Introduced typed telemetry events with runtime property allowlisting/sanitization. - Added lazy anonymous identity creation in `~/.argent/telemetry-id`. - Added consent handling via: `argent telemetry enable`, `argent telemetry disable`, `argent telemetry status` - Added local debug logging with `ARGENT_TELEMETRY_DEBUG=1`. - Tracks installer funnel events for init, global install/update decisions, editor selection, allowlist decisions, skill installation, rules/agents copy, update, and uninstall. - Tracks tool-server start/stop and tool invocation/complete/fail events. - Adds per-tool invocation IDs so request metadata can be correlated without relying on ordering. - Records only coarse platform metadata (`ios` / `android`) for device tools - Ensures short-lived commands drain telemetry with bounded shutdown before exit. - Wires telemetry package into bundling and injects full Argent CLI version metadata at build time. - Added central `FAILURE_CODES` and `FailureSignal` helpers in `@argent/registry`. - Attached structured, sanitized failure metadata across registry errors, tool-server tools/services, HTTP validation/dependency gates, installer flows, and `argent run`. - Added telemetry allowlisting for safe failure fields only: static error codes/stages, coarse area/kind/command, bounded exit codes, allowlisted signals/spawn codes, and coarse network failure classes. - Split CLI-local `argent run` failures into `cli:run_fail` so they are not double-counted as tool failures. - Added installer telemetry for failed package actions, update/uninstall failures, rules/agents copy results, and skill refresh results. - Made telemetry consent writes atomic and kept telemetry status side-effect free via `peekAnonId()`. - Adds a coarse, anonymous signal to tool telemetry: which AI coding tool is driving the MCP server (Claude Code, Codex, Cursor, Gemini, VS Code, Windsurf, Zed, opencode, Copilot, or other). ## Tests Added / Updated - Telemetry unit coverage for consent precedence, identity creation, base props, sanitization, PostHog config, debug logging, shutdown, opt-out, and forget behavior. - Registry/tool-server tests for invocation IDs, platform metadata boundaries, startup failure flushing, and tool lifecycle telemetry. - Installer tests for final telemetry drain, update action classification, and uninstall identity cleanup ordering. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
20cb452fd4 |
feat(remote): artifact transport for files produced by a remote tool-server (#278)
## Why
Files produced on the **tool-server host** (screenshots, profiler
exports) were surfaced to the agent as host paths / `127.0.0.1` media
URLs, which the MCP client (`argent-mcp`) then fetched a *second* time
to get the bytes. When the tool-server runs **remotely**, that localhost
URL resolves to the client's own machine — nothing there — so
screenshots fail with `(Screenshot unavailable: no valid PNG …)`.
Profiler exports have the same shape: paths that only exist on the
remote host.
## What
A reusable **artifact boundary layer** so any file-producing tool works
regardless of where the tool-server runs:
**Foundation**
- **tool-server** (`src/artifacts.ts`, `http.ts`): in-process artifact
registry + `GET /artifacts/:id` streaming route.
`registerArtifact(hostPath)` returns a wire handle (`{ __argentArtifact,
id, filename, mimeType, size }`) instead of a raw path.
- **argent-mcp** (`src/artifacts.ts`, `content.ts`, `mcp-server.ts`): a
client materializer deep-walks tool results for handles, downloads each
over the remote-aware `TOOLS_URL`, writes it into a **structured
cache**, and rewrites the result to the **local** path (+ inline image
rendering).
**Cache layout** (override root with `ARGENT_ARTIFACTS_DIR`):
```
~/.argent/artifacts/<project>/<session>/<device>/<filename>
```
- `project` = `basename(cwd)` + short hash of the full path (readable +
collision-safe)
- `session` = minted once per argent-mcp process (groups a run, easy GC)
- `device` = udid/serial when device-scoped, omitted otherwise
**Consumers wired**
- **screenshot** → returns an image artifact; rendered inline from
downloaded bytes with **no second `127.0.0.1` fetch**. Fixes
`auto-screenshot` and `flow-execute` screenshots via the same path.
- **native-profiler-stop** → `exportedFiles` (XML) become downloadable
artifacts materialized client-side.
## Deferred (follow-ups)
- **`.trace` bundle** — it's an Instruments bundle (a directory);
streaming needs archiving (no archiver dep yet). `native-profiler-stop`
now returns a `traceFileNote` explaining it stays on the profiling host.
- **Project source on remote** — `react-profiler-component-source` /
`react-profiler-analyze` read the user's source tree on the tool-server
host. The profiler analysis chains already work remotely
(server-internal); tracked separately.
## Compatibility
Legacy `{ url, path }` screenshot rendering is retained as a fallback
when no artifact context is present (older tool-servers / unit tests).
## Tests
- tool-server: artifact registry (infer/override), `GET /artifacts/:id`
(200/404/410), updated `stop-recovery` assertions.
- argent-mcp: materializer
(download/rewrite/nested/failure/device-scoping), artifact-aware
`toMcpContent`.
- argent-mcp typecheck + full suite green; tool-server artifact/profiler
tests green. (Note: a full local tool-server typecheck trips a
pre-existing zod-v4-vs-v3 mismatch in `run-sequence` that's unrelated to
this change and resolves on this branch's own lockfile.)
## Notes
Routes around the `argent-private` native simulator-server binary (which
emits the `127.0.0.1` media URL) rather than changing it — no submodule
change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: pFornagiel <pawel.fornagiel2@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Paweł Fornagiel <85541429+pFornagiel@users.noreply.github.com>
|
||
|
|
d017ba340c |
feat: Android emulator support (#148)
### For reviewers - what to focus on: The diff is ~6k LoC; this breakdown should help triage where to spend attention: | Bucket | Lines | Effort | | --- | --- | --- | | **Net-new Android logic**: `boot-device.ts` (660) + `adb.ts` (399) + `uiautomator-parser.ts` (292) | 1351 | **Read carefully** | | Blueprint `DeviceInfo` refactor: `simulator-server`, `ax-service`, `native-devtools` | 365 | Read | | Tool `index.ts` / `types.ts` sprawl across ~20 tools (capability gates, `services()`, descriptions) | ~965 | Skim — watch for cross-file consistency | | `platforms/android.ts` impls (stub → real implementation) | ~426 | Skim | | Skill/docs prose, profiler rename ripple | ~1000 | Skim | | **`platforms/ios.ts` deletions** — 12 files, 0 additions; logic moved into unified handlers | 684 | **Skip — mechanical** | ## What works, what doesn't: ### Just works thanks to either sim server or metro: - `gesture-*` - `button`, `keyboard` - `screenshot` - `run-sequence`, `flow-*` - `debugger-*` - `react-profiler-*` ### Adjusted to work on android too: | tool | android | ios | | --- | --- | --- | | `describe` | `uiautomator dump` → `DescribeNode` | `AXServiceApi` | | `launch-app` | `cmd package resolve-activity` + `am start -W` | `simctl launch` | | `restart-app` | `cmd package resolve-activity` + `am force-stop` + `am start -W` | `simctl terminate` + `simctl launch` | | `reinstall-app` | `adb install -r` (+`-g`/`-d`) | `simctl uninstall` + `simctl install` | | `open-url` | `am start -a VIEW -d <url>` | `simctl openurl` | | `list-devices` | `adb devices` + `emulator -list-avds` | `xcrun simctl list --json` | | `boot-device` | snapshot probe → `-force-snapshot-load` hot boot with screencap-alive guard, falls back to cold boot on any failure | `simctl boot` + `bootstatus -b` | ### Will not work on android for now: - `native-devtools-*` (7 total) - `native-profiler-*` (3 total — was `ios-profiler-*`) - `profiler-stack-query`, `profiler-combined-report` (depend on `native-profiler-*`) - `paste` — unregistered on both platforms for now. --------- Co-authored-by: Paweł Fornagiel <pawel.fornagiel2@gmail.com> |
||
|
|
6355620c4d |
refactor(mcp): split mcp package into argent, argent-cli, argent-installer, argent-mcp, argent-tools-client (#162)
## Summary - Splits the monolithic `packages/mcp` package into five focused packages: - `argent` — the user-facing CLI entry (`argent` binary, init/uninstall/update flows, bundled-paths, scripts). - `argent-cli` — CLI runner internals (flag-parser, run, server, tools). - `argent-installer` — `init`/`update`/`uninstall` flows, MCP config adapters, skills installer. - `argent-mcp` — MCP server itself (mcp-server, tool-mapping, auto-screenshot, content adapters). - `argent-tools-client` — HTTP client + launcher for the tool-server. - Adds Gemini agent definitions, VSCode MCP config, and per-package `tsconfig.json` / `vitest.config.ts`. - Updates root `tsconfig.json`, `scripts/dev.cjs`, CI workflows, and `package.json` to wire the new packages together. ## Test plan - [ ] `npm install` resolves the new workspaces cleanly - [ ] `npm run build` succeeds across all packages - [ ] `npm test` passes (renamed test files keep their assertions) - [ ] `npx argent init` still produces the expected MCP config in a sample project - [ ] `npx argent update` / `argent uninstall` exercise the installer package - [ ] CI workflows (`publish.yml`, `unit-tests.yml`) run on this branch |