killeros 1.5.7 → 2.0.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/CHANGELOG.md +8 -119
- package/Killeros.ts +1 -25
- package/README.md +130 -220
- package/killeros/commands.ts +1 -238
- package/killeros/display.ts +6 -2
- package/killeros/footer.ts +8 -3
- package/killeros/goals.ts +10 -9
- package/killeros/hooks.ts +1 -1
- package/killeros/limits.ts +1 -0
- package/killeros/personal-instructions.ts +3 -1
- package/killeros/question.ts +19 -4
- package/package.json +2 -8
- package/agents/debugger.md +0 -50
- package/agents/documenter.md +0 -49
- package/agents/planner.md +0 -53
- package/agents/reviewer.md +0 -58
- package/agents/scout.md +0 -56
- package/agents/security.md +0 -54
- package/agents/tester.md +0 -50
- package/agents/worker.md +0 -54
- package/killeros/subagent-lifecycle.ts +0 -761
- package/killeros/subagent-persistence.ts +0 -572
- package/killeros/subagent-process.ts +0 -626
- package/killeros/subagent-ui.ts +0 -245
- package/killeros/subagents.ts +0 -3048
- package/subagent-lifecycle.ts +0 -1
- package/subagent-process.ts +0 -1
- package/subagent-ui.ts +0 -1
- package/subagents.ts +0 -1
package/killeros/subagent-ui.ts
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
export type ThreadStatus = "queued" | "running" | "complete" | "failed" | "cancelled" | "limited" | "orphaned";
|
|
2
|
-
|
|
3
|
-
export interface ThreadUsage {
|
|
4
|
-
input: number;
|
|
5
|
-
output: number;
|
|
6
|
-
cacheRead: number;
|
|
7
|
-
cacheWrite: number;
|
|
8
|
-
totalTokens: number;
|
|
9
|
-
turns: number;
|
|
10
|
-
cost?: number | { total: number };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface ThreadRecord {
|
|
14
|
-
id: string;
|
|
15
|
-
displayName?: string;
|
|
16
|
-
attempt?: number;
|
|
17
|
-
agent: string;
|
|
18
|
-
task: string;
|
|
19
|
-
status: ThreadStatus;
|
|
20
|
-
usage: ThreadUsage;
|
|
21
|
-
trace?: readonly string[];
|
|
22
|
-
traceTruncatedBytes?: number;
|
|
23
|
-
handoff?: string;
|
|
24
|
-
output?: string;
|
|
25
|
-
terminationReason?: string;
|
|
26
|
-
errorMessage?: string;
|
|
27
|
-
durationMs?: number;
|
|
28
|
-
step?: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const THREAD_BOARD_CONTROL_LABELS = {
|
|
32
|
-
inspect: "Inspect",
|
|
33
|
-
steer: "Steer",
|
|
34
|
-
interrupt: "Interrupt",
|
|
35
|
-
wait: "Wait",
|
|
36
|
-
collect: "Collect",
|
|
37
|
-
resume: "Resume",
|
|
38
|
-
close: "Close",
|
|
39
|
-
} as const;
|
|
40
|
-
|
|
41
|
-
export type ThreadBoardControlId = keyof typeof THREAD_BOARD_CONTROL_LABELS;
|
|
42
|
-
|
|
43
|
-
export interface ThreadBoardControl {
|
|
44
|
-
id: ThreadBoardControlId;
|
|
45
|
-
label: (typeof THREAD_BOARD_CONTROL_LABELS)[ThreadBoardControlId];
|
|
46
|
-
enabled: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface ThreadStateView {
|
|
50
|
-
status: ThreadStatus;
|
|
51
|
-
label: string;
|
|
52
|
-
reason?: string;
|
|
53
|
-
partialWork?: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface ThreadUsageView {
|
|
57
|
-
label: string;
|
|
58
|
-
turns: number;
|
|
59
|
-
totalTokens: number;
|
|
60
|
-
cost?: number;
|
|
61
|
-
text: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface ThreadTraceView {
|
|
65
|
-
label: "Trace";
|
|
66
|
-
entries: readonly string[];
|
|
67
|
-
truncatedBytes: number;
|
|
68
|
-
summary: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface ThreadHandoffView {
|
|
72
|
-
label: "Handoff";
|
|
73
|
-
text: string;
|
|
74
|
-
isPartial: boolean;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface ThreadListItem {
|
|
78
|
-
record: ThreadRecord;
|
|
79
|
-
id: string;
|
|
80
|
-
displayName?: string;
|
|
81
|
-
attempt?: number;
|
|
82
|
-
agent: string;
|
|
83
|
-
task: string;
|
|
84
|
-
step?: number;
|
|
85
|
-
state: ThreadStateView;
|
|
86
|
-
usage: ThreadUsageView;
|
|
87
|
-
selected: boolean;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export interface ThreadInspectionView {
|
|
91
|
-
id: string;
|
|
92
|
-
displayName?: string;
|
|
93
|
-
attempt?: number;
|
|
94
|
-
agent: string;
|
|
95
|
-
task: string;
|
|
96
|
-
step?: number;
|
|
97
|
-
state: ThreadStateView;
|
|
98
|
-
usage: ThreadUsageView;
|
|
99
|
-
trace: ThreadTraceView;
|
|
100
|
-
handoff: ThreadHandoffView;
|
|
101
|
-
controls: readonly ThreadBoardControl[];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface ParentThreadBoard {
|
|
105
|
-
title: string;
|
|
106
|
-
active: readonly ThreadListItem[];
|
|
107
|
-
done: readonly ThreadListItem[];
|
|
108
|
-
selected?: ThreadInspectionView;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export interface ThreadBoardInput {
|
|
112
|
-
threads: readonly ThreadRecord[];
|
|
113
|
-
selectedThreadId?: string;
|
|
114
|
-
closedThreadIds?: readonly string[];
|
|
115
|
-
previous?: ParentThreadBoard;
|
|
116
|
-
title?: string;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function isDone(status: ThreadStatus): boolean {
|
|
120
|
-
return !["queued", "running"].includes(status);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function toRecord(item: ThreadListItem): ThreadRecord {
|
|
124
|
-
return {
|
|
125
|
-
...item.record,
|
|
126
|
-
trace: item.record.trace ? [...item.record.trace] : undefined,
|
|
127
|
-
usage: { ...item.record.usage },
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function threadStatus(thread: Pick<ThreadRecord, "status" | "terminationReason">): ThreadStatus {
|
|
132
|
-
const reason = thread.terminationReason;
|
|
133
|
-
if (thread.status === "orphaned") return "orphaned";
|
|
134
|
-
if (thread.status === "queued" || thread.status === "running") return thread.status;
|
|
135
|
-
if (thread.status === "failed" || reason === "error" || reason === "model_error" || reason === "spawn_error" || reason === "process_closed" || reason === "missing_assistant_message" || reason === "malformed_jsonl" || reason === "invalid_usage" || reason?.startsWith("exit_")) return "failed";
|
|
136
|
-
if (thread.status === "cancelled" || reason === "abort" || reason === "interrupt") return "cancelled";
|
|
137
|
-
if (thread.status === "complete" || reason === "completed") return "complete";
|
|
138
|
-
return thread.status;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function threadReason(thread: Pick<ThreadRecord, "terminationReason" | "errorMessage">, status: ThreadStatus): string | undefined {
|
|
142
|
-
if (status === "cancelled" && thread.terminationReason === "interrupt") return "Interrupted by user.";
|
|
143
|
-
if (status === "cancelled" && thread.terminationReason === "abort") return "Cancelled by parent.";
|
|
144
|
-
if (status === "failed" && thread.errorMessage && thread.terminationReason) return `${thread.terminationReason}: ${thread.errorMessage}`;
|
|
145
|
-
if (status === "failed") return thread.errorMessage ?? thread.terminationReason ?? "Child process failed.";
|
|
146
|
-
return thread.terminationReason;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function formatThreadState(thread: Pick<ThreadRecord, "status" | "terminationReason" | "errorMessage">): ThreadStateView {
|
|
150
|
-
const status = threadStatus(thread);
|
|
151
|
-
const reason = threadReason(thread, status);
|
|
152
|
-
if (status === "complete") return { status, label: "Complete" };
|
|
153
|
-
if (status === "failed") return { status, label: "Failed", reason, partialWork: "Failed before completion. Any saved output is partial work." };
|
|
154
|
-
if (status === "cancelled") return { status, label: "Stopped", reason, partialWork: "Stopped before completion. Any saved output is partial work." };
|
|
155
|
-
if (status === "limited") return { status, label: "Limited", reason, partialWork: "Stopped at a limit before completion. Any saved output is partial work." };
|
|
156
|
-
if (status === "orphaned") return { status, label: "Orphaned", reason, partialWork: "The parent session restarted before completion. Any saved output is partial work." };
|
|
157
|
-
if (status === "running") return { status, label: "Running", reason };
|
|
158
|
-
return { status, label: "Queued", reason };
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function formatThreadUsage(usage: ThreadUsage): ThreadUsageView {
|
|
162
|
-
const cost = typeof usage.cost === "number" ? usage.cost : usage.cost?.total;
|
|
163
|
-
const parts = [`${usage.turns} turn${usage.turns === 1 ? "" : "s"}`, `${usage.totalTokens} tokens`];
|
|
164
|
-
if (cost) parts.push(`$${cost.toFixed(4)}`);
|
|
165
|
-
return { label: "Usage", turns: usage.turns, totalTokens: usage.totalTokens, cost, text: parts.join(" · ") };
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function formatThreadTrace(thread: Pick<ThreadRecord, "trace" | "traceTruncatedBytes">): ThreadTraceView {
|
|
169
|
-
const entries = [...(thread.trace ?? [])];
|
|
170
|
-
const truncatedBytes = thread.traceTruncatedBytes ?? 0;
|
|
171
|
-
return {
|
|
172
|
-
label: "Trace",
|
|
173
|
-
entries,
|
|
174
|
-
truncatedBytes,
|
|
175
|
-
summary: truncatedBytes ? `${entries.length} entries; ${truncatedBytes} B omitted` : `${entries.length} entries`,
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export function formatThreadHandoff(thread: Pick<ThreadRecord, "status" | "terminationReason" | "handoff" | "output">): ThreadHandoffView {
|
|
180
|
-
const text = thread.handoff ?? thread.output ?? "No handoff yet.";
|
|
181
|
-
return { label: "Handoff", text, isPartial: threadStatus(thread) !== "complete" };
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export function formatThreadControls(status: ThreadStatus): readonly ThreadBoardControl[] {
|
|
185
|
-
const active = !isDone(status);
|
|
186
|
-
return [
|
|
187
|
-
{ id: "inspect", label: THREAD_BOARD_CONTROL_LABELS.inspect, enabled: true },
|
|
188
|
-
{ id: "steer", label: THREAD_BOARD_CONTROL_LABELS.steer, enabled: active },
|
|
189
|
-
{ id: "interrupt", label: THREAD_BOARD_CONTROL_LABELS.interrupt, enabled: active },
|
|
190
|
-
{ id: "wait", label: THREAD_BOARD_CONTROL_LABELS.wait, enabled: active },
|
|
191
|
-
{ id: "collect", label: THREAD_BOARD_CONTROL_LABELS.collect, enabled: isDone(status) },
|
|
192
|
-
{ id: "resume", label: THREAD_BOARD_CONTROL_LABELS.resume, enabled: isDone(status) },
|
|
193
|
-
{ id: "close", label: THREAD_BOARD_CONTROL_LABELS.close, enabled: isDone(status) },
|
|
194
|
-
];
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export function formatThreadInspection(thread: ThreadRecord): ThreadInspectionView {
|
|
198
|
-
const state = formatThreadState(thread);
|
|
199
|
-
return {
|
|
200
|
-
id: thread.id,
|
|
201
|
-
displayName: thread.displayName,
|
|
202
|
-
attempt: thread.attempt,
|
|
203
|
-
agent: thread.agent,
|
|
204
|
-
task: thread.task,
|
|
205
|
-
step: thread.step,
|
|
206
|
-
state,
|
|
207
|
-
usage: formatThreadUsage(thread.usage),
|
|
208
|
-
trace: formatThreadTrace(thread),
|
|
209
|
-
handoff: formatThreadHandoff(thread),
|
|
210
|
-
controls: formatThreadControls(state.status),
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function formatThreadListItem(thread: ThreadRecord, selectedThreadId: string | undefined): ThreadListItem {
|
|
215
|
-
return {
|
|
216
|
-
record: { ...thread, trace: thread.trace ? [...thread.trace] : undefined, usage: { ...thread.usage } },
|
|
217
|
-
id: thread.id,
|
|
218
|
-
displayName: thread.displayName,
|
|
219
|
-
attempt: thread.attempt,
|
|
220
|
-
agent: thread.agent,
|
|
221
|
-
task: thread.task,
|
|
222
|
-
step: thread.step,
|
|
223
|
-
state: formatThreadState(thread),
|
|
224
|
-
usage: formatThreadUsage(thread.usage),
|
|
225
|
-
selected: thread.id === selectedThreadId,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export function formatThreadBoard(input: ThreadBoardInput): ParentThreadBoard {
|
|
230
|
-
const closed = new Set(input.closedThreadIds);
|
|
231
|
-
const current = new Map(input.threads.filter((thread) => !closed.has(thread.id)).map((thread) => [thread.id, thread]));
|
|
232
|
-
const retained = input.previous?.done
|
|
233
|
-
.filter((thread) => !closed.has(thread.id) && !current.has(thread.id))
|
|
234
|
-
.map(toRecord) ?? [];
|
|
235
|
-
const threads = [...current.values(), ...retained];
|
|
236
|
-
const active = threads.filter((thread) => !isDone(threadStatus(thread))).map((thread) => formatThreadListItem(thread, input.selectedThreadId));
|
|
237
|
-
const done = threads.filter((thread) => isDone(threadStatus(thread))).map((thread) => formatThreadListItem(thread, input.selectedThreadId));
|
|
238
|
-
const selectedThread = input.selectedThreadId ? threads.find((thread) => thread.id === input.selectedThreadId) : undefined;
|
|
239
|
-
return {
|
|
240
|
-
title: input.title ?? "Threads",
|
|
241
|
-
active,
|
|
242
|
-
done,
|
|
243
|
-
selected: selectedThread ? formatThreadInspection(selectedThread) : undefined,
|
|
244
|
-
};
|
|
245
|
-
}
|