## 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.
## 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)
## 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).
## 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>