@phnx-labs/agents-cli 1.22.83 → 1.22.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +80 -53
  3. package/dist/bootstrap.d.ts +7 -6
  4. package/dist/bootstrap.js +20 -27
  5. package/dist/cli/command-registry.js +5 -1
  6. package/dist/commands/accounts.d.ts +6 -13
  7. package/dist/commands/accounts.js +330 -143
  8. package/dist/commands/apply.js +1 -1
  9. package/dist/commands/auth-mint.d.ts +7 -3
  10. package/dist/commands/auth-mint.js +21 -9
  11. package/dist/commands/auth.js +2 -3
  12. package/dist/commands/browser.js +10 -10
  13. package/dist/commands/daemon.d.ts +7 -3
  14. package/dist/commands/daemon.js +40 -25
  15. package/dist/commands/doctor.js +28 -2
  16. package/dist/commands/exec.js +87 -39
  17. package/dist/commands/fleet-capture.js +21 -2
  18. package/dist/commands/harness-wizard.js +2 -2
  19. package/dist/commands/lease.js +7 -12
  20. package/dist/commands/profiles.d.ts +2 -2
  21. package/dist/commands/profiles.js +20 -13
  22. package/dist/commands/repo.js +3 -3
  23. package/dist/commands/run-account-picker.d.ts +3 -3
  24. package/dist/commands/run-account-picker.js +29 -30
  25. package/dist/commands/secrets-passthrough.d.ts +20 -0
  26. package/dist/commands/secrets-passthrough.js +43 -0
  27. package/dist/commands/sessions-trace.d.ts +11 -0
  28. package/dist/commands/sessions-trace.js +71 -0
  29. package/dist/commands/setup-accounts.d.ts +3 -2
  30. package/dist/commands/setup-accounts.js +4 -4
  31. package/dist/commands/setup-secrets.d.ts +16 -21
  32. package/dist/commands/setup-secrets.js +43 -224
  33. package/dist/commands/ssh.js +2 -2
  34. package/dist/commands/sync.js +1 -1
  35. package/dist/commands/update.d.ts +10 -0
  36. package/dist/commands/update.js +43 -40
  37. package/dist/commands/versions.d.ts +11 -11
  38. package/dist/commands/versions.js +131 -83
  39. package/dist/commands/view.d.ts +1 -9
  40. package/dist/commands/view.js +41 -55
  41. package/dist/commands/webhook.js +5 -5
  42. package/dist/commands/workflows.js +2 -1
  43. package/dist/index.d.ts +12 -12
  44. package/dist/index.js +13 -42
  45. package/dist/lib/account-capabilities.d.ts +1 -1
  46. package/dist/lib/account-capabilities.js +1 -1
  47. package/dist/lib/account-catalog.d.ts +121 -6
  48. package/dist/lib/account-catalog.js +421 -7
  49. package/dist/lib/account-registry.d.ts +8 -30
  50. package/dist/lib/account-registry.js +36 -79
  51. package/dist/lib/account-schema.d.ts +1 -1
  52. package/dist/lib/account-schema.js +1 -1
  53. package/dist/lib/accounting/account-pool-collect.js +16 -4
  54. package/dist/lib/accounting/rotate.d.ts +20 -7
  55. package/dist/lib/accounting/rotate.js +89 -13
  56. package/dist/lib/accounting/usage.js +11 -16
  57. package/dist/lib/accounts/add.d.ts +138 -0
  58. package/dist/lib/accounts/add.js +651 -0
  59. package/dist/lib/accounts/migrate.d.ts +117 -0
  60. package/dist/lib/accounts/migrate.js +536 -0
  61. package/dist/lib/accounts/slots.d.ts +13 -0
  62. package/dist/lib/accounts/slots.js +100 -0
  63. package/dist/lib/agent-spec/agents.d.ts +16 -0
  64. package/dist/lib/agent-spec/agents.js +32 -4
  65. package/dist/lib/app-bundle-install.js +5 -4
  66. package/dist/lib/auth-health.d.ts +3 -0
  67. package/dist/lib/auth-health.js +11 -0
  68. package/dist/lib/auth-mint.d.ts +52 -16
  69. package/dist/lib/auth-mint.js +117 -39
  70. package/dist/lib/browser/chrome.d.ts +1 -1
  71. package/dist/lib/browser/chrome.js +5 -5
  72. package/dist/lib/byok-usage.js +3 -3
  73. package/dist/lib/claude-account-token.d.ts +47 -3
  74. package/dist/lib/claude-account-token.js +172 -50
  75. package/dist/lib/cloud/antigravity.js +4 -4
  76. package/dist/lib/cloud/cursor.js +4 -4
  77. package/dist/lib/crabbox/cli.d.ts +1 -1
  78. package/dist/lib/crabbox/cli.js +6 -6
  79. package/dist/lib/crabbox/runtimes.d.ts +3 -3
  80. package/dist/lib/crabbox/runtimes.js +5 -5
  81. package/dist/lib/daemon/account-state-daemon-service.d.ts +37 -1
  82. package/dist/lib/daemon/account-state-daemon-service.js +199 -3
  83. package/dist/lib/daemon/auth-sync-service.js +28 -1
  84. package/dist/lib/daemon/daemon.d.ts +6 -16
  85. package/dist/lib/daemon/daemon.js +52 -97
  86. package/dist/lib/daemon/daemon.test-fixture.d.ts +7 -9
  87. package/dist/lib/daemon/daemon.test-fixture.js +22 -40
  88. package/dist/lib/daemon/harness-update-service.d.ts +1 -1
  89. package/dist/lib/daemon/harness-update-service.js +1 -1
  90. package/dist/lib/daemon/runner.d.ts +15 -3
  91. package/dist/lib/daemon/runner.js +49 -24
  92. package/dist/lib/daemon-health.d.ts +1 -2
  93. package/dist/lib/daemon-health.js +7 -6
  94. package/dist/lib/daemon-services.d.ts +1 -1
  95. package/dist/lib/daemon-services.js +1 -11
  96. package/dist/lib/daemon-ticks.js +23 -2
  97. package/dist/lib/daemon-webhooks.d.ts +8 -7
  98. package/dist/lib/daemon-webhooks.js +10 -9
  99. package/dist/lib/device-config.js +1 -1
  100. package/dist/lib/devices/doctor-findings.d.ts +1 -1
  101. package/dist/lib/devices/harness-inventory.d.ts +39 -0
  102. package/dist/lib/devices/harness-inventory.js +126 -4
  103. package/dist/lib/doctor-diff.js +2 -1
  104. package/dist/lib/exec-account-home.d.ts +38 -0
  105. package/dist/lib/exec-account-home.js +164 -0
  106. package/dist/lib/exec.d.ts +30 -0
  107. package/dist/lib/exec.js +101 -31
  108. package/dist/lib/feed/activity-stream.d.ts +60 -0
  109. package/dist/lib/feed/activity-stream.js +271 -0
  110. package/dist/lib/feed/activity.d.ts +7 -0
  111. package/dist/lib/feed/activity.js +10 -4
  112. package/dist/lib/feed/watch.d.ts +9 -3
  113. package/dist/lib/feed/watch.js +72 -36
  114. package/dist/lib/fleet/apply.d.ts +2 -2
  115. package/dist/lib/fleet/apply.js +4 -4
  116. package/dist/lib/fleet/auth-sync.js +4 -3
  117. package/dist/lib/fleet-shared-repo-sync.js +6 -9
  118. package/dist/lib/fleet-shared-state.d.ts +6 -0
  119. package/dist/lib/harness/adapter.d.ts +7 -7
  120. package/dist/lib/harness/adapter.js +10 -6
  121. package/dist/lib/harness/adapters/grok.js +8 -3
  122. package/dist/lib/harness/adapters/muse.js +1 -1
  123. package/dist/lib/harness/adapters/opencode.js +12 -3
  124. package/dist/lib/harness-auth-capabilities.d.ts +61 -0
  125. package/dist/lib/harness-auth-capabilities.js +52 -0
  126. package/dist/lib/helper-versions.d.ts +6 -4
  127. package/dist/lib/helper-versions.js +5 -4
  128. package/dist/lib/hosts/credential-transport.d.ts +10 -0
  129. package/dist/lib/hosts/credential-transport.js +37 -0
  130. package/dist/lib/hosts/dispatch.d.ts +7 -0
  131. package/dist/lib/hosts/dispatch.js +13 -6
  132. package/dist/lib/identity/client.d.ts +3 -3
  133. package/dist/lib/identity/client.js +3 -3
  134. package/dist/lib/installations/index.d.ts +1 -1
  135. package/dist/lib/installations/index.js +1 -1
  136. package/dist/lib/installations/migrate.js +9 -0
  137. package/dist/lib/installations/resolve.js +1 -1
  138. package/dist/lib/installations/shims.d.ts +15 -0
  139. package/dist/lib/installations/shims.js +69 -0
  140. package/dist/lib/installations/store.d.ts +43 -0
  141. package/dist/lib/installations/store.js +75 -7
  142. package/dist/lib/installations/versions.js +1 -1
  143. package/dist/lib/menubar/install-menubar.d.ts +3 -3
  144. package/dist/lib/menubar/install-menubar.js +3 -3
  145. package/dist/lib/native-accounts.d.ts +35 -0
  146. package/dist/lib/native-accounts.js +41 -0
  147. package/dist/lib/net-close.d.ts +11 -0
  148. package/dist/lib/net-close.js +25 -0
  149. package/dist/lib/openclaw-keychain.js +27 -1
  150. package/dist/lib/profiles.js +22 -9
  151. package/dist/lib/project-resources.js +1 -1
  152. package/dist/lib/reserved-stores.d.ts +53 -0
  153. package/dist/lib/reserved-stores.js +120 -0
  154. package/dist/lib/secrets-client.d.ts +191 -0
  155. package/dist/lib/secrets-client.js +710 -0
  156. package/dist/lib/secrets-policy.d.ts +222 -0
  157. package/dist/lib/secrets-policy.js +483 -0
  158. package/dist/lib/secrets-types.d.ts +188 -0
  159. package/dist/lib/secrets-types.js +24 -0
  160. package/dist/lib/service-manifest.js +3 -4
  161. package/dist/lib/session/active.d.ts +38 -4
  162. package/dist/lib/session/active.js +36 -4
  163. package/dist/lib/session/bash-command.js +10 -0
  164. package/dist/lib/session/db.d.ts +65 -2
  165. package/dist/lib/session/db.js +178 -18
  166. package/dist/lib/session/mirror.d.ts +5 -0
  167. package/dist/lib/session/mirror.js +166 -0
  168. package/dist/lib/session/parse.d.ts +49 -0
  169. package/dist/lib/session/parse.js +324 -30
  170. package/dist/lib/session/prompt.d.ts +93 -2
  171. package/dist/lib/session/prompt.js +266 -15
  172. package/dist/lib/session/remote/peer-stream.d.ts +47 -0
  173. package/dist/lib/session/remote/peer-stream.js +142 -0
  174. package/dist/lib/session/remote/watch.d.ts +1 -1
  175. package/dist/lib/session/remote/watch.js +41 -42
  176. package/dist/lib/session/session-cache.d.ts +9 -0
  177. package/dist/lib/session/session-cache.js +40 -2
  178. package/dist/lib/session/sync/config.js +2 -2
  179. package/dist/lib/session/timeline-pass.d.ts +129 -0
  180. package/dist/lib/session/timeline-pass.js +323 -0
  181. package/dist/lib/session/timeline.d.ts +182 -0
  182. package/dist/lib/session/timeline.js +636 -0
  183. package/dist/lib/session/types.d.ts +155 -1
  184. package/dist/lib/sha256-asset.d.ts +11 -16
  185. package/dist/lib/sha256-asset.js +11 -16
  186. package/dist/lib/share/config.js +14 -5
  187. package/dist/lib/signin-badge.d.ts +26 -0
  188. package/dist/lib/signin-badge.js +42 -0
  189. package/dist/lib/staleness/detectors/workflows.js +3 -105
  190. package/dist/lib/staleness/writers/workflows.js +2 -1
  191. package/dist/lib/state.d.ts +7 -4
  192. package/dist/lib/state.js +18 -7
  193. package/dist/lib/summarizer/pass.d.ts +2 -0
  194. package/dist/lib/summarizer/pass.js +14 -1
  195. package/dist/lib/summarizer/summarize.d.ts +7 -0
  196. package/dist/lib/summarizer/summarize.js +3 -0
  197. package/dist/lib/sync-umbrella.js +2 -2
  198. package/dist/lib/teams/agents.js +1 -1
  199. package/dist/lib/types.d.ts +74 -33
  200. package/dist/lib/view-types.d.ts +6 -3
  201. package/dist/lib/workflows-registry.d.ts +71 -0
  202. package/dist/lib/workflows-registry.js +280 -0
  203. package/dist/lib/workflows.d.ts +21 -21
  204. package/dist/lib/workflows.js +12 -327
  205. package/package.json +2 -3
  206. package/scripts/postinstall.js +4 -29
  207. package/dist/commands/secrets-import.d.ts +0 -18
  208. package/dist/commands/secrets-import.js +0 -74
  209. package/dist/commands/secrets-migrate.d.ts +0 -25
  210. package/dist/commands/secrets-migrate.js +0 -334
  211. package/dist/commands/secrets-rotate-passphrase.d.ts +0 -17
  212. package/dist/commands/secrets-rotate-passphrase.js +0 -96
  213. package/dist/commands/secrets-sync.d.ts +0 -11
  214. package/dist/commands/secrets-sync.js +0 -153
  215. package/dist/commands/secrets-vault.d.ts +0 -10
  216. package/dist/commands/secrets-vault.js +0 -130
  217. package/dist/commands/secrets.d.ts +0 -212
  218. package/dist/commands/secrets.js +0 -3030
  219. package/dist/lib/accounts/connect.d.ts +0 -170
  220. package/dist/lib/accounts/connect.js +0 -383
  221. package/dist/lib/daemon/keychain-reap-service.d.ts +0 -17
  222. package/dist/lib/daemon/keychain-reap-service.js +0 -32
  223. package/dist/lib/daemon/secrets-broker-service.d.ts +0 -21
  224. package/dist/lib/daemon/secrets-broker-service.js +0 -51
  225. package/dist/lib/secrets/agent.d.ts +0 -358
  226. package/dist/lib/secrets/agent.js +0 -1291
  227. package/dist/lib/secrets/audit.d.ts +0 -46
  228. package/dist/lib/secrets/audit.js +0 -101
  229. package/dist/lib/secrets/bundles.d.ts +0 -290
  230. package/dist/lib/secrets/bundles.js +0 -1547
  231. package/dist/lib/secrets/download-keychain.d.ts +0 -47
  232. package/dist/lib/secrets/download-keychain.js +0 -70
  233. package/dist/lib/secrets/drivers/rush.d.ts +0 -14
  234. package/dist/lib/secrets/drivers/rush.js +0 -90
  235. package/dist/lib/secrets/fallback.d.ts +0 -48
  236. package/dist/lib/secrets/fallback.js +0 -48
  237. package/dist/lib/secrets/filestore.d.ts +0 -222
  238. package/dist/lib/secrets/filestore.js +0 -1099
  239. package/dist/lib/secrets/headless.d.ts +0 -43
  240. package/dist/lib/secrets/headless.js +0 -56
  241. package/dist/lib/secrets/icloud-import.d.ts +0 -79
  242. package/dist/lib/secrets/icloud-import.js +0 -206
  243. package/dist/lib/secrets/index.d.ts +0 -451
  244. package/dist/lib/secrets/index.js +0 -1568
  245. package/dist/lib/secrets/install-helper.d.ts +0 -72
  246. package/dist/lib/secrets/install-helper.js +0 -245
  247. package/dist/lib/secrets/lease.d.ts +0 -25
  248. package/dist/lib/secrets/lease.js +0 -44
  249. package/dist/lib/secrets/linux.d.ts +0 -77
  250. package/dist/lib/secrets/linux.js +0 -393
  251. package/dist/lib/secrets/list-filter.d.ts +0 -109
  252. package/dist/lib/secrets/list-filter.js +0 -261
  253. package/dist/lib/secrets/mcp.d.ts +0 -93
  254. package/dist/lib/secrets/mcp.js +0 -211
  255. package/dist/lib/secrets/profiles.d.ts +0 -10
  256. package/dist/lib/secrets/profiles.js +0 -13
  257. package/dist/lib/secrets/push.d.ts +0 -133
  258. package/dist/lib/secrets/push.js +0 -273
  259. package/dist/lib/secrets/rc-hygiene.d.ts +0 -63
  260. package/dist/lib/secrets/rc-hygiene.js +0 -143
  261. package/dist/lib/secrets/read-backoff.d.ts +0 -27
  262. package/dist/lib/secrets/read-backoff.js +0 -64
  263. package/dist/lib/secrets/reaper.d.ts +0 -90
  264. package/dist/lib/secrets/reaper.js +0 -243
  265. package/dist/lib/secrets/remote.d.ts +0 -152
  266. package/dist/lib/secrets/remote.js +0 -344
  267. package/dist/lib/secrets/reserved-sync.d.ts +0 -66
  268. package/dist/lib/secrets/reserved-sync.js +0 -147
  269. package/dist/lib/secrets/scope.d.ts +0 -26
  270. package/dist/lib/secrets/scope.js +0 -29
  271. package/dist/lib/secrets/session-store.d.ts +0 -107
  272. package/dist/lib/secrets/session-store.js +0 -342
  273. package/dist/lib/secrets/sync-backend.d.ts +0 -48
  274. package/dist/lib/secrets/sync-backend.js +0 -13
  275. package/dist/lib/secrets/sync-commands.d.ts +0 -21
  276. package/dist/lib/secrets/sync-commands.js +0 -21
  277. package/dist/lib/secrets/sync.d.ts +0 -48
  278. package/dist/lib/secrets/sync.js +0 -237
  279. package/dist/lib/secrets/unlock-hints.d.ts +0 -27
  280. package/dist/lib/secrets/unlock-hints.js +0 -36
  281. package/dist/lib/secrets/usage-db.d.ts +0 -46
  282. package/dist/lib/secrets/usage-db.js +0 -96
  283. package/dist/lib/secrets/vault-age-helper.d.ts +0 -1
  284. package/dist/lib/secrets/vault-age-helper.js +0 -34
  285. package/dist/lib/secrets/vault.d.ts +0 -49
  286. package/dist/lib/secrets/vault.js +0 -399
  287. package/dist/lib/secrets/windows.d.ts +0 -81
  288. package/dist/lib/secrets/windows.js +0 -556
  289. package/scripts/install-helper.js +0 -97
  290. /package/dist/lib/{secrets/sync-passphrase.d.ts → sync-passphrase.d.ts} +0 -0
  291. /package/dist/lib/{secrets/sync-passphrase.js → sync-passphrase.js} +0 -0
