mirror of
https://github.com/software-mansion/argent.git
synced 2026-09-14 19:27:14 +08:00
fix/flow-dir-export-throw
76 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b835de2326 |
fix(packaging): ship one shared copy of the Android screen-sharing agent (#983)
## Summary Fixes the biggest chunk of #980: the published package shipped **four byte-identical copies** of the Android screen-sharing agent (`resources/android/`: jar + per-ABI `.so`, ~12.7 MiB each) — one next to each platform's simulator-server binary, because the binary resolves the agent relative to its working directory and the spawn set cwd to the per-platform dir. This ships **one shared copy** at `bin/resources/android/` and points the spawn cwd at the bin root instead. Package size (built from this branch, same artifact set as 0.22.1): | | before | after | |---|---|---| | unpacked | 115.5 MB | **76.4 MB** | | packed | 37.6 MB | 25.4 MB | 76.4 MB is under npmmirror's 83886080-byte unpacked-size cap (the limit #980 trips — note it applies to `dist.unpackedSize`, not the tarball). Already-published oversized versions are immutable, so the mirror also needs the `cnpm/unpkg-white-list` entry to sync the backlog; this PR keeps future versions under the cap. ## Changes - `scripts/download-simulator-server.sh` extracts the agent tarball once, to `bin/resources/android/`, instead of next to each binary. - `bundle-tools.cjs` copies that single shared directory into the package. - `@argent/native-devtools-ios` replaces `simulatorServerBinaryDir()` with `simulatorServerRunDir()`: the bin root when the shared `resources/android/` exists there, falling back to the per-platform dir so an `ARGENT_SIMULATOR_SERVER_DIR` override pointing at a pre-dedup layout keeps working. - The blueprint spawns simulator-server with `cwd: RUN_DIR` (binary path stays absolute; the agent lookup is the only cwd-relative path in the simulator-server crate — audited: every other fs path there is a tempdir, `dirs::cache_dir()`, or caller-supplied). No symlinks, no postinstall scripts — plain files plus a different cwd, so nothing changes for npm/pnpm/yarn/bun or Windows. ## Testing - Unit: resolver tests updated + new shared-layout case; blueprint test asserts the spawn cwd. - Packaging: ran the modified download script + `npm run pack` end-to-end; tarball contains exactly one `bin/resources/android/` (94 files vs 112). - Live: branch tool-server with `ARGENT_SIMULATOR_SERVER_DIR` pointed at the new layout — iOS simulator (screenshot) and Android emulator (boot-device, screenshot, gesture-tap) green; `lsof` confirms both spawned simulator-servers run with cwd = bin root, where `resources/android/<jar>` and each per-ABI `.so` resolve (verified present at those exact relative paths). - Physical Android phone (Galaxy S24, the one path that actually pushes the agent): live-tested — the `android_device` controller resolved the agent from the shared layout, pushed it, and connected ("All agent connections established successfully"); screenshot and tap through the on-phone agent both green, spawn cwd confirmed as the shared bin root. No docs update needed: internal packaging/layout only — no MCP tool, CLI, config, or flow-file surface changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01UGAsAvYBJ3Jy9DKLaX9aoZ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved simulator-server resource handling by using one shared screen-sharing resource location across host platforms. * Added a warning when required shared resources are unavailable. * Ensured simulator-server processes start from the correct runtime directory. * **Documentation** * Clarified simulator-server runtime and shared resource behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
efb87f1917 |
chore: bump version to 0.22.1 (#956)
Bumps every workspace package, `package-lock.json`, and both version fields in `server.json` from 0.22.0 to 0.22.1. - `npm version 0.22.1 --workspaces --no-git-tag-version --workspaces-update=false` - lockfile regenerated on Node 24 / npm 11 (version-only diff, 16 lines each way) - `npm run check:versions` passes No docs update needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EjrDqoeJa5X8Ry2ND1P714 |
||
|
|
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>
|
||
|
|
366f17c619 |
chore: bump version to 0.22.0 (#891)
Bumps every workspace package, `package-lock.json`, and both `server.json` version fields from 0.21.0 to 0.22.0 (18 files). Lockfile regenerated on Node 24 / npm 11 so the diff is version-only; `npm run check:versions` passes. Covers everything on main since `v0.21.0`: `paste` tool (#879), rotation-aware Android capture (#693), 0.25 default screenshot scale (#878), no-reboot describe on externally booted sims (#583/#877), NDJSON flow progress (#855), OTLP telemetry (#570), native-devtools restart_required derivation (#560), Android profiler empty-CPU explanation (#669), plus test/CI fixes. Full-surface live QA of this main (tgz vs npm 0.21.0) on iOS, Android, tvOS, Electron, CLI and Linux/remote found zero regressions. Two release notes: the published artifact must be built with `ARGENT_OTEL_INGEST_TOKEN` set (a local tgz without it compiles `readIngestToken()` to an empty string, making telemetry a silent no-op), and remember to push the `v0.22.0` git tag so online `init` skills installs resolve. No docs update needed: version-only change. |
||
|
|
0a6dbec87c |
feat(telemetry): export events via OpenTelemetry OTLP logs instead of PostHog (#570)
## What
Swaps the `posthog-node` transport for an OpenTelemetry Logs exporter.
Everything above the transport stays as it is - opt-out consent,
per-machine identity and fingerprint, the sanitizer allowlist, the typed
event surface, crash diagnostics. Only the ~3-method client boundary
changes.
One analytics event becomes one OTLP/HTTP log record:
| PostHog | OpenTelemetry |
| --- | --- |
| `capture({ event, distinctId, properties })` | `logger.emit({ body:
event, attributes: { distinct_id, "event.name", ...props } })` |
| event name | log-record `body` |
| `distinctId` | `distinct_id` attribute |
| event/base properties | log-record attributes |
| `client.shutdown()` | `LoggerProvider.shutdown()` (force-flush +
teardown) |
Records go to a hard-coded Software Mansion collector. The endpoint and
the authorization header are passed to the exporter explicitly in code,
and an explicit value beats the corresponding `OTEL_EXPORTER_OTLP_*`
variable - the same anti-exfiltration property the fixed PostHog host
had.
## Changes
- `packages/telemetry/src/posthog.ts` becomes `otel.ts`:
`LoggerProvider` + `BatchLogRecordProcessor` + `OTLPLogExporter`
(HTTP/JSON). Queue size 20 and a 10 s flush interval mirror the old
client; the per-export deadline is 1.5 s, kept at or below `index.ts`'s
drain budget so a stalled export can't hold a short-lived command open.
- Dependencies: drop `posthog-node`, add
`@opentelemetry/{api,api-logs,sdk-logs,exporter-logs-otlp-http,resources}`.
They inline cleanly into the esbuild bundles.
- Build-time ingest token via esbuild `define`
(`ARGENT_OTEL_INGEST_TOKEN`), same mechanism as `ARGENT_CLI_VERSION`.
Unset in a dev build leaves the client unconstructed and telemetry
inert.
- Base props: drop `$process_person_profile` (a PostHog directive,
meaningless to a collector) and rename `$session_id` to `session_id`.
Null-valued attributes are dropped, since OTel rejects them -
`cloud_agent` is null on the common path, and absence means the same
thing.
- `Telemetry.md`: the "who we disclose to" and "international transfers"
sections describe a Software Mansion-operated OTLP collector instead of
PostHog as a third-party processor.
## A hang this uncovered
`timeoutMillis` only bounds a request once its socket is connected,
because the exporter applies it with `req.setTimeout()`. Against a
collector address that drops packets rather than refusing them - a
corporate egress filter, a dead host behind a firewall - the socket sits
in the connecting state where no export deadline reaches it, and the
process stays alive for the OS connect timeout: 75 s past a `shutdown()`
that had already resolved at 1.75 s.
Pairing the export deadline with an agent-level socket timeout, armed at
socket creation so it covers connection establishment too, fixes it:
| collector state | before | after |
| --- | --- | --- |
| healthy | 0.18 s, delivered | 0.18 s, delivered |
| connection refused | 0.94 s | 1.03 s |
| blackholed (http and https) | 75.0 s | 1.6 s |
| connected but never responds | - | 1.6 s |
`posthog-node` exited in 10.6 s under the same blackhole (undici aborts
a connecting socket), so this was a regression as well as a hang. A unit
test that fails without the fix guards it.
## Found in review
Each of these was reproduced before it was changed, and each is pinned
by a test that fails without the fix.
- **The environment's OTLP headers were forwarded to the collector.**
The SDK merges `OTEL_EXPORTER_OTLP_HEADERS` / `_LOGS_HEADERS` into every
request, keeping any key the code does not set itself. Out in the world
that variable holds the developer's *own* observability credential - a
Honeycomb team key, a Dynatrace `Api-Token`, Grafana Cloud basic auth -
so any machine already running OpenTelemetry shipped that third-party
secret here on every batch, without it passing the sanitizer or
appearing in `Telemetry.md`. Reproduced by watching `x-honeycomb-team:
hcaik_…` arrive at a capture server. The variables are now cleared
across the exporter constructor (where the SDK resolves its header set)
and restored after.
- **`httpAgentOptions` silently disabled connection reuse.** Supplying
it replaces the agent the SDK would build, whose default is `keepAlive:
true`. Measured on loopback: three batches shared one socket by default,
and opened three sockets with `httpAgentOptions` - a fresh TCP+TLS
handshake per 10 s batch in the long-lived tool-server. `keepAlive` is
restated alongside the timeout.
- **`markDisabled()`'s drain had no grace period.** It raced flat
against `SHORT_FLUSH_TIMEOUT_MS` while `shutdown()` allowed `timeoutMs +
250`. Since the exporter's own deadline equals that budget, the flat
race fired at the same instant and always abandoned the batch instead of
letting it finish. Both call sites share one `raceDrain()` now.
- **Export failures reached nobody.** The batch processor hands errors
to OpenTelemetry's global handler, so `LoggerProvider.shutdown()`
resolves identically for a delivered batch and a rejected token - making
`shutdown()`'s `catch` unreachable. The SDK's diagnostics are now routed
into the existing debug channel under `ARGENT_TELEMETRY_DEBUG=1`; a run
without the flag stays silent so no host application's diag logger is
disturbed.
- **The build-time token now beats the `__ARGENT_OTEL_TOKEN_TEST` seam**
rather than losing to it, so the seam reaches unbundled source only.
Verified with esbuild across all three build modes.
- **The endpoint guard test mocked the exporter it guards.** It could
only show that the code passes a `url`; an SDK upgrade that changed the
precedence would have kept it green. `otel-endpoint-live.test.ts` drives
the real exporter against loopback servers - dropping the explicit
`url`, the explicit `authorization`, or the header clearing each fails
it.
- **The wire shape had no pins at all.** Bypassing the sanitizer
entirely, sending an explicit `null`, renaming `service.name` and
dropping `event.name` all left the suite green. Four tests now fail on
those mutations. The sanitizer bypass was unpinned on `main` too.
## Before this ships
1. ~~**Collector URL**~~ - done in
|
||
|
|
aa9ee0a5d6 |
chore: bump version to 0.21.0 (#810)
Bumps the monorepo from 0.20.0 to 0.21.0 across the full 18-file set: - all 16 `packages/*/package.json` (via `npm version --workspaces`) - `package-lock.json` regenerated with `npm install --package-lock-only --ignore-scripts` on Node 24 / npm 11 (version-only diff, matching the lockfile CI job) - `server.json` — both the top-level `version` and `packages[0].version` `npm run check:versions` passes: all workspace packages and server.json are at 0.21.0. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
4a11317706 |
chore: bump to 0.20.0 (#765)
Version-only bump of the workspace to 0.20.0, same shape as #741 (the 0.19.0 bump). ## What changed - All 16 packages under `packages/*` → `0.20.0` - `package-lock.json` — regenerated with `npm install --package-lock-only --ignore-scripts` on Node 24, matching what the Lockfile job runs. Version-only: 16 insertions, 16 deletions, nothing else. - `server.json` — the MCP registry manifest, in **both** places it carries a version: the top-level `version` and `packages[0].version`. It lives outside `packages/*`, so a workspace sweep leaves it behind and the registry then rejects the publish because `packages[].version` names a version npm has never seen. ## Verification - `npm run check:versions` → "All workspace packages and server.json are at 0.20.0." - `npx prettier --check` clean on every touched file - No `"0.19.0"` string left anywhere in the repo No code changes. |
||
|
|
c876fe8dbc |
ci: add knip anti-dead-code gate (#572)
## What Adds a CI gate for dead code, using [Knip](https://knip.dev). We didn't have one. ESLint's `no-unused-vars` only sees unused locals inside a module, so whole files nobody imports, exports nobody uses, and dependencies declared but never required all slipped through. Knip covers that gap in one tool (roughly `ts-prune` + `depcheck` + `unimported` combined). The new `.github/workflows/knip.yml` workflow ("Dead Code", job `Knip`) runs `npm run knip` on push and PR to `main`. `CONTRIBUTING.md`'s pull-request checklist gains it as a step, with the reason it has to run against a tree with no build output. Knip reads source directly, mapping each package's `dist` entry back to `src`, so the job needs no workspace build. It installs with `--ignore-scripts`: an analysis that only reads `package.json` and source gains nothing from the seven packages here that carry a native install script, six of which reach this runner (`fsevents` is darwin-only). Five try a prebuilt binary before compiling, and `dtrace-provider` always runs node-gyp but ends in `|| node suppress-error.js` — and off mac/solaris/freebsd its `binding.gyp` picks a stub target with no sources, so on ubuntu-latest node-gyp builds nothing for it and `node-pty` is the only package that reaches a compiler at all — an `optionalDependency`, whose failure npm ignores. The exposure is a bump that leaves a package with no prebuild for the runner, which is exactly what `dependabot.yml` pins `tree-sitter` against (0.25.0 ships no Node 24 prebuild and its compile breaks `npm ci`). While adding it I checked whether any other installed checker was missing a gate. None were: ESLint (`lint.yml`), Prettier (`format.yml`), `tsc` build + `typecheck:tests` + `typecheck:scripts` + vitest (`unit-tests.yml`), the workspace-version / focused-test / merge-marker checks (`repo-hygiene.yml`) and lockfile sync (`lockfile.yml`) are all already enforced. Dead code was the only gap. ## How it's enforced `npm run knip` is two invocations: ``` knip --exclude exports,types && knip --include exports,types,classMembers,nsExports,nsTypes --max-issues 206 ``` Every issue type knip reports is an error — that is its default severity, so `knip.jsonc` sets no `rules` block at all. The pre-existing backlog is bounded by the `--max-issues` ceiling on the second pass instead of being hidden behind a non-failing severity: it cannot grow unnoticed, and the number comes down as follow-up passes pay it off. When a change legitimately adds an export nothing imports yet, the number moves up in the same commit — that bump is what review should see, rather than the contributor deleting someone else's backlog to make room. Two PRs making that identical one-line edit merge without conflicting, so `main` lands one short of the truth and its push-triggered run is what catches it. Splitting the passes also keeps a real failure out from under the backlog — the enforced classes report on their own, and the second pass only runs once the first is clean. The second pass names `classMembers`, `nsExports` and `nsTypes` explicitly because they sit in knip's own `defaultExcludedIssueTypes`: `--exclude exports,types` never covered them and `--include exports,types` did not ask for them, so a new unused class member cost nothing and moving an export behind opaque namespace use took it out of the ceiling's scope entirely. `classMembers` has 12 findings on the unbuilt tree the ceiling counts (9 on a built one); the other two have none today. None of the three is gated at zero — all five parked classes share the one ceiling, so a new `nsExports` finding passes if something else in the backlog is retired in the same PR. Naming `classMembers` also turns knip's `isSkipLibs` off (`create-options.js:122`), which makes it search declaration files for external references and **suppresses** 44 export/type findings the same run reports without it — 57/181 becomes 44/150. That, not the 12 findings it adds, is why the ceiling is lower than the two counts alone would suggest; `--include-libs` with no `classMembers` reproduces 44/150 exactly. The ceiling counts what CI counts, against a tree with no build output. Whether a workspace's `main`/`types` path resolves to an existing file changes the result, and not by way of anything in that file — a zero-byte `packages/registry/dist/index.js` moves the count just as a real build does, while a zero-byte `dist/zzz.js` does nothing. A built tree reports fewer issues — 43/147/9 = 199 built, against 44/150/12 = 206 unbuilt — so `npm run knip` passing after a local `tsc --build` is not evidence the job will pass, which is how the Knip job first went red on 199. The ceiling is 206 and it is exact: 206 passes, 205 fails. Remove every `dist/` before trusting a number from it. The ceiling is one total across those classes, so it bounds the backlog rather than each class: paying off one parked export licences one new one elsewhere in the same PR. Knip has no per-class ceiling. `treatConfigHintsAsErrors` is on, so an exemption that stops suppressing anything fails the job rather than printing a hint below the backlog. ## Config `knip.jsonc` documents the false positives so the gate is both green and meaningful. - **`@swmansion/argent`** is a thin dispatcher whose real payload is an esbuild bundle of the other workspaces (`packages/argent/scripts/bundle-tools.cjs`). Knip can't follow imports across that boundary, so packages consumed only by the bundled-in code read as unused; 11 are exempted by name here, though not all for that reason — the http3-quiche transport is pulled in by `@fails-components/webtransport` itself at runtime, and no first-party file imports it. They're exempted **by name**, not behind a catch-all: `ignoreDependencies` also suppresses `unlisted`, and a pattern that matches everything would take this workspace's own `src/` and `scripts/` out of that check — where an import with no matching declaration is a genuine bug rather than a bundler artifact. (It reaches `unresolved` only nominally: knip matches the list against a package name parsed out of the specifier, and an unresolvable relative path yields none, so even a catch-all leaves those reported. `ignoreUnresolved` is the option that does silence them.) - **`tool-server`** reaches a few packages in ways static analysis can't see. The exemptions cover two distinct classes, kept apart in the config so each stated reason matches the finding it silences: - *declared but loaded too dynamically to detect* (would be reported as **unused dependencies**): `tree-sitter` / `tree-sitter-typescript` via dynamic `_require`, and the http3-quiche transport as a runtime companion of `@fails-components/webtransport`; - *imported but deliberately absent from that `package.json`* (would be reported as **unlisted dependencies**): `sharp` (kept out so the ~30 MB native binary isn't a cost every consumer pays) and `electron` (an `optionalDependency` of the published package at one call site, the Electron main-process API at the other). - Root `scripts/`: knip resolves those from `package.json` scripts **and** from `run:` steps in `.github/workflows` via its github-actions plugin — multi-line `run: |` blocks included. What the plugin doesn't parse is a PowerShell body, so `scripts/ci/windows-chromium-e2e.mjs` — invoked at `windows-e2e.yml:176`, in the `windows-latest` job where PowerShell is the default shell — is the one entry declared by hand. ### Known limits - `ignoreDependencies` exempts a package **name across its whole workspace**, in both directions; knip has nothing narrower. While `sharp` is listed for `tool-server`, an undeclared `import "sharp"` anywhere in that workspace passes too. The list is held to packages that genuinely cannot be declared, for exactly that reason. - Knip analyzes JavaScript and TypeScript only (`DEFAULT_EXTENSIONS`), so **only 11 of the 30 files under `scripts/` are in the gate at all**. The other 19 — 15 `.sh` files, `e2e-full/lib/report.py`, `ci/e2e-chromium-page.html`, and e2e-full's `README.md` and `results/.gitignore` — are invisible to it however they are reached — including the whole `scripts/e2e-full/` harness (13 files), invoked from nothing outside its own directory, its only mention elsewhere being a `.prettierignore` entry. - Reachability's widest hole is the workspace entry. Whatever `src/index.ts` re-exports is reached, so a single `export { x } from "./dead-module";` takes that module out of `files` altogether — verified against a module reported as an unused file one run earlier. The same line applied to parked exports retires them from the count without deleting anything: re-exporting `equalsCI`, `includesCI` and `Settled` from `tool-server`'s entry takes 206 to 203 and frees three ceiling slots. The ceiling bounds what knip can see, not what is dead. - Test files are entry points, so a production module kept alive only by its own test still passes `files`. Being reached by a test says nothing about being reachable in production, which is what the check approximates, and two modules sit in exactly that gap: `tools/paste` is imported by two test files and registered by nothing, so it is unreachable over MCP and HTTP, and `utils/ios-profiler/lifecycle.ts` is a re-export barrel whose header keeps it "for source compatibility with existing imports", of which its own test is now the only one — its four production consumers all import `profiler-shared/lifecycle` directly. That single test import is exactly what keeps `files` from reporting it: repoint it and knip returns `Unused files (1)`. `knip --production` is the lens that reports the class; the repo isn't clean under it — 13 unused files (those two, seven root scripts, `packages/argent/scripts/{bundle-tools,observe,sync-readme}.cjs` and `packages/registry/tests/helpers.ts`) with the export/type backlog at 227/206 — measured with `classMembers` off, so comparable to the 57/181 above rather than to the ceiling's 44/150 — so a production-mode pass is a follow-up of its own. - The same entry treatment hides the test trees themselves. Root `package.json`'s `test:scripts` runs `node --test`, which is what makes knip's node plugin contribute its test entries, and that plugin registers four entry patterns in **every** workspace: `**/test/**`, plus `*{.,-,_}test.<ext>`, `test-*.<ext>` and `test.<ext>` matched anywhere. So none of the **380** JS/TS files under `packages/*/test/` can be reported unused, and under `packages/*/tests/` only a name none of those three match can — of today's 15 that is `registry/tests/helpers.ts` alone, which is why it is the lone `tests/` entry in the `--production` list above. A `tests/test-utils.ts` or `tests/test.ts` would be just as invisible. A dead `zz.test.ts` planted in `packages/registry/tests/` passes; a dead `zz-helper.ts` in the same directory fails. - `knip@5.88.1` is the last 5.x release ever published — 6.0.0 landed the next day and `latest` is now 6.x. The pin is deliberate: knip 6 removed the `classMembers` issue type outright, and the shipped script hard-errors on it (`ERROR: Invalid issue type: classMembers`, exit 2). Upgrading is therefore not a version bump — it means re-deriving the ceiling, rewriting the paragraph that explains it, and resolving the pass-1 findings knip 6 adds (six unlisted binaries: `tail`, `plutil`, `xctrace`, `netstat`, `pkill`, `pgrep`; two unresolved imports: `/usr/bin/osascript`, `/usr/libexec/PlistBuddy`). Dependabot's `npm-minor-patch` group cannot move it, since no 5.x exists above 5.88.1; the `npm-major` group will keep offering the 6.x jump. - Knip folds `optionalDependencies` into the declared set, so importing `electron` or `node-pty` is not `unlisted` — they pass because it read them. What it never reports is an optionalDependency nothing uses, so only that direction is outside the gate, along with `argent-cli`'s runtime `req("node-pty")`, resolved through a `createRequire(import.meta.url)` in `lens-pty.ts`, which knip can't see either. ## Dead code this found - `@types/semver` and `@argent/telemetry` from `packages/argent` — both were being suppressed by exemptions whose stated bundler-boundary reason could not apply. esbuild strips types and never resolves `@types/*`, and `packages/argent` names `semver` nowhere; `@argent/telemetry` is aliased to an absolute source path by `bundle-tools.cjs`, so the declaration bought nothing. Removing them is proved safe by building: four of the five bundles still emit and telemetry is inlined in each with no runtime `require` of it. The fifth, preview-window's main, sits behind a downloaded native asset absent from a script-free install, so it is covered by mechanism rather than observation — `bundle-tools.cjs` passes the same `alias` map to every build, and esbuild's `alias` bypasses node resolution entirely: deleting `node_modules/@argent/telemetry` outright leaves all four emitted bundles byte-identical. Removed alongside, but **not** gate-reported: the `benchmark` npm script in `packages/argent`, whose `scripts/benchmark.cjs` does not exist. A dangling script target is a blind spot of this gate — restoring the script leaves knip at exit 0. - Four files with no importers: the `render-hook` injected script, react-profiler's `source-map` + `snippet-extractor`, and `scripts/setup-in-workspace.cjs` (referenced nowhere, and its own usage string names a `scripts/setup-project.cjs` that doesn't exist). - `superagent` in `tool-server`'s `test/http-streaming.test.ts` — imported for a type but declared in no manifest in the repo, resolving only through npm hoisting of supertest's own dependency. Reverting that import to `superagent` reports `Unlisted dependencies (1) … :3:32` and exits 1; `@types/supertest/index.d.ts:10` re-exports the identical type (`type Response = superagent.Response`). - `@clack/prompts` and `@moq/lite` from `tool-server`'s `package.json` — declared, imported nowhere. (`@moq/net` is the one actually used; `@moq/lite` isn't a peer of it.) Also deleted here, but **not** something this gate reported: `src/tools/simulator/simulator-server.ts`. It sat in the `files` blind spot above — `interaction-messages.test.ts` imported it, which is enough to count as reached. `setup-registry.ts` never registers it, so it was unreachable over MCP and HTTP, and that catalog roll-call was its only reference; the import and the catalog count (77 → 76) went with it. ## Lockfile Adding knip moves two transitive packages: `@napi-rs/wasm-runtime` 1.1.5 → 1.1.6 and `@tybys/wasm-util` 0.10.2 → 0.10.3. Knip pulls in `@oxc-resolver/binding-wasm32-wasi`, which floors `@napi-rs/wasm-runtime` at `^1.1.6`, lifting the hoisted entry that had resolved to 1.1.5 for `@rolldown/binding-wasm32-wasi`'s `^1.1.4`, which then cascades to `@tybys/wasm-util`. No runtime impact — both are support packages for the wasm32-wasi fallback bindings, which don't get installed where a native binding exists; `npm ls` reports both extraneous on darwin-arm64. Those two are the only resolved versions that change in the diff; the rest is knip's own tree (49 packages added) and `@moq/lite` removed. ## Verification - `npm run knip` exits 0. - **Coverage of the enforced set.** With no `rules` block, knip's included set is 15 issue types: ten enforced at zero tolerance by the first pass, plus the five the second pass names under the ceiling. Eleven mutations cover all ten, each flipping the gate to exit 1 and back to 0 on revert: | class | mutation | | --- | --- | | `files` | a throwaway `.mjs` in `scripts/`; a throwaway `.ts` in `packages/argent/src` | | `dependencies` | a bogus declared dep in `packages/tool-server/package.json` | | `devDependencies` | a bogus declared devDep in the same manifest | | `optionalPeerDependencies` | `bytes` moved to an optional `peerDependency` there | | `unlisted` | an undeclared import in `packages/argent/src/cli.ts` | | `unresolved` | an unresolvable relative specifier in the same file | | `binaries` | a root `package.json` script invoking a nonexistent binary | | `duplicates` | `export default sleep` alongside the existing named export in `utils/timing.ts` | | `enumMembers` | an unused member on an enum a second module imports and uses | | `catalog` | a `catalog` block in the root `package.json` naming a package nothing uses | One nuance worth recording: `duplicates` is narrower than it looks. It reports a symbol exported both by name and as `default` (`sleep|default`); a second *named* alias of the same symbol is not a duplicate, and a freshly added symbol nothing references is not reported at all — so several naive probes read as a miss. `enumMembers` needed a shape the repo does not currently contain, not an unreachable one. The only exported enum here, `ServiceState`, is re-exported through `@argent/registry`'s entry, where knip counts exports as used, so an unused member added to it is **not** reported — but an enum in a non-entry module that another module imports and uses does report one (`Blue ZzColor …/zz-enum.ts:3:3`, exit 1; deleting the unused member returns exit 0). That is the ninth of the ten covered. `catalog` is reachable here despite the repo using npm workspaces: knip's catalog loader falls back to `manifest.catalog` when there is no pnpm or yarn workspace file, so a `catalog` block in the root `package.json` reports `Unused catalog entries (1)` and exits 1. - The two new mechanisms discriminate as well: one extra unused export takes the backlog to 207 and fails the ceiling, and a stale `ignoreDependencies` entry produces `Configuration hints (1) … Remove from ignoreDependencies` and exit 1. - `npm ci --ignore-scripts` in a clean worktree, followed by `npx knip`, is green — the job doesn't need any of the postinstalls it now skips. - `tsc --build`, `typecheck:tests` (all workspaces), `typecheck:scripts`, `test:scripts`, `eslint . --max-warnings 0`, `prettier --check .` and the full workspace vitest suite (4711 passed, 3 skipped across 13 workspaces; 3070 of those are `@argent/tool-server` alone) are green; `package-lock.json` is untouched by the review pass. |
||
|
|
566663bde4 |
chore: bump to 0.19.0 (#741)
Version-only bump of the workspace to 0.19.0, same shape as #603 (the 0.18.1 bump). ## What changed - All 16 packages under `packages/*` → `0.19.0` - `package-lock.json` — regenerated with `npm install --package-lock-only --ignore-scripts` on Node 24, matching what the Lockfile job runs. Version-only: 16 insertions, 16 deletions, nothing else. - `server.json` — the MCP registry manifest, in **both** places it carries a version: the top-level `version` and `packages[0].version`. It lives outside `packages/*`, so a workspace sweep leaves it behind and the registry then rejects the publish because `packages[].version` names a version npm has never seen. ## Verification - `npm run check:versions` → "All workspace packages and server.json are at 0.19.0." - `npx prettier --check` clean on every touched file - No `"0.18.1"` string left anywhere in the repo No code changes. |
||
|
|
a644d52d39 |
feat(flows): run CLI flows from explicit paths (#568)
`argent flow run` now takes an explicit YAML path instead of a saved-flow name: ``` argent flow run .argent/flows/checkout.yaml --platform ios ``` The path may point anywhere on the local filesystem; the filename stem names the run's report/artifacts, so it must be `[A-Za-z0-9_-]+` with a lowercase `.yaml` extension. A bare name fails with the exact replacement command, and `argent flow list` prints paths instead of names. Because sibling `run:` files and `__baselines__` resolve beside the YAML, the CLI now requires the auto-started local tool server and refuses `ARGENT_TOOLS_URL` / `argent link` routing. The `flow-execute` tool stays remotely callable via `name` + `project_root`, and gains a `flow_path` parameter (exactly one of `name`/`flow_path`) that is only honored when the file-input boundary verified it as a real host path — uploads and boundary bypasses are rejected, so it can't execute arbitrary server YAML. Also: the flow-name pattern is now a single shared export from `@argent/registry`, and the recorder composes a `flow_path` call into a `run:` step when it targets a sibling of the recording. |
||
|
|
19782f4e1a |
feat(secrets): resolve {{secret:…}} from .env files, not just the environment (#734)
## Why
A credential could only reach a typing tool through an
`ARGENT_SECRET_<NAME>` environment variable. That is the right CI
contract — and stays the highest-priority source — but interactively it
is poor ergonomics: an editor-hosted tool-server inherits the
environment its editor was launched with, so changing a credential means
restarting the editor, and there is nowhere to write one down that
survives a reboot. "Is loading these from a `.env` file on the roadmap?"
is the recurring ask.
## What
`{{secret:NAME}}` now resolves through an ordered chain, first match
wins, re-read on every resolution — so editing a file applies to the
next keystroke with **no server restart** (the same runtime-read design
`ios.additionalDeviceSets` already uses).
| # | Source | Which keys it exposes |
| - | ------ | --------------------- |
| 1 | `ARGENT_SECRET_<NAME>` in the environment | prefixed variables
only — unchanged, still wins |
| 2 | `<project>/.argent/secrets.env` | every key (gitignore it) |
| 3 | `<project>/.env.local`, then `<project>/.env` | **only
`ARGENT_SECRET_`-prefixed keys** |
| 4 | `~/.argent/secrets.env` | every key, any project |
Covers `keyboard`, `paste`, `run-sequence` keyboard steps, and flow
`type:` steps — all four already funnel through the same resolution
point, so nothing else changed.
Also adds `argent secrets [list] [--json]` so a setup is verifiable
without an agent: names only, never values, shadowed names marked, and a
warning when a linked remote tool-server means resolution happens on a
different machine.
## The one design decision worth reviewing
**Row 3 is why this isn't just "read the `.env`".** An agent composes
the tool call, so anything reachable through `{{secret:…}}` is
exfiltratable by a prompt-injected one — type it into a field, then read
the field back. "Which values may argent type" has to stay an allowlist
the user wrote deliberately.
So: a *dedicated* argent secrets file exists for no other purpose and
therefore **is** the allowlist; a file the app *shares* keeps the prefix
as the allowlist, exactly as the process environment does. Your
`STRIPE_SECRET_KEY` sitting in the same `.env` stays unreachable —
verified live, not just asserted. Adding `ARGENT_SECRET_` to one line is
the deliberate act that exposes it.
Two smaller calls, both reversible:
- The chain lives in `@argent/configuration-core`, not the tool-server,
so the CLI reads the same code; the tool-server keeps only the
placeholder engine.
- The project scope is discovered by the **cwd walk-up every other
project-scoped configuration uses**. A per-request project root (header
→ `ToolContext`) was considered and rejected as new protocol surface
across two client paths; reusing flows' module-global
`setActiveProjectRoot` was rejected as a cross-project leak on a reused
server. The cost is that a tool-server whose cwd sits outside the
project skips project files — mitigated by the failure now listing every
path it consulted, and by `~/.argent/secrets.env` needing no project at
all.
## Verification
Unit + integration: tool-server 3122, configuration-core 122 (19 new),
argent-cli 370 (6 new). Lint and prettier clean. All four publish
bundles build.
Live, driving this branch's tool-server on :3001 against iPhone 17 Pro /
iOS 26.4 and the Electron testbed:
- global `~/.argent/secrets.env` → typed correctly; the response echoed
only the placeholder
- prefixed key in the project `.env` → typed; **unprefixed
`STRIPE_SECRET_KEY` in that same file → rejected**
- `.argent/secrets.env` beat `.env`; the environment variable beat both
- edited a secrets file mid-session → applied on the very next call,
same server pid
- a chromium flow with `type: { text: "{{secret:APP_PASSWORD}}" }` → 3/3
pass, asserting on the greeting the app rendered, so the *correct value*
provably landed
- an undefined name inside a flow surfaces the full source list in the
step report
Sample of the failure output (no value ever appears):
```
Unknown secret "LOGIN_PASSWORD" — no source on the machine running the tool-server defines
LOGIN_PASSWORD. Available secrets: APP_USER.
Sources consulted, first match wins:
1. environment (ARGENT_SECRET_*) — 0 secrets
2. /path/to/project/.argent/secrets.env — found, 1 secret
3. /path/to/project/.env.local — not found
4. /path/to/project/.env — found, 1 secret
5. /Users/me/.argent/secrets.env — not found
To make it available, ask the user to add `LOGIN_PASSWORD=…` to …
```
## Out of scope
No general flow variable/parameter system — a non-secret external value
(a test account's email, a staging tenant id) can use the same
placeholder, but argent treats every such value as a secret: redacted
from errors, never echoed, so it is not for something a report should
show. No config key pointing at an arbitrary secrets file. Remote
(`argent link`) still resolves on the remote host, which the CLI now
says out loud.
|
||
|
|
a6f1bef632 |
fix(cli): stop argent mcp --help starting the server, and argent tools --help dumping the catalogue (#656)
Fixes #638. ## The report understated it The issue says `argent mcp --help` "does not hang and does not start the server — it simply prints nothing". Reproducing it showed the opposite: ``` $ argent mcp --help < /dev/null ; echo $? 0 # 0 bytes ← what the reporter saw $ argent mcp --help # stdin open (a pipe, an editor, a CI step) # HANGS — I hit a 300s timeout ``` `--help` **starts the MCP stdio server**, which blocks reading JSON-RPC from stdin. The "prints nothing, exit 0" is just the server getting an immediate EOF from a closed stdin. So this is the same "`--help` runs the real command" bug that was fixed for the installers — `mcp` was missed. `startMcpServer` takes no argv at all (`mcp-server.ts:96` — its only parameter is `{ paths }`), so a help flag was *structurally* unreachable; there was nowhere downstream that could have handled it. ## Fix `mcp` joins the existing guarded set rather than growing a second help path. That set's defining property is "the handler never inspects its argv", and `mcp` qualifies more strongly than the installers do — it isn't merely ignoring `rest`, it is never handed it. **It cannot fire on a real launch.** The guard tests `rest`, which is `[]` for every generated editor config (all four shapes end at `mcp`, and `isArgentManagedEntry` requires exactly that), and `[].some(...)` evaluates no predicate. This is pinned in both directions, because a guard that *did* fire here would print usage onto the JSON-RPC channel and break every editor at handshake — the highest-cost regression in this file, and it was untested. The top-level table's `mcp` row now reads the same metadata as its own help, so the two cannot drift. **No rename.** An earlier draft renamed the module and six identifiers (`installer-help` → `command-help`, etc.) on the grounds that its comments had become false. They hadn't quite: fixing `mcp` *and* `tools` makes "every other subcommand parses `--help` itself" true again — I checked all ten siblings. Since #530 and #568 both edit `cli.ts`, a rename would have forced them through churn for no behavioural gain. Prose-only. ## Second commit: `argent tools --help` The issue mentions it in passing; it's a different mechanism and a genuinely dead branch. `argv.filter((a) => !a.startsWith("--"))` dropped `--help` before the subcommand was read, so it fell through to listing all 77 tools — **contacting the tool-server, starting one if none was running**, to do it. Only `-h` ever reached the existing help branch. Scoped to the subcommand position on purpose: a global check would have broken `argent tools describe <name> --help`, which today prints *that tool's* flags. It still does — there is a test. Separate commit so it can be reverted alone. ## Verification Live, against the built CLI: | | before | after | |---|---|---| | `mcp --help`, stdin open | hangs indefinitely | usage, returns immediately | | `mcp --help`, stdin closed | 0 bytes, exit 0 | 849 bytes of help, exit 0 | | `mcp` (real launch) | works | works — verified with an actual `initialize` handshake, server replies with its capabilities | | `mcp --metro-port 8082` | starts server | starts server (guard keys on help, not on "any argv") | | `tools --help` | 77-line catalogue | usage | | `tools describe gesture-tap --help` | tool's flags | tool's flags | | `argent --help` `mcp` row | — | byte-identical | argent 80 passed, argent-cli 284 passed. ## Note on the help text Every claim in it is sourced (stdio/JSON-RPC transport, stdout ownership, the `~/.argent/mcp-calls.log` default and `ARGENT_MCP_LOG` override, auto-spawn vs `ARGENT_TOOLS_URL`/`argent link`). It deliberately does **not** suggest running `argent mcp` by hand to check an install — that is the reported hang — and instead says it will look like it has hung and why. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
9489a220b0 |
chore(argent): declare the Node version the package actually needs (#653)
Fixes #640. ```json "engines": { "node": ">=20.12.0" } ``` ## Why 20.12.0 and not 20 My first answer was `>=20` — CI's lowest tested line, satisfied by every runtime dependency, and the version the issue reporter (and I) installed successfully. **It is wrong**, and shipping it would have told npm it is safe to install onto runtimes where the CLI cannot execute a single line. The mistake was looking at first-party `src/`. The published artifacts are four esbuild bundles with their dependencies **inlined**, and that is where the real floor lives. Confirmed in `packages/argent/dist/`: | blocker | added in | consequence below it | |---|---|---| | `import { styleText } from "node:util"` (via inlined `@clack/*`, in `installer.mjs` and `cli-cmds.mjs`) | **20.12.0** | a **link-time** `SyntaxError` — `argent init` and every CLI subcommand fail to load | | `import.meta.dirname` at module scope (`bundled-paths.js`, `cli.js`) | 20.11.0 | `TypeError` during module init | So 20.12.0 is the lowest version on which the package actually loads. It is also the lowest line CI exercises (7 workflows pin Node 20), and it satisfies every runtime dependency's own constraint (`@fails-components/webtransport` `>=20`, `@modelcontextprotocol/sdk` `>=18`). `electron`'s `>=22.12.0` does **not** apply — it is an `optionalDependency`, and npm does not engine-check those. Verified: installing `0.18.0` on Node 20.19.5 produces no `EBADENGINE` at all and electron is never materialized. I did not go to `>=22` on EOL grounds: it would refuse a runtime seven CI workflows still test and that users demonstrably run. ## Docs corrected alongside - `README.md` said **20.11** — one minor below where the package can load. - `CONTRIBUTING.md` said **Node.js 18+** — predates what the repo's own lint toolchain needs (`eslint@10` requires `^20.19.0 || ^22.13.0 || >=24`). `packages/argent/README.md` is generated by `scripts/sync-readme.cjs` on `prepack`, so it follows automatically and is deliberately untouched. ## What a reviewer should know **Enforcement is package-manager-dependent**, which matters because `argent init` installs with whichever PM the project uses: | | behaviour on too-old Node | |---|---| | npm (default) | `npm warn EBADENGINE` — installs anyway | | npm + `engine-strict=true` | hard error, install aborts | | **yarn 1.x** | **hard error by default** | | **pnpm** | **silently ignores it** | So this achieves the issue's "warn" but only conditionally its "refuse". There is no `.npmrc` in the repo, so contributors are unaffected either way. **Nothing in the repo validates `engines`** — `repo-hygiene`, `check-workspace-versions.mjs` and `pack-mcp.cjs` all ignore unknown manifest keys, and `next-canary-version.mjs` round-trips the manifest through `JSON.parse`/`stringify`, which preserves the new field and stays prettier-clean. **One inconsistency I did not resolve:** `packages/argent/scripts/bundle-tools.cjs:383` builds with `target: "node22"`, which now sits above the declared floor. In practice the node20→node22 syntax gap is negligible (tsc targets ES2022 and I found no post-20 *syntax*), so I left the shipped artifact alone rather than change build output in a manifest-only PR — but it should either be lowered to match or consciously kept. Your call. ## Separate bug found while verifying this `ios-remote` is broken on the **entire Node 20 line**, independent of this change: the inlined `@moq/*` client uses `Promise.withResolvers` (Node 22+) ungated — 6 occurrences in `dist/tool-server.cjs`, reached from `utils/moq-client.ts` via the simulator-server blueprint. Reproduced on Node 20.19.5: `TypeError: Promise.withResolvers is not a function`. I deliberately did **not** raise the floor to `>=22` to paper over it — that would refuse Node 20 for every user to hide one broken path. `moq-client.ts` already has an `ensurePolyfill()` that polyfills `WebSocket`/`WebTransport`; this belongs there. Filed separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
23b9ae5c87 |
chore: bump to 0.18.1 (#603)
Patch bump. First release whose npm tarball carries `mcpName` (added in #598), which unblocks the MCP registry publish (`mcp-publisher publish` rejects `0.18.0` because its manifest predates the field). `server.json` is bumped alongside `packages/*` for the first time — `scripts/check-workspace-versions.mjs` now enforces it (`All workspace packages and server.json are at 0.18.1` locally). | Commit | Change | | --- | --- | | `eea6c27c` | `style`: fix prettier formatting on main (#604) | | `7e4ece69` | `chore`: server.json for the official MCP registry (#598) | | `fc09612f` | `feat(config)`: `recordings.directory` — configurable save location for screen recordings (#601) | | `cccda92d` | `feat(config)`: `ios.additionalDeviceSets` — additive array of extra CoreSimulator device sets (#542) | Version-only diff, rebased on main as of #604. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
7e4ece697d |
chore: add server.json for the official MCP registry (#598)
Adds the two files the official MCP registry
(`registry.modelcontextprotocol.io`) needs in order to list argent.
Argent is not in that registry today
(`?search=io.github.software-mansion` returns 0 servers).
The registry is metadata-only — it points at the npm package rather than
hosting anything.
### `server.json`
Describes the server and how a client starts it: `npx @swmansion/argent
mcp`. The `mcp` positional is the dispatcher case in
`packages/argent/src/cli.ts:137`, and it is the same subcommand `argent
init` writes into every client config —
`packages/argent-installer/src/mcp-configs.ts:130-141` spells it four
ways (`node <path> mcp`, `yarn argent mcp`, `npx --no-install argent
mcp`, and the global `{ command: MCP_BINARY_NAME, args: ["mcp"] }`,
where `MCP_BINARY_NAME` is `"argent"`). None of them is literally the
npx-by-package-name form in `server.json`, which is the form the
registry expects a client to construct from `identifier` + `runtimeHint`
— so it is verified below by running it, not by matching a string.
`repository.id` is the GitHub repo id (`1164885639`); the schema
recommends it so a registry can detect a delete-and-recreate of the
repo.
### `mcpName` in `packages/argent/package.json`
The ownership proof. The registry fetches the npm package and requires
`mcpName` to equal the server name in `server.json` before it will
accept a publish under `io.github.software-mansion`. It is the field the
registry's own quickstart names for npm packages. Nothing in the publish
path drops it: `scripts/pack-mcp.cjs` shells out to `npm pack` without
rewriting the manifest, and the canary path's
`scripts/next-canary-version.mjs --write` round-trips the JSON and only
sets `version`.
### Namespace
`io.github.software-mansion/argent` — GitHub OAuth auth. The registry
grants an org namespace only to org **Owners**; plain membership is no
longer enough. If no Owner is available to run the publish, the
alternative is DNS auth via an apex TXT record on `swmansion.com`, which
changes the name to `com.swmansion/argent` (and the `mcpName` value with
it).
### Version sync
`server.json` sits at the repo root, outside `packages/*`, so a release
bump would have left its two `0.18.0`s untouched — and the registry
rejects a publish whose `packages[].version` names a version npm has
never seen. `scripts/check-workspace-versions.mjs` (already run by the
Static checks job) also holds `server.json` to the version in
`packages/argent/package.json` — the package it names — and pins the two
cross-file links a publish depends on: `name` == `mcpName`, `identifier`
== the published package name. Both halves are reported in one run, so a
half-finished bump doesn't cost a CI round-trip per file.
### Not in this PR
- **Publishing.** Nothing has been published; this is just the manifest.
Publishing is `mcp-publisher login github && mcp-publisher publish`, and
it can only succeed **after** a release whose npm tarball carries
`mcpName` — i.e. not against `0.18.0`, which is `latest` (published
2026-07-30) and predates `mcpName` — `curl
registry.npmjs.org/@swmansion%2Fargent/0.18.0 | jq .mcpName` → `null`.
The first publishable release is the next bump.
- **`github.com/mcp`.** A separate, manual step. Onboarding a new server
there is hand-curated: per
[github/github-mcp-server#1257](https://github.com/github/github-mcp-server/discussions/1257)
(trent-j, a collaborator on that repo, 19 May 2026) "onboarding a new
server is still a manual curation process today. Once a server has been
onboarded, newly published versions from the OSS registry should sync
from there." The nomination channel is `partnerships@github.com`, from
GitHub's [registry how-to
post](https://github.blog/ai-and-ml/generative-ai/how-to-find-install-and-manage-mcp-servers-with-the-github-mcp-registry/)
(24 Oct 2025) — that address does not appear anywhere in the discussion
thread.
### Verification
- `mcp-publisher validate` (v1.8.0, which posts the file to the live
registry) → `server.json is valid`. Mutation-checked what that actually
covers: removing `transport` fails it and removing `$schema` is a 422,
but a foreign namespace (`io.github.anthropics/argent`), a nonexistent
npm identifier and a `99.0.0` package version all still pass — so it
checks shape only, and the ownership/existence checks happen at publish
time. Also validated offline against the pinned `2025-12-11` schema.
- Ran the entrypoint the file declares. `npx -y @swmansion/argent@latest
mcp` fed an `initialize` over stdio answered
`{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"argent","version":"0.18.0"},"instructions":"…"}`,
with stderr empty.
- Mutation-checked the new version guard: drifting `server.json`
`version`, drifting `packages[0].version`, deleting `mcpName`, and
typo-ing `identifier` each fail `check-workspace-versions.mjs` with the
specific line; the pre-existing packages/* drift check still fires on
its own.
- Asserted across the two files: `mcpName` == `server.json` `name`,
`identifier` == package `name`, all three versions equal, description 89
chars (registry limit is 100).
- `prettier --check` and `eslint` clean on both changed files.
- Mutation-checked the guard as a whole — 22 mutants, 1 survivor.
Killed: reverting the self-invocation guard to a raw `argv[1]` compare
and making it never match; `exit(1)` → `exit(0)` on the failure path;
dropping either `failed = true`; exiting early on `packages/*` drift
instead of collecting; `packages.slice(0, 1)`; hardcoding `packages[0]`
in either message; dropping the no-packages-array guard, the
non-object-entry guard, the non-object-JSON guard, and the presence
checks for `version`, `name` and `mcpName`; `continue` → `break` in the
`packages/*` scan (both arms) and in the entry loop; dropping the
on-message read, the `git checkout` hint, and the per-version name
accumulator. The survivor is the `packages/*` readdir sort: it fixes the
scan order rather than any output, so no single run can observe it — it
is there so a scan that stops early drops the same packages on every
machine instead of a filesystem-dependent set.
- Reproduced the symlink no-op on the real repo: with
`packages/registry` at `9.9.9` and `server.json` at `0.17.0`, `node
/tmp/argent-alias/scripts/check-workspace-versions.mjs` now exits 1 and
prints both problems, where before it exited 0 with no output at all.
- Closed the vacuous-pass class in `serverJsonMismatches`: all four
comparisons it makes were bare `!==`, so a field absent from *both*
sides compared equal and passed. A `packages/argent/package.json` with
no `version` printed `All workspace packages and server.json are at
undefined.` and exited 0; with no `name`, a `server.json` naming nothing
installable was reported in sync. `version` and `name` now require
presence, as `mcpName` already did.
- `readTrackedJson` guarantees an object, not just parseable bytes — a
`server.json` holding `null` used to reach the field reads and throw,
and `"0.18.0"` or `[]` produced mismatch lines that never said the file
was the wrong shape.
- Full CI parity locally: `test:scripts` 85/85, `tsc -p
tsconfig.scripts.json`, `eslint --max-warnings 0`, `prettier --check`.
|
||
|
|
646f726bc4 |
chore: bump to 0.18.0 (#596)
bump debated myself whether this should be a QoL patch or a minor release and i think the latter makes more sense | Commit | Change | | --- | --- | | `7189333a` | `feat(tool-server)`: human-readable log message (#582) | | `5ac69349` | `feat(flow)`: CSS combinator scopes for flow selectors (#569) | | `e23f0e28` | `feat(flow)`: snapshot `cropOn` for single-element visual diffs (#516) | | `6a53e66a` | `feat(flow)`: rotate directive (#546) | | `68ceb314` | `ci`: cut over npm publishing to the unified trusted-publishing workflow (#571) | | `2546788a` | `ci`: unified publish-npm workflow (#565) | |
||
|
|
a0460eeefe |
chore: bump workspace packages to 0.17.0 (#554)
## What
Lockstep-bump all 16 `packages/*` workspace packages (and the matching
`package-lock.json` entries) from `0.16.1` → **0.17.0**.
Diff is exactly 32 version-field swaps across 17 files — no formatting
or
dependency churn.
## Verification
- **Lockfile CI gate reproduced locally on the exact CI toolchain**
(Node
24.14.1 / npm 11.11.0, matching `lockfile.yml`'s `node-version: "24"`):
`npm install --package-lock-only --ignore-scripts` on top of the commit,
then `git diff --exit-code -- package-lock.json` → **clean**. npm's own
regeneration reproduced the hand-edit byte-for-byte, so none of the
`"peer": true` churn that #513/#539 had to keep out reappears here.
- `node scripts/check-workspace-versions.mjs` → `All workspace packages
are
at 0.17.0.`
- Remaining `repo-hygiene.yml` checks pass: no conflict markers, no
focused
tests.
- `prettier --check` on all 17 changed files → `All matched files use
Prettier code style!`
- **Runtime version actually reports 0.17.0**: `getInstalledVersion()`
(`argent-installer/src/utils.ts:384`) and
`getGloballyInstalledVersion()`
(`topology.ts:94`) both read `version` straight out of the resolved
package
root's `package.json` at runtime, so the bump is the whole mechanism —
no
generated constant or second version file to keep in sync. Exercised
that
resolution against the bumped tree: `PACKAGE_ROOT` → `packages/argent`
(`@swmansion/argent`) → `0.17.0`.
- Verified all 16 lockfile hits belong to workspace packages (parsed the
lockfile's `packages{}` and matched every `0.16.1` entry to a
`packages/*` path) — no unrelated dependency happened to sit at 0.16.1.
- No test asserts a release version string; the only `0.1x.x` matches
under
`*.test.ts` are historical references inside comments.
## Note
`packages/argent-private` needs no pin change here. Its release version
is
carried purely as a git tag — the repo has no version field on the
release
line (its only `package.json` is a `private: true` research CLI on an
independent `0.1.0` line) — and `v0.17.0` is now tagged at `2d6c292`,
which
is **already** the commit this superproject pins. `v0.16.0` and
`v0.16.1`
sit on that same commit, so the submodule entry is correct as-is and
stays
out of this diff.
|
||
|
|
7400179b5b |
Windows support: Android + Chromium host control plane (#421)
## What Makes Argent run on Windows. iOS Simulator is macOS-only (Apple), so on Windows that means the **Android + Chromium** host control plane. The blocker was twofold: (1) no Windows `simulator-server` binary, and (2) POSIX-only assumptions in the tool-server. Companion radon PR builds the binary and runs the Android emulator E2E on Windows: software-mansion/radon#134. ## Changes **Windows-aware tool-server / resolver / bundling** - New shared `commandOnPath()` helper — `where` on Windows, `command -v` via `/bin/sh` on POSIX. `android-binary`, `check-deps`, and `vega-cli` previously hardcoded `/bin/sh`, which never matches on Windows. - `android-binary`: append `.exe` to `adb`/`emulator` in the `$ANDROID_HOME` fallback; probe `%LOCALAPPDATA%\Android\Sdk` (Android Studio's Windows default). - simulator-server resolver + dispatcher + `bundle-tools` + `download-simulator-server.sh`: ship and resolve `simulator-server.exe` on `win32` (new `simulatorServerBinaryName()`), add `win32` to the bundled host keys, add the `simulator-server-argent-windows.exe` download target with PE arch validation. - `stop-metro`: resolve listening PIDs via `netstat -ano` on Windows (`lsof` is POSIX-only and threw ENOENT). - `adb.ts`: AVD root resolution used `$HOME` + `startsWith("/")` (rejects `C:\…`); now `os.homedir()` + `path.isAbsolute()`. - **`boot-device`**: the emulator was spawned `detached` with `stdio:"ignore"`; on Windows a detached emulator with NUL stdout/stderr never reaches `sys.boot_completed` (verified on `windows-latest`: the identical flag set boots fine with real handles, hangs with NUL). Redirect the detached emulator's output to a temp log file on win32. POSIX keeps `"ignore"`. **Tests** — cross-platform unit coverage for `commandOnPath` (both branches), win32 `.exe` Android resolution, win32 `.exe` simulator-server resolution, and a win32 AVD drive-path case; dep-gate tests now mock at the `commandOnPath` boundary so they're platform-agnostic. **CI** — `windows-e2e.yml` (`windows-chromium` on `windows-latest`): runs the resolver/dep unit tests natively on Windows, confirms `adb.exe` resolution via the SDK root, then drives a **real headless Chrome over CDP** through the tool-server (discover → screenshot → describe → tap → observe the DOM mutation). Flow in `scripts/ci/windows-chromium-e2e.mjs` (also runnable locally / in Docker). The `simulator-server.exe` build + the full **Android-emulator E2E on Windows** live in radon CI (the binary's source is the private radon repo). ## Verification (all green) - **Chromium control plane on real Windows** (`windows-latest`): `✓ discovered chromium-cdp-9222 → ✓ screenshot → ✓ describe → ✓ gesture-tap → ✓ DOM mutation observed`. Resolver/dep unit tests run natively; `adb.exe` resolves via the SDK root (it's *not* on PATH on the runner — the gap the resolver closes). - **Android emulator on real Windows** (radon#134, `windows-latest` / WHPX): the real Argent path — `boot-device` → `{ booted: true }` → screenshot via `simulator-server.exe` → gesture-tap — all green. (The boot-device fix above is what makes the detached emulator reach `boot_completed`.) - **Local clean-room E2E**: the Chromium flow runs green in a headless Linux Docker container (fresh `npm ci`, no host pollution). - **No regressions**: full tool-server suite (1624) + native-devtools-ios (16); ESLint/Prettier/typecheck clean; **Wayland E2E** (Linux AVD boot) and **Vega VVD E2E** still pass (they exercise the changed `adb.ts` / `boot-device.ts` / `vega-cli.ts` paths). ## Notes Android-emulator E2E needs WHPX nested virtualization — confirmed available on the current hosted `windows-latest` image (Server 2025); the emulator boots hardware-accelerated in ~3 min. --------- Co-authored-by: Ignacy Łątka <claude-hubert.gancarczyk@swmansion.com> Co-authored-by: Ignacy Łątka <latekvo@users.noreply.github.com> |
||
|
|
8d2a499eaf |
Project-scope configuration with schema-driven merge + argent config (#534)
## Summary Adds a general, **scoped** configuration system on top of the shared `config.json`, plus a universal `argent config` command to manage it. Motivated by the discussion on #401 (iOS device set): config that needs to work naturally with the MCP server should be read off disk at runtime like telemetry consent is — not threaded through CLI flags/env and a kill-and-respawn dance. This lands the reusable machinery; the device-set becomes a one-line schema entry + a runtime reader on top of it. Four pieces, matching the requirements: ### 1. Project-scope config files `config.json` now resolves at two scopes: - `~/.argent/config.json` (**global**, default) - `<project-root>/.argent/config.json` (**project**, resolved by the same `.argent`/`.git`/`package.json` marker walk as feature flags) `configFilePath` / `readConfigObject` / `updateConfig` take an optional `scope` (default `global`), so **every existing caller is unchanged** (telemetry, notices, lens). Per-scope lock + atomic write are preserved. ### 2. Schema-driven merged reads `getConfigValue(def)` reads each scope the value's schema entry allows, merges them under the entry's policy, and falls back to the entry's default. This is the reader consumers should call instead of poking at a single global file. The existing **lens** getters (`getRememberedAgent` etc.) are migrated onto it as the first live consumer — a repo can now pin its lens agent, falling back to the user's global choice. ### 3. A registration file for configurations (`config-schema.ts`) Adding a configuration is a one-liner: `key`, `description`, allowed `scopes`, a `parse` validator, and a `merge` policy. Merge presets: - `prioritize-local` (project wins) · `prioritize-global` (global wins) - `prioritize-restrictive` (booleans/numbers — opt-out/stricter wins) - `union` / `intersection` (arrays) - …plus an escape hatch: pass your **own** `(inputs) => value` function for a bespoke rule. ### 4. `argent config` — one universal command `argent config <list | get | set | unset>` with `--scope global|project` and `--json`. New configs are added as **schema entries**, not new top-level `argent` commands, to avoid bloat. **Telemetry stays backward-compatible** on its dedicated `argent telemetry` command (which also drains/resets the live client). It's surfaced *read-only* under `argent config` via a `manageCommand` guard — so `argent config set telemetry.enabled` refuses and points at `argent telemetry`, and a committed project file can never re-enable a global opt-out (`prioritize-restrictive`, global-only). ## Testing - **Unit / integration**: 71 configuration-core tests (merge presets + custom fn, dotted-path + prototype-pollution guards, scope merge, scope/validation/manage-command errors, `listConfig`, `coerceCliValue`) and 11 real-filesystem CLI tests driving the actual `config()` entry point across sandboxed HOME + project cwd. Full suites green: configuration-core 71, argent-cli 268, telemetry 281, argent 60. - **Live, on the built binary** (`node packages/argent/dist/cli.js …`): set global + project (from a deep subdir) → effective get returns the project value; per-scope gets return each file; both files land in the right place; `argent telemetry disable/enable` writes `config.json` and `argent config get telemetry.enabled` reflects it read-only; unknown-key / invalid-value / bad-scope errors exit non-zero with hints. - `tsc --build` across the workspace, prettier, and eslint (`--max-warnings 0`) all clean. ## Notes / follow-ups - Config-file reads are not yet fingerprint-cached the way telemetry's consent read is; a long-lived tool-server re-reads on each `getConfigValue`. Fine for CLI/low-frequency use; a hot runtime consumer (e.g. a future device-set reader) may want the same mtime/inode cache. |
||
|
|
1f5b155229 |
chore: bump workspace packages to 0.16.1 (#539)
## What Lockstep-bump all 16 `packages/*` workspace packages (and the matching `package-lock.json` entries) from `0.16.0` → **0.16.1**. ## Verification - `node scripts/check-workspace-versions.mjs` → `All workspace packages are at 0.16.1.` - Lockfile diff is exactly 16 version-field swaps — no unrelated churn (the `"peer": true` regeneration noise from a newer npm was again kept out, same as #513). The one remaining `0.16.0` in the lockfile is the unrelated `@humanfs/types` dev dependency. - `packages/argent-private` submodule left pinned at `v0.16.0` — no `v0.16.1` tag exists there yet. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
013d5b60c5 |
fix: get ax-service working on ios-remote (sim-remote --json spawn + TCP artifact diagnostics) (#536)
## Summary
Three fixes that together get `describe` (and the other ax-service /
native-devtools tools) working against **ios-remote** (`sim-remote`)
devices — including from a **Linux** host. Reproduced end-to-end against
a live remote iPhone 17 simulator over the QUIC relay.
Before: `argent run describe --udid remote:<UDID>` returned an empty
`ROOT AXGroup` with a misleading "reboot the simulator" hint.
### 1. `sim-remote spawn` output was never valid JSON
(`fix(tool-server)`)
`simctlSpawn` parses the CLI's stdout as one `{exit_code,stdout,stderr}`
(or `{pid}`) JSON object, but `sim-remote spawn` only emits that when
passed `--json`. Without it a **non-detached** spawn streams the child's
raw output live, so `JSON.parse` throws `Unexpected end of JSON input`.
This broke ios-remote describe at the first step:
`remoteIosHost.bootstrapAx` runs `defaults write com.apple.Accessibility
…` through a non-detached `simctlSpawn`, which failed before the
ax-service daemon ever started — surfacing only as an empty AX tree.
Fix: pass `--json` unconditionally (no-op for the already-JSON
`--detach` path).
### 2. The tcp ax-service was resolved/packaged under a host-platform
dir (`fix(native-devtools-ios)`)
The tcp `ax-service` is a **darwin/iOS-simulator** binary that is
uploaded to and `simctl spawn`d on the **remote** macOS orchestrator, so
it's needed on any *host* platform. But it was resolved (and packaged)
under `bin/<hostPlatform>/tcp` via `platformBinDir()`, so a **Linux host
looked at `bin/linux/tcp` and never found the darwin-built binary** —
the ios-remote path was effectively macOS-host-only. (The tcp dylibs
were already neutral at `dylibs/tcp`.)
Moved it to a platform-neutral `bin/tcp`, mirroring `dylibs/tcp`, and
rewired every producer/consumer:
- resolver: `platformTcpBinDir()` → `tcpBinDir()` = `BIN_DIR/tcp`
- `native-devtools-ios/scripts/build.sh`: `bin/darwin/tcp` → `bin/tcp`
- `scripts/download-native-binaries.sh`: `TCP_BIN_DIR` → `bin/tcp`
- `packages/argent/scripts/bundle-tools.cjs`: copy from/to `bin/tcp`
- tests assert the neutral location on both linux and darwin
### 3. Missing tcp artifacts were undiagnosable
(`fix(native-devtools-ios)`)
When a tcp artifact is absent (local/dev build, older package), the bare
`... not found` error was thrown deep in the ax-service factory, where
`describeIos` swallowed it and returned an empty tree plus
`DEGRADED_HINT` — telling the agent to `boot-device --force`, a dead
end. The only escape was discovering `ARGENT_SIMULATOR_SERVER_TCP_DIR`
by reading source. Fix: `requireTcpArtifact` throws an actionable error
naming the exact path, the override env var, and how to build it;
`describeIos` surfaces that instead of the reboot hint.
## Testing
- New `sim-remote-spawn-json.test.ts` — asserts `--json` on both plain
and `--bin/--detach` argv, before the `--` separator.
- `native-devtools-ios/test/index.test.ts` — the tcp binary resolves
from the neutral `bin/tcp` on **both** linux and darwin; the not-found
errors name their override env var.
- `native-devtools-ios` (16) + ios/describe tool-server suites pass;
typecheck, eslint, prettier clean.
- Manual end-to-end against `remote:<UDID>` (darwin host): binary at
`bin/tcp` → full tree from `source: "ax-service"`, no hint; binary
removed → actionable `ARGENT_SIMULATOR_SERVER_TCP_DIR` hint.
|
||
|
|
b50d51a2de |
chore: bump workspace packages to 0.16.0 (#513)
## What Lockstep-bump all 16 `packages/*` workspace packages (and the matching `package-lock.json` entries) from `0.15.0` → **0.16.0**. ## Why The `packages/argent-private` submodule is already pinned at **v0.16.0**, while the workspace packages sat at 0.15.0. This aligns the whole repo on the single 0.16.0 version. ## Verification - `node scripts/check-workspace-versions.mjs` → `All workspace packages are at 0.16.0.` - `git submodule status` → clean (no `+`), pinned at `v0.16.0`. - Lockfile diff is exactly 17 version-field swaps (no unrelated churn — a full `npm install --package-lock-only` regeneration was rejected because it introduced unrelated `"peer": true` churn from a newer npm). |
||
|
|
07427917e2 |
fix(launcher,lens): drop the npm postinstall — its jobs move to runtime (#510)
## Why Shipping *any* `postinstall` makes pnpm 10+ wall the install behind its build gate: `ERR_PNPM_IGNORED_BUILDS`, `pnpm install` exits 1, and `pnpm exec argent` is unusable until the user runs `pnpm approve-builds` — their first experience of argent is a bricked CLI. The same script is also silently skipped by `--ignore-scripts`, Yarn PnP, and locked-down CI, so anything correctness-relevant in it was already unreliable (the codebase says as much in several places, e.g. `runTrustingDisk`). Live-verified during the 0.15.0 QA: with **all builds declined** in pnpm 11, argent installs, inits, and serves MCP fine — the postinstall was never load-bearing for install correctness. Removing it means pnpm users never see the approve-builds wall for argent itself. ## What the postinstall did, and where it went | Job | New home | |---|---| | SIGTERM a tool-server stranded by an upgrade that replaced its bundle dir (pnpm/yarn version-pinned layouts) | `sweepDeadStateFiles` in the launcher's slow path now retires **live** servers whose recorded bundle is gone from disk, with the same pid-identity guard as `killToolServerForInstallDir` (never signal a recycled pid; keep unidentifiable live records reachable for `server stop`). Same-bundle in-place bumps were already self-healed by the disk-authoritative version gate. | | `chmod +x` node-pty's macOS `spawn-helper` prebuilds (shipped without the exec bit; first `pty.spawn` otherwise fails `posix_spawnp`) | `ensureSpawnHelperExecutable()` in `lens-pty.ts`, run when the module loads, best-effort with the AppleScript fallback intact. | | Print the `argent init` hint | Dropped — init flows drive the install, and the hint never printed on pnpm/PnP anyway. | `ARGENT_SKIP_POSTINSTALL` in `update.ts` is kept deliberately: downgrades and pinned installs fetch older versions whose postinstall still exists and honors it. ## Testing - New `launcher-sweep.test.ts` (6 tests) exercises the sweep against **real processes**: live-server-with-deleted-bundle is terminated and its record unlinked; live server with intact bundle untouched; recycled-pid record kept, not signalled; dead-pid record unlinked; legacy slot untouched; a SIGTERM-trapping orphan doesn't hold the sweep (and the spawn lock above it) hostage for its kill grace window — the record is unlinked and the SIGKILL escalation runs in the background. - New `ensureSpawnHelperExecutable` tests (real fs, darwin-gated) verify the +x restore and silent failure; a regression test pins that `loadNodePty` tolerates req seams without `resolve`. - Full suites green in all touched packages: tools-client 154, installer 535, cli 248, mcp 76, argent 60. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
955c946d18 |
fix(ci): unbreak npm prerelease bundle + de-flake Android await-ui-element tests (#496)
## Why Two independent failures are red on `main`: 1. **Publish prerelease to npm (next)** — failing on *every* push since #367 (2+ days). 2. **Unit Tests** — a flaky Android `await-ui-element` test that finally tripped on the latest commit (and reproduces locally under load). Neither was caused by the commit they surfaced on (#441, an MCP-installer change); both are pre-existing. ## Fix 1 — `dtrace-provider` breaks the esbuild bundle ``` ✘ [ERROR] Could not resolve require("./src/build/**/*/DTraceProviderBindings") node_modules/dtrace-provider/dtrace-provider.js:18:30 npm error command sh -c node scripts/bundle-tools.cjs (build:bundles) ``` - `dtrace-provider` is an **optional** dependency of `bunyan`, which tool-server took on for the event log (#367). It provides **DTrace USDT probes** — macOS/BSD kernel tracing we never fire. - bunyan loads it defensively: `require('dtrace-provider' + '')` inside a `try/catch` (`bunyan.js:79`). The `+ ''` is a deliberate trick to hide the module from bundlers; a failed require just sets `dtrace = null`. - **esbuild constant-folds `'dtrace-provider' + ''` back to a literal**, defeating the trick, pulls dtrace-provider into the graph, and then chokes on *its* dynamic native-binding require (`require('./src/build/'+build+'/DTraceProviderBindings')`). - **Bumping bunyan is not an option**: `1.8.15` *is* the latest (last publish 2025-06-28) and is effectively frozen; dtrace-provider remains an optionalDependency. There is no bunyan 2.x. **Fix:** mark `dtrace-provider` **external** in the tool-server bundle — exactly how `tree-sitter` / `electron` / `@fails-components/webtransport` native deps are already handled. The published `@swmansion/argent` never declares bunyan/dtrace-provider, so the runtime `require("dtrace-provider")` misses and bunyan's `try/catch` nulls it out. **No DTrace probes were ever used, so zero functional impact.** Verified: `build:bundles` now succeeds; the built `dist/tool-server.cjs` contains an external `require("dtrace-provider")` and no `DTraceProviderBindings`. ## Fix 2 — flaky Android `await-ui-element` tests ``` AssertionError: expected false to be true (test/await-ui-element.test.ts:417) AssertionError: expected 'last tree fetch failed: tree fetch did not complete within the 60ms wait budget' to match /empty or unreadable/i ``` Root cause: `describeAndroid` calls `isAndroidTv(serial)` before reading the hierarchy, which spawns a **real `adb` subprocess on every poll**. With no device in a unit test, that real I/O overruns the tight `timeoutMs` budget (60ms in one case); the fetch loses its `settleWithin` race, so the wait reports *"did not complete within the …ms wait budget"* instead of evaluating the (mocked) tree. On a fast dev box it usually beats the budget; on a loaded CI runner it doesn't → flake. **Fix:** stub `isAndroidTv` to an instant `false` so the Android fetch resolves in microtasks and the poll loop is bounded only by its own (mocked, instant) tree reads. Verified stable: 12× clean locally, and **8/8 green under full CPU saturation** (28 busy workers on 14 cores) to reproduce the oversubscribed-runner conditions. ## Checks - Full tool-server suite: **2166/2166 passed** (was 2165 + 1 failed) - `typecheck:tests`, `prettier --check`, `eslint`: all clean 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
551c781fb0 |
feat(flow): support running end-to-end flows without agent (#429)
# Flow E2E
This PR turns flows from replayable tool-call recordings into a
declarative, portable e2e test system that runs headlessly via `argent
flow run <name>` — no LLM in the loop, non-zero exit on failure,
suitable for CI.
Agents can still replay flows via `flow-execute` and get the full output
from each step after it finishes.
## Flow format
Flows are YAML files in `.argent/flows/`, now built from **directives**
interpreted by the runner rather than raw tool calls:
- `launch` — terminate + relaunch the app under test (per-platform app
id map supported); its presence marks a flow as **e2e** (controls its
own start state) vs. a **fragment** (runs against current state,
declares an `executionPrerequisite`, composable via `run:` with
cycle/depth guards).
- `tap`, `type` (focus handshake + optional submit), `scroll-to`
(momentum-free, increments by half the container, `within:` for nested
scrollers), `await`/`assert` (`visible`/`exists`/`hidden`/`text`
conditions), `wait`, `snapshot`, `echo`, and raw `tool:` as escape hatch
— still fully supported, so previously recorded flows keep working
unchanged.
- **Selectors** are `{ text, identifier, role }`; a bare string is a
loose selector resolving identifier-first, then visible text. Any
directive failure hard-stops the flow; later steps report `skip`.
## Execution engine
- Flows store no device id — the runner binds a device at replay
(explicit `--device`/`--platform` or the single booted one).
- Selector resolution runs against **platform-unified UI trees**: iOS
native view hierarchy (full testID coverage, gated on native-devtools
connecting), Android full accessibility hierarchy (full resource-id
coverage), Chromium CDP DOM, and the Vega automation toolkit. A shared
flatten/text-hoisting pass lets `text` assertions read what an
identified container visibly shows. Vega is remote-driven, so touch
directives fail with guidance to use `tv-remote`/`keyboard`.
- Steps wait for the tree to **settle** (two consecutive identical
reads) before acting; `launch` additionally gates on platform
tree-source readiness instead of silently degrading.
## Visual snapshots
`snapshot` diffs a full-resolution screenshot against baselines in
`.argent/flows/__baselines__/<flow>/`, keyed by platform + resolution,
with configurable `maxMismatch` and `--update-baselines`. The status bar
is pinned for the whole run (iOS `simctl status_bar`, Android demo mode)
so clocks/battery don't drive diffs. Baseline/current/diff images are
returned as artifacts on failure (and the written baseline on first
capture/update); a clean pass carries none, keeping reports and agent
context lean.
## Recording
The record-live workflow (`flow-start-recording` → `flow-add-step` →
`flow-finish-recording`) now emits directives automatically: coordinate
taps are rewritten to portable selector `tap:` steps (selector captured
from the pre-tap tree), a leading `restart-app` becomes `launch:`,
`flow-execute` of a sibling fragment becomes `run:`, and device ids are
stripped. The skill instructs the agent to polish the saved YAML
afterwards (fold tap+keyboard into `type:`, swipes-to-reach into
`scroll-to:`, awaits into sugar form).
## Also included
- `argent flow run` / `argent flow list` CLI with per-step report
rendering, artifact materialization, and `--json` output.
- New structured failure codes for flow validation, device resolution,
composition, and devtools readiness.
- Extensive unit test coverage (tree adapters, selector matching,
scrolling, composition, type focus, snapshots, status bar).
|
||
|
|
3f2680788d |
fix(cli): print help for init/update/uninstall instead of running them (#460)
## The bug `argent <cmd> --help` for the installer subcommands `init` / `install` / `update` / `uninstall` / `remove` did not print help — it ran the real, side-effecting command. `argent uninstall --help` even opened the destructive "Remove argent configuration from this workspace?" prompt (with Yes pre-selected). Root cause: `main()` in `packages/argent/src/cli.ts` dispatched these subcommands and forwarded `rest` (including `--help`) to the installer functions, which have no help handling. Only the top-level `--help` case called `printHelp()`. ## The fix Intercept `--help`/`-h` for exactly the installer command set before dispatching, and print a short per-subcommand usage block without loading or invoking any installer code (no network, no wizard, no prompt). - New side-effect-free module `packages/argent/src/installer-help.ts` exports the pure decision function `installerHelpRequested(command, rest)` plus `printInstallerHelp(command)`. - `cli.ts` calls the guard at the top of `main()` and returns early when help is requested. - The other subcommands (`run`, `tools`, `server`, `link`, `flags`, `enable`, `disable`, `telemetry`) already handle `--help` themselves, so they are deliberately excluded — `argent run <tool> --help` still prints that tool's flags. ## Verification - `npm run build` (root tsc) + `npm run build -w @swmansion/argent` — green. - Ran the built CLI end-to-end (stdin from /dev/null): `init --help`, `update --help`, `uninstall --help`, `install --help`, `remove --help`, `uninstall -h` all print usage and exit 0 with no wizard/network/prompt. - Regression: `argent --help` still prints top-level help; `argent run --help` still prints the `run` usage (not intercepted). - Added unit tests in `packages/argent/test/installer-help.test.ts` for `installerHelpRequested` / `isInstallerCommand` (8 tests, all pass). - `prettier` and `eslint` clean on the touched files; test typecheck passes. Fixes #451 |
||
|
|
10a78d0527 |
feat(file-inputs): add tar-upload kind for streaming remote file/directory uploads (#443)
## What A new `tar-upload` file-input kind so a tool that reads a local file or directory (e.g. `reinstall-app`'s app bundle) works when the tool-server runs on a different machine than the caller. ## Why `reinstall-app` assumes the bundle is on the tool-server's filesystem. That breaks with a cloud-hosted simulator — the bundle is on your machine, not the server's. The existing `file` kind inlines base64 and is capped at 32 MB, too small for a real `.app`/`.apk`; `tar-upload` streams instead. ## How When you're not linked to a remote server, an existing local path is used in place. When you are (e.g. `argent link`), the client tars the path, streams it to `POST /upload`, and the tool call carries `uploadId` plus a SHA-256 `contentHash`. The server always extracts from that upload — even if the same path already exists on disk — verifies the hash, and vets tar members before extracting. The client only uploads when the path is on its own machine (a line on stderr so you know it's working). Same command local or remote: ``` argent run reinstall-app --udid <udid> --bundleId <id> --appPath ./MyApp.app ``` ## Shared extraction Per review feedback, the tar pack/unpack logic is unified in a small `@argent/archive` package used by **both** directions — this upload path and the pre-existing artifact download (`streamDirectoryAsTarGz` / `downloadAndExtractArchive`). The shared extractor rejects path-traversal entries, symlinks whose target escapes the extract dir, and non-file/dir members (hardlinks, devices) — while still allowing a bundle's internal symlinks. This also hardens the artifact-download path, which previously extracted without those checks. ## Tests Client + server unit and HTTP round-trip tests: dir and file upload, skip-when-not-local, co-located no-op, hash required, path-traversal / escaping-symlink / hardlink rejection, sidecar handling, single-member resolution, `/upload` auth + size caps, and artifact download extraction. All suites pass. --------- Co-authored-by: Filip131311 <contact@filipkaminski.com> |
||
|
|
2a01e407b3 |
chore: release 0.15.0 (submodule + workspace bump) (#484)
## What - Bump the `packages/argent-private` submodule pointer from `v0.11.0-8-g2953e89` to **v0.15.0** (`41484e4`). The superproject pin had drifted ~4 releases behind the checked-out submodule. - Lockstep-bump all `packages/*` workspace packages from `0.14.0` → **0.15.0** (and the matching `package-lock.json` entries) to line up with the submodule. ## Why The submodule and the workspace were out of sync: the working tree had `argent-private` checked out at v0.15.0 while the superproject still pinned the v0.11 era, and the JS packages sat at 0.14.0. This adopts v0.15.0 as the single, consistent version across the repo. ## Verification - `node scripts/check-workspace-versions.mjs` → `All workspace packages are at 0.15.0.` - `git submodule status` → clean (no `+`), pinned at `v0.15.0`. - Lockfile diff is exactly 15 version-field swaps (no unrelated churn). |
||
|
|
7bd017a796 |
feat(installer): committable repo-local (--local) install mode (#428)
## Summary Adds an opt-in **committable / repo-local** install mode so a team can version Argent _with the repo_. `argent init --local` installs `@swmansion/argent` as a project **devDependency** and writes MCP configs that launch the project-local copy — so after `git clone && npm install`, every teammate has the same Argent version and MCP wiring with **no global install and no per-developer `argent init`**. **Global mode stays the default** and is unchanged; everything here is additive and backward-compatible. Motivation: the workflow some users already do by hand (#207). Supersedes the earlier, since-closed #232 — this version is Windows-safe (`node`, not the `.bin` shim), handles Yarn PnP, and closes the cross-install tool-server hazards rather than leaving them. ## What changed **`init`** - `--local` / `--global` flags + an interactive "How should argent be installed?" prompt. Mutually exclusive; non-interactive (`--yes`) defaults to **global**. - Local mode installs the devDependency with the package manager detected from the project's **lockfile** (run with `cwd = projectRoot`). - MCP entry points at the local copy: `node node_modules/@swmansion/argent/dist/cli.js mcp` (the bin path is derived from the installed `package.json` `bin` and existence-checked — forward slashes, committable, Windows-safe). Yarn PnP → `yarn argent mcp`; an `npx --no-install argent mcp` fallback is used only when the bin can't be resolved. - Records the mode in a committed `<root>/.argent/install.json`. - Drops global-only adapters (Windsurf/Hermes) in local mode; prints team-setup / commit guidance. **`update`** — detects the project's mode; in local mode reads the installed version from `node_modules` (not the global binary / npx cache) and bumps the **devDependency + lockfile**, then re-emits the local MCP command. **`uninstall`** — scoped to the project's mode: a local-mode uninstall removes the **local devDependency only and never the shared global install**, and prunes `.argent/install.json`. Global-mode behavior is unchanged. **Cross-install hardening (the gate that makes per-project pinning safe)** - `launcher`: a tool-server is reused only when its `bundlePath` matches the caller's — a repo-local pin never silently runs against (or kills) a different version's server. - `postinstall`: only stops a tool-server spawned from *this package's own* bundle, so a devDependency install can't tear down an unrelated editor session. **Telemetry** — adds an `install_mode` dimension to init/update/uninstall events. ## Testing - New unit tests: install-mode helpers + record (`utils`), mode-aware `getMcpEntry`/`resolveLocalCommandMode` incl. the opencode array form (`mcp-configs`), local-only uninstall guard (`uninstall`), and bundlePath-gated tool-server reuse (`launcher`). - All existing suites green (installer 346, tools-client 115, telemetry 191, registry 83, argent 13, tool-server 1621). Build + lint clean. - **Live end-to-end** in an isolated sandbox: `init --local` → real MCP stdio handshake serves **69 tools from `node_modules`**; `update --local` reads the local version; `uninstall --local` removes the local install and **leaves the global install intact**; `init --global` unchanged; flag conflict rejected. ## Notes / known limitations - Recommended on mainstream platforms (macOS, Linux x64, Windows x64) with prebuilt native binaries; Linux arm64 / Windows arm need a C/C++ toolchain to build `tree-sitter` on `npm install` (documented in the README). - Concurrent sessions of two *different* Argent versions on one machine each spawn their own tool-server; an orphaned one idle-times-out (no session is ever broken). 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
3393d22edd |
feat(telemetry): derive distinct_id from a stable host fingerprint (#444)
## Summary Replaces the random-UUID telemetry `distinct_id` with a stable per-machine id derived from the host fingerprint, so PostHog's native "Unique users" counts machines (funnels / retention / breakdowns work with no HogQL). Every Argent entry point - installer, CLI, tool-server, MCP - derives the id from one shared code path, so a given machine reports a single identity across every event and across install / uninstall / reinstall. ## What changed - `distinct_id = uuidv5(hostFingerprint, NAMESPACE)`, where the fingerprint comes from `simulator-server fingerprint`. Deterministic, keeps the UUID shape, and never stores the raw hardware value in PostHog (only the SHA-1-derived UUID leaves the process). - The fingerprint is resolved in `buildPayload` - the single `capture()` path shared by every entry point - so installer / CLI / tool-server / MCP all produce the same id. Resolved lazily, once per process, memoized. - One-time, local-only migration: the first time a fingerprint resolves, `~/.argent/telemetry-id` is rewritten from the legacy random UUID to the derived id. No PostHog `alias` / `$identify` event is emitted. - Fallback: if the fingerprint can't be resolved (unsupported platform, binary absent), the stored or a fresh random UUID is used - identically for every entry point on that machine, self-healing to the derived id on the next successful resolve. - Hardening: never throws; the fingerprint is validated (exactly 64 hex, case-insensitive) before hashing; corrupt / empty / unreadable id files self-heal; the binary is spawned at most once per process. ## Why the id is stable across install -> uninstall -> reinstall Uninstall deletes `~/.argent/telemetry-id`. Because the id is `uuidv5(fingerprint)` and the fingerprint is deterministic per machine, a fresh install recomputes the identical id. Previously only the tool-server resolved the fingerprint while the installer emitted under a random UUID, so this cycle produced a different random id each time. ## Bundling note for reviewers `@argent/telemetry` now depends on `@argent/native-devtools-ios` to locate the binary. That package computes its bin dir from `__dirname` at module load, which is undefined in an ES module. The installer / CLI / MCP ship as ESM bundles, so `bundle-tools.cjs`'s ESM banner is extended to shim `__dirname` / `__filename` (the CJS tool-server bundle already has them natively). Without this shim those bundles would crash on load, so the banner change is load-bearing. ## Testing - Unit: 219 telemetry tests - RFC 4122 v5 vectors, migration, idempotency, case/length validation, corrupt-file self-heal, spawn-at-most-once, and all fallbacks. - E2E on a real machine + booted iPhone 16 Pro: installer, CLI, and tool-server runtimes all emit the same derived id; the id is stable across a delete/recreate (uninstall/reinstall) cycle; a legacy v4 id migrates locally with no alias/identify emitted; verified from an ESM bundle placed in the real install's `dist/` so the binary resolves via the bundled `__dirname` with no env override; tool calls against the device carry the same id. |
||
|
|
cbced9aa4b |
docs(readme): cover TV, Fire TV, Electron/web platforms and new CLI commands (#461)
The README still described Argent as an iOS-Simulator / Android-Emulator tool, missing the platforms and commands we've shipped since. Cross-referenced the copy against the actual code (device classifier, capability matrix, MCP tool registry, CLI dispatch, and editor adapters) and brought it up to date. ## What changed **Tagline & new "Supported platforms" table** — Argent now advertises what it actually drives: - iOS Simulators (touch) - Android emulators **and physical devices** over adb (touch) - **TV**: Apple TV (tvOS), Android TV / Google TV, Amazon Fire TV / Vega (D-pad remote) - **Desktop & web**: Electron and Chromium apps incl. React Native Web / Expo web, over CDP (mouse) **Capabilities** — expanded to reflect shipped features that weren't mentioned: - Record & replay flows - Visual regression (screenshot diff with OCR/font-aware comparison) - Richer profiling story (React DevTools / Hermes fibers, native Instruments + Perfetto, cross-correlated commit-vs-hang reports) - Network capture (JS `fetch` + native), JS evaluation, native UIKit / React component tree inspection - Desktop & web control (tabs, cookies, storage, DOM, network over CDP) **Prerequisites** — added tvOS (Xcode), Android TV (SDK), Fire TV (Vega SDK) and Electron/Chromium (`--remote-debugging-port`) notes. **CLI Reference** — added the six commands present in code but missing from the table: `tools`, `run`, `server`, `lens`, `link`, `unlink`. **Supported Editors** — corrected Zed to note its global config path (`~/.config/zed/settings.json`) alongside the project path. ## Notes - Physical iOS devices and physical Fire TV hardware are declared in the capability types but aren't drivable today, so they're intentionally left out. (A physically-connected Fire TV can be surfaced by `list-devices` discovery via `classifyKind()`, but it isn't bootable and the shape-based resolver in `device-info.ts` routes every `amazon-` serial through the VVD gate.) - Remote iOS simulators (`ios-remote` via `sim-remote`) are omitted from the platform table to keep it focused on the common targets. |
||
|
|
c5b9857fa5 |
chore: bump all workspace packages to 0.14.0 (#454)
Bumps every package under `packages/*` from 0.13.0 → 0.14.0 in lockstep. - All 14 workspace packages bumped to `0.14.0`. - `package-lock.json` regenerated to match (also picks up npm's `"peer": true` normalization). - `npm run check:versions` passes: *All workspace packages are at 0.14.0.* Internal deps use `file:../` references, so no dependency version specifiers needed changing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
a92c859d07 |
feat(argent-lens): argent lens — bind a claude session to the preview window (#416)
## What Adds `argent lens` — open Argent Lens bound to a fresh `claude` session. ## Why The Lens preview window and the agent communicate through a shared, process-wide tool-server that carries **no per-agent identity** (only a coarse telemetry header). So when the user requests changes in the window, there's no reliable way to route them to the *specific* agent that opened it. `argent lens` sidesteps the problem by inverting ownership: the human launches Lens, and Lens spawns (and therefore owns) exactly one `claude` terminal. The binding is 1:1 by construction — no identity plumbing required. ## How it works 1. `argent lens` ensures a tool-server and **begins a CLI Lens session**, which opens the preview window up front (no `await_user_selection` needed) and keeps it open across rounds. 2. It spawns a tracked `claude` terminal in the current directory — a TypeScript port of the macOS applet's `osascript` spawn/track mechanism — seeded to propose variants without blocking. 3. A watcher polls `GET /preview/outcome`; on each submitted round it types a one-line feedback summary into that terminal, queuing it to the agent as its next prompt. Requesting changes therefore "talks back" to the bound agent instead of closing the window. macOS only (drives Terminal/iTerm via `osascript`); off-darwin it exits with a clear message. ## Changes - **CLI** `lens-terminal.ts` — `osascript` spawn/track + a new write-into-running-session path (the "outputting" channel; injects input into the running TUI, which a tty write cannot do). - **CLI** `lens.ts` — the command + feedback formatter. - **tool-server** — a `cliSession` flag in the variant store (opens the window, suppresses auto-close on submit); `POST /preview/cli-session` and `GET /preview/outcome` routes. - **UI** — relabels the submit action to "Request changes" while a CLI session is active. Behind the existing `argent-lens` feature flag. ## Verification - Build + typecheck across the workspace; ESLint (`--max-warnings 0`) + Prettier clean. - 34 new unit tests; full `@argent/cli` suite **118 passing**, tool-server variant/preview suites **46 passing**. - **E2E (observed on this machine):** - **tool-server HTTP** — `cli-session` toggles `cliSession` true/false; submitted feedback round-trips through `/preview/outcome`. - **terminal injection** — spawned a window running `cat`, confirmed `writeToSession` lands text in the running program's **stdin** (both iTerm and Terminal), with embedded newlines flattened. - **full relay** — the real `watchAndRelay` loop against a real tool-server typed two distinct submission rounds' feedback into a stand-in agent terminal (dedup on `completedAt` verified). - `argent lens --help` and the feature-flag gate (exit 1 with guidance, no spawn). Note: a real end-to-end with a live `claude` agent was not run (it would drive a paid interactive session); the agent-facing channel is proven by injecting into a stand-in process's stdin via the exact same code path. --------- Co-authored-by: Filip131311 <contact@filipkaminski.com> |
||
|
|
20f5a1282c |
feat: initial sim-remote support (#291)
## Summary
Adds **initial support for remote iOS simulators** ("sim-remote") —
simulators that run in the cloud (radon-cloud orchestrator) and are
driven from the dev's machine over a QUIC/MoQ tunnel, alongside the
existing local iOS simulators. A remote sim is exposed as a new device
platform, `ios-remote`, and the existing
interaction/inspection/profiling tools work against it through the same
tool surface.
To get there without scattering `isRemote` branches across every tool,
the iOS code paths are refactored behind a small set of
host/transport/backend abstractions so each tool stays
transport-agnostic.
## How it works
- **Discovery** — `list-devices` enumerates remote sims via the
`sim-remote` CLI in addition to local `simctl`. They classify as
`platform: "ios-remote"`. Enumeration is best-effort: if `sim-remote`
isn't installed or the user isn't logged in, it silently returns none.
- **Transport** — remote interaction goes over a MoQ relay
(WebTransport/QUIC). `moq-client.ts` subscribes to the server-published
`simulator` broadcast (catalog/video/screenshot) and publishes a
`control` track carrying protobuf-encoded input commands (touch / key /
button / rotate / wheel / screenshot). WebTransport is provided in Node
by `@fails-components/webtransport`, polyfilled lazily on first use.
- **Native devtools over the tunnel** — unix sockets don't bridge the
QUIC tunnel, so on remote sims `ax-service` and `native-devtools` are
forced onto TCP with OS-assigned ephemeral ports, and a reverse proxy is
wired before the in-sim daemon dials back.
## Key components
New (`packages/tool-server/src/`):
- `utils/sim-remote.ts` — thin wrapper around the `sim-remote` CLI
(simctl verbs, `moq-info`, proxy), propagating CLI stderr verbatim.
- `utils/moq-client.ts` — pure-JS MoQ client for the remote
simulator-server relay.
- `utils/datachannel-proto.ts` + `proto/datachannel.proto` — vendored
protobuf schema + encoders for the control channel.
- `utils/ios-host.ts` — `IosHost` abstraction (`localIosHost` /
`remoteIosHost`, picked by `pickIosHost(device)`) capturing the
local-vs-remote differences (transport, env setup, proxying,
`requiresTcp`).
- `utils/simctl-backend.ts` — strategy for simctl verbs so one iOS
handler serves both `xcrun simctl` (local) and `sim-remote simctl`
(remote).
- `utils/ax-prefs.ts` — AX-pref helpers extracted from `ax-service`.
-
`tools/{launch-app,open-url,reinstall-app,restart-app}/platforms/ios-remote.ts`
+ shared handlers.
Refactors:
- **Strategy pattern** to limit `isRemote`/platform branching inside
tool and blueprint implementations.
- `simulator-client.ts` gains a transport abstraction
(`SimulatorServerTransport`) so call sites stay transport-agnostic;
local sims back it with WebSocket+HTTP, remote sims with the MoQ client.
- `ax-service` / `native-devtools` blueprints updated for ephemeral TCP
ports and the `ios-remote` platform.
- Dependency checks: tools that pick a platform path internally now gate
on the right CLI (`sim-remote` vs `xcrun`).
## New dependencies
`@moq/lite`, `@moq/net`, `@fails-components/webtransport`,
`@fails-components/webtransport-transport-http3-quiche`, `protobufjs`.
## Testing
- Existing unit suite passes (CI green); the native-devtools
status/describe tests now stub the platform dep-check so they exercise
their logic, not the host toolchain.
- E2E device-smoke jobs (local iOS sim, Android, Chromium, remote VVD)
pass.
---
<sub>Branch rebased onto latest `main` (linear history). `sim-remote` is
opt-in — only required when driving a remote iOS simulator.</sub>
|
||
|
|
b8afbed183 |
feat(tv): Apple TV (tvOS) and Android TV support (#374)
Adds end-to-end support for driving **Apple TV (tvOS)** and **Android TV (leanback)** targets through argent, using a focus-driven interaction model (TVs have no touchscreen — interaction is moving a focus highlight with the remote). This PR was reworked after review to **reuse the existing cross-platform tool surface and the `tv-remote` tool from the Vega/Fire TV work (#366)** rather than ship a separate family of `tv-*` tools. ## What this delivers TV targets are driven by the **same cross-platform tools as every other platform**, routed through the existing `dispatchByPlatform` fork mechanism — there are no dedicated `tv-describe`/`tv-navigate`/`tv-type`/`tv-set-focus` tools: - **`describe`** — on a `runtimeKind: "tv"` target, returns the focus-driven view (focused + focusable elements) instead of a tap tree. On Android TV it auto-falls-back to the full `uiautomator` tree when the RN focus engine exposes nothing. - **`tv-remote`** — the cross-platform remote/D-pad tool from #366, now extended with `ios` (Apple TV HID daemon) and `android` (Android TV adb keyevents) branches alongside the existing `vega` branch. Single button, a `repeat`, or a whole path (`["up","right","select"]`) in one call. - **`keyboard`** — types into the focused field on a TV target (named keys are rejected there — they're navigation, which belongs to `tv-remote`). - **`button`** stays hardware-only (phones/tablets); it is not a TV tool. **Apple TV** runs two native daemons (in-sim AX service + host-side HID daemon), shipped via the `argent-private` submodule. **Android TV** reuses the same tool surface, adb-backed (`input keyevent`, `uiautomator dump`, `input text`). ## Remote vocabulary parity `tv-remote` exposes the full 16-button vocabulary (`up`/`down`/`left`/`right`/`select`/`back`/`home`/`menu`/`playPause`/`rewind`/`fastForward`/`next`/`previous`/`volumeUp`/`volumeDown`/`mute`): | | Apple TV | Android TV | Vega | |---|---|---|---| | D-pad / select / back / menu / home / playPause | ✅ | ✅ | ✅ | | media-transport + volume/mute | ❌ rejected | ✅ | ✅ | Media-transport/volume keys **genuinely work on Android TV** (real keycodes — verified live: `volumeUp` moved `STREAM_MUSIC`, `mute` toggled per `dumpsys audio`). On the **Apple TV simulator** they are **rejected with a clear error**: on-device testing confirmed the tvOS sim's HID stack silently drops Consumer-Control events, so returning success would be a lie. ## Key design points - **tvOS UDIDs are UUID-shaped and indistinguishable from iOS by shape.** Handled with `runtimeKind` detection (tvOS runtime string for Apple TV; `pm list features` leanback/television for Android TV — *not* `ro.build.characteristics`, which lies on TV emulators). - Converted launch-app / restart-app / screenshot / screenshot-diff / run-sequence from **eager** to **lazy** service resolution, so a tvOS target never spins up (and hangs on) the iOS-only simulator-server / native-devtools blueprints. - Native injection selects the platform-matched (TVOSSIMULATOR) dylib slice; daemons recycle across sim reboots and app relaunches so injection and focus survive. - SKILL.md footprint minimized per review: the two TV skills were collapsed into a single lean **`argent-tv-interact`** (~40 lines). ## Verification - `npm run build`, ESLint, Prettier, and the full tool-server suite (**1565 tests**) all pass; CI green (incl. the Apple TV / Android TV / Vega e2e jobs). - Core flows verified live against real apps on both an Apple TV 4K simulator and a Google ATV emulator. ## Dependency / merge order Pins the `argent-private` submodule to the tip of its `feat/tv-support` branch (software-mansion/argent-private#20). **Merge that PR to `main` first, then bump the submodule pointer here to the merged SHA before merging this PR.** 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
0718e622ab |
chore(deps)(deps): bump the npm-minor-patch group across 2 directories with 9 updates (#422)
Bumps the npm-minor-patch group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [globals](https://github.com/sindresorhus/globals) | `17.6.0` | `17.7.0` | | [prettier](https://github.com/prettier/prettier) | `3.8.4` | `3.8.5` | | [semver](https://github.com/npm/node-semver) | `7.8.4` | `7.8.5` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.61.1` | `8.62.0` | | [@clack/prompts](https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts) | `1.5.1` | `1.6.0` | | [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.35.0` | `5.38.6` | | [smol-toml](https://github.com/squirrelchat/smol-toml) | `1.6.1` | `1.7.0` | | [electron](https://github.com/electron/electron) | `42.4.1` | `42.5.0` | | [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `5.9.2` | `5.9.3` | Bumps the npm-minor-patch group with 1 update in the /packages/telemetry directory: [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node). Updates `globals` from 17.6.0 to 17.7.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/sindresorhus/globals/releases">globals's releases</a>.</em></p> <blockquote> <h2>v17.7.0</h2> <ul> <li>Update globals (2026-06-22) (<a href="https://redirect.github.com/sindresorhus/globals/issues/345">#345</a>) 33b75f9</li> </ul> <hr /> <p><a href="https://github.com/sindresorhus/globals/compare/v17.6.0...v17.7.0">https://github.com/sindresorhus/globals/compare/v17.6.0...v17.7.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sindresorhus/globals/commit/a19670cc86c1218e915657c55ea02ba3e7623834"><code>a19670c</code></a> 17.7.0</li> <li><a href="https://github.com/sindresorhus/globals/commit/9611620bad0ea45531ae0261b986ce694374e42c"><code>9611620</code></a> Update actions (<a href="https://redirect.github.com/sindresorhus/globals/issues/346">#346</a>)</li> <li><a href="https://github.com/sindresorhus/globals/commit/33b75f9ddeb6f9ddd81251b043667eb8104a8d15"><code>33b75f9</code></a> Update globals (2026-06-22) (<a href="https://redirect.github.com/sindresorhus/globals/issues/345">#345</a>)</li> <li><a href="https://github.com/sindresorhus/globals/commit/887dd529bde24486b7f9e31d1b2c515df2b7cf5c"><code>887dd52</code></a> Fix build script (<a href="https://redirect.github.com/sindresorhus/globals/issues/344">#344</a>)</li> <li>See full diff in <a href="https://github.com/sindresorhus/globals/compare/v17.6.0...v17.7.0">compare view</a></li> </ul> </details> <br /> Updates `prettier` from 3.8.4 to 3.8.5 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/releases">prettier's releases</a>.</em></p> <blockquote> <h2>3.8.5</h2> <ul> <li>Fix Flow variance annotation print (<a href="https://redirect.github.com/prettier/prettier/pull/19022">#19022</a> by <a href="https://github.com/marcoww6"><code>@marcoww6</code></a>)</li> </ul> <p>🔗 <a href="https://github.com/prettier/prettier/blob/3.8.5/CHANGELOG.md#385">Changelog</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's changelog</a>.</em></p> <blockquote> <h1>3.8.5</h1> <p><a href="https://github.com/prettier/prettier/compare/3.8.4...3.8.5">diff</a></p> <h4>Flow: Support <code>readonly</code> as a variance annotation (<a href="https://redirect.github.com/prettier/prettier/pull/19022">#19022</a> by <a href="https://github.com/marcoww6"><code>@marcoww6</code></a>)</h4> <p>Flow now accepts <code>readonly</code> as a property variance annotation, equivalent to <code>+</code> (covariant/read-only).</p> <!-- raw HTML omitted --> <pre lang="jsx"><code>// Input type T = { readonly foo: string, }; <p>// Prettier 3.8.4<br /> SyntaxError</p> <p>// Prettier 3.8.5<br /> type T = {<br /> readonly foo: string,<br /> };<br /> </code></pre></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/prettier/prettier/commit/1ce8c47015ab1e9dfa99f6238df60ff1e70e1498"><code>1ce8c47</code></a> Release 3.8.5</li> <li><a href="https://github.com/prettier/prettier/commit/74923fa8316cd78f8461e77290915155efbcd714"><code>74923fa</code></a> Fix variance annotation</li> <li><a href="https://github.com/prettier/prettier/commit/8b4eb339d43edba35a509ff324d4cdb4416b3efc"><code>8b4eb33</code></a> Bump Prettier dependency to 3.8.4</li> <li><a href="https://github.com/prettier/prettier/commit/e9cbdfa1b755e68ea6f97b0b321524a5169a85d1"><code>e9cbdfa</code></a> Clean changelog_unreleased</li> <li>See full diff in <a href="https://github.com/prettier/prettier/compare/3.8.4...3.8.5">compare view</a></li> </ul> </details> <br /> Updates `semver` from 7.8.4 to 7.8.5 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/npm/node-semver/releases">semver's releases</a>.</em></p> <blockquote> <h2>v7.8.5</h2> <h2><a href="https://github.com/npm/node-semver/compare/v7.8.4...v7.8.5">7.8.5</a> (2026-06-19)</h2> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/node-semver/commit/9c8692ae05416e9dbe88d95ffe2b80e6964550fe"><code>9c8692a</code></a> <a href="https://redirect.github.com/npm/node-semver/pull/878">#878</a> include prereleases in tilde range lower bound with includePrerelease (<a href="https://redirect.github.com/npm/node-semver/issues/878">#878</a>) (<a href="https://github.com/chatman-media"><code>@chatman-media</code></a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/npm/node-semver/blob/main/CHANGELOG.md">semver's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/npm/node-semver/compare/v7.8.4...v7.8.5">7.8.5</a> (2026-06-19)</h2> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/node-semver/commit/9c8692ae05416e9dbe88d95ffe2b80e6964550fe"><code>9c8692a</code></a> <a href="https://redirect.github.com/npm/node-semver/pull/878">#878</a> include prereleases in tilde range lower bound with includePrerelease (<a href="https://redirect.github.com/npm/node-semver/issues/878">#878</a>) (<a href="https://github.com/chatman-media"><code>@chatman-media</code></a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/npm/node-semver/commit/6e05b7637396ac66522cff8731f07cfe0ef49a29"><code>6e05b76</code></a> chore: release 7.8.5 (<a href="https://redirect.github.com/npm/node-semver/issues/879">#879</a>)</li> <li><a href="https://github.com/npm/node-semver/commit/9c8692ae05416e9dbe88d95ffe2b80e6964550fe"><code>9c8692a</code></a> fix: include prereleases in tilde range lower bound with includePrerelease (#...</li> <li>See full diff in <a href="https://github.com/npm/node-semver/compare/v7.8.4...v7.8.5">compare view</a></li> </ul> </details> <br /> Updates `typescript-eslint` from 8.61.1 to 8.62.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/typescript-eslint/typescript-eslint/releases">typescript-eslint's releases</a>.</em></p> <blockquote> <h2>v8.62.0</h2> <h2>8.62.0 (2026-06-22)</h2> <h3>🚀 Features</h3> <ul> <li>remove redundant package.json "files" (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12444">#12444</a>)</li> </ul> <h3>🩹 Fixes</h3> <ul> <li>add "files" to rule-schema-to-typescript-types (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12441">#12441</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Kirk Waiblinger <a href="https://github.com/kirkwaiblinger"><code>@kirkwaiblinger</code></a></li> </ul> <p>See <a href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.62.0">GitHub Releases</a> for more information.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md">typescript-eslint's changelog</a>.</em></p> <blockquote> <h2>8.62.0 (2026-06-22)</h2> <h3>🚀 Features</h3> <ul> <li>remove redundant package.json "files" (<a href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12444">#12444</a>)</li> </ul> <h3>❤️ Thank You</h3> <ul> <li>Kirk Waiblinger <a href="https://github.com/kirkwaiblinger"><code>@kirkwaiblinger</code></a></li> </ul> <p>See <a href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.62.0">GitHub Releases</a> for more information.</p> <p>You can read about our <a href="https://typescript-eslint.io/users/versioning">versioning strategy</a> and <a href="https://typescript-eslint.io/users/releases">releases</a> on our website.</p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/54e285728e5d8cb83fadb8041189f0c3b4ab436a"><code>54e2857</code></a> chore(release): publish 8.62.0</li> <li><a href="https://github.com/typescript-eslint/typescript-eslint/commit/81e4c2654c3f4d923766a888691add2c45b5d64a"><code>81e4c26</code></a> feat: remove redundant package.json "files" (<a href="https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint/issues/12444">#12444</a>)</li> <li>See full diff in <a href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.0/packages/typescript-eslint">compare view</a></li> </ul> </details> <br /> Updates `@clack/prompts` from 1.5.1 to 1.6.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/bombshell-dev/clack/releases">@clack/prompts's releases</a>.</em></p> <blockquote> <h2><code>@clack/prompts</code><a href="https://github.com/1"><code>@1</code></a>.6.0</h2> <h3>Minor Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/bombshell-dev/clack/pull/568">#568</a> <a href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a> Thanks <a href="https://github.com/florian-lefebvre"><code>@florian-lefebvre</code></a>! - Updates default formatter of <code>note()</code> to note dim lines anymore</p> <p>If you want the old behavior, provide a <code>format()</code> function:</p> <pre lang="diff"><code>import { note } from '@clack/prompts'; +import { styleText } from 'node:util'; <p>note( 'You can edit the file src/index.jsx', 'Next steps.'</p> <ul> <li>{ format: (text) => styleText('dim', text) } ); </code></pre></li> </ul> </li> <li> <p><a href="https://redirect.github.com/bombshell-dev/clack/pull/567">#567</a> <a href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a> Thanks <a href="https://github.com/dreyfus92"><code>@dreyfus92</code></a>! - Add keyboard instruction footers to <code>select</code>, <code>multiselect</code>, and <code>groupMultiselect</code> in the active state, matching autocomplete. No option — always shown.</p> </li> </ul> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/bombshell-dev/clack/commit/2f2b52f77cbfa9af618c6d929249ab8395fc37a1"><code>2f2b52f</code></a>, <a href="https://github.com/bombshell-dev/clack/commit/e1b6ee71a76e17a3c33ba7ee6e5fb34e886233bb"><code>e1b6ee7</code></a>]: <ul> <li><code>@clack/core</code><a href="https://github.com/1"><code>@1</code></a>.4.2</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/bombshell-dev/clack/blob/main/packages/prompts/CHANGELOG.md">@clack/prompts's changelog</a>.</em></p> <blockquote> <h2>1.6.0</h2> <h3>Minor Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/bombshell-dev/clack/pull/568">#568</a> <a href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a> Thanks <a href="https://github.com/florian-lefebvre"><code>@florian-lefebvre</code></a>! - Updates default formatter of <code>note()</code> to note dim lines anymore</p> <p>If you want the old behavior, provide a <code>format()</code> function:</p> <pre lang="diff"><code>import { note } from '@clack/prompts'; +import { styleText } from 'node:util'; <p>note( 'You can edit the file src/index.jsx', 'Next steps.'</p> <ul> <li>{ format: (text) => styleText('dim', text) } ); </code></pre></li> </ul> </li> <li> <p><a href="https://redirect.github.com/bombshell-dev/clack/pull/567">#567</a> <a href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a> Thanks <a href="https://github.com/dreyfus92"><code>@dreyfus92</code></a>! - Add keyboard instruction footers to <code>select</code>, <code>multiselect</code>, and <code>groupMultiselect</code> in the active state, matching autocomplete. No option — always shown.</p> </li> </ul> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/bombshell-dev/clack/commit/2f2b52f77cbfa9af618c6d929249ab8395fc37a1"><code>2f2b52f</code></a>, <a href="https://github.com/bombshell-dev/clack/commit/e1b6ee71a76e17a3c33ba7ee6e5fb34e886233bb"><code>e1b6ee7</code></a>]: <ul> <li><code>@clack/core</code><a href="https://github.com/1"><code>@1</code></a>.4.2</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/bombshell-dev/clack/commit/0e700562dfb54bd693d98c5b7e28d34213fcb226"><code>0e70056</code></a> [ci] release (<a href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/562">#562</a>)</li> <li><a href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a> fix(prompts): do not dim note contents (<a href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/568">#568</a>)</li> <li><a href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a> feat(prompts): add instructions footer for <code>select</code>, <code>multi-select</code> & `group-...</li> <li>See full diff in <a href="https://github.com/bombshell-dev/clack/commits/@clack/prompts@1.6.0/packages/prompts">compare view</a></li> </ul> </details> <br /> Updates `posthog-node` from 5.35.0 to 5.38.6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/releases">posthog-node's releases</a>.</em></p> <blockquote> <h2>posthog-node@5.38.6</h2> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>posthog-node@5.38.5</h2> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.4</h2> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>posthog-node@5.38.3</h2> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>posthog-node@5.38.2</h2> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.1</h2> <h2>5.38.1</h2> <h3>Patch Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md">posthog-node's changelog</a>.</em></p> <blockquote> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>5.38.1</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3886">#3886</a> <a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Stop sending deprecated no-op top-level <code>type</code>, <code>library</code>, and <code>library_version</code> fields in event batch payloads. Use <code>properties.$lib</code> and <code>properties.$lib_version</code> for SDK metadata; legacy queued <code>library</code> and <code>library_version</code> values are used as fallbacks when the official <code>$</code> properties are missing. (2026-06-18)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.2</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/PostHog/posthog-js/commit/d2faa824af1af2cb50b47178fb953bfc8812b389"><code>d2faa82</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> fix: preserve $groups passed via properties (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3896">#3896</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/5c4838f1671ece80d153aaeb6d946bb3e8c8240a"><code>5c4838f</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> fix: Dedupe feature flag called events by response (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3955">#3955</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2a60c21134dd118c2367e56129bc9427079c3841"><code>2a60c21</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> fix(node): respect URL hash capture config (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3938">#3938</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/a3136c6de3114ee3d58e59a0c86f2b9c4f59a2b0"><code>a3136c6</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/bf6947d3e12ac512c99185be9b8b134c04eb563a"><code>bf6947d</code></a> feat(react-native): support session replay event triggers (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3932">#3932</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2628a1af5f06f73cb2252de002e0da4b2d1a25a5"><code>2628a1a</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> chore(node): mark Sentry integration deprecated (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3937">#3937</a>)</li> <li>Additional commits viewable in <a href="https://github.com/PostHog/posthog-js/commits/posthog-node@5.38.6/packages/node">compare view</a></li> </ul> </details> <br /> Updates `smol-toml` from 1.6.1 to 1.7.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/squirrelchat/smol-toml/releases">smol-toml's releases</a>.</em></p> <blockquote> <h2>v1.7.0</h2> <p>This version slightly changes the behaviour of stringify: integers beyond the safe range are always emitted as float numbers.</p> <p>String decode logic has been rewritten, it is a bit faster now and uses a single-pass approach instead of a dual-pass approach as it did previously. The code should be a bit smaller too, though I didn't actually measure that.</p> <p>The package is now published with source-maps, declaration-maps, and a copy of the original TypeScript source files. This will improve your DX if you're like me and like Ctrl+Click'ing things a lot. ;)</p> <h2>What's Changed</h2> <ul> <li>improve performance of the string decode logic by <a href="https://github.com/cyyynthia"><code>@cyyynthia</code></a></li> <li>fix(stringify): emit integer-valued numbers beyond the safe-integer range as floats by <a href="https://github.com/spokodev"><code>@spokodev</code></a> in <a href="https://redirect.github.com/squirrelchat/smol-toml/pull/56">squirrelchat/smol-toml#56</a></li> <li>publish source-maps, declaration-maps, and original source files by <a href="https://github.com/cyyynthia"><code>@cyyynthia</code></a></li> <li>miscellaneous repository maintenance tasks by <a href="https://github.com/cyyynthia"><code>@cyyynthia</code></a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/spokodev"><code>@spokodev</code></a> made their first contribution in <a href="https://redirect.github.com/squirrelchat/smol-toml/pull/56">squirrelchat/smol-toml#56</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/squirrelchat/smol-toml/compare/v1.6.1...v1.7.0">https://github.com/squirrelchat/smol-toml/compare/v1.6.1...v1.7.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/squirrelchat/smol-toml/commit/a62f06faf4e45ab0a581def86c116f9706edc9df"><code>a62f06f</code></a> revert: keep using vite 7</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/89aa9a394ffc544dce77ab0ff24dfd8204e1f091"><code>89aa9a3</code></a> chore: remove prepare script</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/17c797475f1516da6614e31a1be9f4958bf296c0"><code>17c7974</code></a> chore: make devEngine more lax w/ node version</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/e5280a34630eb25086dca746bedda28ea21ec3d9"><code>e5280a3</code></a> ci: checkout repo first</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/241c256ebda07b2d225c91b7468ed8c90d0e71df"><code>241c256</code></a> chore: version bump</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/0bfe7f4667fa46122663b7b6114d9514dbd1a91f"><code>0bfe7f4</code></a> chore: build cjs with rolldown instead of esbuild</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/e0620ab2ac89c40d291f33df41b110277b1acedf"><code>e0620ab</code></a> chore: fmt</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/96114cb58312084286ae61470ba0f017b87b8023"><code>96114cb</code></a> test: add tests for large integers</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/f4537b6b3763e761069efdd7d688711c8409645c"><code>f4537b6</code></a> fix: handle missed edge-cases in string parse</li> <li><a href="https://github.com/squirrelchat/smol-toml/commit/7b39aed388cdc811189a6a3683fbee2f8d344244"><code>7b39aed</code></a> chore: include source files in published package</li> <li>Additional commits viewable in <a href="https://github.com/squirrelchat/smol-toml/compare/v1.6.1...v1.7.0">compare view</a></li> </ul> </details> <br /> Updates `electron` from 42.4.1 to 42.5.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/electron/electron/releases">electron's releases</a>.</em></p> <blockquote> <h2>electron v42.5.0</h2> <h1>Release Notes for v42.5.0</h1> <h2>Fixes</h2> <ul> <li>Fixed Windows edge case in <code>NativeWindowViews::MoveBehindTaskBarIfNeeded()</code>. <a href="https://redirect.github.com/electron/electron/pull/52022">#52022</a> <!-- raw HTML omitted -->(Also in <a href="https://redirect.github.com/electron/electron/pull/52023">41</a>, <a href="https://redirect.github.com/electron/electron/pull/52021">43</a>)<!-- raw HTML omitted --></li> <li>Fixed an issue where clicking the maximize button could progressively shrink the window in some Wayland environments. <a href="https://redirect.github.com/electron/electron/pull/52045">#52045</a> <!-- raw HTML omitted -->(Also in <a href="https://redirect.github.com/electron/electron/pull/52039">43</a>)<!-- raw HTML omitted --></li> </ul> <h2>Other Changes</h2> <ul> <li>Backported fixes from upstream Chromium. <a href="https://redirect.github.com/electron/electron/pull/51975">#51975</a></li> <li>Updated Chromium to 148.0.7778.271. <a href="https://redirect.github.com/electron/electron/pull/52038">#52038</a></li> <li>Updated Node.js to v24.17.0. <a href="https://redirect.github.com/electron/electron/pull/52066">#52066</a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/electron/electron/commit/d7bccf5b2f27969b4e7f34cf877f55cf0813be7a"><code>d7bccf5</code></a> fix: UAF in api::UtilityProcessWrapper (<a href="https://redirect.github.com/electron/electron/issues/52094">#52094</a>)</li> <li><a href="https://github.com/electron/electron/commit/fb151dcdf1ef7685cb5254b571d9ec50a480c1ae"><code>fb151dc</code></a> chore: bump chromium to 148.0.7778.271 (42-x-y) (<a href="https://redirect.github.com/electron/electron/issues/52038">#52038</a>)</li> <li><a href="https://github.com/electron/electron/commit/526fa0df025b50aea9a8011efa52753db8e7839a"><code>526fa0d</code></a> chore: bump node to v24.17.0 (42-x-y) (<a href="https://redirect.github.com/electron/electron/issues/52066">#52066</a>)</li> <li><a href="https://github.com/electron/electron/commit/22b84b5c304c512005c55569f6344d3e0db12fad"><code>22b84b5</code></a> fix: frameless window shrinks on maximize() when compositor declines (<a href="https://redirect.github.com/electron/electron/issues/52045">#52045</a>)</li> <li><a href="https://github.com/electron/electron/commit/15e8d1cf5db75ed5db00d2f4889deca1ee2c1004"><code>15e8d1c</code></a> docs: fix heap dump screenshot in contentTracing (<a href="https://redirect.github.com/electron/electron/issues/52031">#52031</a>)</li> <li><a href="https://github.com/electron/electron/commit/8902c75dca77c80793fe69971d53b7226d921bf9"><code>8902c75</code></a> build: bump <code>@electron/docs-parser</code> to 3.0.1 (<a href="https://redirect.github.com/electron/electron/issues/52052">#52052</a>)</li> <li><a href="https://github.com/electron/electron/commit/30bf7db164d941ee167cbc2f42f7629b1a6fe452"><code>30bf7db</code></a> test: use node16 moduleResolution in tsconfig and clean up imports (<a href="https://redirect.github.com/electron/electron/issues/52040">#52040</a>)</li> <li><a href="https://github.com/electron/electron/commit/d251baeeb3b0c92a66eaca6ab76542b4bb02e46a"><code>d251bae</code></a> ci: bump linux 64k kernel version (<a href="https://redirect.github.com/electron/electron/issues/52037">#52037</a>)</li> <li><a href="https://github.com/electron/electron/commit/ad73d520595a149149ef60bfbee16fd520b68ee7"><code>ad73d52</code></a> fix: win: check for valid taskbar handle (<a href="https://redirect.github.com/electron/electron/issues/52022">#52022</a>)</li> <li><a href="https://github.com/electron/electron/commit/6abd0348c9ec3fdd8eef4ca4029fbd8747000815"><code>6abd034</code></a> ci: replace dorny/paths-filter usage (reland) (<a href="https://redirect.github.com/electron/electron/issues/52033">#52033</a>)</li> <li>Additional commits viewable in <a href="https://github.com/electron/electron/compare/v42.4.1...v42.5.0">compare view</a></li> </ul> </details> <br /> Updates `fast-xml-parser` from 5.9.2 to 5.9.3 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/NaturalIntelligence/fast-xml-parser/releases">fast-xml-parser's releases</a>.</em></p> <blockquote> <h2>v5.9.3</h2> <h2>What's Changed</h2> <ul> <li>Harden GitHub Actions workflows by <a href="https://github.com/martincostello"><code>@martincostello</code></a> in <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/pull/841">NaturalIntelligence/fast-xml-parser#841</a></li> <li>GitHub Actions workflow fixes by <a href="https://github.com/martincostello"><code>@martincostello</code></a> in <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/pull/844">NaturalIntelligence/fast-xml-parser#844</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/martincostello"><code>@martincostello</code></a> made their first contribution in <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/pull/841">NaturalIntelligence/fast-xml-parser#841</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.9.2...v5.9.3">https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.9.2...v5.9.3</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md">fast-xml-parser's changelog</a>.</em></p> <blockquote> <p><!-- raw HTML omitted -->Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.<!-- raw HTML omitted --></p> <p>Note: Due to some last quick changes on v4, detail of v4.5.3 & v4.5.4 are not updated here. v4.5.4x is the last tag of v4 in github repository. I'm extremely sorry for the confusion</p> <p>*<em>5.9.3 / 2026-06-19</em></p> <ul> <li>update strnum</li> </ul> <p>*<em>5.9.2 / 2026-06-17</em></p> <ul> <li>dummy release to test changes in github action</li> </ul> <p>*<em>5.9.1 / 2026-06-17</em></p> <ul> <li>dummy release to test release from github action</li> </ul> <p>*<em>5.9.0 / 2026-06-15</em></p> <ul> <li>update strnum to 2.3.0 <ul> <li>you can set hex, binary, enotation, infinity, unicode</li> </ul> </li> <li>validate unsafe HTML or XML data in doctype entities unsing 'is-unsafe' library. User can override rules by overriding EntityDecoder.</li> </ul> <p>*<em>5.8.0 / 2026-05-12</em></p> <ul> <li>integrate xml-naming to validate DOCTYPE entity name and notation name (using qname becaue of backward compatibility) <ul> <li>This will consider xml-version as well. '1.0' is default</li> </ul> </li> <li>update strnum to 2.3.0 <ul> <li>You can set octal and binary parsing which is bydeault off</li> </ul> </li> <li>update fast-xml-builder to 1.2.0 <ul> <li>can sanitize tag names if found invalid</li> <li>fix format output</li> </ul> </li> </ul> <p><strong>5.7.3 / 2006-05-05</strong></p> <ul> <li>fix: alwaysCreateTextNode should create text node when attributes are present for self closing node</li> <li>fix stop node expression when ns prefix is removed (found by <a href="https://github.com/iruizsalinas">iruizsalinas</a>)</li> <li>update XML Builder to 1.1.7</li> <li>mark addEntity deprecated</li> </ul> <p><strong>5.7.2 / 2026-04-25</strong></p> <ul> <li>allow numerical external entity for backward compatibility</li> <li>fix <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/705">#705</a>: attributesGroupName working with preserveOrder</li> <li>fix <a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/817">#817</a>: stackoverflow when tag expression is very long</li> </ul> <p><strong>5.7.1 / 2026-04-20</strong></p> <ul> <li>fix typo in CJS typing file</li> </ul> <p><strong>5.7.0 / 2026-04-17</strong></p> <ul> <li>Use <code>@nodable/entities</code> v2.1.0 <ul> <li>breaking changes <ul> <li>single entity scan. You're not allowed to user entity value to form another entity name.</li> <li>you cant add numeric external entity</li> <li>entity error message when expantion limit is crossed might change</li> </ul> </li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/93a09f108d6f457a84e607a6806a7bfd6abc3e55"><code>93a09f1</code></a> 5.9.3</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/9c1905edd7ea28db70770f758e293fcf079060c5"><code>9c1905e</code></a> update strnum</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/8d71292a9aaaa8f4a24294e636bd191cfbf4d8a7"><code>8d71292</code></a> GitHub Actions workflow fixes (<a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/844">#844</a>)</li> <li><a href="https://github.com/NaturalIntelligence/fast-xml-parser/commit/784a0442b697e1498e1f3c3fc1a057ad57424858"><code>784a044</code></a> Harden GitHub Actions workflows (<a href="https://redirect.github.com/NaturalIntelligence/fast-xml-parser/issues/841">#841</a>)</li> <li>See full diff in <a href="https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.9.2...v5.9.3">compare view</a></li> </ul> </details> <br /> Updates `posthog-node` from 5.35.0 to 5.38.6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/releases">posthog-node's releases</a>.</em></p> <blockquote> <h2>posthog-node@5.38.6</h2> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>posthog-node@5.38.5</h2> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.4</h2> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>posthog-node@5.38.3</h2> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>posthog-node@5.38.2</h2> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.1</h2> <h2>5.38.1</h2> <h3>Patch Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md">posthog-node's changelog</a>.</em></p> <blockquote> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>5.38.1</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3886">#3886</a> <a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Stop sending deprecated no-op top-level <code>type</code>, <code>library</code>, and <code>library_version</code> fields in event batch payloads. Use <code>properties.$lib</code> and <code>properties.$lib_version</code> for SDK metadata; legacy queued <code>library</code> and <code>library_version</code> values are used as fallbacks when the official <code>$</code> properties are missing. (2026-06-18)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.2</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/PostHog/posthog-js/commit/d2faa824af1af2cb50b47178fb953bfc8812b389"><code>d2faa82</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> fix: preserve $groups passed via properties (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3896">#3896</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/5c4838f1671ece80d153aaeb6d946bb3e8c8240a"><code>5c4838f</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> fix: Dedupe feature flag called events by response (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3955">#3955</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2a60c21134dd118c2367e56129bc9427079c3841"><code>2a60c21</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> fix(node): respect URL hash capture config (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3938">#3938</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/a3136c6de3114ee3d58e59a0c86f2b9c4f59a2b0"><code>a3136c6</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/bf6947d3e12ac512c99185be9b8b134c04eb563a"><code>bf6947d</code></a> feat(react-native): support session replay event triggers (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3932">#3932</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2628a1af5f06f73cb2252de002e0da4b2d1a25a5"><code>2628a1a</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> chore(node): mark Sentry integration deprecated (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3937">#3937</a>)</li> <li>Additional commits viewable in <a href="https://github.com/PostHog/posthog-js/commits/posthog-node@5.38.6/packages/node">compare view</a></li> </ul> </details> <br /> Updates `posthog-node` from 5.35.0 to 5.38.6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/releases">posthog-node's releases</a>.</em></p> <blockquote> <h2>posthog-node@5.38.6</h2> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>posthog-node@5.38.5</h2> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.4</h2> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>posthog-node@5.38.3</h2> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>posthog-node@5.38.2</h2> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.1</h2> <h2>5.38.1</h2> <h3>Patch Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md">posthog-node's changelog</a>.</em></p> <blockquote> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>5.38.1</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3886">#3886</a> <a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Stop sending deprecated no-op top-level <code>type</code>, <code>library</code>, and <code>library_version</code> fields in event batch payloads. Use <code>properties.$lib</code> and <code>properties.$lib_version</code> for SDK metadata; legacy queued <code>library</code> and <code>library_version</code> values are used as fallbacks when the official <code>$</code> properties are missing. (2026-06-18)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.2</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/PostHog/posthog-js/commit/d2faa824af1af2cb50b47178fb953bfc8812b389"><code>d2faa82</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> fix: preserve $groups passed via properties (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3896">#3896</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/5c4838f1671ece80d153aaeb6d946bb3e8c8240a"><code>5c4838f</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> fix: Dedupe feature flag called events by response (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3955">#3955</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2a60c21134dd118c2367e56129bc9427079c3841"><code>2a60c21</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> fix(node): respect URL hash capture config (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3938">#3938</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/a3136c6de3114ee3d58e59a0c86f2b9c4f59a2b0"><code>a3136c6</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/bf6947d3e12ac512c99185be9b8b134c04eb563a"><code>bf6947d</code></a> feat(react-native): support session replay event triggers (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3932">#3932</a>)</li> <li><a href="https://github.com/PostHog/posthog-js/commit/2628a1af5f06f73cb2252de002e0da4b2d1a25a5"><code>2628a1a</code></a> chore: update versions and lockfile [version bump]</li> <li><a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> chore(node): mark Sentry integration deprecated (<a href="https://github.com/PostHog/posthog-js/tree/HEAD/packages/node/issues/3937">#3937</a>)</li> <li>Additional commits viewable in <a href="https://github.com/PostHog/posthog-js/commits/posthog-node@5.38.6/packages/node">compare view</a></li> </ul> </details> <br /> Updates `posthog-node` from 5.35.0 to 5.38.6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/releases">posthog-node's releases</a>.</em></p> <blockquote> <h2>posthog-node@5.38.6</h2> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>posthog-node@5.38.5</h2> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.4</h2> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>posthog-node@5.38.3</h2> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>posthog-node@5.38.2</h2> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>posthog-node@5.38.1</h2> <h2>5.38.1</h2> <h3>Patch Changes</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md">posthog-node's changelog</a>.</em></p> <blockquote> <h2>5.38.6</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3896">#3896</a> <a href="https://github.com/PostHog/posthog-js/commit/606ef43d69fd09a00a67df2a404d8739cc50c654"><code>606ef43</code></a> Thanks <a href="https://github.com/GauthierPLM"><code>@GauthierPLM</code></a>! - Only stamp $groups from the top-level <code>groups</code> when present (2026-06-26)</li> </ul> <h2>5.38.5</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3955">#3955</a> <a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Dedupe feature flag called events per returned flag value. (2026-06-24)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/8e9689a9018d184b80f32fc4874686d7243970e2"><code>8e9689a</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.3</li> </ul> </li> </ul> <h2>5.38.4</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3938">#3938</a> <a href="https://github.com/PostHog/posthog-js/commit/6391106fd4bcbddb9a63a13338929a4c1918a70a"><code>6391106</code></a> Thanks <a href="https://github.com/dustinbyrne"><code>@dustinbyrne</code></a>! - Respect <code>disable_capture_url_hashes</code> when capturing Express and NestJS request URLs. (2026-06-23)</li> </ul> <h2>5.38.3</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3937">#3937</a> <a href="https://github.com/PostHog/posthog-js/commit/4d59d0e10f92ad3444e14dc171997c21aba57929"><code>4d59d0e</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Deprecate the Node SDK Sentry integration and point users to PostHog Error Tracking for Node. (2026-06-23)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/440e370fda48d629352f3280471a228ee973dcb0"><code>440e370</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.37.0</li> </ul> </li> </ul> <h2>5.38.2</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3903">#3903</a> <a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19)</li> <li>Updated dependencies [<a href="https://github.com/PostHog/posthog-js/commit/6b21f77291aeea64ce8229eb28196d1acacc20ce"><code>6b21f77</code></a>]: <ul> <li><code>@posthog/core</code><a href="https://github.com/1"><code>@1</code></a>.35.3</li> </ul> </li> </ul> <h2>5.38.1</h2> <h3>Patch Changes</h3> <ul> <li><a href="https://redirect.github.com/PostHog/posthog-js/pull/3886">#3886</a> <a href="https://github.com/PostHog/posthog-js/commit/e6d7fe2a5f10d29b3df69392f584970e7a7a4561"><code>e6d7fe2</code></a> Thanks <a href="https://github.com/marandaneto"><code>@marandaneto</code></a>! - Stop sending deprecated no-op top-level <code>type<... _Description has been truncated_ Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
02695e6704 |
chore(deps)(deps): bump the npm-major group across 1 directory with 3 updates (#413)
Bumps the npm-major group with 3 updates in the / directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [dotenv](https://github.com/motdotla/dotenv) and [ini](https://github.com/npm/ini). Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `dotenv` from 16.6.1 to 17.4.2 <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md">dotenv's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.4.1...v17.4.2">17.4.2</a> (2026-04-12)</h2> <h3>Changed</h3> <ul> <li>Improved skill files - tightened up details (<a href="https://redirect.github.com/motdotla/dotenv/pull/1009">#1009</a>)</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.4.0...v17.4.1">17.4.1</a> (2026-04-05)</h2> <h3>Changed</h3> <ul> <li>Change text <code>injecting</code> to <code>injected</code> (<a href="https://redirect.github.com/motdotla/dotenv/pull/1005">#1005</a>)</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.3.1...v17.4.0">17.4.0</a> (2026-04-01)</h2> <h3>Added</h3> <ul> <li>Add <code>skills/</code> folder with focused agent skills: <code>skills/dotenv/SKILL.md</code> (core usage) and <code>skills/dotenvx/SKILL.md</code> (encryption, multiple environments, variable expansion) for AI coding agent discovery via the skills.sh ecosystem (<code>npx skills add motdotla/dotenv</code>)</li> </ul> <h3>Changed</h3> <ul> <li>Tighten up logs: <code>◇ injecting env (14) from .env</code> (<a href="https://redirect.github.com/motdotla/dotenv/pull/1003">#1003</a>)</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.3.0...v17.3.1">17.3.1</a> (2026-02-12)</h2> <h3>Changed</h3> <ul> <li>Fix as2 example command in README and update spanish README</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.2.4...v17.3.0">17.3.0</a> (2026-02-12)</h2> <h3>Added</h3> <ul> <li>Add a new README section on dotenv’s approach to the agentic future.</li> </ul> <h3>Changed</h3> <ul> <li>Rewrite README to get humans started more quickly with less noise while simultaneously making more accessible for llms and agents to go deeper into details.</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.2.3...v17.2.4">17.2.4</a> (2026-02-05)</h2> <h3>Changed</h3> <ul> <li>Make <code>DotenvPopulateInput</code> accept <code>NodeJS.ProcessEnv</code> type (<a href="https://redirect.github.com/motdotla/dotenv/pull/915">#915</a>)</li> </ul> <ul> <li>Give back to dotenv by checking out my newest project <a href="https://github.com/vestauth/vestauth">vestauth</a>. It is auth for agents. Thank you for using my software.</li> </ul> <h2><a href="https://github.com/motdotla/dotenv/compare/v17.2.2...v17.2.3">17.2.3</a> (2025-09-29)</h2> <h3>Changed</h3> <ul> <li>Fixed typescript error definition (<a href="https://redirect.github.com/motdotla/dotenv/pull/912">#912</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/motdotla/dotenv/commit/f116f70310abab44fbfddbaeb833698b5bf84a9b"><code>f116f70</code></a> 17.4.2</li> <li><a href="https://github.com/motdotla/dotenv/commit/3a8161274fdd745239b86e604f4a7e972a1d3902"><code>3a81612</code></a> fix visual order of faq</li> <li><a href="https://github.com/motdotla/dotenv/commit/13f55a89e136b2024e68d277b836dd5260fc16cf"><code>13f55a8</code></a> Merge branch 'skill'</li> <li><a href="https://github.com/motdotla/dotenv/commit/4bbbf73f0906bd69975c48bf310a84b686e5b1b4"><code>4bbbf73</code></a> reorganize faq</li> <li><a href="https://github.com/motdotla/dotenv/commit/c3da64bb2ba1d0e02f8b9b2b7ccb7e6f7a51d56c"><code>c3da64b</code></a> Merge pull request <a href="https://redirect.github.com/motdotla/dotenv/issues/1009">#1009</a> from motdotla/skill</li> <li><a href="https://github.com/motdotla/dotenv/commit/6f743b173fbd6c26f7eab7040d251f9a6c8b977d"><code>6f743b1</code></a> update source</li> <li><a href="https://github.com/motdotla/dotenv/commit/fc2c6247e858a32d4024cb06a5b0c79aa35851f5"><code>fc2c624</code></a> update skill</li> <li><a href="https://github.com/motdotla/dotenv/commit/972315ba74bb2bbba4483d112e853fd26006ef8a"><code>972315b</code></a> Tighten up skill</li> <li><a href="https://github.com/motdotla/dotenv/commit/2795fce3d1ed07b4c570f1e06ab1c0d533c86997"><code>2795fce</code></a> reorganize faq</li> <li><a href="https://github.com/motdotla/dotenv/commit/d5495d4ae8e4e41ef9a682c9e00c81552794274e"><code>d5495d4</code></a> adjust skill</li> <li>Additional commits viewable in <a href="https://github.com/motdotla/dotenv/compare/v16.6.1...v17.4.2">compare view</a></li> </ul> </details> <br /> Updates `ini` from 4.1.3 to 7.0.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/npm/ini/releases">ini's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2><a href="https://github.com/npm/ini/compare/v6.0.0...v7.0.0">7.0.0</a> (2026-05-08)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^22.22.2 || ^24.15.0 || >=26.0.0</code></li> <li>template-oss-apply</li> </ul> <h3>Features</h3> <ul> <li><a href="https://github.com/npm/ini/commit/55b6841261aad580ce979c1ada97885a0617b965"><code>55b6841</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> bump to new node engine range (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/2b11ba8283afa33211844be6fa29794970ccf7b7"><code>2b11ba8</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> template-oss-apply (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/f6ed5bee3d7b1c175b687c703213217b23df9199"><code>f6ed5be</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> template-oss-apply (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/a2c835ec4690c5e67651a403d0f952aaff018f42"><code>a2c835e</code></a> <a href="https://redirect.github.com/npm/ini/pull/293">#293</a> bump <code>@npmcli/eslint-config</code> from 5.1.0 to 6.0.0 (<a href="https://redirect.github.com/npm/ini/issues/293">#293</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> <li><a href="https://github.com/npm/ini/commit/3661dce193f03675ec6ddc0938e2483d0ab41f38"><code>3661dce</code></a> <a href="https://redirect.github.com/npm/ini/pull/296">#296</a> bump <code>@npmcli/template-oss</code> from 4.28.0 to 4.28.1 (<a href="https://redirect.github.com/npm/ini/issues/296">#296</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/npm-cli-bot"><code>@npm-cli-bot</code></a>)</li> </ul> <h2>v6.0.0</h2> <h2><a href="https://github.com/npm/ini/compare/v5.0.0...v6.0.0">6.0.0</a> (2025-10-22)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^20.17.0 || >=22.9.0</code></li> </ul> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/ini/commit/6d395a4aaf7d7a5e32e250809cb7bd04c6a27b66"><code>6d395a4</code></a> <a href="https://redirect.github.com/npm/ini/pull/291">#291</a> align to npm 11 node engine range (<a href="https://redirect.github.com/npm/ini/issues/291">#291</a>) (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/23a36a9ca194d97486ed367f63d13a2cde1d1ce5"><code>23a36a9</code></a> <a href="https://redirect.github.com/npm/ini/pull/290">#290</a> bump <code>@npmcli/template-oss</code> from 4.26.0 to 4.27.1 (<a href="https://redirect.github.com/npm/ini/issues/290">#290</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/npm-cli-bot"><code>@npm-cli-bot</code></a>)</li> </ul> <h2>v5.0.0</h2> <h2><a href="https://github.com/npm/ini/compare/v4.1.3...v5.0.0">5.0.0</a> (2024-09-03)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^18.17.0 || >=20.5.0</code></li> </ul> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/ini/commit/3eca645de8586b8349acd79211b01a9199d8fd32"><code>3eca645</code></a> <a href="https://redirect.github.com/npm/ini/pull/279">#279</a> align to npm 10 node engine range (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/c89e2090d7989bb91255ec46eaaf5f8cb1c34b34"><code>c89e209</code></a> <a href="https://redirect.github.com/npm/ini/pull/279">#279</a> run template-oss-apply (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/fc447500efe6523746fd9db9d3123485eed14b76"><code>fc44750</code></a> <a href="https://redirect.github.com/npm/ini/pull/276">#276</a> bump <code>@npmcli/eslint-config</code> from 4.0.5 to 5.0.0 (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> <li><a href="https://github.com/npm/ini/commit/21c20bb1729005ab46e0f248cea1a881c6ab5b49"><code>21c20bb</code></a> <a href="https://redirect.github.com/npm/ini/pull/277">#277</a> postinstall for dependabot template-oss PR (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/44b3b503fdd923fb230b6a4d859014b9364ee466"><code>44b3b50</code></a> <a href="https://redirect.github.com/npm/ini/pull/277">#277</a> bump <code>@npmcli/template-oss</code> from 4.23.1 to 4.23.3 (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/npm/ini/blob/main/CHANGELOG.md">ini's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/npm/ini/compare/v6.0.0...v7.0.0">7.0.0</a> (2026-05-08)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^22.22.2 || ^24.15.0 || >=26.0.0</code></li> <li>template-oss-apply</li> </ul> <h3>Features</h3> <ul> <li><a href="https://github.com/npm/ini/commit/55b6841261aad580ce979c1ada97885a0617b965"><code>55b6841</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> bump to new node engine range (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/2b11ba8283afa33211844be6fa29794970ccf7b7"><code>2b11ba8</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> template-oss-apply (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/f6ed5bee3d7b1c175b687c703213217b23df9199"><code>f6ed5be</code></a> <a href="https://redirect.github.com/npm/ini/pull/301">#301</a> template-oss-apply (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/a2c835ec4690c5e67651a403d0f952aaff018f42"><code>a2c835e</code></a> <a href="https://redirect.github.com/npm/ini/pull/293">#293</a> bump <code>@npmcli/eslint-config</code> from 5.1.0 to 6.0.0 (<a href="https://redirect.github.com/npm/ini/issues/293">#293</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> <li><a href="https://github.com/npm/ini/commit/3661dce193f03675ec6ddc0938e2483d0ab41f38"><code>3661dce</code></a> <a href="https://redirect.github.com/npm/ini/pull/296">#296</a> bump <code>@npmcli/template-oss</code> from 4.28.0 to 4.28.1 (<a href="https://redirect.github.com/npm/ini/issues/296">#296</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/npm-cli-bot"><code>@npm-cli-bot</code></a>)</li> </ul> <h2><a href="https://github.com/npm/ini/compare/v5.0.0...v6.0.0">6.0.0</a> (2025-10-22)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^20.17.0 || >=22.9.0</code></li> </ul> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/ini/commit/6d395a4aaf7d7a5e32e250809cb7bd04c6a27b66"><code>6d395a4</code></a> <a href="https://redirect.github.com/npm/ini/pull/291">#291</a> align to npm 11 node engine range (<a href="https://redirect.github.com/npm/ini/issues/291">#291</a>) (<a href="https://github.com/owlstronaut"><code>@owlstronaut</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/23a36a9ca194d97486ed367f63d13a2cde1d1ce5"><code>23a36a9</code></a> <a href="https://redirect.github.com/npm/ini/pull/290">#290</a> bump <code>@npmcli/template-oss</code> from 4.26.0 to 4.27.1 (<a href="https://redirect.github.com/npm/ini/issues/290">#290</a>) (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/npm-cli-bot"><code>@npm-cli-bot</code></a>)</li> </ul> <h2><a href="https://github.com/npm/ini/compare/v4.1.3...v5.0.0">5.0.0</a> (2024-09-03)</h2> <h3>⚠️ BREAKING CHANGES</h3> <ul> <li><code>ini</code> now supports node <code>^18.17.0 || >=20.5.0</code></li> </ul> <h3>Bug Fixes</h3> <ul> <li><a href="https://github.com/npm/ini/commit/3eca645de8586b8349acd79211b01a9199d8fd32"><code>3eca645</code></a> <a href="https://redirect.github.com/npm/ini/pull/279">#279</a> align to npm 10 node engine range (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> </ul> <h3>Chores</h3> <ul> <li><a href="https://github.com/npm/ini/commit/c89e2090d7989bb91255ec46eaaf5f8cb1c34b34"><code>c89e209</code></a> <a href="https://redirect.github.com/npm/ini/pull/279">#279</a> run template-oss-apply (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/fc447500efe6523746fd9db9d3123485eed14b76"><code>fc44750</code></a> <a href="https://redirect.github.com/npm/ini/pull/276">#276</a> bump <code>@npmcli/eslint-config</code> from 4.0.5 to 5.0.0 (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> <li><a href="https://github.com/npm/ini/commit/21c20bb1729005ab46e0f248cea1a881c6ab5b49"><code>21c20bb</code></a> <a href="https://redirect.github.com/npm/ini/pull/277">#277</a> postinstall for dependabot template-oss PR (<a href="https://github.com/hashtagchris"><code>@hashtagchris</code></a>)</li> <li><a href="https://github.com/npm/ini/commit/44b3b503fdd923fb230b6a4d859014b9364ee466"><code>44b3b50</code></a> <a href="https://redirect.github.com/npm/ini/pull/277">#277</a> bump <code>@npmcli/template-oss</code> from 4.23.1 to 4.23.3 (<a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/npm/ini/commit/847941ced4fb8465f0ccb383fd8b15c7e5aa09fc"><code>847941c</code></a> chore: release 7.0.0 (<a href="https://redirect.github.com/npm/ini/issues/302">#302</a>)</li> <li><a href="https://github.com/npm/ini/commit/f6ed5bee3d7b1c175b687c703213217b23df9199"><code>f6ed5be</code></a> chore: template-oss-apply</li> <li><a href="https://github.com/npm/ini/commit/55b6841261aad580ce979c1ada97885a0617b965"><code>55b6841</code></a> feat!: bump to new node engine range</li> <li><a href="https://github.com/npm/ini/commit/2b11ba8283afa33211844be6fa29794970ccf7b7"><code>2b11ba8</code></a> feat!: template-oss-apply</li> <li><a href="https://github.com/npm/ini/commit/e8d16cbbbb91d503fe14163024bd2a01a0446d32"><code>e8d16cb</code></a> deps & engine update</li> <li><a href="https://github.com/npm/ini/commit/3661dce193f03675ec6ddc0938e2483d0ab41f38"><code>3661dce</code></a> chore: bump <code>@npmcli/template-oss</code> from 4.28.0 to 4.28.1 (<a href="https://redirect.github.com/npm/ini/issues/296">#296</a>)</li> <li><a href="https://github.com/npm/ini/commit/5d67f4b487a00aa3e2119776192030356e0161ba"><code>5d67f4b</code></a> chore: bump <code>@npmcli/template-oss</code> from 4.27.1 to 4.28.0 (<a href="https://redirect.github.com/npm/ini/issues/294">#294</a>)</li> <li><a href="https://github.com/npm/ini/commit/a2c835ec4690c5e67651a403d0f952aaff018f42"><code>a2c835e</code></a> chore: bump <code>@npmcli/eslint-config</code> from 5.1.0 to 6.0.0 (<a href="https://redirect.github.com/npm/ini/issues/293">#293</a>)</li> <li><a href="https://github.com/npm/ini/commit/180a8d5c72d7f13ed70c53619132f3a8ee5ac6ed"><code>180a8d5</code></a> chore: release 6.0.0 (<a href="https://redirect.github.com/npm/ini/issues/292">#292</a>)</li> <li><a href="https://github.com/npm/ini/commit/6d395a4aaf7d7a5e32e250809cb7bd04c6a27b66"><code>6d395a4</code></a> fix!: align to npm 11 node engine range (<a href="https://redirect.github.com/npm/ini/issues/291">#291</a>)</li> <li>Additional commits viewable in <a href="https://github.com/npm/ini/compare/v4.1.3...v7.0.0">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for ini since your current version.</p> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Updates `@types/node` from 25.9.3 to 26.0.1 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
270c9a158a |
chore: bump to 0.13.0 (#412)
as per title |
||
|
|
31bb59fb60 |
chore: bump all workspace packages to 0.12.1 (#381)
Bumps every workspace package under `packages/*` from `0.12.0` → `0.12.1`, keeping the monorepo's lockstep versioning intact. ## Changes - `version` bumped to `0.12.1` in all 15 workspace `package.json` files - `package-lock.json` workspace entries synced to match ## Verification - `npm run check:versions` → `All workspace packages are at 0.12.1.` 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
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> |
||
|
|
d987c25ad0 |
fix(argent): declare + ship tree-sitter so react-profiler-component-source finds components (#287)
## Problem `react-profiler-component-source` returned `found:false` for **every** component in a standard TS/TSX Expo project. ## Two root causes (both verified live against the Bluesky app) 1. **tree-sitter never declared/shipped.** `@swmansion/argent` didn't depend on `tree-sitter`/`tree-sitter-typescript`, so the parser `require()` threw, was swallowed, and the AST index was always empty. Fixed by adding them as runtime deps and keeping them `external` in the CJS tools bundle so the native addons are `require()`d at runtime (not inlined). Verified: `HostingProvider`, `LoggedOutLayout`, `Login` now resolve with correct file:line. 2. **memo()/forwardRef() components were skipped.** The AST matcher's `variable_declarator` branch only indexed `arrow_function`/`function_expression` value nodes; a wrapped component (`const X = memo(...)` / `forwardRef(...)` / `React.memo(...)`) has a `call_expression` value node, so it was never indexed — and profiler findings are disproportionately memo-wrapped, i.e. exactly the components users look up. Now recognises memo/forwardRef wrapper calls (incl. `React.`-prefixed and nested `memo(forwardRef(...))`) and indexes the declared name; `memo` sets `isMemoized`. Verified live: `ThreadItemReadMore`, `CenteredView`, `ScrollView`, `BookmarkButton`, `Logo` now resolve. ## Tests `ast-index.test.ts` covers the idiomatic forms (default-export/plain/arrow) and the memo/forwardRef/React.memo/nested wrappers; the wrapped-form test fails on pre-fix code. Rebased onto latest main (re-merged the `bundle-tools.cjs` helper refactor; bundle still externalizes tree-sitter). CI green. |
||
|
|
02e500884f |
chore(deps): npm-minor-patch group excluding tree-sitter (fixes #348) (#355)
## What Applies the safe updates from dependabot #348 (`npm-minor-patch` group) and **excludes the one bump that breaks the build**, `tree-sitter`. | Package | From | To | | --- | --- | --- | | prettier | 3.8.3 | 3.8.4 | | @clack/prompts | 1.1.0 / 1.4.0 | 1.5.1 | | @types/node | 25.9.0 | 25.9.3 | | esbuild | 0.28.0 | 0.28.1 | | semver | 7.7.4 / 7.8.0 | 7.8.4 | | vitest | 4.1.6 | 4.1.9 | | tree-sitter | 0.21.1 | **held at 0.21.1** | (`ws` was part of #348's group but is already at 8.21.0 on `main`, so it's untouched here.) ## Why tree-sitter is excluded `tree-sitter@0.25.0` ships **no Node 24 prebuilds**, and its `binding.gyp` forces `-std=c++17` while Node 22+ v8 (cppgc) headers require C++20, so the native build fails `npm ci`/`npm install` on current Node. That's exactly why #348's `ESLint` job (Node 24) fails at install: ``` .../node_modules/tree-sitter ... node-gyp-build .../include/node/v8config.h:13:2: error: #error "C++20 or later required." ``` (#348's `Unit tests` job is pinned to Node 20, where it still compiles — which is why that PR looks half-green.) There is no tree-sitter release between 0.22.4 and 0.25.0, so there's no newer working version. `^0.21.1` ships N-API prebuilds (no compile) and installs cleanly on Node 20 / 22 / 24. This PR also adds a Dependabot `ignore` for tree-sitter minor/major so the group stops re-proposing the broken bump. Patch updates stay allowed; drop the ignore once upstream restores prebuilt binaries. ## Verification (local) - Lockfile regenerated on **Node 20 / npm 10.8.2** (`npm install --package-lock-only --ignore-scripts`), idempotent under a re-run — won't trip the strict lockfile check. tree-sitter resolves to 0.21.1 (prebuilt, no native compile). - Full CI-equivalent on **Node 20**: `tsc --build`, `eslint --max-warnings 0`, `prettier --check`, `typecheck:tests`/`typecheck:scripts`, full unit suite incl. **1250 tool-server tests** — all green. - `npm ci` from the committed lockfile succeeds. - **Live device E2E**: ran the built tool-server with the bumped deps, captured a real screenshot of a booted iPhone 16 Pro Max (`simulator-client` uses `ws`), then downloaded the PNG artifact over HTTP — `200`, 331 KB PNG. Supersedes #348 (Dependabot auto-closes it once the safe bumps land and tree-sitter is ignored). |
||
|
|
37d28fef8f | seciurity and npm i | ||
|
|
c832109573 |
chore: bump versions to 0.12.0 (#358)
Bumps the package suite from `0.11.0` to **`0.12.0`**. ## Changed - All release packages `0.11.0 → 0.12.0`: `@swmansion/argent`, `@argent/cli`, `@argent/installer`, `@argent/mcp`, `@argent/tools-client`, `@argent/native-devtools-android`, `@argent/native-devtools-ios`, `@argent/registry`, `@argent/skills`, `@argent/tool-server`, `@argent/update-core`, `@argent/configuration-core`. - `@argent/preview-window` `0.9.0 → 0.12.0` — aligned to the suite (was lagging a release behind; `private`/unpublished). - Regenerated the matching `package-lock.json` workspace version entries. ## Not changed - `@argent/ui` stays at `0.0.1` (separate pre-release track). - The private workspace root has no version. - Internal deps use `file:../` specifiers, so no dependency ranges needed updating. No source/runtime changes — `argent --version` reads from `package.json` at runtime. |
||
|
|
f3d108a5a1 |
feat: Argent Lens (#271)
Adds a UI for proposing and choosing between multiple agent-generated variants on a running app. **MCP tools** (`packages/tool-server/src/tools/variants/`) - `propose_variant` — non-blocking; agent stages a variant for an on-screen element (text/label/identifier/role matcher). - `await_user_selection` — one blocking call; parks until the human submits, then returns the picks + free-form annotations + a global comment. **Preview UI** (`packages/ui`) - Floating cards anchored to live element frames via the existing `describe` tree, with connector lines. - Comment-mode inspector: hover spotlight (blur+dim everything else), right-click any element to pin a comment. - Sticky padded hitbox + trajectory-aware dismissal so focus doesn't drop on cursor jitter. - Footbar [Complete] [Clear], confirm modal for destructive actions, green toast on submit. - Single source of feel constants in `theme.css`. **Electron host** (`packages/preview-window`) - New workspace package. Frameless transparent BrowserWindow at fixed size; the squeeze open/close is a CSS `transform: scaleY` on `<html>`, GPU-composited — no OS-level resize. - Tool-server spawns it on `await_user_selection` park, reuses it across re-awaits, and asks it to animate-close on submit (1s grace so the toast is visible). - Stdio-line IPC (no extra ports). Ephemeral throughout — the renderer hits the tool-server's already-ephemeral `/preview/*` HTTP. --------- Co-authored-by: Filip131311 <contact@filipkaminski.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
acfe80ab6b |
chore: add ESLint with typescript-eslint (#349)
## What Adds type-aware linting to the workspace. Until now the only static gate on JS/TS was Prettier (formatting) and `tsc` — there was no linter, so the whole class of bugs `tsc` doesn't catch (floating promises, misused promises, throwing non-Errors, unsafe stringification, dead code) went unguarded across ~450 TS files. - **`eslint.config.mjs`** — flat config. `recommendedTypeChecked` runs on the TS sources via an explicit `project` list (each package keeps tests in a separate `tsconfig.test.json` that `projectService` can't auto-discover, so it's listed explicitly). Type-checked rules are disabled for the loosely-typed plain-JS build/dev scripts. The `argent-private` submodule and build artifacts are ignored (mirrors `.prettierignore`). - **`lint` / `lint:fix`** npm scripts. - **`.github/workflows/lint.yml`** — builds the workspace (type-aware rules need the referenced projects' declarations) then runs `eslint .`. Node 24 (ESLint 10 requires `^20.19 || ^22.13 || >=24`). ## Rule calibration This is an adoption PR, so it's deliberately calibrated rather than maximal: - **Kept on (bug-catchers):** `no-floating-promises`, `no-misused-promises` (with `checksVoidReturn: false` to drop the noisy callback variant), `only-throw-error`, `no-base-to-string`, `prefer-promise-reject-errors`, `no-unused-vars` (`_`-prefix escape hatch), plus the ESLint recommended set. - **Parked off as documented debt:** the high-volume style/`any`-family rules — `no-unsafe-*`, `require-await`, `no-unnecessary-type-assertion`, `restrict-template-expressions`, `unbound-method`, `no-explicit-any`, etc. These flag broad classes of pre-existing code and are out of scope here; each is commented as a ratchet target for follow-up passes. All findings from the kept-on rules are fixed in this PR (dead code/imports, error-cause chaining, **3 genuine floating promises**, non-Error throws, unsafe stringification). Stale unused `eslint-disable` directives left over in the tree were removed by `--fix`. ## Verification Locally, all green: `eslint .` (0 errors), `tsc --build`, `typecheck:tests`/`typecheck:scripts`, the full `vitest` suite (no behavior change from the fixes), and `prettier --check`. ## Not included (intentionally) Other static-analysis gates discussed (CodeQL, dependency-audit, ShellCheck, actionlint) are out of scope for this PR. |
||
|
|
8718d82905 |
feat(android): drive connected physical Android devices (#342)
## What Adds support for driving a **physically connected Android phone** (USB or wireless adb), not just emulators. Once a phone with USB debugging is attached, it shows up in `list-devices` and every existing interaction tool works against it — no new tools, no per-tool special-casing. ## How it works A physical phone is driven by a different simulator-server controller than an emulator: it deploys the Android Studio **screen-sharing agent** to the device and streams **H264 over adb** (`android_device` subcommand), whereas an emulator streams decoded RGB over the emulator gRPC bridge (`android` subcommand). Both controllers expose the **same** HTTP/WebSocket/stdin API, so the only thing that has to change on the argent side is *which subcommand the device's service blueprint spawns*. Everything downstream — `screenshot`, the `gesture-*` family, `button`, `keyboard` (simulator-server) and `describe`, `launch-app`, `restart-app`, `reinstall-app`, `open-url` (adb) — is unchanged. - **Classification** (`utils/device-info.ts`): a non-`emulator-*` Android serial (a USB hardware serial, or an `ip:port` from wireless debugging) resolves to kind `device` instead of `emulator`, purely from serial shape — the same signal radon uses to detect connected phones, and with no extra adb round-trip on the hot path. New `isAndroidEmulatorSerial` helper. - **Routing** (`blueprints/simulator-server.ts`): spawn `android_device --id <serial>` for kind `device`, `android` for an emulator, `ios` for a simulator. The capability matrix already declared `android.device: true` across the tools, so nothing else gates physical devices out. - **Surfacing** (`tools/devices/list-devices.ts`): Android entries now carry a `kind` (`"emulator"` | `"device"`); the tool description documents physical-device detection. Physical phones don't need `boot-device` — just connect them. - **describe/android**: resolves the real device kind instead of hard-coding `emulator` (the adb path is identical either way). - **Packaging**: `download-simulator-server.sh` fetches and `bundle-tools.cjs` ships the screen-sharing agent (`.jar` + per-ABI `.so`) next to each platform's simulator-server binary, where the `android_device` controller resolves it at runtime. ## Dependencies (draft) This is a **draft** because it assumes the matching simulator-server changes land and publish: - **software-mansion/radon#128** — Linux/cross-platform OpenH264 H264 *decoder* for the `android_device` controller (macOS keeps VideoToolbox). Gives the argent-built binary a decoder on every host. - **software-mansion/radon#127** — enables `android-device` in `argent` builds and publishes the `screen-sharing-agent.tar.gz` release asset that the download script consumes. Until those release artifacts are available, the download step degrades gracefully (warns, skips) and physical-device support is simply unavailable. ## Testing Verified end-to-end against a physical **Galaxy S24** (`arm64-v8a`, Android API 36) by running the tool-server against a locally built argent simulator-server (radon#128) with the agent resources staged: | tool | path exercised | result | |------|----------------|--------| | `list-devices` | adb | phone listed as `kind: "device"`, `isEmulator: false` | | `screenshot` | screen-sharing agent → H264 → VideoToolbox decode | ✅ correct, correctly-oriented PNG | | `button` (home) | simulator-server stdin `pressKey` | ✅ | | `gesture-swipe` | simulator-server WebSocket touch | ✅ | | `describe` | adb (android-devtools) | ✅ | Full tool-server unit suite: **1157 passed**. Added coverage for the new classification (`device-info.test.ts`) and the `android_device` subcommand routing (`simulator-server-blueprint.test.ts`). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
73cf47bae6 |
feat: support arm64 Linux simulator-server binary (#328)
## Summary The only Linux simulator-server binary argent ships today is x86_64 (`simulator-server-argent-linux` — verified: `ELF 64-bit … x86-64`). On arm64 Linux hosts (Lima/UTM VMs on Apple Silicon, arm cloud instances, Raspberry Pi-class devices) the package has no usable binary — the x86_64 ELF would only fail with `ENOEXEC` at spawn time. This PR teaches the whole binary pipeline about a **host platform key**: `process.platform` everywhere, except arm64 Linux which maps to `linux-arm64`. macOS keeps a single `darwin/` dir because its binary is universal (lipo); Linux binaries are single-arch ELFs, so each arch gets its own platform-keyed directory. x86_64 Linux keeps the existing `linux` key for backward compatibility. ## Changes - **`@argent/native-devtools-ios` resolver** — new exported `hostPlatformKey()`; `simulatorServerBinaryPath()` resolves `bin/linux-arm64/` on arm64 Linux and names the searched key in its error message. - **`argent-simulator-server.cjs` dispatcher** (npm `bin` entry) — mirrors the same key (duplicated deliberately; the dispatcher ships as a standalone file). - **`bundle-tools.cjs`** — `linux-arm64` added to the supported host platform dirs; copied into the package when staged, warn-and-skip otherwise (same as x86_64 Linux). - **`scripts/download-simulator-server.sh`** — downloads `simulator-server-argent-linux-arm64` into `bin/linux-arm64/`; tolerates the asset being absent (warn + skip) until the upstream release ships it, so publishing keeps working in the meantime. - **`scripts/dev.cjs`** — copies the current host's binary by key. - **publish / publish-next / build-package-artifact workflows** — `linux-arm64` added to the binary inventory; gated by the existing `ARGENT_REQUIRE_LINUX_BINARY` flag (now covering both Linux keys via a `linux*` glob). ## Tests - Resolver: new arch-aware suite — `linux`+`arm64` → `bin/linux-arm64`, `linux`+`x64` → `bin/linux`, `darwin`+`arm64` → `bin/darwin`, and the missing-binary error names `linux-arm64`. - Dispatcher: end-to-end test faking `process.platform`/`process.arch` in a child process to exercise the real resolution path on any host. - Full suite: 146 files / 1651 tests pass. `tsc --build` clean. - `download-simulator-server.sh` exercised against the live `radon-main` release: downloads darwin + linux, warn-and-skips the not-yet-published arm64 asset. ## Dependencies Companion PR software-mansion/radon#126 adds the `ubuntu-24.04-arm` build leg that publishes `simulator-server-argent-linux-arm64` to `simulator-server-releases`. This PR is safe to merge first (the download script and verify steps tolerate the missing asset); arm64 hosts start working once a release containing the new asset is cut. |
||
|
|
fa86905fbd |
chore: bump versions to 0.11.0 (#322)
Bumps the package suite from `0.10.0` to **`0.11.0`**. ## Changed - All release packages `0.10.0 → 0.11.0`: `@swmansion/argent`, `@argent/cli`, `@argent/installer`, `@argent/mcp`, `@argent/tools-client`, `@argent/native-devtools-android`, `@argent/native-devtools-ios`, `@argent/registry`, `@argent/skills`, `@argent/tool-server`, `@argent/update-core`. - `@argent/configuration-core` `0.9.0 → 0.11.0` — was lagging a release behind (extracted in #295); aligned to the suite. (It's `private`/unpublished, so this is internal-only.) - Regenerated `package-lock.json` to reflect the new workspace versions. ## Not changed - `@argent/ui` stays at `0.0.1` (separate pre-release track). - The private workspace root has no version. - Internal deps use `file:../` specifiers, so no dependency ranges needed updating. No source/runtime changes — `argent --version` reads from `package.json` at runtime. |
||
|
|
92cc69a75c |
feat: extract configuration-core and migrate auto-screenshot to feature flag (#295)
## Summary - Introduces `@argent/configuration-core` as the shared source of truth for feature-flag storage, the registry, and `isFlagEnabled`, so MCP and CLI can import the same primitives without coupling runtime code to CLI-only modules. - Replaces `ARGENT_AUTO_SCREENSHOT` with the off-by-default `disable-auto-screenshot` flag (auto-screenshot stays on unless enabled via `argent enable disable-auto-screenshot`); renames `ARGENT_AUTO_SHUTDOWN` to `ARGENT_TOOL_SERVER_SHUTDOWN_ON_MCP_EXIT`. - Keeps `@argent/cli` as the command layer (`enable` / `disable` / `flags`) with backward-compat re-exports, colored flag state output (picocolors), and `--help` listings of available flags. --------- Co-authored-by: Filip131311 <contact@filipkaminski.com> Co-authored-by: Cursor <cursoragent@cursor.com> |