@phnx-labs/agents-cli 1.22.84 → 1.22.86
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 +96 -0
- package/README.md +80 -53
- package/dist/bootstrap.d.ts +7 -6
- package/dist/bootstrap.js +20 -27
- package/dist/cli/command-registry.js +5 -1
- package/dist/commands/accounts.d.ts +6 -13
- package/dist/commands/accounts.js +330 -143
- package/dist/commands/alias.js +7 -3
- package/dist/commands/apply.js +1 -1
- package/dist/commands/auth-mint.d.ts +7 -3
- package/dist/commands/auth-mint.js +21 -9
- package/dist/commands/auth.js +2 -3
- package/dist/commands/browser.js +10 -10
- package/dist/commands/daemon.d.ts +7 -3
- package/dist/commands/daemon.js +40 -25
- package/dist/commands/doctor.js +28 -2
- package/dist/commands/exec.js +87 -39
- package/dist/commands/fleet-capture.js +21 -2
- package/dist/commands/harness-wizard.js +2 -2
- package/dist/commands/lease.js +7 -12
- package/dist/commands/profiles.d.ts +2 -2
- package/dist/commands/profiles.js +20 -13
- package/dist/commands/repo.js +3 -3
- package/dist/commands/run-account-picker.d.ts +3 -3
- package/dist/commands/run-account-picker.js +29 -30
- package/dist/commands/secrets-passthrough.d.ts +20 -0
- package/dist/commands/secrets-passthrough.js +43 -0
- package/dist/commands/setup-accounts.d.ts +3 -2
- package/dist/commands/setup-accounts.js +4 -4
- package/dist/commands/setup-secrets.d.ts +16 -21
- package/dist/commands/setup-secrets.js +43 -224
- package/dist/commands/ssh.js +2 -2
- package/dist/commands/sync.js +1 -1
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.js +43 -40
- package/dist/commands/versions.d.ts +11 -11
- package/dist/commands/versions.js +131 -83
- package/dist/commands/view.d.ts +1 -9
- package/dist/commands/view.js +41 -55
- package/dist/commands/webhook.js +5 -5
- package/dist/commands/workflows.js +2 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.js +13 -42
- package/dist/lib/account-capabilities.d.ts +1 -1
- package/dist/lib/account-capabilities.js +1 -1
- package/dist/lib/account-catalog.d.ts +121 -6
- package/dist/lib/account-catalog.js +421 -7
- package/dist/lib/account-registry.d.ts +8 -30
- package/dist/lib/account-registry.js +36 -79
- package/dist/lib/account-schema.d.ts +1 -1
- package/dist/lib/account-schema.js +1 -1
- package/dist/lib/accounting/account-pool-collect.js +16 -4
- package/dist/lib/accounting/rotate.d.ts +20 -7
- package/dist/lib/accounting/rotate.js +89 -13
- package/dist/lib/accounting/usage.js +11 -16
- package/dist/lib/accounts/add.d.ts +138 -0
- package/dist/lib/accounts/add.js +651 -0
- package/dist/lib/accounts/migrate.d.ts +117 -0
- package/dist/lib/accounts/migrate.js +536 -0
- package/dist/lib/accounts/slots.d.ts +13 -0
- package/dist/lib/accounts/slots.js +100 -0
- package/dist/lib/agent-spec/agents.d.ts +16 -0
- package/dist/lib/agent-spec/agents.js +38 -4
- package/dist/lib/app-bundle-install.js +5 -4
- package/dist/lib/auth-health.d.ts +3 -0
- package/dist/lib/auth-health.js +11 -0
- package/dist/lib/auth-mint.d.ts +52 -16
- package/dist/lib/auth-mint.js +117 -39
- package/dist/lib/browser/chrome.d.ts +1 -1
- package/dist/lib/browser/chrome.js +5 -5
- package/dist/lib/byok-usage.js +3 -3
- package/dist/lib/claude-account-token.d.ts +47 -3
- package/dist/lib/claude-account-token.js +172 -50
- package/dist/lib/cloud/antigravity.js +4 -4
- package/dist/lib/cloud/cursor.js +4 -4
- package/dist/lib/crabbox/cli.d.ts +1 -1
- package/dist/lib/crabbox/cli.js +6 -6
- package/dist/lib/crabbox/runtimes.d.ts +3 -3
- package/dist/lib/crabbox/runtimes.js +5 -5
- package/dist/lib/daemon/account-state-daemon-service.d.ts +37 -1
- package/dist/lib/daemon/account-state-daemon-service.js +199 -3
- package/dist/lib/daemon/auth-sync-service.js +32 -1
- package/dist/lib/daemon/daemon.d.ts +6 -16
- package/dist/lib/daemon/daemon.js +52 -97
- package/dist/lib/daemon/daemon.test-fixture.d.ts +7 -9
- package/dist/lib/daemon/daemon.test-fixture.js +22 -40
- package/dist/lib/daemon/harness-update-service.d.ts +1 -1
- package/dist/lib/daemon/harness-update-service.js +1 -1
- package/dist/lib/daemon/runner.d.ts +15 -3
- package/dist/lib/daemon/runner.js +49 -24
- package/dist/lib/daemon-health.d.ts +1 -2
- package/dist/lib/daemon-health.js +7 -6
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +1 -11
- package/dist/lib/daemon-webhooks.d.ts +8 -7
- package/dist/lib/daemon-webhooks.js +10 -9
- package/dist/lib/device-config.js +1 -1
- package/dist/lib/devices/doctor-findings.d.ts +1 -1
- package/dist/lib/devices/harness-inventory.d.ts +39 -0
- package/dist/lib/devices/harness-inventory.js +126 -4
- package/dist/lib/doctor-diff.js +2 -1
- package/dist/lib/exec-account-home.d.ts +38 -0
- package/dist/lib/exec-account-home.js +164 -0
- package/dist/lib/exec.d.ts +30 -0
- package/dist/lib/exec.js +101 -31
- package/dist/lib/fleet/apply.d.ts +2 -2
- package/dist/lib/fleet/apply.js +4 -4
- package/dist/lib/fleet/auth-sync.js +4 -3
- package/dist/lib/fleet-shared-repo-sync.js +6 -9
- package/dist/lib/harness/adapter.d.ts +7 -7
- package/dist/lib/harness/adapter.js +10 -6
- package/dist/lib/harness/adapters/grok.js +8 -3
- package/dist/lib/harness/adapters/muse.js +1 -1
- package/dist/lib/harness/adapters/opencode.js +12 -3
- package/dist/lib/harness-auth-capabilities.d.ts +61 -0
- package/dist/lib/harness-auth-capabilities.js +52 -0
- package/dist/lib/helper-versions.d.ts +6 -4
- package/dist/lib/helper-versions.js +5 -4
- package/dist/lib/hosts/credential-transport.d.ts +10 -0
- package/dist/lib/hosts/credential-transport.js +37 -0
- package/dist/lib/hosts/dispatch.d.ts +7 -0
- package/dist/lib/hosts/dispatch.js +13 -6
- package/dist/lib/identity/client.d.ts +3 -3
- package/dist/lib/identity/client.js +3 -3
- package/dist/lib/installations/index.d.ts +1 -1
- package/dist/lib/installations/index.js +1 -1
- package/dist/lib/installations/migrate.js +9 -0
- package/dist/lib/installations/resolve.js +1 -1
- package/dist/lib/installations/shims.d.ts +21 -4
- package/dist/lib/installations/shims.js +86 -5
- package/dist/lib/installations/store.d.ts +43 -0
- package/dist/lib/installations/store.js +75 -7
- package/dist/lib/installations/versions.js +1 -1
- package/dist/lib/menubar/install-menubar.d.ts +3 -3
- package/dist/lib/menubar/install-menubar.js +3 -3
- package/dist/lib/native-accounts.d.ts +35 -0
- package/dist/lib/native-accounts.js +41 -0
- package/dist/lib/net-close.d.ts +11 -0
- package/dist/lib/net-close.js +25 -0
- package/dist/lib/openclaw-keychain.js +27 -1
- package/dist/lib/profiles.js +22 -9
- package/dist/lib/project-resources.js +1 -1
- package/dist/lib/reserved-stores.d.ts +53 -0
- package/dist/lib/reserved-stores.js +120 -0
- package/dist/lib/secrets-client.d.ts +199 -0
- package/dist/lib/secrets-client.js +718 -0
- package/dist/lib/secrets-policy.d.ts +235 -0
- package/dist/lib/secrets-policy.js +505 -0
- package/dist/lib/secrets-types.d.ts +188 -0
- package/dist/lib/secrets-types.js +24 -0
- package/dist/lib/self-heal/checks/shims.js +5 -3
- package/dist/lib/service-manifest.js +3 -4
- package/dist/lib/session/db.d.ts +18 -0
- package/dist/lib/session/db.js +47 -14
- package/dist/lib/session/sync/config.js +2 -2
- package/dist/lib/sha256-asset.d.ts +11 -16
- package/dist/lib/sha256-asset.js +11 -16
- package/dist/lib/share/config.js +14 -5
- package/dist/lib/signin-badge.d.ts +26 -0
- package/dist/lib/signin-badge.js +42 -0
- package/dist/lib/staleness/detectors/workflows.js +3 -105
- package/dist/lib/staleness/writers/workflows.js +2 -1
- package/dist/lib/state.d.ts +7 -4
- package/dist/lib/state.js +18 -7
- package/dist/lib/sync-umbrella.js +2 -2
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/types.d.ts +74 -33
- package/dist/lib/view-types.d.ts +6 -3
- package/dist/lib/workflows-registry.d.ts +71 -0
- package/dist/lib/workflows-registry.js +280 -0
- package/dist/lib/workflows.d.ts +21 -21
- package/dist/lib/workflows.js +12 -327
- package/package.json +2 -3
- package/scripts/postinstall.js +35 -30
- package/dist/commands/secrets-import.d.ts +0 -18
- package/dist/commands/secrets-import.js +0 -74
- package/dist/commands/secrets-migrate.d.ts +0 -25
- package/dist/commands/secrets-migrate.js +0 -334
- package/dist/commands/secrets-rotate-passphrase.d.ts +0 -17
- package/dist/commands/secrets-rotate-passphrase.js +0 -96
- package/dist/commands/secrets-sync.d.ts +0 -11
- package/dist/commands/secrets-sync.js +0 -153
- package/dist/commands/secrets-vault.d.ts +0 -10
- package/dist/commands/secrets-vault.js +0 -130
- package/dist/commands/secrets.d.ts +0 -212
- package/dist/commands/secrets.js +0 -3030
- package/dist/lib/accounts/connect.d.ts +0 -176
- package/dist/lib/accounts/connect.js +0 -453
- package/dist/lib/daemon/keychain-reap-service.d.ts +0 -17
- package/dist/lib/daemon/keychain-reap-service.js +0 -32
- package/dist/lib/daemon/secrets-broker-service.d.ts +0 -21
- package/dist/lib/daemon/secrets-broker-service.js +0 -51
- package/dist/lib/secrets/agent.d.ts +0 -358
- package/dist/lib/secrets/agent.js +0 -1291
- package/dist/lib/secrets/audit.d.ts +0 -46
- package/dist/lib/secrets/audit.js +0 -101
- package/dist/lib/secrets/bundles.d.ts +0 -290
- package/dist/lib/secrets/bundles.js +0 -1547
- package/dist/lib/secrets/download-keychain.d.ts +0 -47
- package/dist/lib/secrets/download-keychain.js +0 -70
- package/dist/lib/secrets/drivers/rush.d.ts +0 -14
- package/dist/lib/secrets/drivers/rush.js +0 -90
- package/dist/lib/secrets/fallback.d.ts +0 -48
- package/dist/lib/secrets/fallback.js +0 -48
- package/dist/lib/secrets/filestore.d.ts +0 -222
- package/dist/lib/secrets/filestore.js +0 -1099
- package/dist/lib/secrets/headless.d.ts +0 -43
- package/dist/lib/secrets/headless.js +0 -56
- package/dist/lib/secrets/icloud-import.d.ts +0 -79
- package/dist/lib/secrets/icloud-import.js +0 -206
- package/dist/lib/secrets/index.d.ts +0 -451
- package/dist/lib/secrets/index.js +0 -1568
- package/dist/lib/secrets/install-helper.d.ts +0 -72
- package/dist/lib/secrets/install-helper.js +0 -245
- package/dist/lib/secrets/lease.d.ts +0 -25
- package/dist/lib/secrets/lease.js +0 -44
- package/dist/lib/secrets/linux.d.ts +0 -77
- package/dist/lib/secrets/linux.js +0 -393
- package/dist/lib/secrets/list-filter.d.ts +0 -109
- package/dist/lib/secrets/list-filter.js +0 -261
- package/dist/lib/secrets/mcp.d.ts +0 -93
- package/dist/lib/secrets/mcp.js +0 -211
- package/dist/lib/secrets/profiles.d.ts +0 -10
- package/dist/lib/secrets/profiles.js +0 -13
- package/dist/lib/secrets/push.d.ts +0 -133
- package/dist/lib/secrets/push.js +0 -273
- package/dist/lib/secrets/rc-hygiene.d.ts +0 -63
- package/dist/lib/secrets/rc-hygiene.js +0 -143
- package/dist/lib/secrets/read-backoff.d.ts +0 -27
- package/dist/lib/secrets/read-backoff.js +0 -64
- package/dist/lib/secrets/reaper.d.ts +0 -90
- package/dist/lib/secrets/reaper.js +0 -243
- package/dist/lib/secrets/remote.d.ts +0 -152
- package/dist/lib/secrets/remote.js +0 -344
- package/dist/lib/secrets/reserved-sync.d.ts +0 -66
- package/dist/lib/secrets/reserved-sync.js +0 -147
- package/dist/lib/secrets/scope.d.ts +0 -26
- package/dist/lib/secrets/scope.js +0 -29
- package/dist/lib/secrets/session-store.d.ts +0 -107
- package/dist/lib/secrets/session-store.js +0 -342
- package/dist/lib/secrets/sync-backend.d.ts +0 -48
- package/dist/lib/secrets/sync-backend.js +0 -13
- package/dist/lib/secrets/sync-commands.d.ts +0 -21
- package/dist/lib/secrets/sync-commands.js +0 -21
- package/dist/lib/secrets/sync.d.ts +0 -48
- package/dist/lib/secrets/sync.js +0 -237
- package/dist/lib/secrets/unlock-hints.d.ts +0 -27
- package/dist/lib/secrets/unlock-hints.js +0 -36
- package/dist/lib/secrets/usage-db.d.ts +0 -46
- package/dist/lib/secrets/usage-db.js +0 -96
- package/dist/lib/secrets/vault-age-helper.d.ts +0 -1
- package/dist/lib/secrets/vault-age-helper.js +0 -34
- package/dist/lib/secrets/vault.d.ts +0 -49
- package/dist/lib/secrets/vault.js +0 -399
- package/dist/lib/secrets/windows.d.ts +0 -81
- package/dist/lib/secrets/windows.js +0 -556
- package/scripts/install-helper.js +0 -97
- /package/dist/lib/{secrets/sync-passphrase.d.ts → sync-passphrase.d.ts} +0 -0
- /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;
|