claude-code-acp-ts 0.99.2 → 0.99.3

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.
@@ -70,10 +70,12 @@ export declare class ContextCompactionLifecycle {
70
70
  *
71
71
  * A `compaction_update` entity still `in_progress` here never received its
72
72
  * terminal signal from the runtime and gets its one terminal status,
73
- * `cancelled`. The legacy tool call is deliberately left as it was (an
74
- * `in_progress` call): ACP `ToolCallStatus` has no cancelled state and that
75
- * presentation's behavior predates this lifecycle. Never throws — a failed
76
- * send is logged, so callers can settle the turn unconditionally.
73
+ * `cancelled`. The legacy tool call has no `cancelled` status in ACP v1, so
74
+ * it is settled as `completed` with the outcome in `content` instead of
75
+ * being left `in_progress`: a client that counts unclosed tool calls would
76
+ * otherwise resend it after the turn, out of its original position. Never
77
+ * throws — a failed send is logged, so callers can settle the turn
78
+ * unconditionally.
77
79
  */
78
80
  reset(): Promise<void>;
79
81
  /** Abandon the current work before settling its prompt or tearing down the
@@ -1 +1 @@
1
- {"version":3,"file":"context-compaction.d.ts","sourceRoot":"","sources":["../src/context-compaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-compaction.d.ts","sourceRoot":"","sources":["../src/context-compaction.ts"],"names":[],"mappings":"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"}
@@ -123,24 +123,30 @@ export class ContextCompactionLifecycle {
123
123
  *
124
124
  * A `compaction_update` entity still `in_progress` here never received its
125
125
  * terminal signal from the runtime and gets its one terminal status,
126
- * `cancelled`. The legacy tool call is deliberately left as it was (an
127
- * `in_progress` call): ACP `ToolCallStatus` has no cancelled state and that
128
- * presentation's behavior predates this lifecycle. Never throws — a failed
129
- * send is logged, so callers can settle the turn unconditionally.
126
+ * `cancelled`. The legacy tool call has no `cancelled` status in ACP v1, so
127
+ * it is settled as `completed` with the outcome in `content` instead of
128
+ * being left `in_progress`: a client that counts unclosed tool calls would
129
+ * otherwise resend it after the turn, out of its original position. Never
130
+ * throws — a failed send is logged, so callers can settle the turn
131
+ * unconditionally.
130
132
  */
131
133
  async reset() {
132
134
  const state = this.activeCompaction;
133
135
  this.activeCompaction = undefined;
134
136
  this.outputDelivered = false;
135
137
  this.duplicateErrorOutput = undefined;
136
- if (!state || state.terminalStatus || this.presentation !== "compaction_update")
138
+ if (!state || state.terminalStatus)
137
139
  return;
138
140
  state.terminalStatus = "cancelled";
139
- await this.sendQuietly({
140
- sessionUpdate: "compaction_update",
141
- compactionId: state.compactionId,
142
- status: "cancelled",
143
- }, "cancelled compaction");
141
+ if (this.presentation === "compaction_update") {
142
+ await this.sendQuietly({
143
+ sessionUpdate: "compaction_update",
144
+ compactionId: state.compactionId,
145
+ status: "cancelled",
146
+ }, "cancelled compaction");
147
+ return;
148
+ }
149
+ await this.sendQuietly(compactionToolCall.settled(state.compactionId, undefined, this.airClient), "settled compaction");
144
150
  }
145
151
  /** Abandon the current work before settling its prompt or tearing down the
146
152
  * stream. Unlike a normal result boundary, its pending hooks are not safe
@@ -296,7 +302,12 @@ export class ContextCompactionLifecycle {
296
302
  });
297
303
  return;
298
304
  }
299
- await this.send(compactionToolCall.finished(state.compactionId, opened || firstTerminal ? status : undefined, metadata, opened, this.airClient));
305
+ await this.send(compactionToolCall.finished(state.compactionId,
306
+ // A status-less update is a patch for clients that merge, but a client
307
+ // that replaces the whole call reads it as "no longer terminal" and
308
+ // leaves the call running. Repeating the terminal status on the
309
+ // enriching update is idempotent for both.
310
+ opened || firstTerminal || enrichTerminal ? status : undefined, metadata, opened, this.airClient));
300
311
  }
301
312
  /** Make `compactionId` the active entity, moving a pending hook summary onto
302
313
  * it, and mark compaction output as delivered for the owning turn. */
@@ -17,6 +17,16 @@ type ToolCallUpdate = SessionNotification["update"];
17
17
  export declare const compactionToolCall: {
18
18
  started(compactionId: string, airClient?: boolean): ToolCallUpdate;
19
19
  inProgress(compactionId: string, airClient?: boolean): ToolCallUpdate;
20
+ /**
21
+ * Settle a compaction that was abandoned at a turn boundary, so the call
22
+ * does not stay `in_progress` forever.
23
+ *
24
+ * ACP v1's `ToolCallStatus` has no `cancelled` value, so this closes as
25
+ * `completed` and says what actually happened in `content`. Clients that
26
+ * treat a call without a terminal status as unclosed would otherwise resend
27
+ * it later, out of order.
28
+ */
29
+ settled(compactionId: string, note?: string, airClient?: boolean): ToolCallUpdate;
20
30
  /** The terminal report. A missed opening makes it the first report, a `tool_call`. */
21
31
  finished(compactionId: string, status: "completed" | "failed" | undefined, facts: CompactionFacts, first: boolean, airClient?: boolean): ToolCallUpdate;
22
32
  };
@@ -1 +1 @@
1
- {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EACL,KAAK,yBAAyB,EAE/B,MAAM,kCAAkC,CAAC;AAG1C,KAAK,eAAe,GAAG,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AAClE,KAAK,cAAc,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AAIpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB;0BACP,MAAM,wBAAsB,cAAc;6BAWvC,MAAM,wBAAsB,cAAc;IASnE,sFAAsF;2BAEtE,MAAM,UACZ,WAAW,GAAG,QAAQ,GAAG,SAAS,SACnC,eAAe,SACf,OAAO,wBAEb,cAAc;CA2BlB,CAAC"}
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EACL,KAAK,yBAAyB,EAE/B,MAAM,kCAAkC,CAAC;AAG1C,KAAK,eAAe,GAAG,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AAClE,KAAK,cAAc,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AAgCpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB;0BACP,MAAM,wBAAsB,cAAc;6BAWvC,MAAM,wBAAsB,cAAc;IASnE;;;;;;;;OAQG;0BACmB,MAAM,uCAA2C,cAAc;IAUrF,sFAAsF;2BAEtE,MAAM,UACZ,WAAW,GAAG,QAAQ,GAAG,SAAS,SACnC,eAAe,SACf,OAAO,wBAEb,cAAc;CAqClB,CAAC"}
@@ -1,6 +1,31 @@
1
1
  import { createContextCompactionMeta, } from "../../context-compaction-meta.js";
2
2
  import { textContent } from "../content.js";
3
3
  const TITLE = "Compact conversation";
4
+ /** The note a settled (never finished) compaction carries as its result. */
5
+ const SETTLED_NOTE = "Context compaction was cancelled before it finished; the conversation was not summarized.";
6
+ /** The human-readable result of a compaction, for clients that show `content`. */
7
+ function factsText(facts) {
8
+ // Widened to `string`: upstream added the `idle` trigger after this release,
9
+ // and a comparison against it must not be a type error here or after the
10
+ // next rebase.
11
+ const trigger = facts.trigger;
12
+ const what = trigger === "idle"
13
+ ? "Context compacted while idle"
14
+ : trigger === "manual"
15
+ ? "Context compacted on request"
16
+ : "Context compacted";
17
+ const details = [];
18
+ if (typeof facts.preTokens === "number" && typeof facts.postTokens === "number") {
19
+ details.push(`${facts.preTokens} -> ${facts.postTokens} tokens`);
20
+ }
21
+ else if (typeof facts.postTokens === "number") {
22
+ details.push(`${facts.postTokens} tokens after compaction`);
23
+ }
24
+ if (typeof facts.durationMs === "number") {
25
+ details.push(`${(facts.durationMs / 1000).toFixed(1)}s`);
26
+ }
27
+ return details.length > 0 ? `${what}: ${details.join(", ")}` : what;
28
+ }
4
29
  /**
5
30
  * The synthetic "Compact conversation" tool call, for a client without the
6
31
  * ACP compaction updates.
@@ -32,11 +57,36 @@ export const compactionToolCall = {
32
57
  _meta: meta({}, airClient),
33
58
  };
34
59
  },
60
+ /**
61
+ * Settle a compaction that was abandoned at a turn boundary, so the call
62
+ * does not stay `in_progress` forever.
63
+ *
64
+ * ACP v1's `ToolCallStatus` has no `cancelled` value, so this closes as
65
+ * `completed` and says what actually happened in `content`. Clients that
66
+ * treat a call without a terminal status as unclosed would otherwise resend
67
+ * it later, out of order.
68
+ */
69
+ settled(compactionId, note = SETTLED_NOTE, airClient = false) {
70
+ return {
71
+ sessionUpdate: "tool_call_update",
72
+ toolCallId: compactionId,
73
+ status: "completed",
74
+ content: [textContent(note)],
75
+ _meta: meta({}, airClient),
76
+ };
77
+ },
35
78
  /** The terminal report. A missed opening makes it the first report, a `tool_call`. */
36
79
  finished(compactionId, status, facts, first, airClient = false) {
37
80
  const errorContent = status === "failed" && facts.error
38
81
  ? { content: [textContent(`Compaction failed: ${facts.error}`)] }
39
82
  : {};
83
+ // A client that renders `content` needs something to expand; `rawOutput`
84
+ // alone is opaque. The error, when there is one, is the result instead.
85
+ // AIR reads every fact from `_meta.jetbrains.air.contextCompaction`, so it
86
+ // gets no `content`: the docs ask for each fact once.
87
+ const factsContent = airClient || "content" in errorContent || Object.keys(facts).length === 0
88
+ ? {}
89
+ : { content: [textContent(factsText(facts))] };
40
90
  const rawOutput = !airClient && Object.keys(facts).length > 0 ? { rawOutput: facts } : {};
41
91
  if (first) {
42
92
  return {
@@ -46,6 +96,7 @@ export const compactionToolCall = {
46
96
  kind: "think",
47
97
  status: status ?? "completed",
48
98
  ...errorContent,
99
+ ...factsContent,
49
100
  ...rawOutput,
50
101
  _meta: meta(facts, airClient),
51
102
  };
@@ -55,6 +106,7 @@ export const compactionToolCall = {
55
106
  toolCallId: compactionId,
56
107
  ...(status ? { status } : {}),
57
108
  ...errorContent,
109
+ ...factsContent,
58
110
  ...rawOutput,
59
111
  _meta: meta(facts, airClient),
60
112
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.99.2",
6
+ "version": "0.99.3",
7
7
  "description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
8
8
  "main": "dist/lib.js",
9
9
  "types": "dist/lib.d.ts",