@@ -1,451 +0,0 @@
1
- /**
2
- * Cross-platform secure credential storage.
3
- *
4
- * macOS: every keychain operation goes through the signed `Agents CLI.app`
5
- * helper. The helper attaches a biometry-or-passcode access control to every
6
- * item it writes, so the OS itself gates decryption with Touch ID. A single
7
- * LAContext lives for the helper's process lifetime, so a batch read pops
8
- * Touch ID once and reuses the assertion for every item in the same batch.
9
- * No /usr/bin/security fast path: that path bypasses the helper's ACL,
10
- * exposes items to the legacy password sheet, and would defeat the model.
11
- *
12
- * Linux: libsecret (GNOME Keyring) via the `secret-tool` CLI. No biometry —
13
- * items are unlocked when the keyring is open.
14
- *
15
- * Windows: Windows Credential Manager (CRED_TYPE_GENERIC,
16
- * CRED_PERSIST_LOCAL_MACHINE) via a PowerShell P/Invoke shim, with the same
17
- * AES-256-GCM encrypted-file fallback used on Linux when the credential store
18
- * is unreachable (no logon session / no powershell.exe). No biometry.
19
- *
20
- * Items are device-local: the biometry access control requires the OS to
21
- * treat them as bound to this device, so cross-machine propagation goes
22
- * through the explicit export/import flow in src/lib/secrets/sync.ts
23
- * rather than the system's cloud-keychain path.
24
- */
25
- import { type SpawnSyncOptions, type SpawnSyncReturns } from 'child_process';
26
- import type { NativeImportReport } from './fallback.js';
27
- export type { NativeImportReport, NativeImportResult, NativeImportStatus } from './fallback.js';
28
- export declare const SECRETS_ITEM_PREFIX = "agents-cli.secrets.";
29
- /**
30
- * Thrown when a keychain helper / security spawnSync is killed because it
31
- * exceeded its timeout. A wedged coreauthd / LocalAuthentication dialog can hang
32
- * the parent forever; this makes the failure explicit and arms the read back-off.
33
- */
34
- export declare class KeychainHelperTimeoutError extends Error {
35
- readonly bin: string;
36
- readonly args: string[];
37
- constructor(bin: string, args: string[]);
38
- }
39
- /** Test seam: suppress the side-effect daemon boot in unit tests. */
40
- export declare function setKeychainDaemonBootForTest(enabled: boolean): void;
41
- /** Test seam: exercise the timeout wrapper with an arbitrary binary. */
42
- export declare function spawnKeychainHelperForTest(bin: string, args: string[], opts: SpawnSyncOptions, timeoutMs: number): SpawnSyncReturns<Buffer>;
43
- /** Supported secret resolution backends. */
44
- export type SecretProvider = 'keychain' | 'env' | 'file' | 'exec';
45
- /** A typed reference to a secret, consisting of a provider and a provider-specific value. */
46
- export interface SecretRef {
47
- provider: SecretProvider;
48
- value: string;
49
- }
50
- /**
51
- * A bundle value: either a string (literal or provider-prefixed ref) or
52
- * an object `{value: string}` used to escape a literal that would otherwise
53
- * be parsed as a ref (e.g. a URL that happens to start with 'env:').
54
- */
55
- export type BundleValue = string | {
56
- value: string;
57
- };
58
- /** Parse a bundle value into either a literal string or a typed secret ref. */
59
- export declare function parseBundleValue(raw: BundleValue): {
60
- literal: string;
61
- } | {
62
- ref: SecretRef;
63
- };
64
- /** Serialize a secret ref back to its `provider:value` string form. */
65
- export declare function serializeRef(ref: SecretRef): string;
66
- /**
67
- * Guard a secret value before it is written to the current platform's primary
68
- * backend.
69
- *
70
- * A value is empty on every platform → always rejected. Embedded newlines are
71
- * rejected ONLY on darwin: the macOS batch read path (`get-batch`, see
72
- * getKeychainTokens) is newline-delimited, so a value with a newline would
73
- * corrupt record framing on read. Linux (secret-tool), Windows (Credential
74
- * Manager stores the raw UTF-8 blob and emits base64), and the encrypted-file
75
- * fallback all store raw bytes and round-trip multiline values (PEM / SSH keys)
76
- * faithfully, so they accept newlines. `platform` is injectable for tests.
77
- */
78
- export declare function assertValueStorable(value: string, platform?: NodeJS.Platform): void;
79
- /** Build the keychain item name for a profile provider token. */
80
- export declare function profileKeychainItem(provider: string): string;
81
- /** Build the keychain item name for a secrets-bundle key. */
82
- export declare function secretsKeychainItem(bundle: string, key: string): string;
83
- /**
84
- * Test seam: lets bundle storage tests swap the keychain backend for an
85
- * in-memory map without touching the user's real keychain. Mocking is
86
- * justified here because the alternative (touching real keychain in unit
87
- * tests) is destructive and would require an interactive Keychain unlock.
88
- */
89
- export interface KeychainBackend {
90
- has(item: string): boolean;
91
- get(item: string): string;
92
- /** `opts.noAcl` mirrors setKeychainToken's no-ACL write path so tests can
93
- * assert which path a write took; in-memory backends may ignore it. */
94
- set(item: string, value: string, opts?: {
95
- noAcl?: boolean;
96
- }): void;
97
- delete(item: string): boolean;
98
- list(prefix: string): string[];
99
- }
100
- /** Install a custom keychain backend (test only). Returns the previous backend so callers can restore. */
101
- export declare function setKeychainBackendForTest(b: KeychainBackend | null): KeychainBackend | null;
102
- /** True when a test backend is installed (real keychain / biometry bypassed).
103
- * Callers that gate on the live secrets-agent broker use this to stay hermetic —
104
- * with an in-memory backend there is no real keychain to dedup, so the broker
105
- * fast-path must not engage. Always false in production (`backend` is null). */
106
- export declare function isKeychainBackendOverridden(): boolean;
107
- export declare const HMAC_KEY_ITEM = "agents-cli.hmackey";
108
- interface HmacKeyRecord {
109
- v: number;
110
- /** 64 hex chars — the raw HMAC-SHA256 key. */
111
- k: string;
112
- /** True once the one-time re-key has moved every cleartext-named item. */
113
- migrated: boolean;
114
- /** Old cleartext services whose hashed copies are verified but whose
115
- * originals are not yet deleted (crash-resume list; deletes are silent). */
116
- pendingDeletes?: string[];
117
- /** True once this record has been re-stored no-ACL to heal a hmackey item that
118
- * an OLD helper (pre the metadata/hmackey no-ACL migration fix) re-stamped with
119
- * a biometry ACL. Set on the first read that heals it, so the heal runs exactly
120
- * once per machine and never churns the keychain afterward. */
121
- healedNoAcl?: boolean;
122
- }
123
- /** Force hashed service names on with a fixed key (test only). Pass null to
124
- * restore lazy production resolution. Composes with setKeychainBackendForTest
125
- * so unit tests exercise the exact transform production uses. */
126
- export declare function setKeychainServiceHashingForTest(key: Buffer | null): void;
127
- /**
128
- * Run `fn` with service-name hashing suspended: every primitive uses the
129
- * literal names it is given. For migration flows ONLY — they enumerate raw
130
- * names from the helper (which may be pre-re-key cleartext leftovers) and must
131
- * read/delete those exact items, not their hashed transforms.
132
- */
133
- export declare function withRawKeychainServiceNames<T>(fn: () => T): T;
134
- /** The hashed (storage) service name for a cleartext item name. Exported for
135
- * the re-key migration and tests; runtime callers go through the primitives,
136
- * which apply this transparently. */
137
- export declare function hashedServiceName(item: string, key: Buffer): string;
138
- export declare function readHmacKeyRecord(): HmacKeyRecord | null;
139
- /**
140
- * Heal a `hmackey` item that an OLD helper (pre the metadata/hmackey no-ACL
141
- * migration fix) re-stamped with a biometry ACL. Such an item makes EVERY hashed
142
- * keychain lookup pop the generic "Agents CLI needs to authenticate" sheet,
143
- * because the HMAC key is read before every hashed name resolves. The migration
144
- * fix stopped the re-stamping but never un-stamped an already-damaged item, and
145
- * nothing else re-stores it once hashing is already active — so it prompts forever.
146
- *
147
- * This re-stores the record no-ACL exactly once per machine (guarded by
148
- * `healedNoAcl`), turning every future read silent. The read that produced `rec`
149
- * has already happened (and already prompted if it was ACL'd); this only writes.
150
- * Returns true if it healed. Exported for tests. No-op when already healed.
151
- */
152
- export declare function healHmacKeyNoAclOnce(rec: HmacKeyRecord): boolean;
153
- /**
154
- * The storage-layer service name for `item`: hashed when hashing is active,
155
- * the item itself otherwise. For callers that mix helper-enumerated
156
- * (already-hashed) names with computed cleartext names in one lookup map —
157
- * see readAndResolveBundleEnv.
158
- */
159
- export declare function keychainServiceAlias(item: string): string;
160
- /**
161
- * One-shot per process: activate hashing on machines with nothing to move,
162
- * finish a crash-interrupted delete phase (silent), and run the interactive
163
- * one-time re-key when cleartext-named items exist and a human is present.
164
- * Never throws — a failed attempt leaves the process on cleartext names
165
- * (exact pre-#316 behavior) and the next process retries.
166
- */
167
- export declare function maybeAutoRekey(): void;
168
- /** One re-keyed (or failed) item, by its old cleartext service name. */
169
- export interface RekeyPlanItem {
170
- oldService: string;
171
- newService: string;
172
- /** Preserve the no-ACL write path for `never`-policy bundle items. */
173
- noAcl: boolean;
174
- /** Replacement payload (bundle metadata gets `name` injected); absent = copy verbatim. */
175
- payload?: string;
176
- }
177
- /**
178
- * Build the old→new mapping for a set of cleartext services. Bundle metadata
179
- * is parsed first to (a) recover each bundle's prompt policy — the persisted
180
- * `tier` token, where `none`/`never` means the item must be re-written through
181
- * the no-ACL path — and (b) inject the cleartext `name` into the JSON, because
182
- * after hashing the service name can no longer carry it (listBundles reads it
183
- * back from the payload). A value item's tier is resolved from its bundle's
184
- * metadata PAYLOAD in `values` — under the cleartext metadata name or its
185
- * hashed transform — never from the metadata item being part of the same
186
- * `services` batch: a --prefix run can scope a bundle's value items alone, and
187
- * rekeyServiceNames supplies the out-of-scope metadata reads (see the
188
- * supplemental batch there). Exported for unit tests.
189
- */
190
- export declare function computeRekeyPlan(services: string[], values: Map<string, string>, key: Buffer): {
191
- items: RekeyPlanItem[];
192
- unreadable: string[];
193
- };
194
- /** Outcome of one rekeyServiceNames run. */
195
- export interface RekeyReport {
196
- /** Old cleartext services whose items now live under hashed names. */
197
- migrated: string[];
198
- failed: Array<{
199
- item: string;
200
- detail: string;
201
- }>;
202
- /** True when hashed naming is on after this run. */
203
- activated: boolean;
204
- nothingToDo: boolean;
205
- }
206
- /**
207
- * The one-time re-key: move every cleartext-named `agents-cli.*` item to its
208
- * hashed service name. Composed entirely from the existing helper primitives —
209
- * no new Swift command:
210
- *
211
- * 1. Enumerate cleartext services (silent) and batch-read every value behind
212
- * ONE Touch ID (`get-batch`; readItem also sweeps legacy/orphaned copies).
213
- * 2. Write each hashed copy (`set`/`set-no-acl` never prompt), preserving
214
- * the no-ACL tier for `never`-policy bundles.
215
- * 3. Batch-verify every copy round-trips (second Touch ID).
216
- * 4. Only then activate hashing (sentinel + pendingDeletes) and delete the
217
- * old items (silent).
218
- *
219
- * Add-before-delete throughout: a cancel/crash/failure anywhere before step 4
220
- * leaves every old item intact and hashing OFF — same rationale as the
221
- * helper's migrate-orphans, which is also why no pre-write backup is taken.
222
- * On ANY per-item failure nothing is deleted and the sentinel stays off
223
- * (all-or-nothing activation); the report names every failed item. A crash
224
- * between the sentinel write and the deletes is resumed silently by the next
225
- * process (pendingDeletes). Idempotent: re-running converges.
226
- */
227
- export declare function rekeyServiceNames(opts?: {
228
- prefixes?: string[];
229
- announce?: boolean;
230
- log?: (line: string) => void;
231
- }): RekeyReport;
232
- /** Re-key state snapshot for `agents secrets rekey --status`. */
233
- export declare function rekeyStatus(): {
234
- migrated: boolean;
235
- hasKey: boolean;
236
- pendingDeletes: number;
237
- cleartext: string[];
238
- /** False when the enumeration probe fails (locked keybag) — the cleartext
239
- * count is then meaningless. Only probeable once the key record exists. */
240
- enumerationOk: boolean;
241
- };
242
- /**
243
- * Check if a keychain/keyring item exists. Never prompts for biometry.
244
- *
245
- * Throws when the item cannot be reached — on macOS, when the signed helper is
246
- * unavailable. That is deliberate: this primitive gates destructive writes as
247
- * well as reads. Through `bundleExists()` it guards the `--force` overwrite
248
- * checks in `agents secrets create` (`../../commands/secrets.ts`) and the
249
- * bundle-rename purge (`./bundles.ts`), and the pull-rollback bookkeeping
250
- * (`./sync.ts`). A false "absent" silently disarms every one of them, so an
251
- * unreachable keychain must fail loudly rather than answer "no".
252
- *
253
- * Tests needing this path without a helper install a backend via
254
- * `setKeychainBackendForTest()`, which short-circuits on the next line.
255
- */
256
- export declare function hasKeychainToken(item: string): boolean;
257
- /**
258
- * Retrieve a secret value from the keychain/keyring. Throws if not found.
259
- *
260
- * On macOS this triggers Touch ID (or reuses an assertion held by an earlier
261
- * call in the same process). For bundles, prefer getKeychainTokens() so a
262
- * single biometric prompt covers every key in the batch.
263
- */
264
- export interface KeychainReadContext {
265
- agent?: string;
266
- bundle?: string;
267
- sessionId?: string;
268
- reason?: string;
269
- duration?: string;
270
- defaultPolicy?: 'hold' | 'always' | 'never';
271
- forceDuration?: boolean;
272
- /**
273
- * The caller attests the item(s) carry NO biometry ACL (it wrote them with
274
- * `setKeychainToken(..., { noAcl: true })`, or they are bundle metadata /
275
- * `never`-policy bundle items, which are no-ACL by contract) — so the read
276
- * is silent even when no one is at the screen. Skips the headless fail-fast
277
- * and the back-off memo. Never pass this for an ACL-protected item: that
278
- * re-opens the background Touch ID storm the guard exists to stop.
279
- */
280
- silentNoAcl?: boolean;
281
- }
282
- export declare function setKeychainHeadlessDetectorForTest(detector: (() => boolean) | null): void;
283
- export declare function keychainOperationPrompt(context?: KeychainReadContext): string;
284
- export declare function getKeychainToken(item: string, context?: KeychainReadContext): string;
285
- /**
286
- * Batch-read multiple keychain items behind a single Touch ID prompt. The
287
- * macOS helper holds one LAContext for its whole process: the first protected
288
- * item triggers Touch ID, every later item in the same invocation reuses the
289
- * assertion. Missing items are absent from the returned map (caller decides
290
- * whether that's an error).
291
- *
292
- * On Linux or when a test backend is installed, falls back to individual
293
- * lookups — no biometric prompt path on those platforms.
294
- */
295
- export declare function getKeychainTokens(items: string[], context?: KeychainReadContext): Map<string, string>;
296
- /** Store or update a secret value in the keychain/keyring. Device-local;
297
- * biometry-gated on macOS. `opts.noAcl` (the `never` prompt-policy) writes our
298
- * item WITHOUT the biometry access control so later reads are fully silent — it
299
- * routes through the signed helper's `set-no-acl` path. A pinned helper that
300
- * predates that path rejects the unknown command (exit 2) and this throws,
301
- * rather than silently falling back to an ACL'd `set` (which would behave like
302
- * `always`). Ignored by the Linux/Windows/test backends, which have no ACL. */
303
- /**
304
- * argv for writing a bare (non-`agents-cli.`) keychain item via
305
- * `/usr/bin/security add-generic-password`, deliberately WITHOUT the value: the
306
- * secret travels over stdin (see setKeychainToken) so it never lands in argv or
307
- * a `ps` snapshot. Exported so a test can assert the value is absent from argv.
308
- */
309
- export declare function buildAddGenericPasswordArgs(account: string, item: string): string[];
310
- /**
311
- * spawnSync options for the bare `-w` keychain write. Pure so the two
312
- * load-bearing properties are unit-testable without touching the real keychain:
313
- * - `input` pipes the value TWICE (bare `-w` prompts enter+confirm; one line
314
- * fails the confirm and stores an empty secret).
315
- * - `detached: true` runs `security` in a new session with no controlling
316
- * terminal, so readpassphrase(3) falls back to our piped stdin instead of
317
- * prompting the user's `/dev/tty` in an interactive shell (see setKeychainToken).
318
- */
319
- export declare function buildAddGenericPasswordSpawnOptions(value: string): SpawnSyncOptions & {
320
- input: string;
321
- detached: boolean;
322
- };
323
- export declare function setKeychainToken(item: string, value: string, opts?: {
324
- noAcl?: boolean;
325
- }): void;
326
- /** Delete a keychain/keyring item. Returns true if it existed. Never prompts for biometry. */
327
- export declare function deleteKeychainToken(item: string): boolean;
328
- /**
329
- * True when the active keychain backend transparently routes reads/writes to
330
- * the encrypted-file store instead of the OS credential store. This only
331
- * happens on Linux under the headless / locked-collection fallback
332
- * (src/lib/secrets/linux.ts); macOS and the test backend always return false.
333
- *
334
- * Callers that ALSO enumerate the file store directly (e.g. `listBundles`)
335
- * use this to avoid double-counting: under the fallback `listKeychainItems`
336
- * and the direct file enumeration return the same items.
337
- */
338
- export declare function keychainUsesFileFallback(): boolean;
339
- /** Enumerate keychain/keyring item names starting with the given prefix.
340
- * With hashed service names active, the two sub-namespace prefixes callers
341
- * use (bundle metadata; one bundle's value items) are mapped to their hashed
342
- * shapes — the returned names are then storage (opaque) names. */
343
- export declare function listKeychainItems(prefix: string): string[];
344
- /**
345
- * Enumerate ONLY legacy file-based-keychain item names with the given prefix —
346
- * the items that still carry a pre-migration (trusted-app) ACL and pop a
347
- * separate auth sheet on read. Items already in the data-protection keychain are
348
- * excluded (they need no migration). Silent (attributes only, never decrypts).
349
- *
350
- * macOS only: on Linux / the test backend there is no separate legacy keychain,
351
- * so this returns []. Used by `agents secrets migrate-acl` to rewrite only the
352
- * stragglers instead of every item (which would be a Touch ID storm).
353
- */
354
- export declare function listLegacyKeychainItems(prefix: string): string[];
355
- /**
356
- * Test seam for the LEGACY SYNCHRONIZABLE (iCloud Keychain) recovery path.
357
- * The main `KeychainBackend` seam models the live device-local store; this one
358
- * models the orphaned iCloud items that `secrets import --from icloud` reads.
359
- * Kept separate so a test can populate both sides independently.
360
- */
361
- export interface SyncedKeychainBackend {
362
- list(prefix: string): string[];
363
- getBatch(items: string[]): Map<string, string>;
364
- delete(item: string): boolean;
365
- }
366
- export declare function setSyncedKeychainBackendForTest(b: SyncedKeychainBackend | null): SyncedKeychainBackend | null;
367
- /**
368
- * Enumerate LEGACY SYNCHRONIZABLE (iCloud Keychain) item names with the given
369
- * prefix — bundles written by the pre-biometry helper era, which defaulted
370
- * secrets to iCloud Keychain sync. The device-local cutover orphaned them:
371
- * every modern query pins synchronizable=false, so only the helper's
372
- * `list-synced` verb can see them. Silent (attributes only, never decrypts).
373
- * macOS only — Linux/Windows never had iCloud Keychain sync, so this returns [].
374
- */
375
- export declare function listSyncedKeychainItems(prefix: string): string[];
376
- /**
377
- * Batch-read LEGACY SYNCHRONIZABLE (iCloud Keychain) items. Returns a map of
378
- * item name → value; missing items are simply absent. Pre-biometry items carry
379
- * no biometry ACL, so this does not normally prompt. macOS only — returns an
380
- * empty map on Linux/Windows.
381
- */
382
- export declare function getSyncedKeychainTokens(items: string[]): Map<string, string>;
383
- /**
384
- * Delete a LEGACY SYNCHRONIZABLE (iCloud Keychain) item after a successful
385
- * import (`--purge`). Matches synchronizable items only — the device-local
386
- * copy the import wrote is untouched. iCloud propagates the deletion to the
387
- * user's other devices. Returns true if a copy was removed.
388
- */
389
- export declare function deleteSyncedKeychainItem(item: string): boolean;
390
- /**
391
- * One-time upgrade for a keychain item that was written by a previous helper
392
- * generation with a trusted-app ACL. The helper reads the legacy item
393
- * (which may pop the password sheet once), then deletes and re-adds it with
394
- * the biometry access control. Returns true if the item was rewritten, false
395
- * if no item by that name exists. macOS only — Linux backends have no ACL
396
- * concept, so the call is a no-op there.
397
- */
398
- export declare function migrateKeychainItem(item: string): boolean;
399
- /**
400
- * Enumerate data-protection items whose service starts with `prefix` that live
401
- * under a NON-concrete access group — pre-#279 "orphans" filed under the implicit
402
- * default group (the literal `2HTP252L87.*`) that the pinned-group queries can't
403
- * see. Attributes only: never decrypts, never prompts. macOS only — Linux/Windows
404
- * and the test backend have no access-group concept, so this returns [].
405
- */
406
- export declare function listOrphanedKeychainItems(prefix: string): string[];
407
- /** Outcome of re-homing one orphaned keychain item. */
408
- export interface OrphanMigrationResult {
409
- item: string;
410
- status: 'ok' | 'warn' | 'fail';
411
- detail?: string;
412
- }
413
- /**
414
- * Parse the `migrate-orphans` helper summary (one record per line):
415
- * OK <service> re-homed
416
- * WARN <service> <detail> pinned copy written but orphan not removed
417
- * FAIL <service> <detail> could not re-home (orphan left intact)
418
- * Unknown lines are ignored. Exported for unit testing without a keychain.
419
- */
420
- export declare function parseOrphanMigrationOutput(stdout: string): OrphanMigrationResult[];
421
- /**
422
- * Re-home every pre-#279 orphaned data-protection item under `prefix` into the
423
- * concrete access group, behind a SINGLE Touch ID prompt for the whole batch.
424
- * The helper reads each orphan by its exact persistent ref, adds the pinned copy
425
- * (add-before-delete: a failed add leaves the orphan intact), then deletes the
426
- * orphan by ref. Returns one result per item. macOS only — no-op elsewhere.
427
- *
428
- * Throws on Touch ID cancellation (exit 4) so callers can distinguish "user
429
- * aborted" from "nothing to do" (empty array).
430
- */
431
- export declare function migrateOrphanedKeychainItems(prefix: string): OrphanMigrationResult[];
432
- /**
433
- * Import agents-cli secrets from the native store (GNOME Keyring / Windows
434
- * Credential Manager) into the encrypted file store — the Linux/Windows
435
- * analogue of the macOS orphan/legacy migration, exposed as
436
- * `agents secrets import-keyring`. Requires the native store to be
437
- * reachable/unlocked; `commit=false` is a dry-run. macOS returns an empty
438
- * report (it has no file fallback and uses `migrate-acl` instead).
439
- */
440
- export declare function importNativeItems(prefix: string, commit: boolean): NativeImportReport;
441
- /** Options controlling how secret refs are resolved. */
442
- export interface ResolveOptions {
443
- /** Translate a short keychain ID to a fully namespaced item name. */
444
- keychainItemFor?: (shortId: string) => string;
445
- /** Allow exec: refs. When false (default), exec refs throw. */
446
- allowExec?: boolean;
447
- /** Restrict env: refs to this allowlist. When undefined, any env var may be read. */
448
- envAllowlist?: string[];
449
- }
450
- /** Resolve a secret ref to its plaintext value using the appropriate provider. */
451
- export declare function resolveRef(ref: SecretRef, opts?: ResolveOptions): string;