@phnx-labs/agents-cli 1.22.82 → 1.22.84
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 +47 -0
- package/dist/commands/accounts.js +34 -6
- package/dist/commands/sessions-trace.d.ts +11 -0
- package/dist/commands/sessions-trace.js +71 -0
- package/dist/commands/view.js +3 -6
- package/dist/lib/account-registry.d.ts +40 -3
- package/dist/lib/account-registry.js +89 -18
- package/dist/lib/accounts/connect.d.ts +6 -0
- package/dist/lib/accounts/connect.js +70 -0
- package/dist/lib/claude-statusline.d.ts +13 -5
- package/dist/lib/claude-statusline.js +19 -6
- package/dist/lib/daemon-ticks.js +23 -2
- package/dist/lib/devices/fleet-inventory.js +3 -4
- package/dist/lib/devices/harness-inventory.js +4 -5
- 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 +103 -13
- package/dist/lib/feed/watch.d.ts +9 -3
- package/dist/lib/feed/watch.js +72 -36
- package/dist/lib/fleet-shared-state.d.ts +6 -0
- 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 +47 -2
- package/dist/lib/session/db.js +131 -4
- 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/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/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/package.json +1 -1
|
@@ -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
|
|
@@ -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;
|
|
@@ -20,6 +20,13 @@ export interface SummarizeProgress {
|
|
|
20
20
|
plan?: string;
|
|
21
21
|
/** Coarse lifecycle phase (running / waiting / idle / …), when known. */
|
|
22
22
|
phase?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The agent's own narration headlines, oldest first — the last K steps the
|
|
25
|
+
* daemon's timeline fold produced (PHNX-3939). Optional: many sessions never
|
|
26
|
+
* write a checklist, so this is often the only evidence of progress the model
|
|
27
|
+
* gets, but a row with no folded timeline simply passes none.
|
|
28
|
+
*/
|
|
29
|
+
steps?: string[];
|
|
23
30
|
}
|
|
24
31
|
/** The validated model output. `at` timestamps are stamped by the caller. */
|
|
25
32
|
export interface SummarizeResult {
|
|
@@ -32,6 +32,9 @@ export function buildSummarizeUserMessage(prompt, progress) {
|
|
|
32
32
|
}
|
|
33
33
|
if (progress.plan)
|
|
34
34
|
parts.push(`PLAN:\n${progress.plan.trim().slice(0, 4000)}`);
|
|
35
|
+
if (progress.steps?.length) {
|
|
36
|
+
parts.push(`WHAT THE AGENT SAID IT WAS DOING (oldest first):\n${progress.steps.map((step) => `- ${step}`).join('\n')}`);
|
|
37
|
+
}
|
|
35
38
|
return parts.join('\n\n');
|
|
36
39
|
}
|
|
37
40
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.84",
|
|
4
4
|
"description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|