@kynetic-ai/spec 0.9.0 → 0.10.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 +2 -1
- package/dist/acp/client.d.ts +13 -1
- package/dist/acp/client.d.ts.map +1 -1
- package/dist/acp/client.js +17 -2
- package/dist/acp/client.js.map +1 -1
- package/dist/acp/framing.d.ts +12 -1
- package/dist/acp/framing.d.ts.map +1 -1
- package/dist/acp/framing.js +27 -4
- package/dist/acp/framing.js.map +1 -1
- package/dist/agent-runtime/dispatch.d.ts +261 -0
- package/dist/agent-runtime/dispatch.d.ts.map +1 -0
- package/dist/agent-runtime/dispatch.js +791 -0
- package/dist/agent-runtime/dispatch.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +11 -0
- package/dist/agent-runtime/index.d.ts.map +1 -0
- package/dist/agent-runtime/index.js +11 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/agent-runtime/invocation.d.ts +86 -0
- package/dist/agent-runtime/invocation.d.ts.map +1 -0
- package/dist/agent-runtime/invocation.js +442 -0
- package/dist/agent-runtime/invocation.js.map +1 -0
- package/dist/agent-runtime/prompts.d.ts +50 -0
- package/dist/agent-runtime/prompts.d.ts.map +1 -0
- package/dist/agent-runtime/prompts.js +108 -0
- package/dist/agent-runtime/prompts.js.map +1 -0
- package/dist/agents/spawner.d.ts.map +1 -1
- package/dist/agents/spawner.js +60 -4
- package/dist/agents/spawner.js.map +1 -1
- package/dist/cli/batch-exec.d.ts.map +1 -1
- package/dist/cli/batch-exec.js +183 -81
- package/dist/cli/batch-exec.js.map +1 -1
- package/dist/cli/batch-write-buffer.d.ts +141 -0
- package/dist/cli/batch-write-buffer.d.ts.map +1 -0
- package/dist/cli/batch-write-buffer.js +400 -0
- package/dist/cli/batch-write-buffer.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +20 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +831 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +1 -1
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +2 -1
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/batch.js +1 -1
- package/dist/cli/commands/batch.js.map +1 -1
- package/dist/cli/commands/inbox.d.ts.map +1 -1
- package/dist/cli/commands/inbox.js +46 -22
- package/dist/cli/commands/inbox.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +4 -6
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/item.d.ts.map +1 -1
- package/dist/cli/commands/item.js +34 -17
- package/dist/cli/commands/item.js.map +1 -1
- package/dist/cli/commands/log.js +1 -1
- package/dist/cli/commands/log.js.map +1 -1
- package/dist/cli/commands/merge-driver.d.ts.map +1 -1
- package/dist/cli/commands/merge-driver.js +8 -3
- package/dist/cli/commands/merge-driver.js.map +1 -1
- package/dist/cli/commands/meta.d.ts.map +1 -1
- package/dist/cli/commands/meta.js +159 -6
- package/dist/cli/commands/meta.js.map +1 -1
- package/dist/cli/commands/module.d.ts.map +1 -1
- package/dist/cli/commands/module.js +2 -1
- package/dist/cli/commands/module.js.map +1 -1
- package/dist/cli/commands/plan-import.js +19 -3
- package/dist/cli/commands/plan-import.js.map +1 -1
- package/dist/cli/commands/plan.d.ts.map +1 -1
- package/dist/cli/commands/plan.js +87 -43
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/ralph.d.ts +5 -51
- package/dist/cli/commands/ralph.d.ts.map +1 -1
- package/dist/cli/commands/ralph.js +52 -1462
- package/dist/cli/commands/ralph.js.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +22 -13
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +70 -11
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/session/checkpoint.d.ts.map +1 -1
- package/dist/cli/commands/session/checkpoint.js +7 -2
- package/dist/cli/commands/session/checkpoint.js.map +1 -1
- package/dist/cli/commands/session/commands.d.ts.map +1 -1
- package/dist/cli/commands/session/commands.js +15 -0
- package/dist/cli/commands/session/commands.js.map +1 -1
- package/dist/cli/commands/session/context.d.ts.map +1 -1
- package/dist/cli/commands/session/context.js +10 -5
- package/dist/cli/commands/session/context.js.map +1 -1
- package/dist/cli/commands/session/log.d.ts +1 -0
- package/dist/cli/commands/session/log.d.ts.map +1 -1
- package/dist/cli/commands/session/log.js +124 -8
- package/dist/cli/commands/session/log.js.map +1 -1
- package/dist/cli/commands/session/stale-close.d.ts +17 -0
- package/dist/cli/commands/session/stale-close.d.ts.map +1 -0
- package/dist/cli/commands/session/stale-close.js +378 -0
- package/dist/cli/commands/session/stale-close.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +150 -6
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/skill-crud.d.ts.map +1 -1
- package/dist/cli/commands/skill-crud.js +4 -3
- package/dist/cli/commands/skill-crud.js.map +1 -1
- package/dist/cli/commands/skill-diff.d.ts.map +1 -1
- package/dist/cli/commands/skill-diff.js +15 -0
- package/dist/cli/commands/skill-diff.js.map +1 -1
- package/dist/cli/commands/skill-install.d.ts.map +1 -1
- package/dist/cli/commands/skill-install.js +50 -18
- package/dist/cli/commands/skill-install.js.map +1 -1
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +552 -323
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/tasks.js +1 -1
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/triage.d.ts.map +1 -1
- package/dist/cli/commands/triage.js +37 -13
- package/dist/cli/commands/triage.js.map +1 -1
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +99 -50
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/help/content.d.ts.map +1 -1
- package/dist/cli/help/content.js +5 -0
- package/dist/cli/help/content.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +5 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/validators.d.ts +4 -0
- package/dist/cli/validators.d.ts.map +1 -1
- package/dist/cli/validators.js +12 -0
- package/dist/cli/validators.js.map +1 -1
- package/dist/daemon/project-context.ts +22 -0
- package/dist/daemon/routes/agent-dispatch.ts +272 -0
- package/dist/daemon/server.ts +55 -20
- package/dist/daemon/websocket/handler.ts +67 -6
- package/dist/daemon/websocket/lifecycle.ts +19 -0
- package/dist/daemon/websocket/pubsub.ts +74 -3
- package/dist/export/html.d.ts.map +1 -1
- package/dist/export/html.js +5 -2
- package/dist/export/html.js.map +1 -1
- package/dist/export/triage.d.ts +1 -1
- package/dist/export/triage.d.ts.map +1 -1
- package/dist/export/triage.js +5 -3
- package/dist/export/triage.js.map +1 -1
- package/dist/parser/alignment.d.ts.map +1 -1
- package/dist/parser/alignment.js +6 -3
- package/dist/parser/alignment.js.map +1 -1
- package/dist/parser/assess.js +1 -1
- package/dist/parser/assess.js.map +1 -1
- package/dist/parser/config.d.ts +6 -6
- package/dist/parser/meta.d.ts.map +1 -1
- package/dist/parser/meta.js +9 -8
- package/dist/parser/meta.js.map +1 -1
- package/dist/parser/plan-document.d.ts +12 -12
- package/dist/parser/plans.d.ts +7 -0
- package/dist/parser/plans.d.ts.map +1 -1
- package/dist/parser/plans.js +100 -15
- package/dist/parser/plans.js.map +1 -1
- package/dist/parser/refs.d.ts +5 -0
- package/dist/parser/refs.d.ts.map +1 -1
- package/dist/parser/refs.js +17 -12
- package/dist/parser/refs.js.map +1 -1
- package/dist/parser/shadow.d.ts +1 -1
- package/dist/parser/shadow.d.ts.map +1 -1
- package/dist/parser/shadow.js +241 -76
- package/dist/parser/shadow.js.map +1 -1
- package/dist/parser/skill-render.d.ts.map +1 -1
- package/dist/parser/skill-render.js +6 -3
- package/dist/parser/skill-render.js.map +1 -1
- package/dist/parser/validate.d.ts.map +1 -1
- package/dist/parser/validate.js +70 -108
- package/dist/parser/validate.js.map +1 -1
- package/dist/parser/yaml.d.ts +24 -5
- package/dist/parser/yaml.d.ts.map +1 -1
- package/dist/parser/yaml.js +228 -66
- package/dist/parser/yaml.js.map +1 -1
- package/dist/schema/meta.d.ts +442 -119
- package/dist/schema/meta.d.ts.map +1 -1
- package/dist/schema/meta.js +55 -0
- package/dist/schema/meta.js.map +1 -1
- package/dist/schema/plan.d.ts +22 -22
- package/dist/schema/spec.d.ts +39 -39
- package/dist/schema/task.d.ts +43 -32
- package/dist/schema/task.d.ts.map +1 -1
- package/dist/schema/task.js +5 -0
- package/dist/schema/task.js.map +1 -1
- package/dist/sessions/store.d.ts +112 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +414 -22
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +75 -17
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +51 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/triage/actions.d.ts +1 -0
- package/dist/triage/actions.d.ts.map +1 -1
- package/dist/triage/actions.js +34 -7
- package/dist/triage/actions.js.map +1 -1
- package/dist/utils/commit.js +1 -1
- package/dist/utils/commit.js.map +1 -1
- package/dist/web-ui/_app/env.js +1 -0
- package/dist/web-ui/_app/immutable/assets/0.BxCxvrZR.css +1 -0
- package/dist/web-ui/_app/immutable/assets/select-trigger.CV-KWLNP.css +1 -0
- package/dist/web-ui/_app/immutable/chunks/B-CZR0q8.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/B1IR5Su5.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BCkp8Hs8.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/B_Cvvtc4.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BtFaGGII.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Bu8JVsCH.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/C87u-CNA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/CrFkBTYp.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/D1ArdqNb.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/D28BF5MJ.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/D6RtLpzL.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/D7FHSgx2.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DBXrsxZQ.js +2 -0
- package/dist/web-ui/_app/immutable/chunks/Da_hHMuA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Do6LchSF.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DoNPtcAw.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DtUbXRZz.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DyFPRlLl.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DzAP8lRM.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DzVXElzN.js +2 -0
- package/dist/web-ui/_app/immutable/chunks/aoPBFken.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/i-XnOIX0.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/laxtrUO3.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/q1nIWgqB.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/sTLbk5Nm.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/vwKgQu5P.js +5 -0
- package/dist/web-ui/_app/immutable/entry/app.BCwMcqnT.js +2 -0
- package/dist/web-ui/_app/immutable/entry/start.wKCQH-tt.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/0.CjGVMG74.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/1.B6_AIPan.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/2.q4oCS7Ws.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/3.rTKZf9o2.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/4.DVIDRu1d.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/5.8PtPXIOd.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/6.ZZrTemy_.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/7.IP-gxCxi.js +1 -0
- package/dist/web-ui/_app/version.json +1 -0
- package/dist/web-ui/index.html +36 -0
- package/dist/web-ui/robots.txt +3 -0
- package/package.json +3 -2
- package/plugin/.claude-plugin/marketplace.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/plugins/kspec/skills/create-workflow/SKILL.md +1 -1
- package/plugin/plugins/kspec/skills/{observations → observe}/SKILL.md +1 -1
- package/plugin/plugins/kspec/skills/plan/SKILL.md +1 -1
- package/plugin/plugins/kspec/skills/task-work/SKILL.md +26 -3
- package/plugin/plugins/kspec/skills/triage-inbox/SKILL.md +1 -1
- package/plugin/plugins/kspec/skills/writing-specs/SKILL.md +1 -1
- package/templates/agents-sections/01-quick-start.md +1 -0
- package/templates/agents-sections/06-ralph-loop.md +64 -11
- package/templates/skills/create-workflow/SKILL.md +1 -1
- package/templates/skills/manifest.yaml +1 -1
- package/templates/skills/plan/SKILL.md +1 -1
- package/templates/skills/task-work/SKILL.md +26 -3
- package/templates/skills/triage-inbox/SKILL.md +1 -1
- package/templates/skills/writing-specs/SKILL.md +1 -1
- package/dist/ralph/cli-renderer.d.ts +0 -27
- package/dist/ralph/cli-renderer.d.ts.map +0 -1
- package/dist/ralph/cli-renderer.js +0 -250
- package/dist/ralph/cli-renderer.js.map +0 -1
- package/dist/ralph/events.d.ts +0 -65
- package/dist/ralph/events.d.ts.map +0 -1
- package/dist/ralph/events.js +0 -600
- package/dist/ralph/events.js.map +0 -1
- package/dist/ralph/index.d.ts +0 -11
- package/dist/ralph/index.d.ts.map +0 -1
- package/dist/ralph/index.js +0 -16
- package/dist/ralph/index.js.map +0 -1
- package/dist/ralph/loop-errors.d.ts +0 -83
- package/dist/ralph/loop-errors.d.ts.map +0 -1
- package/dist/ralph/loop-errors.js +0 -150
- package/dist/ralph/loop-errors.js.map +0 -1
- package/dist/ralph/subagent.d.ts +0 -96
- package/dist/ralph/subagent.d.ts.map +0 -1
- package/dist/ralph/subagent.js +0 -195
- package/dist/ralph/subagent.js.map +0 -1
- package/dist/ralph/wrap-up.d.ts +0 -127
- package/dist/ralph/wrap-up.d.ts.map +0 -1
- package/dist/ralph/wrap-up.js +0 -271
- package/dist/ralph/wrap-up.js.map +0 -1
- /package/templates/skills/{observations → observe}/SKILL.md +0 -0
package/dist/ralph/events.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ralph Event System
|
|
3
|
-
*
|
|
4
|
-
* Translates ACP SessionUpdate events into structured RalphEvents.
|
|
5
|
-
* This layer is pure data - no rendering concerns. Enables future
|
|
6
|
-
* TUI or other renderers to consume the same event stream.
|
|
7
|
-
*/
|
|
8
|
-
import type { SessionUpdate } from "../acp/types.js";
|
|
9
|
-
export type RalphEventType = "agent_message" | "agent_thought" | "tool_start" | "tool_update" | "tool_result" | "status";
|
|
10
|
-
export interface RalphEvent {
|
|
11
|
-
type: RalphEventType;
|
|
12
|
-
timestamp: number;
|
|
13
|
-
data: RalphEventData;
|
|
14
|
-
}
|
|
15
|
-
export type RalphEventData = AgentMessageData | AgentThoughtData | ToolStartData | ToolUpdateData | ToolResultData | StatusData;
|
|
16
|
-
export interface AgentMessageData {
|
|
17
|
-
kind: "agent_message";
|
|
18
|
-
content: string;
|
|
19
|
-
isStreaming: boolean;
|
|
20
|
-
}
|
|
21
|
-
export interface AgentThoughtData {
|
|
22
|
-
kind: "agent_thought";
|
|
23
|
-
content: string;
|
|
24
|
-
isStreaming: boolean;
|
|
25
|
-
}
|
|
26
|
-
export interface ToolStartData {
|
|
27
|
-
kind: "tool_start";
|
|
28
|
-
toolCallId: string;
|
|
29
|
-
tool: string;
|
|
30
|
-
summary: string;
|
|
31
|
-
input: unknown;
|
|
32
|
-
}
|
|
33
|
-
export interface ToolUpdateData {
|
|
34
|
-
kind: "tool_update";
|
|
35
|
-
toolCallId: string;
|
|
36
|
-
tool: string;
|
|
37
|
-
status: "pending" | "running";
|
|
38
|
-
summary?: string;
|
|
39
|
-
}
|
|
40
|
-
export interface ToolResultData {
|
|
41
|
-
kind: "tool_result";
|
|
42
|
-
toolCallId: string;
|
|
43
|
-
tool: string;
|
|
44
|
-
status: "completed" | "failed" | "cancelled";
|
|
45
|
-
output?: string;
|
|
46
|
-
truncated: boolean;
|
|
47
|
-
}
|
|
48
|
-
export interface StatusData {
|
|
49
|
-
kind: "status";
|
|
50
|
-
status: string;
|
|
51
|
-
message?: string;
|
|
52
|
-
}
|
|
53
|
-
export interface RalphTranslator {
|
|
54
|
-
/**
|
|
55
|
-
* Translate an ACP SessionUpdate to a RalphEvent.
|
|
56
|
-
* Returns null if the update should be suppressed.
|
|
57
|
-
*/
|
|
58
|
-
translate(update: SessionUpdate): RalphEvent | null;
|
|
59
|
-
/**
|
|
60
|
-
* Signal end of stream. Returns final event if there's pending state.
|
|
61
|
-
*/
|
|
62
|
-
finalize(): RalphEvent | null;
|
|
63
|
-
}
|
|
64
|
-
export declare function createTranslator(): RalphTranslator;
|
|
65
|
-
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/ralph/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMrD,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,eAAe,GACf,YAAY,GACZ,aAAa,GACb,aAAa,GACb,QAAQ,CAAC;AAEb,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,cAAc,GACd,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAAC;IAEpD;;OAEG;IACH,QAAQ,IAAI,UAAU,GAAG,IAAI,CAAC;CAC/B;AA2VD,wBAAgB,gBAAgB,IAAI,eAAe,CAqWlD"}
|
package/dist/ralph/events.js
DELETED
|
@@ -1,600 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ralph Event System
|
|
3
|
-
*
|
|
4
|
-
* Translates ACP SessionUpdate events into structured RalphEvents.
|
|
5
|
-
* This layer is pure data - no rendering concerns. Enables future
|
|
6
|
-
* TUI or other renderers to consume the same event stream.
|
|
7
|
-
*/
|
|
8
|
-
// ============================================================================
|
|
9
|
-
// Tool Summary Extraction
|
|
10
|
-
// ============================================================================
|
|
11
|
-
/**
|
|
12
|
-
* Extract a human-readable summary for a tool call.
|
|
13
|
-
* Based on kynetic ui-event-translator.ts patterns.
|
|
14
|
-
*/
|
|
15
|
-
function getToolSummary(tool, input) {
|
|
16
|
-
const inp = input;
|
|
17
|
-
switch (tool) {
|
|
18
|
-
case "Bash": {
|
|
19
|
-
const cmd = inp.command;
|
|
20
|
-
if (cmd) {
|
|
21
|
-
return cmd.length > 50 ? `${cmd.slice(0, 47)}...` : cmd;
|
|
22
|
-
}
|
|
23
|
-
return "";
|
|
24
|
-
}
|
|
25
|
-
case "Read":
|
|
26
|
-
case "Write":
|
|
27
|
-
case "Edit": {
|
|
28
|
-
const filePath = inp.file_path;
|
|
29
|
-
if (filePath) {
|
|
30
|
-
// Extract filename from path
|
|
31
|
-
const parts = filePath.split("/");
|
|
32
|
-
return parts[parts.length - 1] || filePath;
|
|
33
|
-
}
|
|
34
|
-
return "";
|
|
35
|
-
}
|
|
36
|
-
case "Grep": {
|
|
37
|
-
const pattern = inp.pattern;
|
|
38
|
-
return pattern ? `/${pattern}/` : "";
|
|
39
|
-
}
|
|
40
|
-
case "Glob": {
|
|
41
|
-
const pattern = inp.pattern;
|
|
42
|
-
return pattern || "";
|
|
43
|
-
}
|
|
44
|
-
case "WebSearch": {
|
|
45
|
-
const query = inp.query;
|
|
46
|
-
return query || "";
|
|
47
|
-
}
|
|
48
|
-
case "Task": {
|
|
49
|
-
const desc = inp.description;
|
|
50
|
-
return desc || "";
|
|
51
|
-
}
|
|
52
|
-
case "TodoWrite": {
|
|
53
|
-
const todos = inp.todos;
|
|
54
|
-
if (todos && todos.length > 0) {
|
|
55
|
-
return `${todos.length} item(s)`;
|
|
56
|
-
}
|
|
57
|
-
return "";
|
|
58
|
-
}
|
|
59
|
-
default:
|
|
60
|
-
return "";
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Extract tool name from SessionUpdate.
|
|
65
|
-
* Handles Claude Code's _meta.claudeCode.toolName pattern and MCP prefixes.
|
|
66
|
-
*/
|
|
67
|
-
function extractToolName(update) {
|
|
68
|
-
// Try _meta.claudeCode.toolName first (Claude Code pattern)
|
|
69
|
-
const meta = update._meta;
|
|
70
|
-
if (meta) {
|
|
71
|
-
const claudeCode = meta.claudeCode;
|
|
72
|
-
if (claudeCode?.toolName) {
|
|
73
|
-
return normalizeTool(claudeCode.toolName);
|
|
74
|
-
}
|
|
75
|
-
if (meta.toolName) {
|
|
76
|
-
return normalizeTool(meta.toolName);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Fall back to name field
|
|
80
|
-
if (update.name) {
|
|
81
|
-
return normalizeTool(update.name);
|
|
82
|
-
}
|
|
83
|
-
// Fall back to title
|
|
84
|
-
if (update.title) {
|
|
85
|
-
return normalizeTool(update.title);
|
|
86
|
-
}
|
|
87
|
-
return "unknown";
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Normalize tool name by stripping MCP prefixes.
|
|
91
|
-
*/
|
|
92
|
-
function normalizeTool(name) {
|
|
93
|
-
// Strip mcp__<namespace>__ prefix
|
|
94
|
-
const mcpMatch = name.match(/^mcp__[^_]+__(.+)$/);
|
|
95
|
-
if (mcpMatch) {
|
|
96
|
-
return mcpMatch[1];
|
|
97
|
-
}
|
|
98
|
-
return name;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Extract tool output, handling Claude Code's non-standard delivery.
|
|
102
|
-
*/
|
|
103
|
-
function extractToolOutput(update) {
|
|
104
|
-
// Try rawOutput first
|
|
105
|
-
if (update.rawOutput !== undefined) {
|
|
106
|
-
return truncateOutput(stringify(update.rawOutput));
|
|
107
|
-
}
|
|
108
|
-
// Try _meta.claudeCode.toolResponse (Claude Code pattern)
|
|
109
|
-
// toolResponse is an object with stdout/stderr, not a string
|
|
110
|
-
const meta = update._meta;
|
|
111
|
-
if (meta) {
|
|
112
|
-
const claudeCode = meta.claudeCode;
|
|
113
|
-
if (claudeCode?.toolResponse !== undefined) {
|
|
114
|
-
const toolResponse = claudeCode.toolResponse;
|
|
115
|
-
// Extract stdout, falling back to stringifying the whole response
|
|
116
|
-
if (typeof toolResponse.stdout === "string") {
|
|
117
|
-
const combined = toolResponse.stdout +
|
|
118
|
-
(toolResponse.stderr ? `\n${toolResponse.stderr}` : "");
|
|
119
|
-
return truncateOutput(combined.trim());
|
|
120
|
-
}
|
|
121
|
-
return truncateOutput(stringify(toolResponse));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Try output field
|
|
125
|
-
if (update.output !== undefined) {
|
|
126
|
-
return truncateOutput(stringify(update.output));
|
|
127
|
-
}
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Extract original (non-truncated) output for truncation detection.
|
|
132
|
-
*/
|
|
133
|
-
function extractOriginalOutput(update) {
|
|
134
|
-
if (update.rawOutput !== undefined) {
|
|
135
|
-
return stringify(update.rawOutput);
|
|
136
|
-
}
|
|
137
|
-
const meta = update._meta;
|
|
138
|
-
if (meta) {
|
|
139
|
-
const claudeCode = meta.claudeCode;
|
|
140
|
-
if (claudeCode?.toolResponse !== undefined) {
|
|
141
|
-
const toolResponse = claudeCode.toolResponse;
|
|
142
|
-
if (typeof toolResponse.stdout === "string") {
|
|
143
|
-
return (toolResponse.stdout +
|
|
144
|
-
(toolResponse.stderr ? `\n${toolResponse.stderr}` : "")).trim();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
if (update.output !== undefined) {
|
|
149
|
-
return stringify(update.output);
|
|
150
|
-
}
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Safely stringify a value that may be a string, array of content blocks, or object.
|
|
155
|
-
* Handles ACP tool results delivered as arrays like [{type:'text',text:'...'},...]
|
|
156
|
-
*/
|
|
157
|
-
function stringify(value) {
|
|
158
|
-
if (typeof value === "string")
|
|
159
|
-
return value;
|
|
160
|
-
if (Array.isArray(value)) {
|
|
161
|
-
// Array of content blocks: extract .text fields
|
|
162
|
-
const texts = value
|
|
163
|
-
.map((item) => typeof item === "string"
|
|
164
|
-
? item
|
|
165
|
-
: typeof item === "object" && item !== null && "text" in item
|
|
166
|
-
? String(item.text)
|
|
167
|
-
: JSON.stringify(item))
|
|
168
|
-
.filter(Boolean);
|
|
169
|
-
return texts.join("\n");
|
|
170
|
-
}
|
|
171
|
-
if (typeof value === "object" && value !== null) {
|
|
172
|
-
return JSON.stringify(value);
|
|
173
|
-
}
|
|
174
|
-
return String(value);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Truncate output to reasonable size.
|
|
178
|
-
*/
|
|
179
|
-
function truncateOutput(output) {
|
|
180
|
-
const MAX_LINES = 20;
|
|
181
|
-
const MAX_CHARS = 1000;
|
|
182
|
-
const lines = output.split("\n");
|
|
183
|
-
if (lines.length > MAX_LINES) {
|
|
184
|
-
return lines.slice(0, MAX_LINES).join("\n");
|
|
185
|
-
}
|
|
186
|
-
if (output.length > MAX_CHARS) {
|
|
187
|
-
return output.slice(0, MAX_CHARS);
|
|
188
|
-
}
|
|
189
|
-
return output;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Check if output was truncated.
|
|
193
|
-
*/
|
|
194
|
-
function wasOutputTruncated(original, truncated) {
|
|
195
|
-
if (!original || !truncated)
|
|
196
|
-
return false;
|
|
197
|
-
return original.length > truncated.length;
|
|
198
|
-
}
|
|
199
|
-
// ============================================================================
|
|
200
|
-
// Noise Suppression
|
|
201
|
-
// ============================================================================
|
|
202
|
-
/**
|
|
203
|
-
* Noise patterns to strip from streaming content.
|
|
204
|
-
* These match Claude Code hook warning messages that leak into agent output.
|
|
205
|
-
* Pattern structure handles various noise forms:
|
|
206
|
-
* - "No on[Pre|Post]ToolUseHook found"
|
|
207
|
-
* - "No on[Pre|Post]ToolUseHook found for tool use"
|
|
208
|
-
* - "No on[Pre|Post]ToolUseHook found for tool use ID: toolu_<24 chars>"
|
|
209
|
-
* Tool IDs are exactly 24 base62 characters after "toolu_".
|
|
210
|
-
*/
|
|
211
|
-
const NOISE_PATTERNS = [
|
|
212
|
-
/No onPostToolUseHook found(?:\s+for\s+tool\s+use(?:\s+ID:\s*toolu_[A-Za-z0-9]{24})?)?/gi,
|
|
213
|
-
/No onPreToolUseHook found(?:\s+for\s+tool\s+use(?:\s+ID:\s*toolu_[A-Za-z0-9]{24})?)?/gi,
|
|
214
|
-
];
|
|
215
|
-
/**
|
|
216
|
-
* Full noise pattern strings (without tool ID suffix).
|
|
217
|
-
* Used to check if a suffix could be a prefix of a noise pattern.
|
|
218
|
-
*/
|
|
219
|
-
const NOISE_PATTERN_STRINGS = [
|
|
220
|
-
"No onPostToolUseHook found for tool use ID: toolu_",
|
|
221
|
-
"No onPreToolUseHook found for tool use ID: toolu_",
|
|
222
|
-
"No onPostToolUseHook found for tool use",
|
|
223
|
-
"No onPreToolUseHook found for tool use",
|
|
224
|
-
"No onPostToolUseHook found",
|
|
225
|
-
"No onPreToolUseHook found",
|
|
226
|
-
];
|
|
227
|
-
// Maximum length to check for potential partial match
|
|
228
|
-
const MAX_NOISE_PATTERN_LEN = Math.max(...NOISE_PATTERN_STRINGS.map((p) => p.length)) + 24; // +24 for tool ID
|
|
229
|
-
/**
|
|
230
|
-
* Check if the content ends with a potential partial noise pattern.
|
|
231
|
-
* Returns the partial match length if found, 0 otherwise.
|
|
232
|
-
*
|
|
233
|
-
* A partial match occurs when:
|
|
234
|
-
* 1. The content ends with something that is a PREFIX of a noise pattern
|
|
235
|
-
* (e.g., "No on" or "No onPostToolUseHook found"), OR
|
|
236
|
-
* 2. The content ends with a complete noise pattern prefix followed by
|
|
237
|
-
* a partial tool ID (< 24 chars)
|
|
238
|
-
*/
|
|
239
|
-
function getPartialNoiseLength(content) {
|
|
240
|
-
// Check suffixes of decreasing length (longer matches first)
|
|
241
|
-
const maxCheck = Math.min(content.length, MAX_NOISE_PATTERN_LEN);
|
|
242
|
-
for (let len = maxCheck; len > 0; len--) {
|
|
243
|
-
const suffix = content.slice(-len);
|
|
244
|
-
for (const pattern of NOISE_PATTERN_STRINGS) {
|
|
245
|
-
// Case 1: suffix is a prefix of a pattern (suffix is shorter than pattern)
|
|
246
|
-
// e.g., suffix="No onPost" is a prefix of pattern="No onPostToolUseHook found..."
|
|
247
|
-
if (suffix.length <= pattern.length && pattern.startsWith(suffix)) {
|
|
248
|
-
return len;
|
|
249
|
-
}
|
|
250
|
-
// Case 2: suffix starts with a complete toolu_ pattern and has partial tool ID
|
|
251
|
-
// e.g., suffix="No onPostToolUseHook found for tool use ID: toolu_ABC123"
|
|
252
|
-
// where the tool ID is < 24 chars
|
|
253
|
-
if (pattern.endsWith("toolu_") && suffix.startsWith(pattern)) {
|
|
254
|
-
const afterToolu = suffix.slice(pattern.length);
|
|
255
|
-
// If tool ID is incomplete (< 24 chars) and valid chars, it's a partial match
|
|
256
|
-
if (afterToolu.length < 24 && /^[A-Za-z0-9]*$/.test(afterToolu)) {
|
|
257
|
-
return len;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
return 0;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Strip noise patterns from content.
|
|
266
|
-
* Returns the cleaned content, or null if nothing remains after stripping.
|
|
267
|
-
* Preserves whitespace-only chunks that aren't noise to maintain streaming formatting.
|
|
268
|
-
*/
|
|
269
|
-
function stripNoise(content) {
|
|
270
|
-
let cleaned = content;
|
|
271
|
-
for (const pattern of NOISE_PATTERNS) {
|
|
272
|
-
cleaned = cleaned.replace(pattern, "");
|
|
273
|
-
}
|
|
274
|
-
// If nothing was stripped, return original (preserves pure whitespace chunks)
|
|
275
|
-
if (cleaned === content) {
|
|
276
|
-
return content;
|
|
277
|
-
}
|
|
278
|
-
// Something was stripped - return cleaned if non-empty, null otherwise
|
|
279
|
-
return cleaned.length > 0 ? cleaned : null;
|
|
280
|
-
}
|
|
281
|
-
export function createTranslator() {
|
|
282
|
-
const state = {
|
|
283
|
-
sessionStart: Date.now(),
|
|
284
|
-
activeMessage: null,
|
|
285
|
-
pendingTools: new Map(),
|
|
286
|
-
noiseBuffer: "",
|
|
287
|
-
};
|
|
288
|
-
function getTimestamp() {
|
|
289
|
-
return Date.now() - state.sessionStart;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Process a text chunk with boundary-aware noise stripping.
|
|
293
|
-
* Returns the safe content to emit, and updates the noise buffer.
|
|
294
|
-
* Returns null if the entire chunk should be suppressed.
|
|
295
|
-
*
|
|
296
|
-
* The key insight is that we need to check for partial noise patterns
|
|
297
|
-
* BEFORE stripping, because partial patterns won't match the full regex
|
|
298
|
-
* and could leave fragments behind.
|
|
299
|
-
*/
|
|
300
|
-
function processChunkWithBuffer(text) {
|
|
301
|
-
// Combine buffer with new text
|
|
302
|
-
const combined = state.noiseBuffer + text;
|
|
303
|
-
state.noiseBuffer = "";
|
|
304
|
-
// First, check if the combined content ends with a partial noise pattern
|
|
305
|
-
// This must happen BEFORE stripping, because partial patterns at the end
|
|
306
|
-
// won't match the regex and could leave fragments
|
|
307
|
-
const partialLen = getPartialNoiseLength(combined);
|
|
308
|
-
if (partialLen > 0) {
|
|
309
|
-
// Buffer the potential partial match
|
|
310
|
-
state.noiseBuffer = combined.slice(-partialLen);
|
|
311
|
-
const safeContent = combined.slice(0, -partialLen);
|
|
312
|
-
// Strip complete noise patterns from the safe content
|
|
313
|
-
const cleaned = stripNoise(safeContent);
|
|
314
|
-
if (cleaned === null || cleaned.length === 0) {
|
|
315
|
-
return null;
|
|
316
|
-
}
|
|
317
|
-
return cleaned;
|
|
318
|
-
}
|
|
319
|
-
// No partial match at the end - strip complete patterns
|
|
320
|
-
const cleaned = stripNoise(combined);
|
|
321
|
-
if (cleaned === null) {
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
return cleaned;
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Flush any remaining buffer content at finalization.
|
|
328
|
-
* Strips any complete noise patterns from the buffer.
|
|
329
|
-
*/
|
|
330
|
-
function flushBuffer() {
|
|
331
|
-
const buffered = state.noiseBuffer;
|
|
332
|
-
state.noiseBuffer = "";
|
|
333
|
-
// Strip any complete noise from the buffer
|
|
334
|
-
const cleaned = stripNoise(buffered);
|
|
335
|
-
return cleaned ?? "";
|
|
336
|
-
}
|
|
337
|
-
function translate(update) {
|
|
338
|
-
const updateType = update.sessionUpdate;
|
|
339
|
-
const timestamp = getTimestamp();
|
|
340
|
-
switch (updateType) {
|
|
341
|
-
// ─── Content Chunks ─────────────────────────────────────────────────────
|
|
342
|
-
case "agent_message_chunk": {
|
|
343
|
-
const content = update.content;
|
|
344
|
-
if (content?.type === "text" && typeof content.text === "string") {
|
|
345
|
-
// Empty string signals finalization
|
|
346
|
-
if (content.text === "") {
|
|
347
|
-
if (state.activeMessage?.type === "agent_message") {
|
|
348
|
-
// Flush buffer and strip noise from accumulated content
|
|
349
|
-
const buffered = flushBuffer();
|
|
350
|
-
const combined = state.activeMessage.content + buffered;
|
|
351
|
-
const finalContent = stripNoise(combined);
|
|
352
|
-
state.activeMessage = null;
|
|
353
|
-
if (finalContent === null || finalContent.trim() === "") {
|
|
354
|
-
return null;
|
|
355
|
-
}
|
|
356
|
-
return {
|
|
357
|
-
type: "agent_message",
|
|
358
|
-
timestamp,
|
|
359
|
-
data: {
|
|
360
|
-
kind: "agent_message",
|
|
361
|
-
content: finalContent,
|
|
362
|
-
isStreaming: false,
|
|
363
|
-
},
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
// Process chunk with boundary-aware noise stripping
|
|
369
|
-
const cleanedText = processChunkWithBuffer(content.text);
|
|
370
|
-
if (cleanedText === null) {
|
|
371
|
-
return null;
|
|
372
|
-
}
|
|
373
|
-
// Accumulate content
|
|
374
|
-
if (state.activeMessage?.type === "agent_message") {
|
|
375
|
-
state.activeMessage.content += cleanedText;
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
state.activeMessage = {
|
|
379
|
-
type: "agent_message",
|
|
380
|
-
content: cleanedText,
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
return {
|
|
384
|
-
type: "agent_message",
|
|
385
|
-
timestamp,
|
|
386
|
-
data: {
|
|
387
|
-
kind: "agent_message",
|
|
388
|
-
content: cleanedText,
|
|
389
|
-
isStreaming: true,
|
|
390
|
-
},
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
return null;
|
|
394
|
-
}
|
|
395
|
-
case "agent_thought_chunk": {
|
|
396
|
-
const content = update.content;
|
|
397
|
-
if (content?.type === "text" && typeof content.text === "string") {
|
|
398
|
-
if (content.text === "") {
|
|
399
|
-
if (state.activeMessage?.type === "agent_thought") {
|
|
400
|
-
// Flush buffer and strip noise from accumulated content
|
|
401
|
-
const buffered = flushBuffer();
|
|
402
|
-
const combined = state.activeMessage.content + buffered;
|
|
403
|
-
const finalContent = stripNoise(combined);
|
|
404
|
-
state.activeMessage = null;
|
|
405
|
-
if (finalContent === null || finalContent.trim() === "") {
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
return {
|
|
409
|
-
type: "agent_thought",
|
|
410
|
-
timestamp,
|
|
411
|
-
data: {
|
|
412
|
-
kind: "agent_thought",
|
|
413
|
-
content: finalContent,
|
|
414
|
-
isStreaming: false,
|
|
415
|
-
},
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
return null;
|
|
419
|
-
}
|
|
420
|
-
// Process chunk with boundary-aware noise stripping
|
|
421
|
-
const cleanedText = processChunkWithBuffer(content.text);
|
|
422
|
-
if (cleanedText === null) {
|
|
423
|
-
return null;
|
|
424
|
-
}
|
|
425
|
-
if (state.activeMessage?.type === "agent_thought") {
|
|
426
|
-
state.activeMessage.content += cleanedText;
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
state.activeMessage = {
|
|
430
|
-
type: "agent_thought",
|
|
431
|
-
content: cleanedText,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
return {
|
|
435
|
-
type: "agent_thought",
|
|
436
|
-
timestamp,
|
|
437
|
-
data: {
|
|
438
|
-
kind: "agent_thought",
|
|
439
|
-
content: cleanedText,
|
|
440
|
-
isStreaming: true,
|
|
441
|
-
},
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
return null;
|
|
445
|
-
}
|
|
446
|
-
case "user_message_chunk": {
|
|
447
|
-
// User messages are typically the prompt we sent, skip display
|
|
448
|
-
return null;
|
|
449
|
-
}
|
|
450
|
-
// ─── Tool Events ────────────────────────────────────────────────────────
|
|
451
|
-
case "tool_call": {
|
|
452
|
-
const u = update;
|
|
453
|
-
const toolCallId = (u.tool_call_id || u.toolCallId || u.id);
|
|
454
|
-
const tool = extractToolName(u);
|
|
455
|
-
const input = u.rawInput || u.input || u.params || {};
|
|
456
|
-
const summary = getToolSummary(tool, input);
|
|
457
|
-
// Check if this is an update to an existing tool call (phased events)
|
|
458
|
-
const existing = state.pendingTools.get(toolCallId);
|
|
459
|
-
if (existing) {
|
|
460
|
-
// Update existing entry with new input if present
|
|
461
|
-
const hadSummary = getToolSummary(existing.tool, existing.input);
|
|
462
|
-
existing.input = input;
|
|
463
|
-
existing.tool = tool;
|
|
464
|
-
// Only emit update if we now have a summary we didn't have before
|
|
465
|
-
if (summary && !hadSummary) {
|
|
466
|
-
return {
|
|
467
|
-
type: "tool_update",
|
|
468
|
-
timestamp,
|
|
469
|
-
data: {
|
|
470
|
-
kind: "tool_update",
|
|
471
|
-
toolCallId,
|
|
472
|
-
tool,
|
|
473
|
-
status: "pending",
|
|
474
|
-
summary,
|
|
475
|
-
},
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
// No meaningful change, suppress event
|
|
479
|
-
return null;
|
|
480
|
-
}
|
|
481
|
-
// First time seeing this tool_call_id - create entry and emit tool_start
|
|
482
|
-
state.pendingTools.set(toolCallId, {
|
|
483
|
-
tool,
|
|
484
|
-
input,
|
|
485
|
-
startTime: timestamp,
|
|
486
|
-
});
|
|
487
|
-
return {
|
|
488
|
-
type: "tool_start",
|
|
489
|
-
timestamp,
|
|
490
|
-
data: {
|
|
491
|
-
kind: "tool_start",
|
|
492
|
-
toolCallId,
|
|
493
|
-
tool,
|
|
494
|
-
summary,
|
|
495
|
-
input,
|
|
496
|
-
},
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
case "tool_call_update": {
|
|
500
|
-
const u = update;
|
|
501
|
-
const toolCallId = (u.tool_call_id || u.toolCallId || u.id);
|
|
502
|
-
const status = u.status;
|
|
503
|
-
const pending = state.pendingTools.get(toolCallId);
|
|
504
|
-
const tool = pending?.tool || extractToolName(u);
|
|
505
|
-
// Check if rawInput arrived with this update (phased event pattern)
|
|
506
|
-
const newInput = u.rawInput || u.input || u.params;
|
|
507
|
-
if (newInput && pending) {
|
|
508
|
-
const oldSummary = getToolSummary(pending.tool, pending.input);
|
|
509
|
-
const newSummary = getToolSummary(tool, newInput);
|
|
510
|
-
if (newSummary && !oldSummary) {
|
|
511
|
-
// Input became available - update pending entry and emit summary
|
|
512
|
-
pending.input = newInput;
|
|
513
|
-
pending.tool = tool;
|
|
514
|
-
return {
|
|
515
|
-
type: "tool_update",
|
|
516
|
-
timestamp,
|
|
517
|
-
data: {
|
|
518
|
-
kind: "tool_update",
|
|
519
|
-
toolCallId,
|
|
520
|
-
tool,
|
|
521
|
-
status: "pending",
|
|
522
|
-
summary: newSummary,
|
|
523
|
-
},
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
// Update the pending entry even if summary didn't change
|
|
527
|
-
pending.input = newInput;
|
|
528
|
-
}
|
|
529
|
-
// Non-terminal status update
|
|
530
|
-
if (status === "pending" ||
|
|
531
|
-
status === "in_progress" ||
|
|
532
|
-
status === "running") {
|
|
533
|
-
return {
|
|
534
|
-
type: "tool_update",
|
|
535
|
-
timestamp,
|
|
536
|
-
data: {
|
|
537
|
-
kind: "tool_update",
|
|
538
|
-
toolCallId,
|
|
539
|
-
tool,
|
|
540
|
-
status: status === "in_progress"
|
|
541
|
-
? "running"
|
|
542
|
-
: status,
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
// Terminal status - treat as result
|
|
547
|
-
if (status === "completed" ||
|
|
548
|
-
status === "failed" ||
|
|
549
|
-
status === "cancelled") {
|
|
550
|
-
const rawOutput = extractToolOutput(u);
|
|
551
|
-
const originalOutput = extractOriginalOutput(u);
|
|
552
|
-
state.pendingTools.delete(toolCallId);
|
|
553
|
-
return {
|
|
554
|
-
type: "tool_result",
|
|
555
|
-
timestamp,
|
|
556
|
-
data: {
|
|
557
|
-
kind: "tool_result",
|
|
558
|
-
toolCallId,
|
|
559
|
-
tool,
|
|
560
|
-
status,
|
|
561
|
-
output: rawOutput,
|
|
562
|
-
truncated: wasOutputTruncated(originalOutput, rawOutput),
|
|
563
|
-
},
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
return null;
|
|
567
|
-
}
|
|
568
|
-
// Note: 'status' is not a SessionUpdate type in the ACP spec.
|
|
569
|
-
// Status changes come through other mechanisms (e.g., prompt completion).
|
|
570
|
-
default:
|
|
571
|
-
// Unknown update type - ignore
|
|
572
|
-
return null;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
function finalize() {
|
|
576
|
-
if (state.activeMessage) {
|
|
577
|
-
// Flush buffer and strip noise from accumulated content
|
|
578
|
-
const buffered = flushBuffer();
|
|
579
|
-
const combined = state.activeMessage.content + buffered;
|
|
580
|
-
const finalContent = stripNoise(combined);
|
|
581
|
-
const type = state.activeMessage.type;
|
|
582
|
-
state.activeMessage = null;
|
|
583
|
-
if (finalContent === null || finalContent.trim() === "") {
|
|
584
|
-
return null;
|
|
585
|
-
}
|
|
586
|
-
return {
|
|
587
|
-
type,
|
|
588
|
-
timestamp: getTimestamp(),
|
|
589
|
-
data: {
|
|
590
|
-
kind: type,
|
|
591
|
-
content: finalContent,
|
|
592
|
-
isStreaming: false,
|
|
593
|
-
},
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
return null;
|
|
597
|
-
}
|
|
598
|
-
return { translate, finalize };
|
|
599
|
-
}
|
|
600
|
-
//# sourceMappingURL=events.js.map
|