zas-agent 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -1
- package/README.md +102 -12
- package/dist/cli.js +3783 -2425
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.11.0] - 2026-10-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Automatic npm release checks and separately staged updates, enabled by default.
|
|
15
|
+
Verified releases take effect on the next launch without interrupting transfers
|
|
16
|
+
or changing pairing data. Add `update`, `updates [on|off]`, the
|
|
17
|
+
`ZAS_AGENT_AUTO_UPDATE` override, and update information in `zas_status`.
|
|
18
|
+
Source checkouts stay on their working code; offline or failed checks keep the
|
|
19
|
+
current agent running.
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- Sanitize local filenames with the pinned web rules, enforce containment, and
|
|
24
|
+
publish downloads and Directo receives without overwriting competing files (#13).
|
|
25
|
+
- Migrate private keys and pairing secrets to Windows DPAPI, macOS Keychain or
|
|
26
|
+
Linux Secret Service, with an owner-only headless fallback. Check POSIX secret
|
|
27
|
+
permissions and report the storage backend in status (#14).
|
|
28
|
+
- Refuse unsafe HTTP bases and emulator credential mixing, revalidate saved
|
|
29
|
+
endpoints, and reject redirects on credential-bearing requests (#15).
|
|
30
|
+
- Update compatible production dependencies to pass the high-severity audit.
|
|
31
|
+
- Mirror zas.web `46d727a` shared codecs and vectors: reject invalid OPRF points,
|
|
32
|
+
read v2 envelopes while retaining v1 writes, and verify server-selected VOPRF
|
|
33
|
+
against configured public-key pins. CI checks pinned shared sources (#16).
|
|
34
|
+
|
|
35
|
+
## [0.10.0] - 2026-09-28
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Transfer telemetry. File and note sends, item downloads, and Directo sends
|
|
40
|
+
and receives (live and reliable delivery) report `transfer.started`,
|
|
41
|
+
`transfer.stage_started`, `transfer.slow` (after 30 s),
|
|
42
|
+
`transfer.phase_timing` and `transfer.finished`. Each report carries the
|
|
43
|
+
item category, the transport, byte counts, a size bucket, stage durations and
|
|
44
|
+
the outcome (success, failure or cancellation), joined by a random
|
|
45
|
+
per-attempt ID. No file name, content, path or channel name. The same
|
|
46
|
+
opt-out as `agent.tool_call` covers it. The telemetry notice names the new
|
|
47
|
+
fields.
|
|
48
|
+
|
|
49
|
+
- `plan_inactive`. A send, replace or Directo transfer in an organization
|
|
50
|
+
channel whose plan is inactive now says so, and names who can reactivate
|
|
51
|
+
it. It used to arrive as `upload_failed`, which told the agent to retry.
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- Reports never delay or fail a tool call. The `agent.tool_call` report is
|
|
56
|
+
sent after the answer, on a later tick. Transfer events are queued, at most
|
|
57
|
+
32 per batch, and sent in one request on a later tick. A report is one
|
|
58
|
+
request with a 2 s timeout and no retry. It is skipped when there is no
|
|
59
|
+
valid session, so it never starts or refreshes a sign-in.
|
|
60
|
+
|
|
10
61
|
## [0.9.0] - 2026-09-09
|
|
11
62
|
|
|
12
63
|
### Added
|
|
@@ -333,7 +384,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
333
384
|
two separate identities that cannot read each other's keys.
|
|
334
385
|
- Install snippets for Claude Code and Codex, printed by `zas-agent pair`.
|
|
335
386
|
|
|
336
|
-
[Unreleased]: https://github.com/soke1556/zas-agent/compare/v0.
|
|
387
|
+
[Unreleased]: https://github.com/soke1556/zas-agent/compare/v0.11.0...HEAD
|
|
388
|
+
[0.11.0]: https://github.com/soke1556/zas-agent/compare/v0.10.0...v0.11.0
|
|
389
|
+
[0.10.0]: https://github.com/soke1556/zas-agent/compare/v0.9.0...v0.10.0
|
|
337
390
|
[0.9.0]: https://github.com/soke1556/zas-agent/compare/v0.8.0...v0.9.0
|
|
338
391
|
[0.8.0]: https://github.com/soke1556/zas-agent/compare/v0.7.0...v0.8.0
|
|
339
392
|
[0.7.0]: https://github.com/soke1556/zas-agent/compare/v0.6.3...v0.7.0
|
package/README.md
CHANGED
|
@@ -112,6 +112,40 @@ You can also start the flow from the coding agent with the `zas_pair` tool:
|
|
|
112
112
|
the first call hands back the URL, a later call says whether the approval
|
|
113
113
|
landed, and if the page shows a code, a call with `code` claims with it.
|
|
114
114
|
|
|
115
|
+
## Updates
|
|
116
|
+
|
|
117
|
+
Automatic updates are on by default in published installations. While serving,
|
|
118
|
+
the agent checks npm's `latest` stable release in the background, at most once
|
|
119
|
+
per day. It installs newer releases in a separate directory and verifies that
|
|
120
|
+
the installed executable reports the expected version. The next agent launch
|
|
121
|
+
uses that release. Restart the MCP connection (or your coding agent) to apply it;
|
|
122
|
+
running transfers are never restarted by the updater. Pairing and channel grants
|
|
123
|
+
stay in place, and an offline or failed update leaves the current version usable.
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
zas-agent updates # show the setting and any release ready to use
|
|
127
|
+
zas-agent updates off # disable automatic downloads and staged launch selection
|
|
128
|
+
zas-agent updates on # enable them again
|
|
129
|
+
zas-agent update # check and stage a release now
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use `npx -y zas-agent@latest` in place of `zas-agent` if you have no global
|
|
133
|
+
installation. `zas_status` also reports the running version and staged update.
|
|
134
|
+
`ZAS_AGENT_AUTO_UPDATE=0` disables the built-in updater; `1` enables it, overriding
|
|
135
|
+
the saved setting. An explicit `update` command can still download a release while
|
|
136
|
+
updates are off, but it will not be selected until updates are enabled again.
|
|
137
|
+
For a pinned installation, use an exact version in the launch command and disable
|
|
138
|
+
automatic updates. The documented `npx ...@latest` command still asks npm for the
|
|
139
|
+
latest package even when the built-in updater is off.
|
|
140
|
+
|
|
141
|
+
Updates require npm and install the official `zas-agent` package from
|
|
142
|
+
`https://registry.npmjs.org`, including its normal dependency installation scripts
|
|
143
|
+
and npm integrity checks. No administrator access is needed. Staged packages live
|
|
144
|
+
under `~/.zas/agent/.updates` (or `ZAS_AGENT_HOME/.updates`); old installations are
|
|
145
|
+
retained and can be removed with the agent stopped. Source checkouts and prerelease
|
|
146
|
+
builds do not update themselves. Existing installations need to upgrade once to a
|
|
147
|
+
release containing this updater before these controls are available.
|
|
148
|
+
|
|
115
149
|
## Why you can trust it
|
|
116
150
|
|
|
117
151
|
Every line here is a fact. The ones about this package you can check in this
|
|
@@ -159,8 +193,13 @@ The package refuses some of these on its own, before a request is made. The
|
|
|
159
193
|
ones marked *(server-side)* are enforced by the Zas server.
|
|
160
194
|
|
|
161
195
|
- **No channel you did not grant.** Not by name, not by id.
|
|
162
|
-
- **No shared channel you
|
|
163
|
-
|
|
196
|
+
- **No shared channel you joined, unless its owner allows it.** You can grant
|
|
197
|
+
a channel you joined, but the grant stays `grant_pending` until that
|
|
198
|
+
channel's owner allows this agent in Zas. The plan also caps how many of
|
|
199
|
+
these channels one agent holds: 2 on Free *(server-side)*.
|
|
200
|
+
- **No workspace channel, unless the organization allows agents.** A channel
|
|
201
|
+
an organization manages, or one you created inside its workspace, can be
|
|
202
|
+
granted only while the organization is active and an admin turned agents on
|
|
164
203
|
*(server-side)*.
|
|
165
204
|
- **No reading unless the grant says so.** `read` is a separate switch from
|
|
166
205
|
`send`; without it, `zas_list_items` and `zas_get_item` are refused.
|
|
@@ -196,10 +235,16 @@ string ever reaches a terminal.
|
|
|
196
235
|
| Code | What it means |
|
|
197
236
|
| --- | --- |
|
|
198
237
|
| `not_paired` | This agent is not paired yet. |
|
|
238
|
+
| `unsafe_endpoint` | An endpoint or emulator configuration could expose credentials. |
|
|
239
|
+
| `identity_permissions` | A secret file is not private to its owner. |
|
|
240
|
+
| `secret_store_failed` | The OS secret store cannot save or open this profile. |
|
|
241
|
+
| `invalid_voprf_configuration` | The server-selected encryption key has no valid local pin. |
|
|
242
|
+
| `invalid_voprf_proof` | The encryption service response failed verification. |
|
|
199
243
|
| `identity_corrupt` | The identity file on disk is damaged. |
|
|
200
244
|
| `agent_revoked` | The owner revoked this agent. |
|
|
201
245
|
| `agent_forbidden` | Only the account owner can do that. |
|
|
202
246
|
| `grant_missing` | This agent has no access to that channel. |
|
|
247
|
+
| `grant_pending` | That channel belongs to somebody else, and its owner has not allowed this agent yet. |
|
|
203
248
|
| `send_forbidden` | This agent cannot send to that channel. |
|
|
204
249
|
| `read_forbidden` | This agent cannot read that channel. |
|
|
205
250
|
| `direct_mode` | That channel is in Directo mode. |
|
|
@@ -215,6 +260,7 @@ string ever reaches a terminal.
|
|
|
215
260
|
| `fallback_unavailable` | Reliable delivery is not available right now. |
|
|
216
261
|
| `key_stale` | The channel key changed; the owner refreshes it by opening Zas. |
|
|
217
262
|
| `quota_exceeded` | The account reached its storage limit. |
|
|
263
|
+
| `plan_inactive` | The organization's plan is inactive, so sending to its channels is paused; the owner or a billing admin reactivates it. |
|
|
218
264
|
| `rate_limited` | Too many sends in a row. |
|
|
219
265
|
| `file_too_big` | The file is over the plan limit. |
|
|
220
266
|
| `duplicate` | That item is already in the channel. |
|
|
@@ -228,6 +274,12 @@ string ever reaches a terminal.
|
|
|
228
274
|
| `write_failed` | The download destination could not be written. |
|
|
229
275
|
| `pairing_expired` | The pairing expired; pair again. |
|
|
230
276
|
| `pairing_cancelled` | The owner cancelled the pairing. |
|
|
277
|
+
| `claim_mismatch` | The code does not match. |
|
|
278
|
+
| `pairing_not_approved` | Nobody has approved this pairing yet. |
|
|
279
|
+
| `pairing_claimed` | This pairing was already claimed; pair again. |
|
|
280
|
+
| `agent_limit` | The account cannot take another agent; the owner deletes one from Settings → Agents. |
|
|
281
|
+
| `grant_limit` | The plan allows fewer channels per agent than this pairing grants. |
|
|
282
|
+
| `foreign_limit` | The plan allows this agent fewer channels of other people than this pairing asks for. |
|
|
231
283
|
| `feature_disabled` | Agents are not enabled for this account yet. |
|
|
232
284
|
| `upload_failed` | The upload failed. |
|
|
233
285
|
| `oprf_failed` | Zas did not answer correctly while preparing the file. |
|
|
@@ -306,14 +358,16 @@ covers every profile on the machine; pairing again does not reset it.
|
|
|
306
358
|
|
|
307
359
|
What one report carries, and nothing else: the tool that ran, whether it
|
|
308
360
|
worked, the closed error code when it did not, which of four duration buckets
|
|
309
|
-
it fell in, and the package version.
|
|
361
|
+
it fell in, and the package version. Item transfers also report item category,
|
|
362
|
+
transport, byte counts, stage durations, and success/failure/cancellation, joined
|
|
363
|
+
by a random per-attempt ID. No file name, no file contents, no path,
|
|
310
364
|
no channel name, no error message, no stack.
|
|
311
365
|
|
|
312
366
|
Where it goes: to Zas, never to an analytics service directly. This package
|
|
313
367
|
holds no analytics token and opens no connection to a third party, so no
|
|
314
368
|
address of yours reaches one. The report is attributed to the Zas account the
|
|
315
369
|
agent is paired with, which the server reads from the session — the request
|
|
316
|
-
carries no
|
|
370
|
+
carries no account or content identifier. Nothing is reported before pairing, because
|
|
317
371
|
until then there is no account it could belong to.
|
|
318
372
|
|
|
319
373
|
A report is never allowed to matter: it is sent after the answer, waited on
|
|
@@ -329,8 +383,8 @@ Codex agent side by side without either reading the other's keys:
|
|
|
329
383
|
| macOS, Linux | `~/.zas/agent/<profile>/` |
|
|
330
384
|
| Windows | `%USERPROFILE%\.zas\agent\<profile>\` |
|
|
331
385
|
|
|
332
|
-
|
|
333
|
-
|
|
386
|
+
Profile metadata is written through temporary files and renamed into place,
|
|
387
|
+
so a crash mid-write cannot leave half a file behind:
|
|
334
388
|
|
|
335
389
|
- `identity.json` — the agent uid, the owner uid, the name, and the two key
|
|
336
390
|
pairs. Back it up like a private key, or delete it and pair again.
|
|
@@ -349,11 +403,24 @@ One more file sits next to the profiles, in `~/.zas/agent/`:
|
|
|
349
403
|
above was last printed. It belongs to the machine, not to a profile, so one
|
|
350
404
|
decision covers every agent on it.
|
|
351
405
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
406
|
+
Private keys, polling secrets and legacy pairing codes migrate out of the old
|
|
407
|
+
JSON files on the next start. The replacement metadata is committed only after
|
|
408
|
+
storage succeeds. Windows uses current-user DPAPI and an owner-only directory
|
|
409
|
+
ACL without inherited grants. macOS uses Keychain; Linux uses Secret Service
|
|
410
|
+
through `secret-tool` when a desktop session and that tool are available. A
|
|
411
|
+
locked or failing desktop store must be unlocked or repaired before retrying.
|
|
412
|
+
Headless Linux uses a `0600` file in a `0700` directory. POSIX secret reads reject
|
|
413
|
+
files owned by another user, symlinks, hard links, and group/world permissions;
|
|
414
|
+
the error includes the `chmod 600` repair command. `zas_status` reports the store.
|
|
415
|
+
|
|
416
|
+
Older agent versions cannot read the migrated secret references; keep the
|
|
417
|
+
updated agent installed after migration. OS-protected profiles are not portable backups. Pair a new profile on another
|
|
418
|
+
machine; do not copy its JSON files and expect them to sign in. OS protection
|
|
419
|
+
does not prevent a process already running as your user from using your keys.
|
|
420
|
+
|
|
421
|
+
Deleting the directory removes the local references. Keychain/Secret Service
|
|
422
|
+
entries may remain under service `red.zas.agent`; remove those with the OS
|
|
423
|
+
credential manager when discarding a profile. It does not revoke
|
|
357
424
|
anything: the account side is closed from the web app, under
|
|
358
425
|
Settings → Agents → Revoke.
|
|
359
426
|
|
|
@@ -386,12 +453,22 @@ agent: same keys, same channels, one row.
|
|
|
386
453
|
| `ZAS_TOKEN_BASE` | `https://zas.red/anon-token` | The challenge and token routes. |
|
|
387
454
|
| `ZAS_OPRF_BASE` | `https://zas.red/oprf` | The blind key-derivation service. |
|
|
388
455
|
| `ZAS_FIREBASE_PROJECT` | `zas-me` | The project whose Firestore the read path queries. |
|
|
456
|
+
| `ZAS_ALLOW_INSECURE_DEV` | unset | `1` permits HTTP only on `localhost`, `127.0.0.1`, or `::1`. |
|
|
457
|
+
| `ZAS_VOPRF_PUBLIC_KEYS` | unset | Operator-provided JSON mapping key IDs to pinned base64 VOPRF public keys. Required when the server selects mode 1. |
|
|
389
458
|
| `ZAS_FIREBASE_API_KEY` | the public web key | The key used to exchange a custom token for a session. |
|
|
390
459
|
|
|
391
460
|
Only `--profile`, `ZAS_AGENT_HOME` and the two telemetry switches are worth
|
|
392
461
|
setting by hand. The rest exist
|
|
393
462
|
so the package can be pointed at a test deployment.
|
|
394
463
|
|
|
464
|
+
Saved API/token/OPRF bases are validated on every load. Non-loopback HTTP is
|
|
465
|
+
refused even with the dev flag. To run Firebase emulators, set both
|
|
466
|
+
`FIREBASE_AUTH_EMULATOR_HOST` and `FIRESTORE_EMULATOR_HOST` to loopback hosts,
|
|
467
|
+
all three Zas service bases to loopback, `ZAS_FIREBASE_PROJECT` to a `demo-*`
|
|
468
|
+
project, and `ZAS_ALLOW_INSECURE_DEV=1`. Production profiles cannot use these
|
|
469
|
+
emulators. Credential-bearing requests refuse redirects. Use a separate
|
|
470
|
+
profile for development; repair unsafe saved bases before loading an old one.
|
|
471
|
+
|
|
395
472
|
## Development
|
|
396
473
|
|
|
397
474
|
```
|
|
@@ -407,7 +484,7 @@ node dist/cli.js --version
|
|
|
407
484
|
This repository is the public mirror of the `agent/` package of Zas's private
|
|
408
485
|
monorepo. It is produced by `scripts/export-public.mjs`, which builds the
|
|
409
486
|
package with esbuild and uses the build's own metafile to decide what to copy:
|
|
410
|
-
`src/`, `test/`, the package files, and the
|
|
487
|
+
`src/`, `test/`, the package files, and the `src/shared/*` modules the
|
|
411
488
|
agent imports. Those shared modules are the client-side crypto and format code — the
|
|
412
489
|
chunker, the manifest, the envelope, the key derivation — that the Zas web app
|
|
413
490
|
also ships, which is why the encryption the agent performs is the encryption the
|
|
@@ -417,6 +494,19 @@ Pull requests are welcome against this repository. The maintainer applies
|
|
|
417
494
|
accepted changes back into the monorepo, and the next export brings them here.
|
|
418
495
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
419
496
|
|
|
497
|
+
`shared-source.json` pins the shared modules and interoperability fixtures to
|
|
498
|
+
zas.web commit `46d727a870c64728b42b768950d55d7d7a575181`. CI runs
|
|
499
|
+
`npm run check:shared` to detect drift using upstream Git blob IDs. Maintainers
|
|
500
|
+
with the private checkout can verify the pin against the actual commit with
|
|
501
|
+
`npm run check:shared -- --source ../zas.web`. Apply these agent changes back
|
|
502
|
+
to the monorepo before the next export.
|
|
503
|
+
|
|
504
|
+
This release follows the web reader phase: legacy/v1 and authenticated v2
|
|
505
|
+
envelopes can be read; application writers still produce v1. VOPRF mode is
|
|
506
|
+
selected by `GET /v1/agents/me`; mode 1 requires a local public-key pin and a
|
|
507
|
+
valid batch proof, with no downgrade on failure. Enabling production v2 writes
|
|
508
|
+
and coordinating VOPRF adoption across clients remain separate rollout work.
|
|
509
|
+
|
|
420
510
|
## Security
|
|
421
511
|
|
|
422
512
|
Please report vulnerabilities privately. [SECURITY.md](SECURITY.md) says how,
|