killeros 3.0.4 → 3.0.6

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.
@@ -87,8 +87,10 @@ type QuestionDetails = SingleQuestionDetails | MultipleQuestionDetails;
87
87
 
88
88
  export function registerQuestionTool(pi: ExtensionAPI): void {
89
89
  const customInputHistory: string[] = [];
90
+ const pendingQuestions = new Set<AbortController>();
90
91
  let customInputHistoryBytes = 0;
91
92
  const clearCustomInputHistory = (): void => {
93
+ for (const pending of pendingQuestions) pending.abort();
92
94
  customInputHistory.length = 0;
93
95
  customInputHistoryBytes = 0;
94
96
  };
@@ -132,32 +134,37 @@ export function registerQuestionTool(pi: ExtensionAPI): void {
132
134
  if (signal?.aborted) throw new Error("Question cancelled before it opened");
133
135
 
134
136
  const question = safeTerminalText(params.question);
135
- const options: DisplayOption[] = [
136
- ...params.options.map((option, index) => ({
137
+ const options: DisplayOption[] = params.options.map((option, index) => ({
137
138
  label: safeTerminalText(option.label),
139
+ answer: option.label,
138
140
  description: option.description === undefined ? undefined : safeTerminalText(option.description),
139
141
  preview: option.preview === undefined ? undefined : safeTerminalText(option.preview),
140
142
  originalIndex: index + 1,
141
- isOther: false,
142
- })),
143
- { label: "Type a custom answer", originalIndex: params.options.length + 1, isOther: true },
144
- ];
145
-
146
- const result = await openQuestionUi({
147
- ctx,
148
- signal,
149
- question,
150
- options,
151
- originalOptions: params.options,
152
- mode,
153
- minSelections,
154
- maxSelections,
155
- customInputHistory,
156
- rememberCustomInput,
157
- });
143
+ }));
144
+
145
+ const pending = new AbortController();
146
+ pendingQuestions.add(pending);
147
+ let result;
148
+ try {
149
+ result = await openQuestionUi({
150
+ ctx,
151
+ signal: signal ? AbortSignal.any([signal, pending.signal]) : pending.signal,
152
+ question,
153
+ options,
154
+ mode,
155
+ minSelections,
156
+ maxSelections,
157
+ customInputHistory,
158
+ rememberCustomInput,
159
+ });
160
+ } finally {
161
+ pendingQuestions.delete(pending);
162
+ }
158
163
 
159
164
  const simpleOptions = params.options.map((option) => option.label);
160
- if (result.kind === "aborted") throw new Error("Question cancelled because the agent operation was aborted");
165
+ if (result.kind === "aborted" || pending.signal.aborted || signal?.aborted) {
166
+ throw new Error("Question cancelled because the agent operation was aborted");
167
+ }
161
168
  if (result.kind === "cancelled" && mode === "multiple") {
162
169
  return {
163
170
  content: [{ type: "text", text: "User cancelled the question" }],
@@ -454,7 +454,7 @@ export function registerWorkedFor(
454
454
  }
455
455
  });
456
456
 
457
- pi.on("agent_settled", async (_event, ctx) => {
457
+ pi.on("agent_settled", async (event, ctx) => {
458
458
  if (!active || ctx.mode !== "tui") return;
459
459
  const settled = active;
460
460
  const generation = lifecycleGeneration;
@@ -469,7 +469,7 @@ export function registerWorkedFor(
469
469
  ctx.ui.notify(`Change receipt unavailable: ${changes.reason}`, "warning");
470
470
  }
471
471
  const settledTokens = sessionTokenTotal(ctx);
472
- const outcome = workedForOutcome(settled.stopReason);
472
+ const outcome = "aborted" in event && event.aborted === true ? "stopped" : workedForOutcome(settled.stopReason);
473
473
  const throughput = outcome === "done" && !settled.throughputInvalid && settled.responseStartedAt === undefined
474
474
  && positiveInteger(settled.outputTokens) && positiveDuration(settled.responseMilliseconds)
475
475
  ? { outputTokens: settled.outputTokens, responseMilliseconds: settled.responseMilliseconds }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "killeros",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "TUI, goals, and workflow automation for the Pi coding agent",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -45,21 +45,23 @@
45
45
  ]
46
46
  },
47
47
  "peerDependencies": {
48
- "@earendil-works/pi-ai": ">=1.0.4 <2",
49
- "@earendil-works/pi-coding-agent": ">=1.0.4 <2",
50
- "@earendil-works/pi-tui": ">=1.0.4 <2",
48
+ "@earendil-works/pi-ai": ">=1.1.0 <2",
49
+ "@earendil-works/pi-coding-agent": ">=1.1.0 <2",
50
+ "@earendil-works/pi-tui": ">=1.1.0 <2",
51
51
  "typebox": ">=1.1.38 <2"
52
52
  },
53
53
  "devDependencies": {
54
- "@earendil-works/pi-ai": "1.0.4",
55
- "@earendil-works/pi-coding-agent": "1.0.4",
56
- "@earendil-works/pi-server": "1.0.4",
57
- "@earendil-works/pi-tui": "1.0.4",
54
+ "@earendil-works/pi-ai": "1.1.0",
55
+ "@earendil-works/pi-coding-agent": "1.1.0",
56
+ "@earendil-works/pi-server": "1.1.0",
57
+ "@earendil-works/pi-tui": "1.1.0",
58
58
  "@types/node": "24.12.4",
59
+ "@xterm/headless": "6.0.0",
59
60
  "eslint": "^10.9.1",
60
61
  "typebox": "1.3.20",
61
62
  "typescript": "5.9.3",
62
- "typescript-eslint": "^8.68.0"
63
+ "typescript-eslint": "^8.68.0",
64
+ "zigpty": "0.2.1"
63
65
  },
64
66
  "overrides": {
65
67
  "brace-expansion": "5.0.12"