killeros 1.5.8 → 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 +6 -135
- package/Killeros.ts +1 -25
- package/README.md +130 -209
- package/killeros/commands.ts +1 -238
- package/killeros/display.ts +6 -2
- package/killeros/footer.ts +8 -3
- package/killeros/goals.ts +1 -1
- package/killeros/hooks.ts +1 -1
- package/killeros/limits.ts +1 -0
- package/killeros/personal-instructions.ts +3 -1
- package/package.json +1 -6
- 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 -3257
- 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/commands.ts
CHANGED
|
@@ -1,76 +1,5 @@
|
|
|
1
|
-
import { type ExtensionAPI, type ExtensionCommandContext
|
|
1
|
+
import { type ExtensionAPI, type ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { AutocompleteItem } from "@earendil-works/pi-tui";
|
|
3
|
-
import { formatThreadControls, type ThreadStatus } from "./subagent-ui.ts";
|
|
4
|
-
|
|
5
|
-
export type SubagentControlAction = "list" | "inspect" | "wait" | "steer" | "interrupt" | "collect" | "resume" | "close";
|
|
6
|
-
|
|
7
|
-
export interface SubagentControlRequest {
|
|
8
|
-
action: SubagentControlAction;
|
|
9
|
-
threadId?: string;
|
|
10
|
-
all?: true;
|
|
11
|
-
message?: string;
|
|
12
|
-
task?: string;
|
|
13
|
-
timeoutMs?: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface SubagentControlThread {
|
|
17
|
-
id: string;
|
|
18
|
-
displayName?: string;
|
|
19
|
-
name?: string;
|
|
20
|
-
agent?: string;
|
|
21
|
-
role?: string;
|
|
22
|
-
task?: string;
|
|
23
|
-
prompt?: string;
|
|
24
|
-
status?: string;
|
|
25
|
-
state?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface SubagentControlDetails {
|
|
29
|
-
results?: readonly SubagentControlThread[];
|
|
30
|
-
threads?: readonly SubagentControlThread[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface SubagentControlResult {
|
|
34
|
-
text: string;
|
|
35
|
-
details?: SubagentControlDetails;
|
|
36
|
-
usage?: unknown;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface SubagentControlApi {
|
|
40
|
-
execute(request: SubagentControlRequest, ctx: ExtensionContext): Promise<SubagentControlResult>;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface SubagentToolLike {
|
|
44
|
-
name: string;
|
|
45
|
-
execute(
|
|
46
|
-
toolCallId: string,
|
|
47
|
-
params: unknown,
|
|
48
|
-
signal: AbortSignal | undefined,
|
|
49
|
-
onUpdate: undefined,
|
|
50
|
-
ctx: ExtensionContext,
|
|
51
|
-
): Promise<{
|
|
52
|
-
content?: readonly { type: string; text?: string }[];
|
|
53
|
-
details?: unknown;
|
|
54
|
-
usage?: unknown;
|
|
55
|
-
}>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function createSubagentControlApi(tool: SubagentToolLike): SubagentControlApi {
|
|
59
|
-
return {
|
|
60
|
-
async execute(request, ctx) {
|
|
61
|
-
const toolRequest = request.action === "interrupt" && request.threadId === "all"
|
|
62
|
-
? { action: "interrupt", all: true }
|
|
63
|
-
: request;
|
|
64
|
-
const result = await tool.execute("subagents-command", toolRequest, ctx.signal, undefined, ctx);
|
|
65
|
-
const text = result.content?.find((item) => item.type === "text")?.text ?? "";
|
|
66
|
-
return {
|
|
67
|
-
text,
|
|
68
|
-
details: result.details as SubagentControlDetails | undefined,
|
|
69
|
-
usage: result.usage,
|
|
70
|
-
};
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
3
|
|
|
75
4
|
async function confirmNewSession(ctx: ExtensionCommandContext): Promise<boolean> {
|
|
76
5
|
if (!ctx.hasUI) return true;
|
|
@@ -128,7 +57,6 @@ const BUILTIN_COMMANDS: ReadonlyArray<{ name: string; description: string }> = [
|
|
|
128
57
|
const COMMAND_SYNTAX_HINTS: Readonly<Record<string, string>> = {
|
|
129
58
|
goal: "/goal [objective|clear|edit|pause|resume]",
|
|
130
59
|
variants: "/variants [level]",
|
|
131
|
-
subagents: "/subagents [list|inspect|wait|steer|interrupt|collect|resume|close] [thread]",
|
|
132
60
|
model: "/model [provider/model]",
|
|
133
61
|
"scoped-models": "/scoped-models",
|
|
134
62
|
login: "/login [provider]",
|
|
@@ -151,162 +79,6 @@ function scoreCommandMatch(name: string, prefix: string): number {
|
|
|
151
79
|
return 0;
|
|
152
80
|
}
|
|
153
81
|
|
|
154
|
-
const SUBAGENT_COMMAND_USAGE = "/subagents [list|inspect|wait|steer|interrupt|collect|resume|close] [thread]";
|
|
155
|
-
|
|
156
|
-
function subagentCommandError(message: string): Error {
|
|
157
|
-
return new Error(`${message} Usage: ${SUBAGENT_COMMAND_USAGE}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function parseThreadReference(action: SubagentControlAction, tail: string): string {
|
|
161
|
-
const reference = tail.match(/^(\S+)(?:\s+([\s\S]*))?$/u)?.[1];
|
|
162
|
-
if (!reference) throw subagentCommandError(`/subagents ${action} requires a thread reference.`);
|
|
163
|
-
return reference;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function parseExplicitSubagentCommand(args: string): SubagentControlRequest {
|
|
167
|
-
const trimmed = args.trim();
|
|
168
|
-
const match = trimmed.match(/^(\S+)(?:\s+([\s\S]*))?$/u);
|
|
169
|
-
if (!match) throw subagentCommandError("/subagents requires an explicit verb outside TUI.");
|
|
170
|
-
const action = match[1]!.toLocaleLowerCase() as SubagentControlAction;
|
|
171
|
-
const tail = match[2]?.trim() ?? "";
|
|
172
|
-
|
|
173
|
-
if (action === "list") {
|
|
174
|
-
if (tail) throw subagentCommandError("/subagents list does not accept arguments.");
|
|
175
|
-
return { action };
|
|
176
|
-
}
|
|
177
|
-
if (action === "wait") {
|
|
178
|
-
if (!tail) return { action };
|
|
179
|
-
const parts = tail.split(/\s+/u);
|
|
180
|
-
if (parts.length > 2) throw subagentCommandError("/subagents wait accepts one thread reference and one timeout-ms value.");
|
|
181
|
-
if (parts.length === 1 && /^\d+$/u.test(parts[0]!)) {
|
|
182
|
-
return { action, timeoutMs: parseTimeout(parts[0]!) };
|
|
183
|
-
}
|
|
184
|
-
const request: SubagentControlRequest = { action, threadId: parts[0] };
|
|
185
|
-
if (parts[1] !== undefined) request.timeoutMs = parseTimeout(parts[1]);
|
|
186
|
-
return request;
|
|
187
|
-
}
|
|
188
|
-
if (action === "steer") {
|
|
189
|
-
const referenceAndMessage = tail.match(/^(\S+)(?:\s+([\s\S]+))?$/u);
|
|
190
|
-
if (!referenceAndMessage?.[1]) throw subagentCommandError("/subagents steer requires a thread reference.");
|
|
191
|
-
if (!referenceAndMessage[2]?.trim()) throw subagentCommandError("/subagents steer requires a message.");
|
|
192
|
-
return { action, threadId: referenceAndMessage[1], message: referenceAndMessage[2] };
|
|
193
|
-
}
|
|
194
|
-
if (action === "resume") {
|
|
195
|
-
const referenceAndTask = tail.match(/^(\S+)(?:\s+([\s\S]+))?$/u);
|
|
196
|
-
if (!referenceAndTask?.[1]) throw subagentCommandError("/subagents resume requires a thread reference.");
|
|
197
|
-
return {
|
|
198
|
-
action,
|
|
199
|
-
threadId: referenceAndTask[1],
|
|
200
|
-
...(referenceAndTask[2] ? { task: referenceAndTask[2] } : {}),
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
if (action === "inspect" || action === "interrupt" || action === "collect" || action === "close") {
|
|
204
|
-
const threadId = parseThreadReference(action, tail);
|
|
205
|
-
if (tail.slice(threadId.length).trim()) throw subagentCommandError(`/subagents ${action} accepts one thread reference.`);
|
|
206
|
-
return { action, threadId };
|
|
207
|
-
}
|
|
208
|
-
throw subagentCommandError(`Unknown /subagents action ${JSON.stringify(match[1])}.`);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function parseTimeout(value: string): number {
|
|
212
|
-
const timeoutMs = Number(value);
|
|
213
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 0) {
|
|
214
|
-
throw subagentCommandError("/subagents wait timeout-ms must be a non-negative integer.");
|
|
215
|
-
}
|
|
216
|
-
return timeoutMs;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function controlThreads(result: SubagentControlResult): SubagentControlThread[] {
|
|
220
|
-
const details = result.details;
|
|
221
|
-
if (!details) return [];
|
|
222
|
-
const results = [...(details.results ?? [])];
|
|
223
|
-
const threads = [...(details.threads ?? [])];
|
|
224
|
-
const candidates = results.length ? results : threads;
|
|
225
|
-
return candidates.filter((thread) => thread && typeof thread.id === "string" && thread.state !== "closed" && thread.status !== "closed");
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function threadStatus(thread: SubagentControlThread): ThreadStatus {
|
|
229
|
-
const status = (thread.status ?? thread.state ?? "queued").toLocaleLowerCase();
|
|
230
|
-
if (status === "active" || status === "running") return "running";
|
|
231
|
-
if (status === "done" || status === "complete" || status === "closed") return "complete";
|
|
232
|
-
if (status === "stopped" || status === "cancelled") return "cancelled";
|
|
233
|
-
if (status === "limited") return "limited";
|
|
234
|
-
if (status === "orphaned") return "orphaned";
|
|
235
|
-
if (status === "failed") return "failed";
|
|
236
|
-
return "queued";
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function threadLabel(thread: SubagentControlThread): string {
|
|
240
|
-
const name = thread.displayName ?? thread.name ?? thread.agent ?? thread.role ?? thread.id;
|
|
241
|
-
return `${name} · ${thread.id} · ${threadStatus(thread)}`;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function selectedThread(threads: readonly SubagentControlThread[], labels: readonly string[], choice: string): SubagentControlThread | undefined {
|
|
245
|
-
const index = labels.indexOf(choice);
|
|
246
|
-
if (index >= 0) return threads[index];
|
|
247
|
-
return threads.find((thread) => thread.id === choice || thread.displayName === choice || thread.name === choice);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async function executeSubagentControl(
|
|
251
|
-
control: SubagentControlApi | undefined,
|
|
252
|
-
request: SubagentControlRequest,
|
|
253
|
-
ctx: ExtensionCommandContext,
|
|
254
|
-
): Promise<void> {
|
|
255
|
-
if (!control) throw new Error("Subagent control API is not available.");
|
|
256
|
-
const result = await control.execute(request, ctx);
|
|
257
|
-
if (result?.text) ctx.ui.notify(result.text, "info");
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
async function runTuiSubagentCommand(control: SubagentControlApi | undefined, ctx: ExtensionCommandContext): Promise<void> {
|
|
261
|
-
if (!control) throw new Error("Subagent control API is not available.");
|
|
262
|
-
const listed = await control.execute({ action: "list" }, ctx);
|
|
263
|
-
const threads = controlThreads(listed);
|
|
264
|
-
if (!threads.length) {
|
|
265
|
-
ctx.ui.notify("No child threads.", "info");
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const labels = threads.map(threadLabel);
|
|
270
|
-
const selected = await ctx.ui.select("Select a thread", labels);
|
|
271
|
-
if (selected === undefined) return;
|
|
272
|
-
const thread = selectedThread(threads, labels, selected);
|
|
273
|
-
if (!thread) return;
|
|
274
|
-
|
|
275
|
-
const controls = formatThreadControls(threadStatus(thread)).filter((item) => item.enabled);
|
|
276
|
-
const controlLabels = controls.map((item) => item.label);
|
|
277
|
-
const selectedControl = await ctx.ui.select("Select a control", controlLabels);
|
|
278
|
-
if (selectedControl === undefined) return;
|
|
279
|
-
const chosen = controls.find((item) => item.label === selectedControl || item.id === selectedControl);
|
|
280
|
-
if (!chosen) return;
|
|
281
|
-
|
|
282
|
-
const request: SubagentControlRequest = { action: chosen.id, threadId: thread.id };
|
|
283
|
-
if (chosen.id === "steer") {
|
|
284
|
-
const message = await ctx.ui.input("Steer child thread", "Message");
|
|
285
|
-
if (message === undefined || !message.trim()) return;
|
|
286
|
-
request.message = message;
|
|
287
|
-
} else if (chosen.id === "resume") {
|
|
288
|
-
const task = await ctx.ui.input("Resume child thread", "Optional task");
|
|
289
|
-
if (task === undefined) return;
|
|
290
|
-
if (task) request.task = task;
|
|
291
|
-
}
|
|
292
|
-
await executeSubagentControl(control, request, ctx);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export function registerSubagentCommand(pi: ExtensionAPI, control?: SubagentControlApi | void): void {
|
|
296
|
-
const api = control && typeof control.execute === "function" ? control : undefined;
|
|
297
|
-
pi.registerCommand("subagents", {
|
|
298
|
-
description: "Inspect and control child threads",
|
|
299
|
-
handler: async (args, ctx) => {
|
|
300
|
-
if (!args.trim()) {
|
|
301
|
-
if (ctx.mode !== "tui") throw subagentCommandError("/subagents requires an explicit verb outside TUI.");
|
|
302
|
-
await runTuiSubagentCommand(api, ctx);
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
await executeSubagentControl(api, parseExplicitSubagentCommand(args), ctx);
|
|
306
|
-
},
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
|
|
310
82
|
export function registerSlashAutocomplete(pi: ExtensionAPI): void {
|
|
311
83
|
const usage = new Map<string, number>();
|
|
312
84
|
pi.on("session_start", (_event, ctx) => {
|
|
@@ -349,15 +121,6 @@ export function registerSlashAutocomplete(pi: ExtensionAPI): void {
|
|
|
349
121
|
}
|
|
350
122
|
}
|
|
351
123
|
|
|
352
|
-
if (!commands.has("subagents")) {
|
|
353
|
-
commands.set("subagents", {
|
|
354
|
-
name: "subagents",
|
|
355
|
-
description: "Inspect and control child threads",
|
|
356
|
-
category: "Extension",
|
|
357
|
-
syntaxHint: COMMAND_SYNTAX_HINTS.subagents,
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
|
|
361
124
|
const ranked = [...commands.values()]
|
|
362
125
|
.map((command) => ({
|
|
363
126
|
command,
|
package/killeros/display.ts
CHANGED
|
@@ -6,9 +6,11 @@ export function formatCwd(cwd: string): string {
|
|
|
6
6
|
if (!home) return cwd;
|
|
7
7
|
const normalizedHome = home.replace(/[\\/]+$/, "");
|
|
8
8
|
const normalizedCwd = cwd.replace(/[\\/]+$/, "");
|
|
9
|
-
|
|
9
|
+
const comparedHome = process.platform === "win32" ? normalizedHome.toLocaleLowerCase() : normalizedHome;
|
|
10
|
+
const comparedCwd = process.platform === "win32" ? normalizedCwd.toLocaleLowerCase() : normalizedCwd;
|
|
11
|
+
if (comparedCwd === comparedHome) return "~";
|
|
10
12
|
const separator = normalizedCwd.slice(normalizedHome.length, normalizedHome.length + 1);
|
|
11
|
-
return
|
|
13
|
+
return comparedCwd.startsWith(comparedHome) && (separator === "/" || separator === "\\")
|
|
12
14
|
? `~${normalizedCwd.slice(normalizedHome.length)}`
|
|
13
15
|
: cwd;
|
|
14
16
|
}
|
|
@@ -20,6 +22,7 @@ export function padRight(text: string, width: number): string {
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export function formatTime(milliseconds: number): string {
|
|
25
|
+
if (!Number.isFinite(milliseconds)) return "0s";
|
|
23
26
|
const totalSeconds = Math.max(0, Math.floor(milliseconds / 1_000));
|
|
24
27
|
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
25
28
|
const minutes = Math.floor(totalSeconds / 60);
|
|
@@ -28,6 +31,7 @@ export function formatTime(milliseconds: number): string {
|
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export function formatTokens(value: number): string {
|
|
34
|
+
if (!Number.isFinite(value)) return "0";
|
|
31
35
|
const amount = Math.max(0, value);
|
|
32
36
|
if (amount < 1_000) return `${Math.round(amount)}`;
|
|
33
37
|
if (amount >= 1_000_000) {
|
package/killeros/footer.ts
CHANGED
|
@@ -13,8 +13,8 @@ export function formatCost(usd: number): string {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function formatContextProgress(tokensUsed: number | null, contextWindow: number, theme: Theme): string {
|
|
16
|
-
if (tokensUsed === null) return theme.fg("dim", "—% left (—)");
|
|
17
|
-
const windowSize = contextWindow > 0 ? contextWindow : 128_000;
|
|
16
|
+
if (tokensUsed === null || !Number.isFinite(tokensUsed)) return theme.fg("dim", "—% left (—)");
|
|
17
|
+
const windowSize = Number.isFinite(contextWindow) && contextWindow > 0 ? contextWindow : 128_000;
|
|
18
18
|
const remaining = Math.max(0, Math.min(windowSize, windowSize - Math.max(0, tokensUsed)));
|
|
19
19
|
const percentLeft = Math.max(0, Math.min(100, Math.round((remaining / windowSize) * 100)));
|
|
20
20
|
const color: ThemeColor = percentLeft < 20 ? "error" : percentLeft <= 50 ? "warning" : "success";
|
|
@@ -150,7 +150,12 @@ export function registerFooter(pi: ExtensionAPI, goalRuntime: GoalRuntime): void
|
|
|
150
150
|
const level = model?.reasoning === false
|
|
151
151
|
? theme.fg("thinkingOff", "no reasoning")
|
|
152
152
|
: theme.fg(LEVEL_COLORS[thinkingLevel], thinkingLevel);
|
|
153
|
-
|
|
153
|
+
let usage: ReturnType<ExtensionContext["getContextUsage"]>;
|
|
154
|
+
try {
|
|
155
|
+
usage = ctx.getContextUsage();
|
|
156
|
+
} catch {
|
|
157
|
+
usage = undefined;
|
|
158
|
+
}
|
|
154
159
|
const contextWindow = usage?.contextWindow ?? model?.contextWindow ?? 128_000;
|
|
155
160
|
const context = formatContextProgress(usage?.tokens ?? null, contextWindow, theme);
|
|
156
161
|
const branch = footerData.getGitBranch();
|
package/killeros/goals.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ExtensionAPI, type ExtensionContext, type ThemeColor } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Text } from "@earendil-works/pi-tui";
|
|
3
3
|
import { Type } from "typebox";
|
|
4
|
-
import { MAX_NODE_TIMER_MS } from "./
|
|
4
|
+
import { MAX_NODE_TIMER_MS } from "./limits.ts";
|
|
5
5
|
import { CONCISE_SYSTEM_PROMPT } from "./concise.ts";
|
|
6
6
|
import { formatTime, formatTokens } from "./display.ts";
|
|
7
7
|
import { reportError } from "./errors.ts";
|
package/killeros/hooks.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { CONFIG_DIR_NAME, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
import { reportError } from "./errors.ts";
|
|
6
|
-
import { MAX_NODE_TIMER_MS } from "./
|
|
6
|
+
import { MAX_NODE_TIMER_MS } from "./limits.ts";
|
|
7
7
|
|
|
8
8
|
type KillerosHookEvent = "tool_call" | "tool_result" | "agent_settled";
|
|
9
9
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MAX_NODE_TIMER_MS = 2_147_483_647;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { closeSync, existsSync, openSync, readFileSync, readSync } from "node:fs";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { StringDecoder } from "node:string_decoder";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { CONFIG_DIR_NAME, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
7
|
import type { InitRuntime } from "./runtime.ts";
|
|
@@ -14,7 +15,8 @@ function readBoundedText(filePath: string, limit = PERSONAL_INSTRUCTIONS_LIMIT):
|
|
|
14
15
|
descriptor = openSync(filePath, "r");
|
|
15
16
|
const buffer = Buffer.alloc(limit + 1);
|
|
16
17
|
const bytesRead = readSync(descriptor, buffer, 0, buffer.length, 0);
|
|
17
|
-
const
|
|
18
|
+
const decoder = new StringDecoder("utf8");
|
|
19
|
+
const content = decoder.write(buffer.subarray(0, Math.min(bytesRead, limit)));
|
|
18
20
|
if (!content.trim()) return undefined;
|
|
19
21
|
return bytesRead > limit
|
|
20
22
|
? `${content}\n\n[Personal instructions truncated by KillerOS]`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "killeros",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A production-hardened TUI and workflow extension for the Pi coding agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -22,10 +22,6 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"Killeros.ts",
|
|
24
24
|
"killeros/*.ts",
|
|
25
|
-
"subagents.ts",
|
|
26
|
-
"subagent-lifecycle.ts",
|
|
27
|
-
"subagent-process.ts",
|
|
28
|
-
"subagent-ui.ts",
|
|
29
25
|
"themes/killeros.json",
|
|
30
26
|
"README.md",
|
|
31
27
|
"CHANGELOG.md"
|
|
@@ -49,7 +45,6 @@
|
|
|
49
45
|
"@earendil-works/pi-ai": ">=0.82.1",
|
|
50
46
|
"@earendil-works/pi-coding-agent": ">=0.82.1",
|
|
51
47
|
"@earendil-works/pi-tui": ">=0.82.1",
|
|
52
|
-
"pi-web-access": ">=0.17.1",
|
|
53
48
|
"typebox": ">=1.1.38 <2"
|
|
54
49
|
},
|
|
55
50
|
"devDependencies": {
|