ai-obs-cli 0.0.0-stage → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +666 -2
- package/bin/ai-obs.js +8 -0
- package/dist/adapters/claude-code/analyze.js +189 -0
- package/dist/adapters/claude-code/analyze.js.map +1 -0
- package/dist/adapters/claude-code/detect.js +60 -0
- package/dist/adapters/claude-code/detect.js.map +1 -0
- package/dist/adapters/claude-code/handlers.js +183 -0
- package/dist/adapters/claude-code/handlers.js.map +1 -0
- package/dist/adapters/claude-code/index.js +55 -0
- package/dist/adapters/claude-code/index.js.map +1 -0
- package/dist/adapters/claude-code/run-links.js +53 -0
- package/dist/adapters/claude-code/run-links.js.map +1 -0
- package/dist/adapters/claude-code/session.js +427 -0
- package/dist/adapters/claude-code/session.js.map +1 -0
- package/dist/adapters/claude-code/settings.js +161 -0
- package/dist/adapters/claude-code/settings.js.map +1 -0
- package/dist/adapters/claude-code/state.js +66 -0
- package/dist/adapters/claude-code/state.js.map +1 -0
- package/dist/adapters/claude-code/subagents.js +246 -0
- package/dist/adapters/claude-code/subagents.js.map +1 -0
- package/dist/adapters/claude-code/transcript.js +309 -0
- package/dist/adapters/claude-code/transcript.js.map +1 -0
- package/dist/adapters/codex/accumulator.js +135 -0
- package/dist/adapters/codex/accumulator.js.map +1 -0
- package/dist/adapters/codex/detect.js +93 -0
- package/dist/adapters/codex/detect.js.map +1 -0
- package/dist/adapters/codex/hooks-config.js +158 -0
- package/dist/adapters/codex/hooks-config.js.map +1 -0
- package/dist/adapters/codex/index.js +270 -0
- package/dist/adapters/codex/index.js.map +1 -0
- package/dist/adapters/codex/locate.js +72 -0
- package/dist/adapters/codex/locate.js.map +1 -0
- package/dist/adapters/codex/records.js +194 -0
- package/dist/adapters/codex/records.js.map +1 -0
- package/dist/adapters/codex/rollout.js +72 -0
- package/dist/adapters/codex/rollout.js.map +1 -0
- package/dist/adapters/codex/session.js +212 -0
- package/dist/adapters/codex/session.js.map +1 -0
- package/dist/adapters/codex/subagents.js +139 -0
- package/dist/adapters/codex/subagents.js.map +1 -0
- package/dist/adapters/codex/summarize.js +84 -0
- package/dist/adapters/codex/summarize.js.map +1 -0
- package/dist/adapters/codex/tools.js +145 -0
- package/dist/adapters/codex/tools.js.map +1 -0
- package/dist/adapters/hook-command.js +94 -0
- package/dist/adapters/hook-command.js.map +1 -0
- package/dist/adapters/index.js +12 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analysis/corrections.js +79 -0
- package/dist/analysis/corrections.js.map +1 -0
- package/dist/analysis/digest.js +16 -0
- package/dist/analysis/digest.js.map +1 -0
- package/dist/analysis/outcome.js +76 -0
- package/dist/analysis/outcome.js.map +1 -0
- package/dist/analysis/phases.js +203 -0
- package/dist/analysis/phases.js.map +1 -0
- package/dist/analysis/summaries.js +350 -0
- package/dist/analysis/summaries.js.map +1 -0
- package/dist/analysis/tokens.js +67 -0
- package/dist/analysis/tokens.js.map +1 -0
- package/dist/analysis/usage.js +229 -0
- package/dist/analysis/usage.js.map +1 -0
- package/dist/cc-cache.js +81 -0
- package/dist/cc-cache.js.map +1 -0
- package/dist/cli.js +128 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/common.js +235 -0
- package/dist/commands/common.js.map +1 -0
- package/dist/commands/doctor.js +193 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/flush.js +131 -0
- package/dist/commands/flush.js.map +1 -0
- package/dist/commands/init.js +119 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link.js +171 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/live.js +130 -0
- package/dist/commands/live.js.map +1 -0
- package/dist/commands/login.js +397 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/status.js +155 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/token.js +92 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/commands/uninstall.js +56 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/config.js +305 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +109 -0
- package/dist/context.js.map +1 -0
- package/dist/delivery.js +151 -0
- package/dist/delivery.js.map +1 -0
- package/dist/dotfile.js +187 -0
- package/dist/dotfile.js.map +1 -0
- package/dist/events.js +259 -0
- package/dist/events.js.map +1 -0
- package/dist/fsutil.js +50 -0
- package/dist/fsutil.js.map +1 -0
- package/dist/git.js +139 -0
- package/dist/git.js.map +1 -0
- package/dist/hook.js +147 -0
- package/dist/hook.js.map +1 -0
- package/dist/http.js +35 -0
- package/dist/http.js.map +1 -0
- package/dist/jobs.js +53 -0
- package/dist/jobs.js.map +1 -0
- package/dist/live/claude-code.js +226 -0
- package/dist/live/claude-code.js.map +1 -0
- package/dist/live/codex.js +91 -0
- package/dist/live/codex.js.map +1 -0
- package/dist/live/monitor.js +229 -0
- package/dist/live/monitor.js.map +1 -0
- package/dist/live/render.js +92 -0
- package/dist/live/render.js.map +1 -0
- package/dist/lock.js +93 -0
- package/dist/lock.js.map +1 -0
- package/dist/log.js +36 -0
- package/dist/log.js.map +1 -0
- package/dist/migrate.js +109 -0
- package/dist/migrate.js.map +1 -0
- package/dist/nudge.js +231 -0
- package/dist/nudge.js.map +1 -0
- package/dist/paths.js +73 -0
- package/dist/paths.js.map +1 -0
- package/dist/pk-cache.js +110 -0
- package/dist/pk-cache.js.map +1 -0
- package/dist/prices.js +45 -0
- package/dist/prices.js.map +1 -0
- package/dist/project-key.js +144 -0
- package/dist/project-key.js.map +1 -0
- package/dist/protocol-types.js +30 -0
- package/dist/protocol-types.js.map +1 -0
- package/dist/queue.js +649 -0
- package/dist/queue.js.map +1 -0
- package/dist/routing.js +122 -0
- package/dist/routing.js.map +1 -0
- package/dist/runtime.js +54 -0
- package/dist/runtime.js.map +1 -0
- package/dist/sender.js +559 -0
- package/dist/sender.js.map +1 -0
- package/dist/state.js +59 -0
- package/dist/state.js.map +1 -0
- package/dist/ulid.js +73 -0
- package/dist/ulid.js.map +1 -0
- package/dist/version.js +26 -0
- package/dist/version.js.map +1 -0
- package/dist/warnings.js +71 -0
- package/dist/warnings.js.map +1 -0
- package/dist/worker-main.js +14 -0
- package/dist/worker-main.js.map +1 -0
- package/dist/worker.js +295 -0
- package/dist/worker.js.map +1 -0
- package/package.json +25 -4
package/bin/ai-obs.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// HARD RULE (BRIEF §5.6): the collector's own summarizer runs a headless harness with
|
|
3
|
+
// AI_OBS_SUMMARIZING=1; every hook invocation inside it must exit immediately, before any work,
|
|
4
|
+
// or summarizing would recurse. Keep this the first statement of the entry file.
|
|
5
|
+
if (process.env.AI_OBS_SUMMARIZING) process.exit(0);
|
|
6
|
+
|
|
7
|
+
const { main } = await import('../dist/cli.js');
|
|
8
|
+
process.exitCode = await main(process.argv.slice(2));
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { addPhaseTotals, attributeTime, emptyPhaseTotals } from '../../analysis/phases.js';
|
|
3
|
+
import { mergeUsage, sumUsage } from '../../analysis/tokens.js';
|
|
4
|
+
import { addMcp, addMcpResult, addSkill, mergeMcp, mergeMcpStats, mergeSkills, parseMcpTool } from '../../analysis/usage.js';
|
|
5
|
+
import { toolKey } from '../../events.js';
|
|
6
|
+
/** Stored caps: state files stay small even for very long sessions. */
|
|
7
|
+
const MAX_IDS = 400;
|
|
8
|
+
const MAX_FP = 1000;
|
|
9
|
+
const MAX_FILE_KEYS = 500;
|
|
10
|
+
/** `agentCalls` key of a Workflow launch (its sub-agents are linked to the key, not to a tool_use id). */
|
|
11
|
+
export const workflowKey = (runId) => `wf:${runId}`;
|
|
12
|
+
export const isWorkflowKey = (key) => typeof key === 'string' && key.startsWith('wf:');
|
|
13
|
+
const pathKey = (p) => createHash('sha256').update(p).digest('base64url').slice(0, 16);
|
|
14
|
+
const uniqCap = (xs, cap) => [...new Set(xs)].slice(-cap);
|
|
15
|
+
export function emptyAgg(at) {
|
|
16
|
+
return {
|
|
17
|
+
startedAt: at,
|
|
18
|
+
endedAt: at,
|
|
19
|
+
usage: [],
|
|
20
|
+
responseIds: [],
|
|
21
|
+
phases: emptyPhaseTotals(),
|
|
22
|
+
tools: {},
|
|
23
|
+
skills: {},
|
|
24
|
+
mcp: {},
|
|
25
|
+
mcpStats: {},
|
|
26
|
+
toolNames: [],
|
|
27
|
+
fileKeys: [],
|
|
28
|
+
linesAdded: 0,
|
|
29
|
+
linesRemoved: 0,
|
|
30
|
+
fp: { added: [], removed: [] },
|
|
31
|
+
interrupted: false,
|
|
32
|
+
lastCheck: null,
|
|
33
|
+
agentCalls: {},
|
|
34
|
+
lastMessage: '',
|
|
35
|
+
active: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Analyzes entries of one stretch in transcript order. Tokens: usage per assistant entry, de-duplicated
|
|
40
|
+
* per API response (Claude Code writes one entry per content block, each repeating the usage). Phases:
|
|
41
|
+
* the shared time-attribution rules over prompt / output / tool_call / tool_result moments.
|
|
42
|
+
*/
|
|
43
|
+
export function analyzeEntries(entries, opts = {}) {
|
|
44
|
+
const first = entries[0];
|
|
45
|
+
const start = opts.startAt ?? first?.at ?? 0;
|
|
46
|
+
const agg = emptyAgg(start);
|
|
47
|
+
const timeline = [{ at: start, type: 'prompt' }];
|
|
48
|
+
const records = [];
|
|
49
|
+
const toolNames = [];
|
|
50
|
+
const toolCalls = [];
|
|
51
|
+
const pendingEdits = new Map();
|
|
52
|
+
const checks = new Map();
|
|
53
|
+
/** open MCP calls by tool_use id, paired with their result for errors and latency */
|
|
54
|
+
const mcpCalls = new Map();
|
|
55
|
+
const files = new Set();
|
|
56
|
+
const fpAdded = [];
|
|
57
|
+
const fpRemoved = [];
|
|
58
|
+
let end = start;
|
|
59
|
+
/** a typed slash command waiting for its expansion (only skills / custom commands have one) */
|
|
60
|
+
let command = null;
|
|
61
|
+
for (const e of entries) {
|
|
62
|
+
if (e.k === 'stop')
|
|
63
|
+
continue;
|
|
64
|
+
// A command's expansion is written with the prompt; it is not activity and does not move the turn's end.
|
|
65
|
+
if (e.k === 'expansion') {
|
|
66
|
+
if (command)
|
|
67
|
+
addSkill(agg.skills, command, 'user');
|
|
68
|
+
command = null;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
end = Math.max(end, e.at);
|
|
72
|
+
if (e.k === 'prompt') {
|
|
73
|
+
if (e.at > start)
|
|
74
|
+
timeline.push({ at: e.at, type: 'prompt' });
|
|
75
|
+
command = e.command;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (e.k === 'interrupt') {
|
|
79
|
+
agg.interrupted = true;
|
|
80
|
+
timeline.push({ at: e.at, type: 'output' });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (e.k === 'assistant') {
|
|
84
|
+
agg.active = true;
|
|
85
|
+
command = null;
|
|
86
|
+
if (e.usage && !(e.usage.responseId && opts.skipResponseIds?.has(e.usage.responseId)))
|
|
87
|
+
records.push(e.usage);
|
|
88
|
+
for (const b of e.blocks) {
|
|
89
|
+
if (b.t === 'output') {
|
|
90
|
+
timeline.push({ at: e.at, type: 'output' });
|
|
91
|
+
if (b.text?.trim())
|
|
92
|
+
agg.lastMessage = b.text;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
timeline.push({ at: e.at, type: 'tool_call', id: b.id, phase: b.phase });
|
|
96
|
+
toolCalls.push(b.name);
|
|
97
|
+
toolNames.push(b.name);
|
|
98
|
+
if (b.skill)
|
|
99
|
+
addSkill(agg.skills, b.skill, 'model');
|
|
100
|
+
const mcp = parseMcpTool(b.name);
|
|
101
|
+
if (mcp) {
|
|
102
|
+
addMcp(agg.mcp, mcp.server, mcp.tool);
|
|
103
|
+
if (b.id)
|
|
104
|
+
mcpCalls.set(b.id, { ...mcp, at: e.at });
|
|
105
|
+
}
|
|
106
|
+
if (b.edit && b.filePath)
|
|
107
|
+
pendingEdits.set(b.id, { filePath: b.filePath, estimate: b.edit.fp, added: b.edit.added, removed: b.edit.removed });
|
|
108
|
+
if (b.phase === 'testing' || b.phase === 'validating')
|
|
109
|
+
checks.set(b.id, b.phase);
|
|
110
|
+
if (b.agent)
|
|
111
|
+
agg.agentCalls[b.id] = { type: b.agent.type, background: b.agent.background, completed: false };
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (e.userInterrupt)
|
|
116
|
+
agg.interrupted = true;
|
|
117
|
+
for (const r of e.results) {
|
|
118
|
+
timeline.push({ at: e.at, type: 'tool_result', id: r.id });
|
|
119
|
+
applyResult(r, e.at);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function applyResult(r, at) {
|
|
123
|
+
const call = mcpCalls.get(r.id);
|
|
124
|
+
if (call) {
|
|
125
|
+
addMcpResult(agg.mcpStats, call.server, call.tool, { error: r.isError, denied: r.denied, ms: at - call.at });
|
|
126
|
+
mcpCalls.delete(r.id);
|
|
127
|
+
}
|
|
128
|
+
const edit = pendingEdits.get(r.id);
|
|
129
|
+
if (edit && !r.isError) {
|
|
130
|
+
const exact = r.edit;
|
|
131
|
+
agg.linesAdded += exact ? exact.added : edit.added;
|
|
132
|
+
agg.linesRemoved += exact ? exact.removed : edit.removed;
|
|
133
|
+
const fp = exact?.fp ?? edit.estimate;
|
|
134
|
+
if (fp) {
|
|
135
|
+
fpAdded.push(...fp.added);
|
|
136
|
+
fpRemoved.push(...fp.removed);
|
|
137
|
+
}
|
|
138
|
+
files.add(pathKey(edit.filePath));
|
|
139
|
+
}
|
|
140
|
+
pendingEdits.delete(r.id);
|
|
141
|
+
const kind = checks.get(r.id);
|
|
142
|
+
if (kind && r.exitCode !== null && !r.interrupted)
|
|
143
|
+
agg.lastCheck = { kind, exitCode: r.exitCode };
|
|
144
|
+
if (r.workflowRunId)
|
|
145
|
+
agg.agentCalls[workflowKey(r.workflowRunId)] = { type: 'workflow', background: true, completed: false };
|
|
146
|
+
const agent = agg.agentCalls[r.id];
|
|
147
|
+
if (agent)
|
|
148
|
+
agent.completed = !r.isError && r.agentStatus !== 'async_launched' && !agent.background;
|
|
149
|
+
}
|
|
150
|
+
agg.endedAt = end;
|
|
151
|
+
agg.phases = attributeTime(timeline, end);
|
|
152
|
+
agg.usage = sumUsage(records);
|
|
153
|
+
agg.responseIds = uniqCap(records.flatMap((r) => (r.responseId ? [r.responseId] : [])), MAX_IDS);
|
|
154
|
+
for (const n of toolCalls)
|
|
155
|
+
agg.tools[toolKey(n)] = (agg.tools[toolKey(n)] ?? 0) + 1;
|
|
156
|
+
agg.toolNames = [...new Set(toolNames)].slice(0, 30);
|
|
157
|
+
agg.fileKeys = uniqCap(files, MAX_FILE_KEYS);
|
|
158
|
+
agg.fp = { added: uniqCap(fpAdded, MAX_FP), removed: uniqCap(fpRemoved, MAX_FP) };
|
|
159
|
+
return agg;
|
|
160
|
+
}
|
|
161
|
+
/** Adds a later stretch (continuation) to an earlier one. */
|
|
162
|
+
export function mergeAgg(a, b) {
|
|
163
|
+
const tools = { ...a.tools };
|
|
164
|
+
for (const [k, v] of Object.entries(b.tools))
|
|
165
|
+
tools[k] = (tools[k] ?? 0) + v;
|
|
166
|
+
const calls = { ...a.agentCalls, ...b.agentCalls };
|
|
167
|
+
return {
|
|
168
|
+
startedAt: Math.min(a.startedAt, b.startedAt),
|
|
169
|
+
endedAt: Math.max(a.endedAt, b.endedAt),
|
|
170
|
+
usage: mergeUsage(a.usage, b.usage),
|
|
171
|
+
responseIds: uniqCap([...a.responseIds, ...b.responseIds], MAX_IDS),
|
|
172
|
+
phases: addPhaseTotals(a.phases, b.phases),
|
|
173
|
+
tools,
|
|
174
|
+
skills: mergeSkills(a.skills, b.skills),
|
|
175
|
+
mcp: mergeMcp(a.mcp, b.mcp),
|
|
176
|
+
mcpStats: mergeMcpStats(a.mcpStats, b.mcpStats),
|
|
177
|
+
toolNames: [...new Set([...a.toolNames, ...b.toolNames])].slice(0, 30),
|
|
178
|
+
fileKeys: uniqCap([...a.fileKeys, ...b.fileKeys], MAX_FILE_KEYS),
|
|
179
|
+
linesAdded: a.linesAdded + b.linesAdded,
|
|
180
|
+
linesRemoved: a.linesRemoved + b.linesRemoved,
|
|
181
|
+
fp: { added: uniqCap([...a.fp.added, ...b.fp.added], MAX_FP), removed: uniqCap([...a.fp.removed, ...b.fp.removed], MAX_FP) },
|
|
182
|
+
interrupted: a.interrupted || b.interrupted,
|
|
183
|
+
lastCheck: b.lastCheck ?? a.lastCheck,
|
|
184
|
+
agentCalls: calls,
|
|
185
|
+
lastMessage: b.lastMessage || a.lastMessage,
|
|
186
|
+
active: a.active || b.active,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readJsonFile, writeJsonAtomic } from '../../fsutil.js';
|
|
5
|
+
import { compareVersions } from '../../version.js';
|
|
6
|
+
import { hooksDisabledAt, hooksInstalledAt, settingsPath } from './settings.js';
|
|
7
|
+
/** Oldest version whose hooks / transcript format this adapter was built against (FORMAT.md). */
|
|
8
|
+
export const MIN_SUPPORTED_VERSION = '2.1.0';
|
|
9
|
+
const VERSION_TTL_MS = 6 * 3600_000;
|
|
10
|
+
/** `claude --version` → "2.1.289" (null when the binary is missing or silent). */
|
|
11
|
+
export const probeClaudeVersion = () => new Promise((resolve) => {
|
|
12
|
+
try {
|
|
13
|
+
execFile('claude', ['--version'], { timeout: 10_000, windowsHide: true, env: { ...process.env, AI_OBS_SUMMARIZING: '1' } }, (err, stdout) => {
|
|
14
|
+
if (err)
|
|
15
|
+
return resolve(null);
|
|
16
|
+
resolve(/(\d+\.\d+\.\d+)/.exec(String(stdout))?.[1] ?? null);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
resolve(null);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Version for session_start events, cached in <state>/claude-code.version.json for a few hours, so
|
|
25
|
+
* the worker does not start the claude binary on every SessionStart.
|
|
26
|
+
*/
|
|
27
|
+
export async function cachedVersion(stateDir, probe, now) {
|
|
28
|
+
const file = join(stateDir, 'claude-code.version.json');
|
|
29
|
+
const cached = readJsonFile(file);
|
|
30
|
+
if (cached && now - cached.at < VERSION_TTL_MS && cached.version)
|
|
31
|
+
return cached.version;
|
|
32
|
+
const version = await probe();
|
|
33
|
+
try {
|
|
34
|
+
writeJsonAtomic(file, { version, at: now });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* cache only */
|
|
38
|
+
}
|
|
39
|
+
return version;
|
|
40
|
+
}
|
|
41
|
+
export async function detectClaudeCode(opts) {
|
|
42
|
+
const version = await opts.probe().catch(() => null);
|
|
43
|
+
const userSettings = settingsPath('user', { claudeDir: opts.claudeDir });
|
|
44
|
+
const installed = version !== null || existsSync(opts.claudeDir);
|
|
45
|
+
const projectSettings = opts.projectDir ? settingsPath('project', { projectDir: opts.projectDir }) : null;
|
|
46
|
+
const notes = [];
|
|
47
|
+
if (version === null && installed)
|
|
48
|
+
notes.push('`claude` not found on PATH; hooks will only fire once Claude Code is installed');
|
|
49
|
+
if (hooksDisabledAt(userSettings) || (projectSettings && hooksDisabledAt(projectSettings)))
|
|
50
|
+
notes.push('disableAllHooks is set; no hooks run');
|
|
51
|
+
return {
|
|
52
|
+
installed,
|
|
53
|
+
version,
|
|
54
|
+
versionSupported: version ? compareVersions(version, MIN_SUPPORTED_VERSION) >= 0 : null,
|
|
55
|
+
hooksInstalled: { user: hooksInstalledAt(userSettings), project: projectSettings ? hooksInstalledAt(projectSettings) : null },
|
|
56
|
+
configPath: userSettings,
|
|
57
|
+
...(notes.length ? { notes } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhF,iGAAiG;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAC7C,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,CAAC;AAIpC,kFAAkF;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAiB,GAAG,EAAE,CACnD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YAC1I,IAAI,GAAG;gBAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9B,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,KAAmB,EAAE,GAAW;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,YAAY,CAAyC,IAAI,CAAC,CAAC;IAC1E,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,GAAG,cAAc,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IACxF,MAAM,OAAO,GAAG,MAAM,KAAK,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,eAAe,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAgE;IACrG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,OAAO,KAAK,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1G,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,KAAK,IAAI,IAAI,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAChI,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,eAAe,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IAC/I,OAAO;QACL,SAAS;QACT,OAAO;QACP,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACvF,cAAc,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAC7H,UAAU,EAAE,YAAY;QACxB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { looksLikeCorrection } from '../../analysis/corrections.js';
|
|
4
|
+
import { summariesDue } from '../../analysis/summaries.js';
|
|
5
|
+
import { sessionEndEvent, sessionStartEvent, turnStartedEvent } from '../../events.js';
|
|
6
|
+
import { cachedVersion } from './detect.js';
|
|
7
|
+
import { collectWorkflowRuns, emitSessionTitle, Emitter, flushOpenRuns, followUpTurns, processTranscript, settleLastTurn, settleTurns, subagentFailed, subagentFinished, } from './session.js';
|
|
8
|
+
import { evictedUnsettledTurns, loadSession, newSessionState, saveSession } from './state.js';
|
|
9
|
+
/** A session silent for this long without SessionEnd is considered crashed. */
|
|
10
|
+
export const CRASH_AFTER_MS = 24 * 3600_000;
|
|
11
|
+
/** Ended sessions' state is kept this long (a resumed session continues from its cursor). */
|
|
12
|
+
export const KEEP_ENDED_MS = 30 * 24 * 3600_000;
|
|
13
|
+
const str = (v) => (typeof v === 'string' && v ? v : null);
|
|
14
|
+
/** A transcript prompt matched by time is at most this long before the UserPromptSubmit hook fired … */
|
|
15
|
+
export const PROMPT_MATCH_BEFORE_MS = 10_000;
|
|
16
|
+
/** … and at most this long after it. */
|
|
17
|
+
export const PROMPT_MATCH_AFTER_MS = 1_000;
|
|
18
|
+
/** Whether a transcript prompt is the one this UserPromptSubmit announced: prompt_id = promptId when both exist, else by time. */
|
|
19
|
+
export function isHookPrompt(p, promptId, receivedAt) {
|
|
20
|
+
if (promptId && p.promptId)
|
|
21
|
+
return p.promptId === promptId;
|
|
22
|
+
return p.at >= receivedAt - PROMPT_MATCH_BEFORE_MS && p.at <= receivedAt + PROMPT_MATCH_AFTER_MS;
|
|
23
|
+
}
|
|
24
|
+
/** Where Claude Code keeps a session transcript when the payload does not say. */
|
|
25
|
+
export function defaultTranscriptPath(claudeDir, cwd, sessionId) {
|
|
26
|
+
return join(claudeDir, 'projects', cwd.replace(/[^A-Za-z0-9]/g, '-'), `${sessionId}.jsonl`);
|
|
27
|
+
}
|
|
28
|
+
function fileSize(path) {
|
|
29
|
+
try {
|
|
30
|
+
return statSync(path).size;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function handleHook(event, ctx, deps) {
|
|
37
|
+
const p = (event.payload && typeof event.payload === 'object' ? event.payload : {});
|
|
38
|
+
const sessionId = str(p.session_id);
|
|
39
|
+
if (!sessionId) {
|
|
40
|
+
ctx.log.warn('claude-code: hook without session_id', { hook: event.hook });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const receivedAt = Number.isFinite(Date.parse(event.receivedAt)) ? Date.parse(event.receivedAt) : ctx.now().getTime();
|
|
44
|
+
const transcriptPath = str(p.transcript_path) ?? defaultTranscriptPath(deps.claudeDir, event.cwd, sessionId);
|
|
45
|
+
let st = loadSession(ctx.state, sessionId);
|
|
46
|
+
if (!st) {
|
|
47
|
+
st = newSessionState(sessionId, transcriptPath, event.cwd, receivedAt);
|
|
48
|
+
// A resumed / compacted / forked session we never saw: do not back-fill its history. A fork's
|
|
49
|
+
// transcript starts with a copy of the parent conversation, already counted under the parent.
|
|
50
|
+
if (event.hook === 'SessionStart' && (p.source === 'resume' || p.source === 'compact' || p.source === 'fork')) {
|
|
51
|
+
st.offset = fileSize(transcriptPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
st.transcriptPath = transcriptPath;
|
|
56
|
+
st.pkCwd ??= st.cwd; // state written by 0.1.x: pin the session's own cwd before it is overwritten
|
|
57
|
+
st.cwd = event.cwd;
|
|
58
|
+
}
|
|
59
|
+
if (st.ended && event.hook !== 'SessionEnd')
|
|
60
|
+
st.ended = false; // resumed
|
|
61
|
+
st.lastSeen = Math.max(st.lastSeen, receivedAt);
|
|
62
|
+
const em = new Emitter(ctx.harness, st);
|
|
63
|
+
// Turn-scoped hooks fired inside a sub-agent carry `agent_id`: they are not about the main turn.
|
|
64
|
+
const subagent = str(p.agent_id);
|
|
65
|
+
switch (event.hook) {
|
|
66
|
+
case 'UserPromptSubmit': {
|
|
67
|
+
if (subagent)
|
|
68
|
+
break;
|
|
69
|
+
const promptId = str(p.prompt_id);
|
|
70
|
+
const own = (q) => isHookPrompt(q, promptId, receivedAt);
|
|
71
|
+
const { prompts } = processTranscript(em, { mode: 'prompt', receivedAt, ownPrompt: own });
|
|
72
|
+
const prompt = typeof p.prompt === 'string' ? p.prompt : null;
|
|
73
|
+
if (prompt !== null) {
|
|
74
|
+
const human = !/^\s*<task-notification>/.test(prompt);
|
|
75
|
+
followUpTurns(em, { human, correction: human && looksLikeCorrection(prompt), revertOf: () => false }, receivedAt);
|
|
76
|
+
}
|
|
77
|
+
// live status (ADR-0027): the session is working until this turn's `turn` arrives
|
|
78
|
+
em.events.push(turnStartedEvent({ harness: ctx.harness, sessionId, turnId: prompts.filter(own).at(-1)?.uuid ?? null, startedAt: receivedAt }));
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case 'Stop':
|
|
82
|
+
if (subagent)
|
|
83
|
+
break;
|
|
84
|
+
processTranscript(em, { mode: 'stop', receivedAt });
|
|
85
|
+
break;
|
|
86
|
+
case 'StopFailure':
|
|
87
|
+
// An API error inside a sub-agent fails that run only; the main turn keeps running.
|
|
88
|
+
if (subagent)
|
|
89
|
+
subagentFailed(em, subagent);
|
|
90
|
+
else
|
|
91
|
+
processTranscript(em, { mode: 'stop', receivedAt, stopFailure: true });
|
|
92
|
+
break;
|
|
93
|
+
case 'SubagentStop': {
|
|
94
|
+
const agentId = str(p.agent_id);
|
|
95
|
+
if (agentId)
|
|
96
|
+
subagentFinished(em, agentId);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'SessionEnd':
|
|
100
|
+
endSession(em, str(p.reason) ?? 'other', receivedAt);
|
|
101
|
+
break;
|
|
102
|
+
default:
|
|
103
|
+
break; // SessionStart: only session_start below
|
|
104
|
+
}
|
|
105
|
+
if (event.hook !== 'SessionEnd')
|
|
106
|
+
collectWorkflowRuns(em);
|
|
107
|
+
if (!st.startedSent) {
|
|
108
|
+
const firstTurn = st.turns[0]?.agg.startedAt;
|
|
109
|
+
const at = firstTurn !== undefined ? Math.min(firstTurn, receivedAt) : receivedAt;
|
|
110
|
+
const harnessVersion = await cachedVersion(ctx.paths.state, deps.probe, ctx.now().getTime());
|
|
111
|
+
const project = await ctx.projectKey(st.pkCwd ?? st.cwd);
|
|
112
|
+
em.events.unshift(sessionStartEvent({ harness: ctx.harness, sessionId, at, harnessVersion, project }));
|
|
113
|
+
st.startedSent = true;
|
|
114
|
+
}
|
|
115
|
+
await finish(em, ctx, receivedAt);
|
|
116
|
+
}
|
|
117
|
+
/** Ends a session: remaining turns, open sub-agents, final outcome of every unsettled turn, session_end. */
|
|
118
|
+
function endSession(em, reason, at) {
|
|
119
|
+
processTranscript(em, { mode: 'end', receivedAt: at });
|
|
120
|
+
flushOpenRuns(em);
|
|
121
|
+
const lastActivity = em.state.turns.at(-1)?.agg.endedAt ?? 0;
|
|
122
|
+
const endAt = Math.max(at, lastActivity);
|
|
123
|
+
settleLastTurn(em, endAt);
|
|
124
|
+
em.events.push(sessionEndEvent({ harness: em.harness, sessionId: em.state.sessionId, reason, at: endAt }));
|
|
125
|
+
em.state.ended = true;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Enqueue into the session's stream (pinned at its first hook, which always carries `session_start`;
|
|
129
|
+
* `capturedAt` = that job's received_at; C12, C15), hand the waiting turns to the summariser when they are
|
|
130
|
+
* due (session over, 10 waiting, or the first has waited 10 minutes; ADR-0023), then save the cursor and the
|
|
131
|
+
* pin. The digests are staged durably before the state forgets them; the worker summarises them after its
|
|
132
|
+
* flush, so a slow summary never delays the next hook's events (ADR-0027).
|
|
133
|
+
*/
|
|
134
|
+
async function finish(em, ctx, capturedAt) {
|
|
135
|
+
const st = em.state;
|
|
136
|
+
// Turns about to fall out of the state file never see a follow-up: settle them now.
|
|
137
|
+
settleTurns(em, evictedUnsettledTurns(st), st.lastSeen);
|
|
138
|
+
emitSessionTitle(em);
|
|
139
|
+
if (st.digests.length > 0 && st.digestsSince === undefined)
|
|
140
|
+
st.digestsSince = capturedAt;
|
|
141
|
+
const summarize = summariesDue({ ended: st.ended, pending: st.digests.length, since: st.digestsSince, now: capturedAt });
|
|
142
|
+
const key = em.events.length || summarize ? await ctx.streamFor(st, capturedAt) : null;
|
|
143
|
+
if (em.events.length)
|
|
144
|
+
ctx.queue.enqueue(em.events, key);
|
|
145
|
+
// durable before the state forgets them (ADR-0027); the worker summarises after its flush
|
|
146
|
+
if (summarize && ctx.scheduleSummaries(st.digests, key)) {
|
|
147
|
+
st.digests = [];
|
|
148
|
+
delete st.digestsSince;
|
|
149
|
+
}
|
|
150
|
+
saveSession(ctx.state, st);
|
|
151
|
+
}
|
|
152
|
+
/** SessionStart sweep: sessions silent for 24 h without SessionEnd get session_end "crashed". */
|
|
153
|
+
export async function sweepCrashedSessions(ctx) {
|
|
154
|
+
const now = ctx.now().getTime();
|
|
155
|
+
for (const { sessionId, updatedAt } of ctx.state.list()) {
|
|
156
|
+
if (now - updatedAt < CRASH_AFTER_MS)
|
|
157
|
+
continue;
|
|
158
|
+
let st;
|
|
159
|
+
try {
|
|
160
|
+
st = loadSession(ctx.state, sessionId);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
st = null;
|
|
164
|
+
}
|
|
165
|
+
if (!st)
|
|
166
|
+
continue;
|
|
167
|
+
if (st.ended) {
|
|
168
|
+
if (now - updatedAt > KEEP_ENDED_MS)
|
|
169
|
+
ctx.state.delete(sessionId);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
st.pkCwd ??= st.cwd;
|
|
174
|
+
const em = new Emitter(ctx.harness, st);
|
|
175
|
+
endSession(em, 'crashed', st.lastSeen);
|
|
176
|
+
await finish(em, ctx, now);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
ctx.log.warn('claude-code: sweep failed for a session', { error: String(err).slice(0, 200) });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { tmpdir } from 'node:os';
|
|
2
|
+
import { summarizeWithCommand } from '../../analysis/summaries.js';
|
|
3
|
+
import { detectClaudeCode, probeClaudeVersion } from './detect.js';
|
|
4
|
+
import { handleHook, sweepCrashedSessions } from './handlers.js';
|
|
5
|
+
import { claudeDir as defaultClaudeDir, installHooksAt, ourCommandsAt, settingsPath, uninstallHooksAt } from './settings.js';
|
|
6
|
+
/**
|
|
7
|
+
* Headless summary call: cheapest model, JSON envelope, no tools, no saved session. The prompt goes
|
|
8
|
+
* on stdin; the core adds AI_OBS_SUMMARIZING=1 so our own hooks exit at once inside it.
|
|
9
|
+
*/
|
|
10
|
+
export const SUMMARY_ARGV = ['claude', '-p', '--model', 'haiku', '--output-format', 'json', '--no-session-persistence', '--tools', ''];
|
|
11
|
+
/** `--output-format json` prints `{ "type": "result", "is_error": false, "result": "<text>", … }`. */
|
|
12
|
+
export function extractResultText(stdout) {
|
|
13
|
+
try {
|
|
14
|
+
const o = JSON.parse(stdout);
|
|
15
|
+
if (o.is_error === true)
|
|
16
|
+
throw new Error('claude reported an error');
|
|
17
|
+
return typeof o.result === 'string' ? o.result : '';
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
if (err instanceof SyntaxError)
|
|
21
|
+
return stdout;
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function createClaudeCodeAdapter(opts = {}) {
|
|
26
|
+
const dir = () => opts.claudeDir ?? defaultClaudeDir();
|
|
27
|
+
const probe = opts.probe ?? probeClaudeVersion;
|
|
28
|
+
const argv = [...(opts.summaryArgv ?? SUMMARY_ARGV)];
|
|
29
|
+
return {
|
|
30
|
+
name: 'claude-code',
|
|
31
|
+
displayName: 'Claude Code',
|
|
32
|
+
sessionStartHooks: ['SessionStart'],
|
|
33
|
+
detect: (d = {}) => detectClaudeCode({ ...d, claudeDir: dir(), probe }),
|
|
34
|
+
async installedHookCommands(d = {}) {
|
|
35
|
+
const paths = [settingsPath('user', { claudeDir: dir() }), ...(d.projectDir ? [settingsPath('project', { claudeDir: dir(), projectDir: d.projectDir })] : [])];
|
|
36
|
+
return paths.flatMap(ourCommandsAt);
|
|
37
|
+
},
|
|
38
|
+
async installHooks(o) {
|
|
39
|
+
const path = settingsPath(o.scope, { claudeDir: dir(), ...(o.projectDir ? { projectDir: o.projectDir } : {}) });
|
|
40
|
+
installHooksAt(path, o.hookCommand, o.scope === 'project' ? 0o644 : 0o600);
|
|
41
|
+
},
|
|
42
|
+
async uninstallHooks(o) {
|
|
43
|
+
uninstallHooksAt(settingsPath(o.scope, { claudeDir: dir(), ...(o.projectDir ? { projectDir: o.projectDir } : {}) }));
|
|
44
|
+
},
|
|
45
|
+
handleHook: (event, ctx) => handleHook(event, ctx, { claudeDir: dir(), probe }),
|
|
46
|
+
sweepCrashedSessions: (ctx) => sweepCrashedSessions(ctx),
|
|
47
|
+
summarize: (digests) => summarizeWithCommand(digests, {
|
|
48
|
+
command: (prompt) => ({ argv, input: prompt }),
|
|
49
|
+
extractText: extractResultText,
|
|
50
|
+
cwd: tmpdir(),
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export const adapter = createClaudeCodeAdapter();
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function computeRunLinks(runs) {
|
|
2
|
+
const byId = new Map();
|
|
3
|
+
for (const r of runs)
|
|
4
|
+
if (!byId.has(r.runId))
|
|
5
|
+
byId.set(r.runId, r);
|
|
6
|
+
const out = new Map();
|
|
7
|
+
const add = (to, fromRunId, kind) => {
|
|
8
|
+
if (to === fromRunId)
|
|
9
|
+
return;
|
|
10
|
+
const list = out.get(to) ?? [];
|
|
11
|
+
if (!list.some((l) => l.fromRunId === fromRunId && l.kind === kind))
|
|
12
|
+
list.push({ fromRunId, kind });
|
|
13
|
+
out.set(to, list);
|
|
14
|
+
};
|
|
15
|
+
const byRunId = (a, b) => (a.runId < b.runId ? -1 : a.runId > b.runId ? 1 : 0);
|
|
16
|
+
const items = new Map();
|
|
17
|
+
const siblings = new Map();
|
|
18
|
+
for (const r of byId.values()) {
|
|
19
|
+
if (r.orchestrationId) {
|
|
20
|
+
if (!r.flowKey)
|
|
21
|
+
continue;
|
|
22
|
+
const k = JSON.stringify([r.orchestrationId, r.flowKey]);
|
|
23
|
+
items.set(k, [...(items.get(k) ?? []), r]);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const k = r.parentRunId ?? '';
|
|
27
|
+
siblings.set(k, [...(siblings.get(k) ?? []), r]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const chain of items.values()) {
|
|
31
|
+
chain.sort((a, b) => a.startedMs - b.startedMs || byRunId(a, b));
|
|
32
|
+
for (let i = 1; i < chain.length; i++)
|
|
33
|
+
add(chain[i].runId, chain[i - 1].runId, 'item');
|
|
34
|
+
}
|
|
35
|
+
for (const group of siblings.values()) {
|
|
36
|
+
for (const b of group) {
|
|
37
|
+
let best = null;
|
|
38
|
+
for (const a of group) {
|
|
39
|
+
if (a === b || a.endedMs > b.startedMs)
|
|
40
|
+
continue;
|
|
41
|
+
// two zero-length runs at the same instant would link both ways: only the lower run id leads
|
|
42
|
+
if (a.startedMs === b.startedMs && byRunId(a, b) > 0)
|
|
43
|
+
continue;
|
|
44
|
+
if (!best || a.endedMs > best.endedMs || (a.endedMs === best.endedMs && byRunId(a, best) > 0))
|
|
45
|
+
best = a;
|
|
46
|
+
}
|
|
47
|
+
if (best)
|
|
48
|
+
add(b.runId, best.runId, 'sequence');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=run-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-links.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/run-links.ts"],"names":[],"mappings":"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"}
|