killeros 2.1.30 → 2.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -29
- package/README.md +2 -2
- package/killeros/goal-state.ts +4 -0
- package/killeros/handoff.ts +7 -1
- package/killeros/worked-for.ts +35 -39
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to KillerOS are documented here.
|
|
3
|
+
All notable changes to KillerOS are documented here. Releases use New Features for new capabilities, Added for smaller additions, Changed for updates and removals, and Fixed for corrections. Empty sections are omitted.
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.1.32] - 2026-09-24
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Restored tok/s on completed worked-for receipts using reported output tokens over observed model-response intervals, including reasoning and mixed-model tasks; incomplete or failed calls omit the rate.
|
|
12
|
+
- Prevented file-verified goal completion when an objective names another unquoted relative file, such as ``Fix `a.ts` plus b.ts``.
|
|
13
|
+
- Added release-metadata checks for ordinary npm publication and the GitHub release workflow, including the README's pinned version example.
|
|
14
|
+
|
|
15
|
+
## [2.1.31] - 2026-09-22
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Made `/handoff` honor Pi context edits by using the canonical session projection when available while retaining compatibility with Pi 0.85 and 0.86.
|
|
20
|
+
- Omitted worked-for throughput unless the provider explicitly reports zero reasoning tokens.
|
|
21
|
+
|
|
7
22
|
## [2.1.30] - 2026-09-21
|
|
8
23
|
|
|
9
24
|
### Added
|
|
@@ -21,7 +36,7 @@ All notable changes to KillerOS are documented here.
|
|
|
21
36
|
|
|
22
37
|
## [2.1.29] - 2026-09-19
|
|
23
38
|
|
|
24
|
-
###
|
|
39
|
+
### New Features
|
|
25
40
|
|
|
26
41
|
- Added `/auto-compact [status|on|off|<percent>]` to inspect and update the global automatic compaction preference without restarting Pi.
|
|
27
42
|
|
|
@@ -35,15 +50,15 @@ All notable changes to KillerOS are documented here.
|
|
|
35
50
|
|
|
36
51
|
## [2.1.28] - 2026-09-15
|
|
37
52
|
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- Appended the selected model ID as a gray `· <model-id>` suffix to every TUI activity working message, retained for the full request cycle and falling back to `unknown model` when no usable ID exists.
|
|
56
|
+
|
|
38
57
|
### Changed
|
|
39
58
|
|
|
40
59
|
- Simplified goal presentation without changing goal behavior: transcript history shows one iconless event row per lifecycle change (`Goal started`, `Goal replaced`, `Goal paused`, `Goal resumed`, `Goal cleared`), progress and blocker outcomes render once through the goal tool result, the footer shows compact `/goal active · 1/20 · 10s` status, the `/goal` panel leads with status then objective then `Pause goal` / `Resume goal` / `Clear goal` actions, and duplicate TUI success notifications are suppressed while RPC confirmations remain. Active-goal labels use muted teal `#6FAEB2` through the packaged theme's extension-label role.
|
|
41
60
|
- Removed the legacy `✻` marker from version-1 `Worked for …` transcript rows; stored entries are unchanged and remain readable.
|
|
42
61
|
|
|
43
|
-
### Added
|
|
44
|
-
|
|
45
|
-
- Appended the selected model ID as a gray `· <model-id>` suffix to every TUI activity working message, retained for the full request cycle and falling back to `unknown model` when no usable ID exists.
|
|
46
|
-
|
|
47
62
|
### Fixed
|
|
48
63
|
|
|
49
64
|
- Kept resumed blocked goals and goals paused by truncated provider errors readable after reload.
|
|
@@ -57,6 +72,10 @@ All notable changes to KillerOS are documented here.
|
|
|
57
72
|
|
|
58
73
|
- Added `/codex-fast status` to report whether Codex fast mode is enabled without changing it.
|
|
59
74
|
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- Removed `/init` and its `killeros_init_*` tools, prompts, workflow APIs, runtime state, and lifecycle handlers. Upgrading leaves existing `AGENTS.md` and recovery files untouched, and commands from other providers named `/init` pass through KillerOS unhandled.
|
|
78
|
+
|
|
60
79
|
### Fixed
|
|
61
80
|
|
|
62
81
|
- Restricted automatic startup, footer, and change-receipt Git scans to trusted projects, preventing repository executables and configuration races from launching commands before trust is granted.
|
|
@@ -67,10 +86,6 @@ All notable changes to KillerOS are documented here.
|
|
|
67
86
|
- Recorded focused Node test runs in response receipts without persisting their test paths.
|
|
68
87
|
- Kept passive footer Git status from running configured filters, bounded loose and packed receipt blobs, and stopped stale `/handoff` summaries from replacing sessions with new work.
|
|
69
88
|
|
|
70
|
-
### Removed
|
|
71
|
-
|
|
72
|
-
- Removed `/init` and its `killeros_init_*` tools, prompts, workflow APIs, runtime state, and lifecycle handlers. Upgrading leaves existing `AGENTS.md` and recovery files untouched, and commands from other providers named `/init` pass through KillerOS unhandled.
|
|
73
|
-
|
|
74
89
|
## [2.1.26] - 2026-09-08
|
|
75
90
|
|
|
76
91
|
### Fixed
|
|
@@ -81,10 +96,6 @@ All notable changes to KillerOS are documented here.
|
|
|
81
96
|
|
|
82
97
|
## [2.1.25] - 2026-09-06
|
|
83
98
|
|
|
84
|
-
### Fixed
|
|
85
|
-
|
|
86
|
-
- Left-aligned settled `✓ Done` receipt lines so every row shares the assistant text edge.
|
|
87
|
-
|
|
88
99
|
### Changed
|
|
89
100
|
|
|
90
101
|
- Replaced the boxed startup card with a three-row masthead: coral fade mark, versions, model and reasoning level, directory and branch, and an italic tip.
|
|
@@ -92,10 +103,11 @@ All notable changes to KillerOS are documented here.
|
|
|
92
103
|
- Restored the leading `❯` prompt marker in white in the chat editor.
|
|
93
104
|
- Rendered footer model names and the `fast` badge in non-bold white.
|
|
94
105
|
- Showed the current Pi version beside the KillerOS version in the startup header.
|
|
106
|
+
- Removed the `/variants` reasoning-level command in favor of Pi's native `/thinking` selector.
|
|
95
107
|
|
|
96
|
-
###
|
|
108
|
+
### Fixed
|
|
97
109
|
|
|
98
|
-
-
|
|
110
|
+
- Left-aligned settled `✓ Done` receipt lines so every row shares the assistant text edge.
|
|
99
111
|
|
|
100
112
|
## [2.1.24] - 2026-09-05
|
|
101
113
|
|
|
@@ -260,7 +272,7 @@ All notable changes to KillerOS are documented here.
|
|
|
260
272
|
|
|
261
273
|
## [2.0.15] - 2026-08-23
|
|
262
274
|
|
|
263
|
-
###
|
|
275
|
+
### New Features
|
|
264
276
|
|
|
265
277
|
- Added `/handoff [focus]` for fresh linked sessions with visible continuation context.
|
|
266
278
|
|
|
@@ -299,18 +311,18 @@ All notable changes to KillerOS are documented here.
|
|
|
299
311
|
|
|
300
312
|
## [2.0.11] - 2026-08-17
|
|
301
313
|
|
|
314
|
+
### Changed
|
|
315
|
+
|
|
316
|
+
- Removed the decision-gated workflow subsystem, its skill-specific policy, public extension interface, and YAML dependency. Skills now remain instruction-only.
|
|
317
|
+
|
|
302
318
|
### Fixed
|
|
303
319
|
|
|
304
320
|
- Made automated npm publication and GitHub release recovery idempotent, aligned the documented and tested Pi floor, and made machine-identifier casing locale-independent.
|
|
305
321
|
- Extended strict type checking to release scripts and typed test suites, while correctly identifying JavaScript-only suites as `.js`.
|
|
306
322
|
|
|
307
|
-
### Removed
|
|
308
|
-
|
|
309
|
-
- Removed the decision-gated workflow subsystem, its skill-specific policy, public extension interface, and YAML dependency. Skills now remain instruction-only.
|
|
310
|
-
|
|
311
323
|
## [2.0.10] - 2026-08-16
|
|
312
324
|
|
|
313
|
-
###
|
|
325
|
+
### New Features
|
|
314
326
|
|
|
315
327
|
- Added proactive turn-boundary compaction with Pi-owned settings and safe continuation for ordinary prompts and active goals.
|
|
316
328
|
- Added reusable multi-activation decision-gated workflow registrations while preserving exact-match behavior.
|
|
@@ -328,12 +340,9 @@ All notable changes to KillerOS are documented here.
|
|
|
328
340
|
- Added a reusable, opt-in pre-turn gate for explicitly activated decision-gated workflows. It opens the shared structured question UI before skill expansion, keeps the selected policy active, blocks unknown and disallowed tools, and clears safely across lifecycle boundaries.
|
|
329
341
|
- Added a disposable decision-gated workflow fixture and focused coverage for activation ordering, pending safety, policy allowlists, lifecycle cleanup, adapter reuse, and Pi 0.84.2 compatibility.
|
|
330
342
|
|
|
331
|
-
### Removed
|
|
332
|
-
|
|
333
|
-
- Removed KillerOS's always-on concise response policy and provider-specific concise defaults; Pi now owns response-style guidance.
|
|
334
|
-
|
|
335
343
|
### Changed
|
|
336
344
|
|
|
345
|
+
- Removed KillerOS's always-on concise response policy and provider-specific concise defaults; Pi now owns response-style guidance.
|
|
337
346
|
- Raised the locked direct Pi development packages to 0.84.2 while keeping the peer dependency floor at 0.84.1.
|
|
338
347
|
|
|
339
348
|
## [2.0.7] - 2026-08-13
|
|
@@ -520,11 +529,14 @@ All notable changes to KillerOS are documented here.
|
|
|
520
529
|
|
|
521
530
|
## [1.3.0] - 2026-07-31
|
|
522
531
|
|
|
523
|
-
###
|
|
532
|
+
### New Features
|
|
524
533
|
|
|
525
534
|
- Claude Code-style `/init` that builds a bounded repository snapshot and generates a concise root `AGENTS.md` with one controlled write.
|
|
526
535
|
- Codex-style `/goal` with durable branch-scoped state, automatic one-turn continuation, pause/resume/edit/clear controls, and explicit model-reported completion or blocking.
|
|
527
536
|
- Trusted `AGENTS.local.md` personal guidance and project lifecycle hooks for tool-call, tool-result, and settled-agent events.
|
|
537
|
+
|
|
538
|
+
### Added
|
|
539
|
+
|
|
528
540
|
- Focused coverage for goal transitions, recovery paths, branch restoration, mode gating, footer cutdowns, and repository initialization safeguards.
|
|
529
541
|
|
|
530
542
|
### Changed
|
|
@@ -534,12 +546,15 @@ All notable changes to KillerOS are documented here.
|
|
|
534
546
|
|
|
535
547
|
## [1.2.0] - 2026-07-30
|
|
536
548
|
|
|
537
|
-
###
|
|
549
|
+
### New Features
|
|
538
550
|
|
|
539
551
|
- A 52-column Compact startup card with inline version, polished model/provider identity, reasoning level, `/model`, working directory, and conditional Git branch.
|
|
540
|
-
- A shuffled startup-tip deck that keeps one tip stable per session and exhausts the bank before repeating.
|
|
541
552
|
- A responsive footer that preserves model and context while progressively removing lower-priority telemetry.
|
|
542
553
|
- Packaged KillerOS theme with coral accents and one neutral tool-call surface across pending, success, and error states.
|
|
554
|
+
|
|
555
|
+
### Added
|
|
556
|
+
|
|
557
|
+
- A shuffled startup-tip deck that keeps one tip stable per session and exhausts the bank before repeating.
|
|
543
558
|
- Single-glyph Spark activity indicator with a restrained color pulse.
|
|
544
559
|
- Claude-adjacent activity word bank that advances between agent runs.
|
|
545
560
|
- Static `└ Thinking…` label for hidden reasoning blocks.
|
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ Or from GitHub:
|
|
|
32
32
|
pi install git:github.com/KyrosHendrix/pi-KillerOS
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Pin a release by appending its tag, for example `@v2.1.
|
|
35
|
+
Pin a release by appending its tag, for example `@v2.1.32`. Add `-l` to install only for the current project. Restart Pi after installing.
|
|
36
36
|
|
|
37
37
|
## Commands
|
|
38
38
|
|
|
@@ -101,7 +101,7 @@ Strict TypeScript throughout. Tests run on Node's built-in test runner:
|
|
|
101
101
|
npm ci && npm run check && npm test
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
Releases go through CI on `main`; do not push version tags manually.
|
|
104
|
+
Releases go through CI on `main`; do not push version tags manually. The prepublish check rejects ordinary direct `npm publish`, but `--ignore-scripts` can bypass it. Configure npm's trusted publisher for `release.yml`, set package publishing access to "Require two-factor authentication and disallow tokens", and revoke unused publish tokens. npm maintainers can still publish interactively with 2FA, so workflow-only publishing also depends on maintainer policy.
|
|
105
105
|
|
|
106
106
|
## Security
|
|
107
107
|
|
package/killeros/goal-state.ts
CHANGED
|
@@ -349,6 +349,7 @@ const GOAL_URL_PATTERN = /(?:https?|file):\/\/[^\s"'`]+/giu;
|
|
|
349
349
|
const GOAL_QUOTED_PATTERN = /`([^`\r\n]+)`|"([^"\r\n]+)"|'([^'\r\n]+)'/gu;
|
|
350
350
|
const GOAL_ABSOLUTE_PATTERN = /(?:^|[\s"'`(\[{,;])([A-Za-z]:[\\/][^\s,;'"`]+|\/[^\s,;'"`]+)/gu;
|
|
351
351
|
const GOAL_LIST_FILE_PATTERN = /(?:\band\b|\bor\b|[,;&+])\s*(?:`([^`\r\n]+)`|"([^"\r\n]+)"|'([^'\r\n]+)'|([A-Za-z0-9_][A-Za-z0-9_.-]*(?:[\\/][A-Za-z0-9_.-]+)*\.[A-Za-z0-9]{1,12})\b)/giu;
|
|
352
|
+
const GOAL_RELATIVE_FILE_PATTERN = /(?:^|[\s"'`(\[{,;])((?:\.{1,2}[\\/])*[A-Za-z0-9_][A-Za-z0-9_.-]*(?:[\\/][A-Za-z0-9_.-]+)*\.[A-Za-z0-9]{1,12})\b/gu;
|
|
352
353
|
|
|
353
354
|
function isQuotedGoalFileMention(raw: string): boolean {
|
|
354
355
|
const value = raw.trim();
|
|
@@ -381,6 +382,9 @@ function countGoalTargetFiles(objective: string, cwd: string, target: string): n
|
|
|
381
382
|
if (match[1]) add(stripUnquotedPathPunctuation(match[1].trim()));
|
|
382
383
|
}
|
|
383
384
|
for (const match of prose.matchAll(GOAL_LIST_FILE_PATTERN)) add(match[1] ?? match[2] ?? match[3] ?? match[4] ?? "");
|
|
385
|
+
for (const match of prose.replace(GOAL_QUOTED_PATTERN, " ").matchAll(GOAL_RELATIVE_FILE_PATTERN)) {
|
|
386
|
+
if (match[1]) add(match[1]);
|
|
387
|
+
}
|
|
384
388
|
return mentions.size;
|
|
385
389
|
}
|
|
386
390
|
|
package/killeros/handoff.ts
CHANGED
|
@@ -240,7 +240,13 @@ export function registerHandoff(pi: ExtensionAPI, goalRuntime: GoalRuntime, hand
|
|
|
240
240
|
try {
|
|
241
241
|
const entries = ctx.sessionManager.buildContextEntries();
|
|
242
242
|
const sourceLeaf = entries.at(-1)?.id;
|
|
243
|
-
const
|
|
243
|
+
const sessionManager = ctx.sessionManager as typeof ctx.sessionManager & {
|
|
244
|
+
buildSessionProjection?: () => { messages: ReturnType<typeof sessionEntryToContextMessages> };
|
|
245
|
+
};
|
|
246
|
+
const messages = typeof sessionManager.buildSessionProjection === "function"
|
|
247
|
+
? sessionManager.buildSessionProjection().messages
|
|
248
|
+
: entries.flatMap(sessionEntryToContextMessages);
|
|
249
|
+
const conversation = serializeConversation(convertToLlm(messages));
|
|
244
250
|
if (!conversation.trim()) throw new Error("No usable session context is available");
|
|
245
251
|
focus = safeTerminalText(args).trim();
|
|
246
252
|
let maxTokens = handoffMaxTokens;
|
package/killeros/worked-for.ts
CHANGED
|
@@ -50,6 +50,7 @@ export interface WorkedForEntryDataV4 {
|
|
|
50
50
|
model?: string;
|
|
51
51
|
outputTokens?: number;
|
|
52
52
|
decodeMilliseconds?: number;
|
|
53
|
+
responseMilliseconds?: number;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
type WorkedForEntryData = WorkedForEntryDataV1 | WorkedForEntryDataV2 | WorkedForEntryDataV3 | WorkedForEntryDataV4;
|
|
@@ -72,6 +73,10 @@ function positiveInteger(value: unknown): value is number {
|
|
|
72
73
|
return integer(value) && value > 0;
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
function positiveDuration(value: unknown): value is number {
|
|
77
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
75
80
|
function record(value: unknown): value is Record<string, unknown> {
|
|
76
81
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
77
82
|
}
|
|
@@ -154,9 +159,11 @@ function parseV4(data: Record<string, unknown>): WorkedForEntryDataV4 | undefine
|
|
|
154
159
|
checks.push({ label, outcome: check.outcome });
|
|
155
160
|
}
|
|
156
161
|
const model = parseModelName(data.model);
|
|
157
|
-
const throughput = positiveInteger(data.outputTokens) &&
|
|
158
|
-
? { outputTokens: data.outputTokens,
|
|
159
|
-
:
|
|
162
|
+
const throughput = positiveInteger(data.outputTokens) && data.decodeMilliseconds === undefined && positiveDuration(data.responseMilliseconds)
|
|
163
|
+
? { outputTokens: data.outputTokens, responseMilliseconds: data.responseMilliseconds }
|
|
164
|
+
: positiveInteger(data.outputTokens) && data.responseMilliseconds === undefined && positiveInteger(data.decodeMilliseconds)
|
|
165
|
+
? { outputTokens: data.outputTokens, decodeMilliseconds: data.decodeMilliseconds }
|
|
166
|
+
: {};
|
|
160
167
|
return {
|
|
161
168
|
version: 4,
|
|
162
169
|
milliseconds: data.milliseconds,
|
|
@@ -231,11 +238,12 @@ class WorkedForV4Component implements Component {
|
|
|
231
238
|
const { data, theme } = this;
|
|
232
239
|
const outcome = OUTCOMES[data.outcome];
|
|
233
240
|
const headline = theme.fg(outcome.color, outcome.label);
|
|
234
|
-
const
|
|
235
|
-
|
|
241
|
+
const duration = data.responseMilliseconds ?? data.decodeMilliseconds;
|
|
242
|
+
const tokensPerSecond = data.outputTokens !== undefined && duration !== undefined && (data.responseMilliseconds === undefined || data.outcome === "done")
|
|
243
|
+
? data.outputTokens / (duration / 1_000)
|
|
236
244
|
: undefined;
|
|
237
245
|
const speedSuffix = tokensPerSecond !== undefined && Number.isFinite(tokensPerSecond) && tokensPerSecond > 0
|
|
238
|
-
? ` · ${tokensPerSecond.toFixed(1)} tok/s`
|
|
246
|
+
? ` · ${data.responseMilliseconds !== undefined && tokensPerSecond < 0.05 ? "<0.1" : tokensPerSecond.toFixed(1)} tok/s`
|
|
239
247
|
: "";
|
|
240
248
|
const modelSuffix = data.model ? ` · ${data.model}` : "";
|
|
241
249
|
const lines = [
|
|
@@ -304,31 +312,19 @@ type ActiveReceipt = {
|
|
|
304
312
|
modelId: string | undefined;
|
|
305
313
|
modelMismatch: boolean;
|
|
306
314
|
outputTokens: number;
|
|
307
|
-
|
|
308
|
-
|
|
315
|
+
responseMilliseconds: number;
|
|
316
|
+
responseStartedAt: number | undefined;
|
|
309
317
|
throughputInvalid: boolean;
|
|
310
318
|
};
|
|
311
319
|
|
|
312
|
-
function finishAssistantStream(
|
|
313
|
-
receipt:
|
|
314
|
-
outputTokens
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (failed) {
|
|
319
|
-
if (receipt.decodeStartedAt !== undefined) receipt.throughputInvalid = true;
|
|
320
|
-
} else if (receipt.decodeStartedAt !== undefined) {
|
|
321
|
-
const decodeMilliseconds = endedAt - receipt.decodeStartedAt;
|
|
322
|
-
if (positiveInteger(outputTokens) && positiveInteger(decodeMilliseconds)) {
|
|
323
|
-
receipt.outputTokens += outputTokens;
|
|
324
|
-
receipt.decodeMilliseconds += decodeMilliseconds;
|
|
325
|
-
} else {
|
|
326
|
-
receipt.throughputInvalid = true;
|
|
327
|
-
}
|
|
328
|
-
} else if (outputTokens !== 0) {
|
|
329
|
-
receipt.throughputInvalid = true;
|
|
320
|
+
function finishAssistantStream(receipt: ActiveReceipt, outputTokens: unknown, endedAt: number, failed: boolean): void {
|
|
321
|
+
const duration = receipt.responseStartedAt === undefined ? undefined : endedAt - receipt.responseStartedAt;
|
|
322
|
+
if (failed || !integer(outputTokens) || !positiveDuration(duration)) receipt.throughputInvalid = true;
|
|
323
|
+
else {
|
|
324
|
+
receipt.outputTokens += outputTokens;
|
|
325
|
+
receipt.responseMilliseconds += duration;
|
|
330
326
|
}
|
|
331
|
-
receipt.
|
|
327
|
+
receipt.responseStartedAt = undefined;
|
|
332
328
|
}
|
|
333
329
|
|
|
334
330
|
function receiptModelName(
|
|
@@ -392,8 +388,8 @@ export function registerWorkedFor(
|
|
|
392
388
|
modelId: undefined,
|
|
393
389
|
modelMismatch: false,
|
|
394
390
|
outputTokens: 0,
|
|
395
|
-
|
|
396
|
-
|
|
391
|
+
responseMilliseconds: 0,
|
|
392
|
+
responseStartedAt: undefined,
|
|
397
393
|
throughputInvalid: false,
|
|
398
394
|
};
|
|
399
395
|
active = state;
|
|
@@ -401,11 +397,10 @@ export function registerWorkedFor(
|
|
|
401
397
|
if (active !== state) await collection.dispose();
|
|
402
398
|
});
|
|
403
399
|
|
|
404
|
-
pi.on("
|
|
405
|
-
if (ctx.mode !== "tui" || !active) return;
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
&& update.delta.length > 0) active.decodeStartedAt ??= now();
|
|
400
|
+
pi.on("message_start", (event, ctx) => {
|
|
401
|
+
if (ctx.mode !== "tui" || !active || event.message.role !== "assistant") return;
|
|
402
|
+
if (active.responseStartedAt !== undefined) active.throughputInvalid = true;
|
|
403
|
+
active.responseStartedAt = now();
|
|
409
404
|
});
|
|
410
405
|
|
|
411
406
|
pi.on("message_end", (event, ctx) => {
|
|
@@ -427,7 +422,7 @@ export function registerWorkedFor(
|
|
|
427
422
|
}
|
|
428
423
|
finishAssistantStream(
|
|
429
424
|
active,
|
|
430
|
-
event.message.usage
|
|
425
|
+
event.message.usage?.output,
|
|
431
426
|
now(),
|
|
432
427
|
event.message.stopReason === "error" || event.message.stopReason === "aborted",
|
|
433
428
|
);
|
|
@@ -462,14 +457,15 @@ export function registerWorkedFor(
|
|
|
462
457
|
ctx.ui.notify(`Change receipt unavailable: ${changes.reason}`, "warning");
|
|
463
458
|
}
|
|
464
459
|
const settledTokens = sessionTokenTotal(ctx);
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
460
|
+
const outcome = workedForOutcome(settled.stopReason);
|
|
461
|
+
const throughput = outcome === "done" && !settled.throughputInvalid && settled.responseStartedAt === undefined
|
|
462
|
+
&& positiveInteger(settled.outputTokens) && positiveDuration(settled.responseMilliseconds)
|
|
463
|
+
? { outputTokens: settled.outputTokens, responseMilliseconds: settled.responseMilliseconds }
|
|
468
464
|
: {};
|
|
469
465
|
const data = fitPayload({
|
|
470
466
|
version: 4,
|
|
471
467
|
milliseconds: Math.max(0, now() - settled.startedAt),
|
|
472
|
-
outcome
|
|
468
|
+
outcome,
|
|
473
469
|
tokens: settled.startedTokens === undefined || settledTokens === undefined ? 0 : Math.max(0, settledTokens - settled.startedTokens),
|
|
474
470
|
changes,
|
|
475
471
|
checks: settled.checks,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "killeros",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.32",
|
|
4
4
|
"description": "TUI, goals, and workflow automation for the Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"benchmark:change-receipt": "node --test --experimental-strip-types test/ChangeReceipt.bench.ts",
|
|
34
34
|
"check": "tsc --noEmit && eslint .",
|
|
35
35
|
"lint": "eslint .",
|
|
36
|
+
"prepublishOnly": "node --experimental-strip-types scripts/verify-release.ts",
|
|
36
37
|
"test": "node --test --test-force-exit --experimental-strip-types test/*.test.*"
|
|
37
38
|
},
|
|
38
39
|
"pi": {
|