opencodekit 0.14.4 → 0.14.5
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/dist/index.js +7 -7
- package/dist/template/.opencode/.background-tasks.json +18 -0
- package/dist/template/.opencode/command/analyze-project.md +187 -358
- package/dist/template/.opencode/command/implement.md +29 -30
- package/dist/template/.opencode/command/new-feature.md +10 -10
- package/dist/template/.opencode/command/plan.md +13 -15
- package/dist/template/.opencode/command/start.md +11 -12
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/tool/background.ts +147 -99
- package/package.json +7 -7
|
@@ -1,22 +1,45 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @experimental Background Task Tool
|
|
3
|
+
*
|
|
4
|
+
* LIMITATION: Creates SEPARATE sessions, NOT child sessions of the parent.
|
|
5
|
+
* This means background tasks don't inherit context from the build agent's session.
|
|
6
|
+
*
|
|
7
|
+
* USE CASES:
|
|
8
|
+
* - True fire-and-forget async execution
|
|
9
|
+
* - When you need to continue working before results are ready
|
|
10
|
+
*
|
|
11
|
+
* FOR MOST CASES: Use the Task tool instead. Multiple Task calls in one message
|
|
12
|
+
* run in parallel AND create proper child sessions.
|
|
13
|
+
*
|
|
14
|
+
* Example with Task (recommended):
|
|
15
|
+
* Task({ subagent_type: "scout", prompt: "..." }) // ┐
|
|
16
|
+
* Task({ subagent_type: "explore", prompt: "..." }) // ┘ Parallel, proper sessions
|
|
17
|
+
*
|
|
18
|
+
* Example with Background (fire-and-forget):
|
|
19
|
+
* background_start({ agent: "scout", prompt: "..." }) // → taskId
|
|
20
|
+
* // ... continue other work ...
|
|
21
|
+
* background_output({ taskId }) // collect later
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { type ChildProcess, execSync, spawn } from "node:child_process";
|
|
2
25
|
import fs from "node:fs/promises";
|
|
3
26
|
import path from "node:path";
|
|
4
27
|
import { tool } from "@opencode-ai/plugin";
|
|
5
|
-
import { createOpencodeClient } from "@opencode-ai/sdk";
|
|
6
28
|
|
|
7
29
|
const TASKS_FILE = ".opencode/.background-tasks.json";
|
|
30
|
+
const OUTPUT_DIR = ".opencode/.background-output";
|
|
8
31
|
|
|
9
32
|
interface BackgroundTask {
|
|
10
33
|
taskId: string;
|
|
11
|
-
|
|
12
|
-
|
|
34
|
+
pid: number;
|
|
35
|
+
outputFile: string;
|
|
13
36
|
agent: string;
|
|
14
37
|
prompt: string;
|
|
15
38
|
started: number;
|
|
16
|
-
status: "running" | "completed" | "cancelled";
|
|
39
|
+
status: "running" | "completed" | "cancelled" | "failed";
|
|
17
40
|
// Beads integration
|
|
18
41
|
beadId?: string;
|
|
19
|
-
autoCloseBead?: boolean;
|
|
42
|
+
autoCloseBead?: boolean;
|
|
20
43
|
}
|
|
21
44
|
|
|
22
45
|
interface TasksStore {
|
|
@@ -37,8 +60,8 @@ async function saveTasks(store: TasksStore): Promise<void> {
|
|
|
37
60
|
await fs.writeFile(TASKS_FILE, JSON.stringify(store, null, 2));
|
|
38
61
|
}
|
|
39
62
|
|
|
40
|
-
function
|
|
41
|
-
|
|
63
|
+
async function ensureOutputDir(): Promise<void> {
|
|
64
|
+
await fs.mkdir(OUTPUT_DIR, { recursive: true });
|
|
42
65
|
}
|
|
43
66
|
|
|
44
67
|
/**
|
|
@@ -46,7 +69,6 @@ function createClient() {
|
|
|
46
69
|
*/
|
|
47
70
|
function findBdPath(): string {
|
|
48
71
|
try {
|
|
49
|
-
// Try to find bd in PATH using shell
|
|
50
72
|
const result = execSync("which bd || command -v bd", {
|
|
51
73
|
encoding: "utf-8",
|
|
52
74
|
timeout: 5000,
|
|
@@ -54,7 +76,6 @@ function findBdPath(): string {
|
|
|
54
76
|
}).trim();
|
|
55
77
|
if (result) return result;
|
|
56
78
|
} catch {
|
|
57
|
-
// Fallback to common locations
|
|
58
79
|
const commonPaths = [
|
|
59
80
|
`${process.env.HOME}/.local/bin/bd`,
|
|
60
81
|
`${process.env.HOME}/.bun/bin/bd`,
|
|
@@ -70,11 +91,9 @@ function findBdPath(): string {
|
|
|
70
91
|
}
|
|
71
92
|
}
|
|
72
93
|
}
|
|
73
|
-
// Last resort - assume it's in PATH
|
|
74
94
|
return "bd";
|
|
75
95
|
}
|
|
76
96
|
|
|
77
|
-
// Cache the bd path
|
|
78
97
|
let bdPath: string | null = null;
|
|
79
98
|
function getBdPath(): string {
|
|
80
99
|
if (!bdPath) {
|
|
@@ -90,11 +109,9 @@ async function runBeadsCommand(
|
|
|
90
109
|
args: string[],
|
|
91
110
|
): Promise<{ success: boolean; output: string }> {
|
|
92
111
|
try {
|
|
93
|
-
// Quote arguments that contain spaces
|
|
94
112
|
const quotedArgs = args.map((arg) =>
|
|
95
113
|
arg.includes(" ") ? `"${arg}"` : arg,
|
|
96
114
|
);
|
|
97
|
-
// Use dynamically detected bd path with shell for proper PATH resolution
|
|
98
115
|
const output = execSync(`${getBdPath()} ${quotedArgs.join(" ")}`, {
|
|
99
116
|
encoding: "utf-8",
|
|
100
117
|
timeout: 30000,
|
|
@@ -111,10 +128,19 @@ async function runBeadsCommand(
|
|
|
111
128
|
}
|
|
112
129
|
}
|
|
113
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Check if a process is still running by PID
|
|
133
|
+
*/
|
|
134
|
+
function isProcessRunning(pid: number): boolean {
|
|
135
|
+
try {
|
|
136
|
+
process.kill(pid, 0); // Signal 0 = check if process exists
|
|
137
|
+
return true;
|
|
138
|
+
} catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
114
143
|
// Allowed agents for background delegation
|
|
115
|
-
// - Subagents: explore, scout, review, planner, vision, looker (stateless workers)
|
|
116
|
-
// - Primary: rush (autonomous execution)
|
|
117
|
-
// - NOT allowed: build (build is the orchestrator that uses this tool)
|
|
118
144
|
const ALLOWED_AGENTS = [
|
|
119
145
|
"explore",
|
|
120
146
|
"scout",
|
|
@@ -127,7 +153,6 @@ const ALLOWED_AGENTS = [
|
|
|
127
153
|
type AllowedAgent = (typeof ALLOWED_AGENTS)[number];
|
|
128
154
|
|
|
129
155
|
// Agents safe for autoCloseBead (pure research, no side effects)
|
|
130
|
-
// These only return information, don't make changes that need verification
|
|
131
156
|
const SAFE_AUTOCLOSE_AGENTS: readonly string[] = [
|
|
132
157
|
"explore",
|
|
133
158
|
"scout",
|
|
@@ -135,8 +160,8 @@ const SAFE_AUTOCLOSE_AGENTS: readonly string[] = [
|
|
|
135
160
|
] as const;
|
|
136
161
|
|
|
137
162
|
/**
|
|
138
|
-
* Start a background subagent task
|
|
139
|
-
*
|
|
163
|
+
* Start a background subagent task using `opencode run`.
|
|
164
|
+
* Spawns a separate process that runs independently.
|
|
140
165
|
*/
|
|
141
166
|
export const start = tool({
|
|
142
167
|
description:
|
|
@@ -145,7 +170,7 @@ export const start = tool({
|
|
|
145
170
|
agent: tool.schema
|
|
146
171
|
.string()
|
|
147
172
|
.describe(
|
|
148
|
-
"Agent type: explore, scout, review, planner, vision, looker, rush (NOT build
|
|
173
|
+
"Agent type: explore, scout, review, planner, vision, looker, rush (NOT build)",
|
|
149
174
|
),
|
|
150
175
|
prompt: tool.schema.string().describe("Task prompt for the agent"),
|
|
151
176
|
title: tool.schema
|
|
@@ -160,15 +185,15 @@ export const start = tool({
|
|
|
160
185
|
.boolean()
|
|
161
186
|
.optional()
|
|
162
187
|
.describe(
|
|
163
|
-
"Auto-close bead on completion. Only allowed for safe agents (explore, scout
|
|
188
|
+
"Auto-close bead on completion. Only allowed for safe agents (explore, scout, looker).",
|
|
164
189
|
),
|
|
165
190
|
},
|
|
166
|
-
execute: async (args
|
|
167
|
-
// Validate agent type
|
|
191
|
+
execute: async (args) => {
|
|
192
|
+
// Validate agent type
|
|
168
193
|
if (args.agent === "build") {
|
|
169
194
|
return JSON.stringify({
|
|
170
195
|
error:
|
|
171
|
-
"Cannot delegate to 'build' agent. Build is the orchestrator
|
|
196
|
+
"Cannot delegate to 'build' agent. Build is the orchestrator. Use subagents instead.",
|
|
172
197
|
});
|
|
173
198
|
}
|
|
174
199
|
|
|
@@ -178,56 +203,61 @@ export const start = tool({
|
|
|
178
203
|
});
|
|
179
204
|
}
|
|
180
205
|
|
|
181
|
-
// Validate autoCloseBead
|
|
206
|
+
// Validate autoCloseBead
|
|
182
207
|
if (args.autoCloseBead && !SAFE_AUTOCLOSE_AGENTS.includes(args.agent)) {
|
|
183
208
|
return JSON.stringify({
|
|
184
|
-
error: `autoCloseBead not allowed for '${args.agent}' agent. Only safe for: ${SAFE_AUTOCLOSE_AGENTS.join(", ")}
|
|
209
|
+
error: `autoCloseBead not allowed for '${args.agent}' agent. Only safe for: ${SAFE_AUTOCLOSE_AGENTS.join(", ")}`,
|
|
185
210
|
});
|
|
186
211
|
}
|
|
187
212
|
|
|
188
|
-
|
|
213
|
+
await ensureOutputDir();
|
|
214
|
+
|
|
189
215
|
const taskId = `bg_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
190
|
-
const title = args.title || `bg-${args.agent}-${
|
|
216
|
+
const title = args.title || `bg-${args.agent}-${taskId}`;
|
|
217
|
+
const outputFile = path.join(OUTPUT_DIR, `${taskId}.txt`);
|
|
191
218
|
|
|
192
219
|
try {
|
|
193
|
-
// Create
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
220
|
+
// Create output file to capture stdout
|
|
221
|
+
const outFd = await fs.open(outputFile, "w");
|
|
222
|
+
|
|
223
|
+
// Spawn opencode run with the agent and prompt
|
|
224
|
+
// Using --format default for readable output (json is too verbose for collection)
|
|
225
|
+
const proc = spawn(
|
|
226
|
+
"opencode",
|
|
227
|
+
[
|
|
228
|
+
"run",
|
|
229
|
+
"--agent",
|
|
230
|
+
args.agent,
|
|
231
|
+
"--title",
|
|
197
232
|
title,
|
|
198
|
-
|
|
233
|
+
"--format",
|
|
234
|
+
"default",
|
|
235
|
+
args.prompt,
|
|
236
|
+
],
|
|
237
|
+
{
|
|
238
|
+
detached: true, // Run independently of parent
|
|
239
|
+
stdio: ["ignore", outFd.fd, outFd.fd], // Redirect stdout/stderr to file
|
|
240
|
+
cwd: process.cwd(),
|
|
241
|
+
env: { ...process.env },
|
|
199
242
|
},
|
|
200
|
-
|
|
243
|
+
);
|
|
201
244
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
245
|
+
// Don't wait for completion - let it run in background
|
|
246
|
+
proc.unref();
|
|
205
247
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
parts: [
|
|
213
|
-
{
|
|
214
|
-
type: "agent" as const,
|
|
215
|
-
name: args.agent, // AgentPartInput triggers agent routing
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
type: "text" as const,
|
|
219
|
-
text: args.prompt,
|
|
220
|
-
},
|
|
221
|
-
],
|
|
222
|
-
},
|
|
223
|
-
});
|
|
248
|
+
// Close our handle to the output file (process keeps its own)
|
|
249
|
+
await outFd.close();
|
|
250
|
+
|
|
251
|
+
if (!proc.pid) {
|
|
252
|
+
return JSON.stringify({ error: "Failed to spawn opencode process" });
|
|
253
|
+
}
|
|
224
254
|
|
|
225
255
|
// Persist task info
|
|
226
256
|
const store = await loadTasks();
|
|
227
257
|
store.tasks[taskId] = {
|
|
228
258
|
taskId,
|
|
229
|
-
|
|
230
|
-
|
|
259
|
+
pid: proc.pid,
|
|
260
|
+
outputFile,
|
|
231
261
|
agent: args.agent,
|
|
232
262
|
prompt: args.prompt,
|
|
233
263
|
started: Date.now(),
|
|
@@ -249,7 +279,7 @@ export const start = tool({
|
|
|
249
279
|
|
|
250
280
|
return JSON.stringify({
|
|
251
281
|
taskId,
|
|
252
|
-
|
|
282
|
+
pid: proc.pid,
|
|
253
283
|
agent: args.agent,
|
|
254
284
|
beadId: args.beadId,
|
|
255
285
|
status: "started",
|
|
@@ -266,7 +296,7 @@ export const start = tool({
|
|
|
266
296
|
|
|
267
297
|
/**
|
|
268
298
|
* Get output from a background task.
|
|
269
|
-
*
|
|
299
|
+
* Reads the output file and checks if the process has completed.
|
|
270
300
|
*/
|
|
271
301
|
export const output = tool({
|
|
272
302
|
description:
|
|
@@ -275,7 +305,6 @@ export const output = tool({
|
|
|
275
305
|
taskId: tool.schema.string().describe("Task ID from background_start"),
|
|
276
306
|
},
|
|
277
307
|
execute: async (args) => {
|
|
278
|
-
const client = createClient();
|
|
279
308
|
const store = await loadTasks();
|
|
280
309
|
const task = store.tasks[args.taskId];
|
|
281
310
|
|
|
@@ -287,54 +316,47 @@ export const output = tool({
|
|
|
287
316
|
}
|
|
288
317
|
|
|
289
318
|
try {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
});
|
|
319
|
+
// Check if process is still running
|
|
320
|
+
const running = isProcessRunning(task.pid);
|
|
293
321
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
322
|
+
// Read output file
|
|
323
|
+
let output = "";
|
|
324
|
+
try {
|
|
325
|
+
output = await fs.readFile(task.outputFile, "utf-8");
|
|
326
|
+
} catch {
|
|
327
|
+
output = "(no output yet)";
|
|
300
328
|
}
|
|
301
329
|
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
(m) => m.info?.role === "assistant",
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
if (!assistantMessages.length) {
|
|
330
|
+
// If still running and no substantial output
|
|
331
|
+
if (running && output.length < 100) {
|
|
308
332
|
return JSON.stringify({
|
|
309
333
|
taskId: args.taskId,
|
|
334
|
+
agent: task.agent,
|
|
310
335
|
status: "running",
|
|
311
|
-
message: "Task running - no response yet",
|
|
336
|
+
message: "Task still running - no complete response yet",
|
|
337
|
+
partialOutput: output.slice(0, 500),
|
|
312
338
|
});
|
|
313
339
|
}
|
|
314
340
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
// Update status
|
|
322
|
-
task.status = "completed";
|
|
323
|
-
await saveTasks(store);
|
|
341
|
+
// Process completed or has substantial output
|
|
342
|
+
if (!running) {
|
|
343
|
+
// Update status
|
|
344
|
+
task.status = output.length > 0 ? "completed" : "failed";
|
|
345
|
+
await saveTasks(store);
|
|
346
|
+
}
|
|
324
347
|
|
|
325
348
|
// Build result object
|
|
326
349
|
const result: Record<string, unknown> = {
|
|
327
350
|
taskId: args.taskId,
|
|
328
351
|
agent: task.agent,
|
|
329
|
-
status: "
|
|
330
|
-
output:
|
|
352
|
+
status: running ? "running" : task.status,
|
|
353
|
+
output: output || "(empty response)",
|
|
331
354
|
};
|
|
332
355
|
|
|
333
|
-
// Handle bead closing
|
|
334
|
-
if (task.beadId) {
|
|
356
|
+
// Handle bead closing (only if completed)
|
|
357
|
+
if (task.beadId && !running && task.status === "completed") {
|
|
335
358
|
result.beadId = task.beadId;
|
|
336
359
|
|
|
337
|
-
// Auto-close for safe agents (explore, scout)
|
|
338
360
|
if (task.autoCloseBead && SAFE_AUTOCLOSE_AGENTS.includes(task.agent)) {
|
|
339
361
|
const closeResult = await runBeadsCommand([
|
|
340
362
|
"close",
|
|
@@ -347,8 +369,7 @@ export const output = tool({
|
|
|
347
369
|
result.beadCloseError = closeResult.output;
|
|
348
370
|
}
|
|
349
371
|
} else {
|
|
350
|
-
|
|
351
|
-
result.beadAction = `VERIFY output, then run: bd close ${task.beadId} --reason "..." `;
|
|
372
|
+
result.beadAction = `VERIFY output, then run: bd close ${task.beadId} --reason "..."`;
|
|
352
373
|
}
|
|
353
374
|
}
|
|
354
375
|
|
|
@@ -364,8 +385,7 @@ export const output = tool({
|
|
|
364
385
|
});
|
|
365
386
|
|
|
366
387
|
/**
|
|
367
|
-
* Cancel background tasks.
|
|
368
|
-
* Aborts running sessions and cleans up task records.
|
|
388
|
+
* Cancel background tasks by killing the process.
|
|
369
389
|
*/
|
|
370
390
|
export const cancel = tool({
|
|
371
391
|
description:
|
|
@@ -381,7 +401,6 @@ export const cancel = tool({
|
|
|
381
401
|
.describe("Specific task ID to cancel"),
|
|
382
402
|
},
|
|
383
403
|
execute: async (args) => {
|
|
384
|
-
const client = createClient();
|
|
385
404
|
const store = await loadTasks();
|
|
386
405
|
const cancelled: string[] = [];
|
|
387
406
|
const errors: string[] = [];
|
|
@@ -405,12 +424,24 @@ export const cancel = tool({
|
|
|
405
424
|
|
|
406
425
|
for (const task of tasksToCancel) {
|
|
407
426
|
try {
|
|
408
|
-
|
|
427
|
+
// Kill the process and its children (negative PID kills process group)
|
|
428
|
+
try {
|
|
429
|
+
process.kill(-task.pid, "SIGTERM");
|
|
430
|
+
} catch {
|
|
431
|
+
// Try without process group
|
|
432
|
+
process.kill(task.pid, "SIGTERM");
|
|
433
|
+
}
|
|
409
434
|
task.status = "cancelled";
|
|
410
435
|
cancelled.push(task.taskId);
|
|
411
436
|
} catch (e) {
|
|
412
437
|
const error = e instanceof Error ? e.message : String(e);
|
|
413
|
-
|
|
438
|
+
// Process might already be dead
|
|
439
|
+
if (error.includes("ESRCH")) {
|
|
440
|
+
task.status = "cancelled";
|
|
441
|
+
cancelled.push(task.taskId);
|
|
442
|
+
} else {
|
|
443
|
+
errors.push(`${task.taskId}: ${error}`);
|
|
444
|
+
}
|
|
414
445
|
}
|
|
415
446
|
}
|
|
416
447
|
|
|
@@ -433,7 +464,7 @@ export const list = tool({
|
|
|
433
464
|
description: "List all background tasks with their status.",
|
|
434
465
|
args: {
|
|
435
466
|
status: tool.schema
|
|
436
|
-
.enum(["running", "completed", "cancelled", "all"])
|
|
467
|
+
.enum(["running", "completed", "cancelled", "failed", "all"])
|
|
437
468
|
.optional()
|
|
438
469
|
.default("all")
|
|
439
470
|
.describe("Filter by status"),
|
|
@@ -442,6 +473,20 @@ export const list = tool({
|
|
|
442
473
|
const store = await loadTasks();
|
|
443
474
|
const tasks = Object.values(store.tasks);
|
|
444
475
|
|
|
476
|
+
// Update status of running tasks
|
|
477
|
+
for (const task of tasks) {
|
|
478
|
+
if (task.status === "running" && !isProcessRunning(task.pid)) {
|
|
479
|
+
// Process finished, check if it has output
|
|
480
|
+
try {
|
|
481
|
+
const output = await fs.readFile(task.outputFile, "utf-8");
|
|
482
|
+
task.status = output.length > 0 ? "completed" : "failed";
|
|
483
|
+
} catch {
|
|
484
|
+
task.status = "failed";
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
await saveTasks(store);
|
|
489
|
+
|
|
445
490
|
const filtered =
|
|
446
491
|
args.status === "all"
|
|
447
492
|
? tasks
|
|
@@ -453,8 +498,11 @@ export const list = tool({
|
|
|
453
498
|
taskId: t.taskId,
|
|
454
499
|
agent: t.agent,
|
|
455
500
|
status: t.status,
|
|
501
|
+
pid: t.pid,
|
|
456
502
|
started: new Date(t.started).toISOString(),
|
|
503
|
+
running: t.status === "running" ? isProcessRunning(t.pid) : false,
|
|
457
504
|
prompt: t.prompt.slice(0, 100) + (t.prompt.length > 100 ? "..." : ""),
|
|
505
|
+
beadId: t.beadId,
|
|
458
506
|
})),
|
|
459
507
|
});
|
|
460
508
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencodekit",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.5",
|
|
4
4
|
"description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -34,23 +34,23 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@clack/prompts": "^0.7.0",
|
|
37
|
-
"@opencode-ai/plugin": "^1.1.
|
|
38
|
-
"@opentui/core": "^0.1.
|
|
39
|
-
"@opentui/solid": "^0.1.
|
|
37
|
+
"@opencode-ai/plugin": "^1.1.12",
|
|
38
|
+
"@opentui/core": "^0.1.72",
|
|
39
|
+
"@opentui/solid": "^0.1.72",
|
|
40
40
|
"beads-village": "^1.3.3",
|
|
41
41
|
"cac": "^6.7.14",
|
|
42
42
|
"cli-table3": "^0.6.5",
|
|
43
43
|
"ora": "^9.0.0",
|
|
44
44
|
"picocolors": "^1.1.1",
|
|
45
45
|
"solid-js": "^1.9.10",
|
|
46
|
-
"zod": "^3.
|
|
46
|
+
"zod": "^3.25.76"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@beads/bd": "^0.29.0",
|
|
50
50
|
"@biomejs/biome": "^1.9.4",
|
|
51
51
|
"@types/bun": "latest",
|
|
52
|
-
"@types/node": "^22.
|
|
53
|
-
"typescript": "^5.
|
|
52
|
+
"@types/node": "^22.19.5",
|
|
53
|
+
"typescript": "^5.9.3"
|
|
54
54
|
},
|
|
55
55
|
"trustedDependencies": ["@beads/bd"]
|
|
56
56
|
}
|