@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.
- 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/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/sessions-trace.d.ts +11 -0
- package/dist/commands/sessions-trace.js +71 -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 +32 -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 +28 -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-ticks.js +23 -2
- 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/feed/activity-stream.d.ts +60 -0
- package/dist/lib/feed/activity-stream.js +271 -0
- package/dist/lib/feed/activity.d.ts +7 -0
- package/dist/lib/feed/activity.js +10 -4
- package/dist/lib/feed/watch.d.ts +9 -3
- package/dist/lib/feed/watch.js +72 -36
- 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/fleet-shared-state.d.ts +6 -0
- 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 +15 -0
- package/dist/lib/installations/shims.js +69 -0
- 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 +191 -0
- package/dist/lib/secrets-client.js +710 -0
- package/dist/lib/secrets-policy.d.ts +222 -0
- package/dist/lib/secrets-policy.js +483 -0
- package/dist/lib/secrets-types.d.ts +188 -0
- package/dist/lib/secrets-types.js +24 -0
- package/dist/lib/service-manifest.js +3 -4
- package/dist/lib/session/active.d.ts +38 -4
- package/dist/lib/session/active.js +36 -4
- package/dist/lib/session/bash-command.js +10 -0
- package/dist/lib/session/db.d.ts +65 -2
- package/dist/lib/session/db.js +178 -18
- package/dist/lib/session/mirror.d.ts +5 -0
- package/dist/lib/session/mirror.js +166 -0
- package/dist/lib/session/parse.d.ts +49 -0
- package/dist/lib/session/parse.js +324 -30
- package/dist/lib/session/prompt.d.ts +93 -2
- package/dist/lib/session/prompt.js +266 -15
- package/dist/lib/session/remote/peer-stream.d.ts +47 -0
- package/dist/lib/session/remote/peer-stream.js +142 -0
- package/dist/lib/session/remote/watch.d.ts +1 -1
- package/dist/lib/session/remote/watch.js +41 -42
- package/dist/lib/session/session-cache.d.ts +9 -0
- package/dist/lib/session/session-cache.js +40 -2
- package/dist/lib/session/sync/config.js +2 -2
- package/dist/lib/session/timeline-pass.d.ts +129 -0
- package/dist/lib/session/timeline-pass.js +323 -0
- package/dist/lib/session/timeline.d.ts +182 -0
- package/dist/lib/session/timeline.js +636 -0
- package/dist/lib/session/types.d.ts +155 -1
- 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/summarizer/pass.d.ts +2 -0
- package/dist/lib/summarizer/pass.js +14 -1
- package/dist/lib/summarizer/summarize.d.ts +7 -0
- package/dist/lib/summarizer/summarize.js +3 -0
- 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 +4 -29
- 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 -170
- package/dist/lib/accounts/connect.js +0 -383
- 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
|
@@ -43,7 +43,13 @@ export declare function sessionDisplayAgent(session: {
|
|
|
43
43
|
}): string;
|
|
44
44
|
/** A single normalized event within a session (message, tool call, thinking, etc.). */
|
|
45
45
|
export interface SessionEvent {
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* `file_change` is the harness's own file ledger (Claude `file-history-delta`,
|
|
48
|
+
* Codex `FileChange`, OpenCode `patch`) rather than a tool call. It is emitted
|
|
49
|
+
* only on request (`includeFileHistory`) or by the Codex item reader, never in
|
|
50
|
+
* the default published stream — see `ParseSessionOptions.includeFileHistory`.
|
|
51
|
+
*/
|
|
52
|
+
type: 'message' | 'tool_use' | 'tool_result' | 'thinking' | 'error' | 'init' | 'result' | 'usage' | 'attachment' | 'hook' | 'interrupt' | 'file_change';
|
|
47
53
|
agent: SessionAgentId;
|
|
48
54
|
timestamp: string;
|
|
49
55
|
role?: 'user' | 'assistant';
|
|
@@ -57,6 +63,13 @@ export interface SessionEvent {
|
|
|
57
63
|
success?: boolean;
|
|
58
64
|
/** Structured harness outcome; never inferred from free-text output. */
|
|
59
65
|
outcome?: 'ok' | 'error' | 'unknown';
|
|
66
|
+
/**
|
|
67
|
+
* The call never RAN: a permission rule or hook denied it (Claude
|
|
68
|
+
* `toolDenialKind`), or the turn was aborted. Distinct from a failure — a
|
|
69
|
+
* blocked call says nothing about whether the work would have succeeded, so
|
|
70
|
+
* the timeline counts the two separately.
|
|
71
|
+
*/
|
|
72
|
+
blocked?: boolean;
|
|
60
73
|
exitCode?: number;
|
|
61
74
|
statusCode?: number;
|
|
62
75
|
errorCode?: string;
|
|
@@ -93,6 +106,35 @@ export interface SessionEvent {
|
|
|
93
106
|
* programmatically, not the user). Undefined for every other event.
|
|
94
107
|
*/
|
|
95
108
|
slashCommand?: string;
|
|
109
|
+
/**
|
|
110
|
+
* The label the HARNESS itself wrote for this call — Claude's Bash
|
|
111
|
+
* `input.description` ("Locate the prior session transcript on disk"), Kimi's
|
|
112
|
+
* `tool.call.description`, OpenCode's `state.title` / `state.input.description`,
|
|
113
|
+
* Codex's `CommandExecution.command`. Human-written, one per call, and exactly
|
|
114
|
+
* what a now-line needs; `summarizeToolUse` renders the mechanical form
|
|
115
|
+
* instead, which is why this is kept separately rather than folded into it.
|
|
116
|
+
*/
|
|
117
|
+
label?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Verb class the HARNESS assigned (Codex `parsed_cmd.type`, a typed tool
|
|
120
|
+
* name). Absent when the harness does not classify its own call — then the
|
|
121
|
+
* consumer derives one from `command`.
|
|
122
|
+
*/
|
|
123
|
+
verbClass?: SessionVerbClass;
|
|
124
|
+
/**
|
|
125
|
+
* Per-path file operations the harness recorded for this call (Codex
|
|
126
|
+
* `FileChange.changes`, OpenCode `patch.files`). The exact edit ledger, as
|
|
127
|
+
* opposed to inferring one from Edit/Write arguments.
|
|
128
|
+
*/
|
|
129
|
+
changes?: Array<{
|
|
130
|
+
path: string;
|
|
131
|
+
op: 'created' | 'modified' | 'deleted';
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Codex tags an `AgentMessage` with the role it played in the turn
|
|
135
|
+
* (`commentary` is the narration between tool calls). Absent elsewhere.
|
|
136
|
+
*/
|
|
137
|
+
phase?: string;
|
|
96
138
|
}
|
|
97
139
|
/** A displayable file attachment discovered in a session transcript. */
|
|
98
140
|
export interface SessionAttachment {
|
|
@@ -148,6 +190,110 @@ export interface SessionChecklistItem {
|
|
|
148
190
|
* left no summary; the row deliberately carries no goal/checkpoints.
|
|
149
191
|
*/
|
|
150
192
|
export type SummaryState = 'pending' | 'ready' | 'skipped';
|
|
193
|
+
/**
|
|
194
|
+
* How a tool call is bucketed on a timeline step (PHNX-3939). Coarse on purpose
|
|
195
|
+
* — a step renders as "6 run · 2 blocked", not as a tool histogram. Taken from
|
|
196
|
+
* the harness when it classifies its own call (Codex `parsed_cmd.type`, a
|
|
197
|
+
* harness tool name) and derived from the command otherwise.
|
|
198
|
+
*/
|
|
199
|
+
export type SessionVerbClass = 'read' | 'edit' | 'run' | 'git' | 'test' | 'browser' | 'agent' | 'other';
|
|
200
|
+
/**
|
|
201
|
+
* One step of the narration-anchored timeline (PHNX-3939): the agent's own
|
|
202
|
+
* short line about what it is doing, plus the tool calls that ran under it.
|
|
203
|
+
*
|
|
204
|
+
* The text is never model-written — it is the harness's own narration (Claude
|
|
205
|
+
* assistant text, Codex `AgentMessage` commentary, Gemini thought subject), a
|
|
206
|
+
* thinking block when there is no narration, the user's tidied turn, or a
|
|
207
|
+
* mix-derived line when tools ran with nothing said. `source` says which.
|
|
208
|
+
*/
|
|
209
|
+
export interface SessionStep {
|
|
210
|
+
/** Headline: the first sentence of the narration, capped. */
|
|
211
|
+
text: string;
|
|
212
|
+
/** ISO time this step opened. */
|
|
213
|
+
at: string;
|
|
214
|
+
/** ISO time of the last event folded into it. */
|
|
215
|
+
endedAt?: string;
|
|
216
|
+
source: 'narration' | 'thinking' | 'derived' | 'user';
|
|
217
|
+
/** Tool calls attached to this step. */
|
|
218
|
+
tools: number;
|
|
219
|
+
/** Calls that RAN and failed (non-zero exit, `is_error`, harness error status). */
|
|
220
|
+
failed: number;
|
|
221
|
+
/** Calls that never ran: a permission rule, a hook denial, an aborted turn. */
|
|
222
|
+
blocked: number;
|
|
223
|
+
/** Per-verb-class tally of the attached calls. */
|
|
224
|
+
mix?: Partial<Record<SessionVerbClass, number>>;
|
|
225
|
+
/** Milestones recognized under this step ("worktree created", "PR opened", "files changed"). */
|
|
226
|
+
marks?: string[];
|
|
227
|
+
/** True on the newest step while the session is working. */
|
|
228
|
+
live?: boolean;
|
|
229
|
+
/** Harness label of the running tool on a live step — the now-line. */
|
|
230
|
+
now?: string;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* The bounded projection of a session's timeline that rides the row (PHNX-3939).
|
|
234
|
+
*
|
|
235
|
+
* `steps` is the tail; everything before it collapses into `earlier` so the
|
|
236
|
+
* payload stays flat as a session grows. `state` is honest about harnesses that
|
|
237
|
+
* cannot supply one: `partial` when an event cap was hit, `unavailable` with a
|
|
238
|
+
* `reason` when the harness writes no parseable transcript (OpenClaw) — never
|
|
239
|
+
* an empty step list presented as "nothing happened".
|
|
240
|
+
*/
|
|
241
|
+
export interface SessionTimeline {
|
|
242
|
+
/** Newest last, at most `keep` (8). */
|
|
243
|
+
steps: SessionStep[];
|
|
244
|
+
earlier: {
|
|
245
|
+
steps: number;
|
|
246
|
+
tools: number;
|
|
247
|
+
failed: number;
|
|
248
|
+
};
|
|
249
|
+
/** Totals across the WHOLE session, not just `steps`. */
|
|
250
|
+
tools: number;
|
|
251
|
+
failed: number;
|
|
252
|
+
blocked: number;
|
|
253
|
+
spanMs: number;
|
|
254
|
+
state: 'ready' | 'partial' | 'unavailable';
|
|
255
|
+
reason?: string;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The session's operative request: the latest genuine user turn, tidied but
|
|
259
|
+
* never rewritten (PHNX-3939). `turns` counts every genuine user turn so a
|
|
260
|
+
* consumer can say "latest of 6"; `continues` names the session a `/continue`
|
|
261
|
+
* picked up.
|
|
262
|
+
*/
|
|
263
|
+
export type SessionRequest = import('./prompt.js').TidyRequest & {
|
|
264
|
+
/**
|
|
265
|
+
* Genuine user turns in the session so far, so a consumer can say "latest of
|
|
266
|
+
* 6". Present only when the daemon's timeline fold counted them; a request
|
|
267
|
+
* tidied inline from the indexed turn alone does not know the count and says
|
|
268
|
+
* nothing rather than claiming 1.
|
|
269
|
+
*/
|
|
270
|
+
turns?: number;
|
|
271
|
+
continues?: {
|
|
272
|
+
id: string;
|
|
273
|
+
label?: string;
|
|
274
|
+
};
|
|
275
|
+
};
|
|
276
|
+
/** One file the session created, modified or deleted. */
|
|
277
|
+
export interface SessionFileChange {
|
|
278
|
+
path: string;
|
|
279
|
+
op: 'created' | 'modified' | 'deleted';
|
|
280
|
+
/** How many times the session touched it. */
|
|
281
|
+
edits: number;
|
|
282
|
+
/** ISO time of the last touch. */
|
|
283
|
+
at: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The files a session changed (PHNX-3939). `source: 'harness'` means the
|
|
287
|
+
* harness recorded the change itself (Codex `FileChange`, OpenCode `patch`,
|
|
288
|
+
* Claude `file-history-delta`); `'tools'` means it was derived from Edit/Write
|
|
289
|
+
* calls because the harness records no file ledger. `changes` is bounded to 8
|
|
290
|
+
* rows; `total` is the real count.
|
|
291
|
+
*/
|
|
292
|
+
export interface SessionFiles {
|
|
293
|
+
changes: SessionFileChange[];
|
|
294
|
+
total: number;
|
|
295
|
+
source: 'harness' | 'tools';
|
|
296
|
+
}
|
|
151
297
|
/** Metadata attached when a session was spawned by `agents teams`. */
|
|
152
298
|
export interface TeamOrigin {
|
|
153
299
|
/** Teammate name if set, otherwise first 8 chars of the agent UUID. */
|
|
@@ -256,6 +402,14 @@ export interface SessionMeta {
|
|
|
256
402
|
topic?: string;
|
|
257
403
|
/** Full, cleaned first genuine user turn; distinct from the one-line topic. */
|
|
258
404
|
firstUserMessage?: string;
|
|
405
|
+
/**
|
|
406
|
+
* Full, cleaned LATEST genuine user turn. For a `/continue`, a redirect, or an
|
|
407
|
+
* interrupted-and-restated session the operative request is the last thing the
|
|
408
|
+
* user said, not the first — which is what the session row and the sidebar's
|
|
409
|
+
* Request card show (PHNX-3939). Equal to {@link firstUserMessage} for a
|
|
410
|
+
* single-turn session; absent for rows indexed before this field shipped.
|
|
411
|
+
*/
|
|
412
|
+
lastUserMessage?: string;
|
|
259
413
|
/**
|
|
260
414
|
* The session's human-readable name — one field, several sources with a plain
|
|
261
415
|
* priority: an agent-generated title / Claude `/rename` wins; else the launch
|
|
@@ -3,22 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* These live in their own LEAF module — importing only `node:crypto` and
|
|
5
5
|
* `node:fs` — on purpose. They used to sit in `computer/ssh-tunnel.ts`, whose
|
|
6
|
-
* own import graph
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* which threw `ReferenceError: Cannot access 'EXPECTED_TEAM_ID' before
|
|
19
|
-
* initialization` at `secrets/download-keychain.ts:45` for any entry point that
|
|
20
|
-
* reached `helper-download.ts` first (RUSH-3113). Keep this module a leaf: adding
|
|
21
|
-
* a local import here can reintroduce that cycle.
|
|
6
|
+
* own import graph reached `browser/drivers/ssh.ts` -> `browser/chrome.ts` ->
|
|
7
|
+
* the in-repo secrets engine's own keychain-helper downloader, which imported
|
|
8
|
+
* back into `helper-download.ts` while it was still evaluating — before
|
|
9
|
+
* `EXPECTED_TEAM_ID` was bound, throwing `ReferenceError: Cannot access
|
|
10
|
+
* 'EXPECTED_TEAM_ID' before initialization` for any entry point that reached
|
|
11
|
+
* `helper-download.ts` first (RUSH-3113). The secrets engine that closed that
|
|
12
|
+
* cycle is gone now (PHNX-3989 — the standalone `secrets` CLI downloads its own
|
|
13
|
+
* helper), but the discipline that fixed it still holds: keep this module a
|
|
14
|
+
* leaf, since `helper-download.ts` needs nothing beyond these two pure
|
|
15
|
+
* functions and adding a local import here can reintroduce a cycle with
|
|
16
|
+
* whatever imports it next.
|
|
22
17
|
*/
|
|
23
18
|
/** Pull the digest out of a `<sha256> <filename>` release asset. */
|
|
24
19
|
export declare function parseSha256Asset(text: string): string;
|
package/dist/lib/sha256-asset.js
CHANGED
|
@@ -3,22 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* These live in their own LEAF module — importing only `node:crypto` and
|
|
5
5
|
* `node:fs` — on purpose. They used to sit in `computer/ssh-tunnel.ts`, whose
|
|
6
|
-
* own import graph
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* which threw `ReferenceError: Cannot access 'EXPECTED_TEAM_ID' before
|
|
19
|
-
* initialization` at `secrets/download-keychain.ts:45` for any entry point that
|
|
20
|
-
* reached `helper-download.ts` first (RUSH-3113). Keep this module a leaf: adding
|
|
21
|
-
* a local import here can reintroduce that cycle.
|
|
6
|
+
* own import graph reached `browser/drivers/ssh.ts` -> `browser/chrome.ts` ->
|
|
7
|
+
* the in-repo secrets engine's own keychain-helper downloader, which imported
|
|
8
|
+
* back into `helper-download.ts` while it was still evaluating — before
|
|
9
|
+
* `EXPECTED_TEAM_ID` was bound, throwing `ReferenceError: Cannot access
|
|
10
|
+
* 'EXPECTED_TEAM_ID' before initialization` for any entry point that reached
|
|
11
|
+
* `helper-download.ts` first (RUSH-3113). The secrets engine that closed that
|
|
12
|
+
* cycle is gone now (PHNX-3989 — the standalone `secrets` CLI downloads its own
|
|
13
|
+
* helper), but the discipline that fixed it still holds: keep this module a
|
|
14
|
+
* leaf, since `helper-download.ts` needs nothing beyond these two pure
|
|
15
|
+
* functions and adding a local import here can reintroduce a cycle with
|
|
16
|
+
* whatever imports it next.
|
|
22
17
|
*/
|
|
23
18
|
import { createHash } from 'node:crypto';
|
|
24
19
|
import * as fs from 'node:fs';
|
package/dist/lib/share/config.js
CHANGED
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
// `cloudflare` bundle.
|
|
10
10
|
import { randomBytes } from 'node:crypto';
|
|
11
11
|
import { readMeta, updateMeta } from '../state.js';
|
|
12
|
-
import {
|
|
13
|
-
import { secretsKeychainItem } from '../secrets/index.js';
|
|
12
|
+
import { bundleExistsSync as bundleExists, keychainRef, readAndResolveBundleEnvSync as readAndResolveBundleEnv, readBundleSync as readBundle, secretsKeychainItem, writeBundleWithItemsSync as writeBundleWithItems, } from '../secrets-client.js';
|
|
14
13
|
export const SHARE_BUNDLE = 'share';
|
|
15
14
|
export const SHARE_TOKEN_KEY = 'WRITE_TOKEN';
|
|
16
15
|
export const SHARE_TOKEN_ENV_KEY = 'SHARE_WRITE_TOKEN';
|
|
@@ -113,10 +112,12 @@ export function storeWriteToken(token) {
|
|
|
113
112
|
vars: {},
|
|
114
113
|
};
|
|
115
114
|
}
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
// writeBundleWithItems decides the ACL (keychain backend) purely from
|
|
116
|
+
// `bundle.policy === 'never'` — the fresh-bundle case above sets it
|
|
117
|
+
// explicitly, and an existing bundle already carries its own explicit tier.
|
|
118
118
|
bundle.vars[SHARE_TOKEN_KEY] = keychainRef(SHARE_TOKEN_KEY);
|
|
119
|
-
|
|
119
|
+
const item = secretsKeychainItem(bundle.name, SHARE_TOKEN_KEY);
|
|
120
|
+
writeBundleWithItems(bundle, new Map([[item, token]]));
|
|
120
121
|
}
|
|
121
122
|
/** Read the raw write token from the `share` secrets bundle. */
|
|
122
123
|
export function readWriteTokenFromBundle() {
|
|
@@ -178,6 +179,14 @@ export function readCloudflareCreds(bundle = DEFAULT_CF_BUNDLE, override) {
|
|
|
178
179
|
if (override?.apiToken) {
|
|
179
180
|
return { apiToken: override.apiToken, accountId: override.accountId ?? '' };
|
|
180
181
|
}
|
|
182
|
+
// Check existence first (same guard as readShareToken above): resolving a
|
|
183
|
+
// missing bundle through the process client surfaces an opaque transport code
|
|
184
|
+
// (e.g. LOCKED), never naming the bundle the user typed — so name it here.
|
|
185
|
+
if (!bundleExists(bundle)) {
|
|
186
|
+
throw new Error(`The '${bundle}' bundle does not exist. ` +
|
|
187
|
+
`Pass credentials directly with --token <t> [--account <id>], or create it: ` +
|
|
188
|
+
`agents secrets add ${bundle} CLOUDFLARE_API_TOKEN`);
|
|
189
|
+
}
|
|
181
190
|
const { env } = readAndResolveBundleEnv(bundle, {
|
|
182
191
|
caller: 'share',
|
|
183
192
|
// Setup is still a read; only `agents secrets unlock` may authenticate.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { AccountInfo } from './agents.js';
|
|
2
|
+
import type { AuthVerdict } from './auth-health.js';
|
|
2
3
|
import type { AgentId } from './types.js';
|
|
4
|
+
export type AccountVerdict = Exclude<AuthVerdict, 'unconfigured' | 'error'> | 'missing' | 'per-device' | 'ready';
|
|
5
|
+
export type AccountProvisioning = 'portable' | 'per-device';
|
|
3
6
|
/**
|
|
4
7
|
* The exact command that logs a given agent in — for warn banners and nudges.
|
|
5
8
|
* Driven off the registry `cliCommand` with the per-agent subcommand overrides
|
|
@@ -8,6 +11,29 @@ import type { AgentId } from './types.js';
|
|
|
8
11
|
* remaining agents (kimi, gemini, …) start their device/oauth flow on launch.
|
|
9
12
|
*/
|
|
10
13
|
export declare function loginHint(agentId: AgentId): string;
|
|
14
|
+
/**
|
|
15
|
+
* Exact action shown beside a non-live account. Every emitted command exists
|
|
16
|
+
* today — never a planned surface and never a hidden verb:
|
|
17
|
+
* - Per-device harnesses repair per box via `agents devices login`.
|
|
18
|
+
* - Named accounts re-auth through `agents accounts login <harness>#<name>`.
|
|
19
|
+
* A known account with no slot on a headed device is onboarded with
|
|
20
|
+
* `agents accounts add <harness> <name>`. A worker never runs an
|
|
21
|
+
* interactive login — the hint is `add.ts`'s worker refusal (add on the
|
|
22
|
+
* personal device; this box is provisioned from the durable credential).
|
|
23
|
+
* - Unnamed legacy homes use the same version-targeted command shape as
|
|
24
|
+
* doctor, so the hint never logs a different/default home in by accident.
|
|
25
|
+
* - `unverified` emits nothing: the probe could not confirm state (e.g. a
|
|
26
|
+
* worker whose token lacks the usage scope), so there is nothing to repair.
|
|
27
|
+
*/
|
|
28
|
+
export declare function fixFor(input: {
|
|
29
|
+
agent: AgentId;
|
|
30
|
+
verdict: AccountVerdict;
|
|
31
|
+
name?: string | null;
|
|
32
|
+
version?: string | null;
|
|
33
|
+
provisioning?: AccountProvisioning;
|
|
34
|
+
/** When false, this named account has no slot on this device yet. */
|
|
35
|
+
hasSlot?: boolean;
|
|
36
|
+
}): string | null;
|
|
11
37
|
/**
|
|
12
38
|
* Whether `agents run` should probe login state before launching. True only for
|
|
13
39
|
* a launch that actually opens the interactive TUI — where discovering a logged-out
|
package/dist/lib/signin-badge.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* on it (the run preflight) WARN and continue; they never block.
|
|
10
10
|
*/
|
|
11
11
|
import chalk from 'chalk';
|
|
12
|
+
import { addWorkerRefusal } from './accounts/add.js';
|
|
12
13
|
import { AGENTS } from './agents.js';
|
|
14
|
+
import { CONFIG_ENV_ISOLATED_AGENTS } from './installations/shims.js';
|
|
13
15
|
/**
|
|
14
16
|
* The exact command that logs a given agent in — for warn banners and nudges.
|
|
15
17
|
* Driven off the registry `cliCommand` with the per-agent subcommand overrides
|
|
@@ -34,6 +36,46 @@ export function loginHint(agentId) {
|
|
|
34
36
|
return cli;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Exact action shown beside a non-live account. Every emitted command exists
|
|
41
|
+
* today — never a planned surface and never a hidden verb:
|
|
42
|
+
* - Per-device harnesses repair per box via `agents devices login`.
|
|
43
|
+
* - Named accounts re-auth through `agents accounts login <harness>#<name>`.
|
|
44
|
+
* A known account with no slot on a headed device is onboarded with
|
|
45
|
+
* `agents accounts add <harness> <name>`. A worker never runs an
|
|
46
|
+
* interactive login — the hint is `add.ts`'s worker refusal (add on the
|
|
47
|
+
* personal device; this box is provisioned from the durable credential).
|
|
48
|
+
* - Unnamed legacy homes use the same version-targeted command shape as
|
|
49
|
+
* doctor, so the hint never logs a different/default home in by accident.
|
|
50
|
+
* - `unverified` emits nothing: the probe could not confirm state (e.g. a
|
|
51
|
+
* worker whose token lacks the usage scope), so there is nothing to repair.
|
|
52
|
+
*/
|
|
53
|
+
export function fixFor(input) {
|
|
54
|
+
const { agent, verdict } = input;
|
|
55
|
+
if (verdict === 'live' || verdict === 'rate_limited' || verdict === 'unverified' || verdict === 'ready')
|
|
56
|
+
return null;
|
|
57
|
+
if (input.provisioning === 'per-device' || verdict === 'per-device') {
|
|
58
|
+
return `agents devices login --agents ${agent}`;
|
|
59
|
+
}
|
|
60
|
+
if (input.name) {
|
|
61
|
+
const worker = addWorkerRefusal(agent, input.name);
|
|
62
|
+
if (worker)
|
|
63
|
+
return worker;
|
|
64
|
+
if (input.hasSlot === false)
|
|
65
|
+
return `agents accounts add ${agent} ${input.name}`;
|
|
66
|
+
return `agents accounts login ${agent}#${input.name}`;
|
|
67
|
+
}
|
|
68
|
+
const version = input.version ?? null;
|
|
69
|
+
if (!version || !CONFIG_ENV_ISOLATED_AGENTS.includes(agent))
|
|
70
|
+
return loginHint(agent);
|
|
71
|
+
if (agent === 'claude')
|
|
72
|
+
return `agents run ${agent}@${version}, then /login`;
|
|
73
|
+
if (agent === 'codex' || agent === 'grok')
|
|
74
|
+
return `agents run ${agent}@${version} -- login`;
|
|
75
|
+
if (agent === 'opencode')
|
|
76
|
+
return `agents run ${agent}@${version} -- auth login`;
|
|
77
|
+
return `agents run ${agent}@${version}`;
|
|
78
|
+
}
|
|
37
79
|
/**
|
|
38
80
|
* Whether `agents run` should probe login state before launching. True only for
|
|
39
81
|
* a launch that actually opens the interactive TUI — where discovering a logged-out
|
|
@@ -1,115 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflows detector — scans the agent-specific on-disk layout for synced
|
|
3
|
-
* workflow names (Claude WORKFLOW.md trees, Kimi flow skills, Antigravity
|
|
4
|
-
* global_workflows, Goose recipes, OpenClaw Lobster, Grok Rhai).
|
|
5
|
-
*/
|
|
6
|
-
import * as fs from 'fs';
|
|
7
|
-
import * as os from 'os';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import * as yaml from 'yaml';
|
|
10
1
|
import { capableAgents } from '../../capabilities.js';
|
|
11
|
-
import {
|
|
2
|
+
import { workflowTarget } from '../../workflows-registry.js';
|
|
12
3
|
import { lazyAgentMap } from '../writers/lazy-map.js';
|
|
13
4
|
function buildWorkflowsDetector(agent) {
|
|
14
5
|
return {
|
|
15
6
|
kind: 'workflows',
|
|
16
7
|
agent,
|
|
17
8
|
list({ versionHome }) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!fs.existsSync(skillsDir))
|
|
21
|
-
return [];
|
|
22
|
-
return fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
23
|
-
.filter(d => d.isDirectory() && fs.existsSync(path.join(skillsDir, d.name, 'SKILL.md')))
|
|
24
|
-
.filter(d => {
|
|
25
|
-
try {
|
|
26
|
-
const skill = fs.readFileSync(path.join(skillsDir, d.name, 'SKILL.md'), 'utf-8');
|
|
27
|
-
const lines = skill.split('\n');
|
|
28
|
-
if (lines[0] !== '---')
|
|
29
|
-
return false;
|
|
30
|
-
const endIndex = lines.slice(1).findIndex(l => l === '---');
|
|
31
|
-
if (endIndex < 0)
|
|
32
|
-
return false;
|
|
33
|
-
const parsed = yaml.parse(lines.slice(1, endIndex + 1).join('\n'));
|
|
34
|
-
return parsed?.type === 'flow' && parsed.agents_workflow === d.name;
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
.map(d => d.name);
|
|
41
|
-
}
|
|
42
|
-
if (agent === 'antigravity') {
|
|
43
|
-
// Antigravity user workflows are HOME-global and shared across versions,
|
|
44
|
-
// not version-isolated — see workflows.ts:antigravityWorkflowsDir(). agy
|
|
45
|
-
// scans the real ~/.gemini/config/global_workflows/, so the detector reads
|
|
46
|
-
// the same shared dir the writer targets (versionHome is intentionally unused).
|
|
47
|
-
const dir = path.join(process.env.HOME ?? os.homedir(), '.gemini', 'config', 'global_workflows');
|
|
48
|
-
if (!fs.existsSync(dir))
|
|
49
|
-
return [];
|
|
50
|
-
return fs.readdirSync(dir, { withFileTypes: true })
|
|
51
|
-
.filter(d => d.isFile() && d.name.endsWith('.md') && !d.name.startsWith('.'))
|
|
52
|
-
.filter(d => {
|
|
53
|
-
try {
|
|
54
|
-
const content = fs.readFileSync(path.join(dir, d.name), 'utf-8');
|
|
55
|
-
const lines = content.split('\n');
|
|
56
|
-
if (lines[0] !== '---')
|
|
57
|
-
return false;
|
|
58
|
-
const endIndex = lines.slice(1).findIndex(l => l === '---');
|
|
59
|
-
if (endIndex < 0)
|
|
60
|
-
return false;
|
|
61
|
-
const parsed = yaml.parse(lines.slice(1, endIndex + 1).join('\n'));
|
|
62
|
-
return parsed?.agents_workflow === d.name.slice(0, -'.md'.length);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
})
|
|
68
|
-
.map(d => d.name.slice(0, -'.md'.length));
|
|
69
|
-
}
|
|
70
|
-
if (agent === 'goose') {
|
|
71
|
-
const recipesDir = path.join(versionHome, '.config', 'goose', 'recipes');
|
|
72
|
-
if (!fs.existsSync(recipesDir))
|
|
73
|
-
return [];
|
|
74
|
-
return fs.readdirSync(recipesDir, { withFileTypes: true })
|
|
75
|
-
.filter(d => d.isFile() && d.name.endsWith('.yaml') && !d.name.startsWith('.'))
|
|
76
|
-
.map(d => d.name.slice(0, -'.yaml'.length));
|
|
77
|
-
}
|
|
78
|
-
if (agent === 'openclaw') {
|
|
79
|
-
const dir = path.join(versionHome, '.openclaw', 'workflows');
|
|
80
|
-
if (!fs.existsSync(dir))
|
|
81
|
-
return [];
|
|
82
|
-
return fs.readdirSync(dir, { withFileTypes: true })
|
|
83
|
-
.filter(d => d.isFile() && d.name.endsWith('.lobster') && !d.name.startsWith('.'))
|
|
84
|
-
.filter(d => {
|
|
85
|
-
try {
|
|
86
|
-
const parsed = yaml.parse(fs.readFileSync(path.join(dir, d.name), 'utf-8'));
|
|
87
|
-
const env = parsed && typeof parsed === 'object' && parsed.env && typeof parsed.env === 'object' && !Array.isArray(parsed.env)
|
|
88
|
-
? parsed.env
|
|
89
|
-
: {};
|
|
90
|
-
return env.AGENTS_CLI_WORKFLOW === d.name.slice(0, -'.lobster'.length);
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
.map(d => d.name.slice(0, -'.lobster'.length));
|
|
97
|
-
}
|
|
98
|
-
if (agent === 'grok') {
|
|
99
|
-
const workflowsDir = path.join(versionHome, '.grok', 'workflows');
|
|
100
|
-
if (!fs.existsSync(workflowsDir))
|
|
101
|
-
return [];
|
|
102
|
-
return fs.readdirSync(workflowsDir, { withFileTypes: true })
|
|
103
|
-
.filter(d => d.isFile() && d.name.endsWith('.rhai') && !d.name.startsWith('.'))
|
|
104
|
-
.filter(d => grokWorkflowMarker(path.join(workflowsDir, d.name)) === d.name.slice(0, -'.rhai'.length))
|
|
105
|
-
.map(d => d.name.slice(0, -'.rhai'.length));
|
|
106
|
-
}
|
|
107
|
-
const workflowsDir = path.join(versionHome, 'workflows');
|
|
108
|
-
if (!fs.existsSync(workflowsDir))
|
|
109
|
-
return [];
|
|
110
|
-
return fs.readdirSync(workflowsDir, { withFileTypes: true })
|
|
111
|
-
.filter(d => d.isDirectory() && fs.existsSync(path.join(workflowsDir, d.name, 'WORKFLOW.md')))
|
|
112
|
-
.map(d => d.name);
|
|
9
|
+
const target = workflowTarget(agent);
|
|
10
|
+
return target.names(target.dir(versionHome));
|
|
113
11
|
},
|
|
114
12
|
};
|
|
115
13
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { capableAgents } from '../../capabilities.js';
|
|
2
|
-
import { listInstalledWorkflows
|
|
2
|
+
import { listInstalledWorkflows } from '../../workflows.js';
|
|
3
|
+
import { syncWorkflowToVersion } from '../../workflows-registry.js';
|
|
3
4
|
import { lazyAgentMap } from './lazy-map.js';
|
|
4
5
|
function buildWorkflowsWriter(agent) {
|
|
5
6
|
return {
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -123,10 +123,13 @@ export declare function getUserSecretsDir(): string;
|
|
|
123
123
|
* AGENTS_SECRETS_DB without racing the module-load capture of USER_SECRETS_DIR —
|
|
124
124
|
* mirrors the AGENTS_EVENTS_PATH / AGENTS_DEVICES_DIR escape hatches. Holds only
|
|
125
125
|
* value-free usage telemetry (which bundle was created/imported/exported/viewed/
|
|
126
|
-
* accessed/unlocked, when, by whom), never a secret value. It
|
|
127
|
-
* fed FROM the
|
|
128
|
-
*
|
|
129
|
-
* metadata off the real session flow
|
|
126
|
+
* accessed/unlocked, when, by whom), never a secret value. It used to be a
|
|
127
|
+
* derived index fed FROM the in-repo secrets engine's own emitSecretAudit
|
|
128
|
+
* chokepoint — not a second write path — the same way sessions.db indexes
|
|
129
|
+
* session metadata off the real session flow. That engine (and its audit
|
|
130
|
+
* emission) moved out of this repo entirely with the standalone `secrets`
|
|
131
|
+
* engine (PHNX-3989), so nothing writes this DB from agents-cli today; the
|
|
132
|
+
* read-side queries in `analytics/usage-db.ts` have no current caller.
|
|
130
133
|
*/
|
|
131
134
|
export declare function getSecretsDbPath(): string;
|
|
132
135
|
/**
|
package/dist/lib/state.js
CHANGED
|
@@ -396,10 +396,13 @@ export function getUserSecretsDir() { return USER_SECRETS_DIR; }
|
|
|
396
396
|
* AGENTS_SECRETS_DB without racing the module-load capture of USER_SECRETS_DIR —
|
|
397
397
|
* mirrors the AGENTS_EVENTS_PATH / AGENTS_DEVICES_DIR escape hatches. Holds only
|
|
398
398
|
* value-free usage telemetry (which bundle was created/imported/exported/viewed/
|
|
399
|
-
* accessed/unlocked, when, by whom), never a secret value. It
|
|
400
|
-
* fed FROM the
|
|
401
|
-
*
|
|
402
|
-
* metadata off the real session flow
|
|
399
|
+
* accessed/unlocked, when, by whom), never a secret value. It used to be a
|
|
400
|
+
* derived index fed FROM the in-repo secrets engine's own emitSecretAudit
|
|
401
|
+
* chokepoint — not a second write path — the same way sessions.db indexes
|
|
402
|
+
* session metadata off the real session flow. That engine (and its audit
|
|
403
|
+
* emission) moved out of this repo entirely with the standalone `secrets`
|
|
404
|
+
* engine (PHNX-3989), so nothing writes this DB from agents-cli today; the
|
|
405
|
+
* read-side queries in `analytics/usage-db.ts` have no current caller.
|
|
403
406
|
*/
|
|
404
407
|
export function getSecretsDbPath() {
|
|
405
408
|
return process.env.AGENTS_SECRETS_DB ?? path.join(USER_SECRETS_DIR, 'secrets.db');
|
|
@@ -1332,7 +1335,9 @@ export function writeMetaUnlocked(meta) {
|
|
|
1332
1335
|
// In-flight connect attempts (PHNX-3940), device-scoped like homes.
|
|
1333
1336
|
const accountsPending = deviceAccounts?.pendingConnects && Object.keys(deviceAccounts.pendingConnects).length > 0
|
|
1334
1337
|
? deviceAccounts.pendingConnects : undefined;
|
|
1335
|
-
|
|
1338
|
+
const accountsSlots = deviceAccounts?.slots && Object.keys(deviceAccounts.slots).length > 0
|
|
1339
|
+
? deviceAccounts.slots : undefined;
|
|
1340
|
+
if (accountsNative || accountsBindings || accountsHomes || accountsPending || accountsSlots) {
|
|
1336
1341
|
const da = {};
|
|
1337
1342
|
if (accountsNative)
|
|
1338
1343
|
da.native = accountsNative;
|
|
@@ -1342,6 +1347,8 @@ export function writeMetaUnlocked(meta) {
|
|
|
1342
1347
|
da.homes = accountsHomes;
|
|
1343
1348
|
if (accountsPending)
|
|
1344
1349
|
da.pendingConnects = accountsPending;
|
|
1350
|
+
if (accountsSlots)
|
|
1351
|
+
da.slots = accountsSlots;
|
|
1345
1352
|
doc.accounts = da;
|
|
1346
1353
|
}
|
|
1347
1354
|
else if (writesDeviceAccounts)
|
|
@@ -1487,12 +1494,16 @@ function overlayMachineLocal(meta) {
|
|
|
1487
1494
|
if (acc.pendingConnects !== undefined && !isMap(acc.pendingConnects)) {
|
|
1488
1495
|
throw new Error(`Device config corrupted at ${devicePath}: accounts.pendingConnects must be a map.`);
|
|
1489
1496
|
}
|
|
1497
|
+
if (acc.slots !== undefined && !isMap(acc.slots)) {
|
|
1498
|
+
throw new Error(`Device config corrupted at ${devicePath}: accounts.slots must be a map.`);
|
|
1499
|
+
}
|
|
1490
1500
|
const native = acc.native;
|
|
1491
1501
|
const bindings = acc.bindings;
|
|
1492
1502
|
const homes = acc.homes;
|
|
1493
1503
|
const pendingConnects = acc.pendingConnects;
|
|
1494
|
-
|
|
1495
|
-
|
|
1504
|
+
const slots = acc.slots;
|
|
1505
|
+
if (native || bindings || homes || pendingConnects || slots)
|
|
1506
|
+
meta.deviceAccounts = { ...(native ? { native } : {}), ...(bindings ? { bindings } : {}), ...(homes ? { homes } : {}), ...(pendingConnects ? { pendingConnects } : {}), ...(slots ? { slots } : {}) };
|
|
1496
1507
|
}
|
|
1497
1508
|
if (Object.prototype.hasOwnProperty.call(dm, 'routines')) {
|
|
1498
1509
|
if (!Array.isArray(dm.routines) || dm.routines.some((name) => typeof name !== 'string')) {
|
|
@@ -15,6 +15,8 @@ import { type SummarizerConfig } from './config.js';
|
|
|
15
15
|
import { summarize as defaultSummarize } from './summarize.js';
|
|
16
16
|
/** Max sessions summarized per tick — a debounce ceiling on local-model calls. */
|
|
17
17
|
export declare const SUMMARIZER_MAX_PER_TICK = 8;
|
|
18
|
+
/** Narration headlines handed to the model per session — the recent tail, not the history. */
|
|
19
|
+
export declare const SUMMARIZER_STEP_INPUT = 12;
|
|
18
20
|
export interface SummarizerPassOptions {
|
|
19
21
|
now?: number;
|
|
20
22
|
config?: SummarizerConfig;
|
|
@@ -17,6 +17,8 @@ import { resolveSummarizerConfig, isSummarizerRunnable } from './config.js';
|
|
|
17
17
|
import { summarize as defaultSummarize } from './summarize.js';
|
|
18
18
|
/** Max sessions summarized per tick — a debounce ceiling on local-model calls. */
|
|
19
19
|
export const SUMMARIZER_MAX_PER_TICK = 8;
|
|
20
|
+
/** Narration headlines handed to the model per session — the recent tail, not the history. */
|
|
21
|
+
export const SUMMARIZER_STEP_INPUT = 12;
|
|
20
22
|
/**
|
|
21
23
|
* Merge model checkpoint TEXTS with any prior stored checkpoints so a line that
|
|
22
24
|
* already existed keeps its original `at`, and only genuinely new lines get
|
|
@@ -87,7 +89,18 @@ export async function runSummarizerPass(opts = {}) {
|
|
|
87
89
|
}
|
|
88
90
|
let computed;
|
|
89
91
|
try {
|
|
90
|
-
computed = await runSummarize(prompt, {
|
|
92
|
+
computed = await runSummarize(prompt, {
|
|
93
|
+
todos: s.todos,
|
|
94
|
+
plan: s.plan,
|
|
95
|
+
phase: s.phase,
|
|
96
|
+
// The agent's own narration headlines, when the timeline pass has
|
|
97
|
+
// folded them (PHNX-3939) — the model's progress input was previously
|
|
98
|
+
// only the checklist, which many sessions never write. Optional by
|
|
99
|
+
// construction: a row with no timeline passes nothing extra.
|
|
100
|
+
...(s.timeline?.steps.length
|
|
101
|
+
? { steps: s.timeline.steps.slice(-SUMMARIZER_STEP_INPUT).map((step) => step.text) }
|
|
102
|
+
: {}),
|
|
103
|
+
}, { baseUrl: config.baseUrl, model: config.model, ...(opts.signal ? { signal: opts.signal } : {}) });
|
|
91
104
|
}
|
|
92
105
|
catch {
|
|
93
106
|
computed = undefined;
|