killeros 2.0.18 → 2.0.20
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 +24 -0
- package/Killeros.ts +3 -1
- package/README.md +5 -2
- package/killeros/activity.ts +4 -0
- package/killeros/auto-compaction.ts +40 -10
- package/killeros/codex-fast-state.ts +5 -7
- package/killeros/commands.ts +5 -3
- package/killeros/errors.ts +8 -0
- package/killeros/footer.ts +3 -3
- package/killeros/goals.ts +326 -116
- package/killeros/handoff.ts +40 -10
- package/killeros/hooks.ts +121 -48
- package/killeros/init-evidence.ts +4 -2
- package/killeros/init-target.ts +28 -20
- package/killeros/init.ts +12 -5
- package/killeros/personal-instructions.ts +3 -4
- package/killeros/question.ts +15 -8
- package/killeros/runtime.ts +42 -7
- package/killeros/settings.ts +8 -5
- package/killeros/shell-ui.ts +14 -6
- package/package.json +6 -3
package/killeros/runtime.ts
CHANGED
|
@@ -38,31 +38,66 @@ export interface GoalFileVerification {
|
|
|
38
38
|
baseline: GoalFileBaseline;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export interface
|
|
41
|
+
export interface GoalStateCommon {
|
|
42
42
|
version: 1;
|
|
43
43
|
revision: number;
|
|
44
44
|
objective: string;
|
|
45
|
-
status: GoalStatus;
|
|
46
45
|
createdAt: number;
|
|
47
46
|
updatedAt: number;
|
|
48
47
|
activeMilliseconds: number;
|
|
49
|
-
activeStartedAt?: number;
|
|
50
48
|
turns: number;
|
|
51
49
|
blockedAuditStartTurn: number;
|
|
52
50
|
baselineTokens: number;
|
|
53
|
-
result?: string;
|
|
54
|
-
resumeAfterManualCompaction?: true;
|
|
55
|
-
blockerAudit?: GoalBlockerAudit;
|
|
56
51
|
verification?: GoalFileVerification;
|
|
57
52
|
}
|
|
58
53
|
|
|
54
|
+
export type GoalState = GoalStateCommon & (
|
|
55
|
+
| {
|
|
56
|
+
status: "active";
|
|
57
|
+
activeStartedAt: number;
|
|
58
|
+
result?: string;
|
|
59
|
+
blockerAudit?: GoalBlockerAudit;
|
|
60
|
+
resumeAfterManualCompaction?: never;
|
|
61
|
+
}
|
|
62
|
+
| {
|
|
63
|
+
status: "paused";
|
|
64
|
+
activeStartedAt?: never;
|
|
65
|
+
result?: string;
|
|
66
|
+
blockerAudit?: GoalBlockerAudit;
|
|
67
|
+
resumeAfterManualCompaction?: true;
|
|
68
|
+
}
|
|
69
|
+
| {
|
|
70
|
+
status: "blocked";
|
|
71
|
+
activeStartedAt?: never;
|
|
72
|
+
result: string;
|
|
73
|
+
blockerAudit?: GoalBlockerAudit;
|
|
74
|
+
resumeAfterManualCompaction?: never;
|
|
75
|
+
}
|
|
76
|
+
| {
|
|
77
|
+
status: "complete";
|
|
78
|
+
activeStartedAt?: never;
|
|
79
|
+
result: string;
|
|
80
|
+
blockerAudit?: never;
|
|
81
|
+
resumeAfterManualCompaction?: never;
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
/** Pi request outcomes for goal recovery: awaiting result, compacted, or rejected as session-too-small. */
|
|
86
|
+
export type AutomaticGoalCompactionOutcome = "pending" | "completed" | "skipped";
|
|
87
|
+
|
|
88
|
+
export interface AutomaticGoalCompaction {
|
|
89
|
+
pausedRevision: number;
|
|
90
|
+
outcome: AutomaticGoalCompactionOutcome;
|
|
91
|
+
turnSettled: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
59
94
|
export interface GoalRuntime {
|
|
60
95
|
state?: GoalState;
|
|
61
96
|
continuationScheduled: boolean;
|
|
62
97
|
continuationHeld: boolean;
|
|
63
98
|
goalTurnInFlight: boolean;
|
|
64
99
|
agentEndObserved: boolean;
|
|
65
|
-
automaticCompaction?:
|
|
100
|
+
automaticCompaction?: AutomaticGoalCompaction;
|
|
66
101
|
persistenceRetryNeeded: boolean;
|
|
67
102
|
lastStopReason?: string;
|
|
68
103
|
lastError?: string;
|
package/killeros/settings.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { hasErrorCode } from "./errors.ts";
|
|
5
6
|
|
|
6
7
|
export type KillerosSettings = Record<string, unknown>;
|
|
7
8
|
|
|
@@ -10,15 +11,17 @@ export interface KillerosSettingsStore {
|
|
|
10
11
|
update(patch: Readonly<Record<string, unknown>>): void;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
function isSettings(value: unknown): value is KillerosSettings {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
function readStoredSettings(settingsPath: string): KillerosSettings {
|
|
14
19
|
try {
|
|
15
20
|
const parsed: unknown = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
16
|
-
if (!parsed
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
return parsed as KillerosSettings;
|
|
21
|
+
if (!isSettings(parsed)) throw new Error("KillerOS settings must contain a JSON object");
|
|
22
|
+
return parsed;
|
|
20
23
|
} catch (error) {
|
|
21
|
-
if ((error
|
|
24
|
+
if (hasErrorCode(error, "ENOENT")) return {};
|
|
22
25
|
throw error;
|
|
23
26
|
}
|
|
24
27
|
}
|
package/killeros/shell-ui.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import {
|
|
4
4
|
CustomEditor,
|
|
5
|
-
VERSION,
|
|
6
5
|
type ExtensionAPI,
|
|
7
6
|
type ExtensionContext,
|
|
8
7
|
type KeybindingsManager,
|
|
@@ -25,14 +24,19 @@ import {
|
|
|
25
24
|
} from "./commands.ts";
|
|
26
25
|
import { reportError } from "./errors.ts";
|
|
27
26
|
import { formatModel } from "./footer.ts";
|
|
28
|
-
import { LEVEL_COLORS
|
|
27
|
+
import { LEVEL_COLORS } from "./variants.ts";
|
|
29
28
|
|
|
30
29
|
const COMPACT_HEADER_MAX_WIDTH = 52;
|
|
31
30
|
|
|
32
31
|
function readPackageVersion(path: string | URL): string | undefined {
|
|
33
32
|
try {
|
|
34
|
-
const value = JSON.parse(readFileSync(path, "utf8"))
|
|
35
|
-
return typeof value
|
|
33
|
+
const value: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
34
|
+
return typeof value === "object"
|
|
35
|
+
&& value !== null
|
|
36
|
+
&& "version" in value
|
|
37
|
+
&& typeof value.version === "string"
|
|
38
|
+
? value.version
|
|
39
|
+
: undefined;
|
|
36
40
|
} catch {
|
|
37
41
|
return undefined;
|
|
38
42
|
}
|
|
@@ -93,7 +97,11 @@ function shuffledDeck(values: readonly string[]): string[] {
|
|
|
93
97
|
const deck = [...values];
|
|
94
98
|
for (let index = deck.length - 1; index > 0; index -= 1) {
|
|
95
99
|
const swapIndex = Math.floor(Math.random() * (index + 1));
|
|
96
|
-
|
|
100
|
+
const current = deck[index];
|
|
101
|
+
const swap = deck[swapIndex];
|
|
102
|
+
if (current === undefined || swap === undefined) continue;
|
|
103
|
+
deck[index] = swap;
|
|
104
|
+
deck[swapIndex] = current;
|
|
97
105
|
}
|
|
98
106
|
return deck;
|
|
99
107
|
}
|
|
@@ -152,7 +160,7 @@ class PiStartupHeader {
|
|
|
152
160
|
const innerWidth = panelWidth - 4;
|
|
153
161
|
const version = KILLEROS_VERSION ? theme.fg("dim", ` (v${KILLEROS_VERSION})`) : "";
|
|
154
162
|
const identity = `${theme.fg("dim", "›")} ${theme.fg("text", theme.bold("KillerOS"))}${version}`;
|
|
155
|
-
const thinkingLevel = this.pi.getThinkingLevel()
|
|
163
|
+
const thinkingLevel = this.pi.getThinkingLevel();
|
|
156
164
|
const reasoning = this.ctx.model?.reasoning === false
|
|
157
165
|
? theme.fg("thinkingOff", "no reasoning")
|
|
158
166
|
: theme.fg(LEVEL_COLORS[thinkingLevel], thinkingLevel);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "killeros",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.20",
|
|
4
4
|
"description": "TUI, goals, and workflow automation for the Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"node": ">=22.19.0"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
|
-
"check": "tsc --noEmit",
|
|
33
|
+
"check": "tsc --noEmit && eslint .",
|
|
34
|
+
"lint": "eslint .",
|
|
34
35
|
"test": "node --test --experimental-strip-types test/*.test.*"
|
|
35
36
|
},
|
|
36
37
|
"pi": {
|
|
@@ -52,8 +53,10 @@
|
|
|
52
53
|
"@earendil-works/pi-coding-agent": "0.84.3",
|
|
53
54
|
"@earendil-works/pi-tui": "0.84.3",
|
|
54
55
|
"@types/node": "24.12.4",
|
|
56
|
+
"eslint": "^10.9.1",
|
|
55
57
|
"typebox": "1.1.38",
|
|
56
|
-
"typescript": "5.9.3"
|
|
58
|
+
"typescript": "5.9.3",
|
|
59
|
+
"typescript-eslint": "^8.68.0"
|
|
57
60
|
},
|
|
58
61
|
"overrides": {
|
|
59
62
|
"brace-expansion": "5.0.9",
|