runcastle 1.2.0 → 1.2.2
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/bin/runcastle.js +233 -22
- package/drizzle/0018_nice_lorna_dane.sql +10 -0
- package/drizzle/meta/0018_snapshot.json +846 -0
- package/drizzle/meta/_journal.json +7 -0
- package/index.js +231 -20
- package/package.json +1 -1
- package/web/assets/index-Co7aViQi.js +142 -0
- package/web/assets/{index-D0dcZNJp.css → index-o2brqt2b.css} +1 -1
- package/web/index.html +2 -2
- package/web/assets/index-g3KG__Hv.js +0 -142
package/bin/runcastle.js
CHANGED
|
@@ -246,7 +246,7 @@ var init_ids = () => {};
|
|
|
246
246
|
|
|
247
247
|
// ../core/src/schemas.ts
|
|
248
248
|
import * as z2 from "zod";
|
|
249
|
-
var Phase, TicketStatus, SessionKind, RunStatus, FeatureStatus, SessionStatus, TicketInput, Ticket, WaypointType, WaypointStatus, WaypointDisposition, WaypointInput, Waypoint, PREPARED_KEYS, PreparedKey, DRIVE_LOOP_KEYS, FindingSource, PROJECT_NAME_MAX = 80, ProjectName, Project, ProjectFinding, Feature, SessionRow, Run, SettingSource, SettingScope, SettingField, SettingsView, SettingsUpdateInput, EventRow;
|
|
249
|
+
var Phase, TicketStatus, SessionKind, RunStatus, FeatureStatus, SessionStatus, TicketInput, Ticket, WaypointType, WaypointStatus, WaypointDisposition, WaypointInput, Waypoint, TestNoteStatus, TestNote, PREPARED_KEYS, PreparedKey, DRIVE_LOOP_KEYS, FindingSource, PROJECT_NAME_MAX = 80, ProjectName, Project, ProjectFinding, Feature, SessionRow, Run, SettingSource, SettingScope, SettingField, SettingsView, SettingsUpdateInput, EventRow;
|
|
250
250
|
var init_schemas = __esm(() => {
|
|
251
251
|
Phase = z2.enum([
|
|
252
252
|
"ideation",
|
|
@@ -308,6 +308,17 @@ var init_schemas = __esm(() => {
|
|
|
308
308
|
lastSessionId: z2.string().optional(),
|
|
309
309
|
summary: z2.string().optional()
|
|
310
310
|
});
|
|
311
|
+
TestNoteStatus = z2.enum(["open", "done", "promoted"]);
|
|
312
|
+
TestNote = z2.object({
|
|
313
|
+
id: z2.string(),
|
|
314
|
+
featureId: z2.string(),
|
|
315
|
+
lap: z2.number(),
|
|
316
|
+
text: z2.string(),
|
|
317
|
+
status: TestNoteStatus,
|
|
318
|
+
ticketId: z2.string().optional(),
|
|
319
|
+
createdAt: z2.number(),
|
|
320
|
+
updatedAt: z2.number()
|
|
321
|
+
});
|
|
311
322
|
PREPARED_KEYS = [
|
|
312
323
|
"setupCommand",
|
|
313
324
|
"verifyCommands",
|
|
@@ -560,7 +571,7 @@ var init_pipeline = __esm(() => {
|
|
|
560
571
|
|
|
561
572
|
// ../core/src/db-schema.ts
|
|
562
573
|
import { integer, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
563
|
-
var projects, projectFindings, features, sessions, tickets, waypoints, runs, events, gateOverrides;
|
|
574
|
+
var projects, projectFindings, features, sessions, tickets, testNotes, waypoints, runs, events, gateOverrides;
|
|
564
575
|
var init_db_schema = __esm(() => {
|
|
565
576
|
projects = sqliteTable("projects", {
|
|
566
577
|
id: text("id").primaryKey(),
|
|
@@ -632,6 +643,16 @@ var init_db_schema = __esm(() => {
|
|
|
632
643
|
attemptBranch: text("attempt_branch"),
|
|
633
644
|
conflictFiles: text("conflict_files", { mode: "json" }).$type()
|
|
634
645
|
});
|
|
646
|
+
testNotes = sqliteTable("test_notes", {
|
|
647
|
+
id: text("id").primaryKey(),
|
|
648
|
+
featureId: text("feature_id").notNull(),
|
|
649
|
+
lap: integer("lap").notNull(),
|
|
650
|
+
text: text("text").notNull(),
|
|
651
|
+
status: text("status").notNull().$type(),
|
|
652
|
+
ticketId: text("ticket_id"),
|
|
653
|
+
createdAt: integer("created_at").notNull(),
|
|
654
|
+
updatedAt: integer("updated_at").notNull()
|
|
655
|
+
});
|
|
635
656
|
waypoints = sqliteTable("waypoints", {
|
|
636
657
|
id: text("id").primaryKey(),
|
|
637
658
|
featureId: text("feature_id").notNull(),
|
|
@@ -694,6 +715,7 @@ var init_schema = __esm(() => {
|
|
|
694
715
|
features,
|
|
695
716
|
sessions,
|
|
696
717
|
tickets,
|
|
718
|
+
testNotes,
|
|
697
719
|
waypoints,
|
|
698
720
|
runs,
|
|
699
721
|
events,
|
|
@@ -1774,6 +1796,7 @@ var init_waypoints = __esm(() => {
|
|
|
1774
1796
|
});
|
|
1775
1797
|
|
|
1776
1798
|
// src/pty/dev-pane.ts
|
|
1799
|
+
import { execFileSync } from "child_process";
|
|
1777
1800
|
function drivePaneId(ownerId) {
|
|
1778
1801
|
return `${DRIVE_PREFIX}${ownerId}`;
|
|
1779
1802
|
}
|
|
@@ -1833,14 +1856,20 @@ function devPaneLive(paneId) {
|
|
|
1833
1856
|
const entry = ptyRegistry().get(paneId);
|
|
1834
1857
|
return !!entry && !entry.exited;
|
|
1835
1858
|
}
|
|
1859
|
+
function killProcessTree(pid) {
|
|
1860
|
+
try {
|
|
1861
|
+
if (process.platform === "win32") {
|
|
1862
|
+
execFileSync("taskkill", ["/pid", String(pid), "/T", "/F"], { stdio: "ignore" });
|
|
1863
|
+
} else {
|
|
1864
|
+
process.kill(-pid, "SIGTERM");
|
|
1865
|
+
}
|
|
1866
|
+
} catch {}
|
|
1867
|
+
}
|
|
1836
1868
|
function stopDevPane(paneId) {
|
|
1837
1869
|
const reg = ptyRegistry();
|
|
1838
1870
|
const entry = reg.get(paneId);
|
|
1839
|
-
if (entry && !entry.exited
|
|
1840
|
-
|
|
1841
|
-
process.kill(-entry.pty.pid, "SIGTERM");
|
|
1842
|
-
} catch {}
|
|
1843
|
-
}
|
|
1871
|
+
if (entry && !entry.exited)
|
|
1872
|
+
killProcessTree(entry.pty.pid);
|
|
1844
1873
|
reg.kill(paneId);
|
|
1845
1874
|
reg.remove(paneId);
|
|
1846
1875
|
}
|
|
@@ -9346,8 +9375,188 @@ var init_system = __esm(() => {
|
|
|
9346
9375
|
});
|
|
9347
9376
|
});
|
|
9348
9377
|
|
|
9349
|
-
// src/
|
|
9378
|
+
// src/services/test-notes.ts
|
|
9379
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
9380
|
+
import { dirname as dirname10 } from "path";
|
|
9381
|
+
import { asc as asc4, eq as eq14 } from "drizzle-orm";
|
|
9382
|
+
function rowToNote(row) {
|
|
9383
|
+
return {
|
|
9384
|
+
id: row.id,
|
|
9385
|
+
featureId: row.featureId,
|
|
9386
|
+
lap: row.lap,
|
|
9387
|
+
text: row.text,
|
|
9388
|
+
status: row.status,
|
|
9389
|
+
ticketId: row.ticketId ?? undefined,
|
|
9390
|
+
createdAt: row.createdAt,
|
|
9391
|
+
updatedAt: row.updatedAt
|
|
9392
|
+
};
|
|
9393
|
+
}
|
|
9394
|
+
function getNote(ctx, id) {
|
|
9395
|
+
const row = ctx.db.select().from(testNotes).where(eq14(testNotes.id, id)).get();
|
|
9396
|
+
if (!row)
|
|
9397
|
+
throw new NotFoundError(`test note ${id} not found`);
|
|
9398
|
+
return rowToNote(row);
|
|
9399
|
+
}
|
|
9400
|
+
function cleanText(text2) {
|
|
9401
|
+
const trimmed = text2.trim();
|
|
9402
|
+
if (!trimmed)
|
|
9403
|
+
throw new InvalidInputError("note text cannot be empty");
|
|
9404
|
+
return trimmed;
|
|
9405
|
+
}
|
|
9406
|
+
function assertOpen(note, action) {
|
|
9407
|
+
if (note.status !== "open") {
|
|
9408
|
+
throw new InvalidInputError(`cannot ${action} note ${note.id} \u2014 it is ${note.status}; only open notes can be changed`);
|
|
9409
|
+
}
|
|
9410
|
+
}
|
|
9411
|
+
function listByFeature3(ctx, featureId) {
|
|
9412
|
+
return ctx.db.select().from(testNotes).where(eq14(testNotes.featureId, featureId)).orderBy(asc4(testNotes.createdAt), asc4(testNotes.id)).all().map(rowToNote);
|
|
9413
|
+
}
|
|
9414
|
+
function addNote(ctx, featureId, text2) {
|
|
9415
|
+
const body = cleanText(text2);
|
|
9416
|
+
const feature = getFeatureRow(ctx, featureId);
|
|
9417
|
+
const now = Date.now();
|
|
9418
|
+
const row = ctx.db.insert(testNotes).values({
|
|
9419
|
+
id: newId("note"),
|
|
9420
|
+
featureId,
|
|
9421
|
+
lap: feature.lap,
|
|
9422
|
+
text: body,
|
|
9423
|
+
status: "open",
|
|
9424
|
+
ticketId: null,
|
|
9425
|
+
createdAt: now,
|
|
9426
|
+
updatedAt: now
|
|
9427
|
+
}).returning().get();
|
|
9428
|
+
const note = rowToNote(row);
|
|
9429
|
+
emit(ctx, featureId, {
|
|
9430
|
+
type: "note.added",
|
|
9431
|
+
message: `note captured on lap ${note.lap}`,
|
|
9432
|
+
data: { noteId: note.id, lap: note.lap }
|
|
9433
|
+
});
|
|
9434
|
+
renderTestNotes(ctx, feature);
|
|
9435
|
+
return note;
|
|
9436
|
+
}
|
|
9437
|
+
function editNote(ctx, noteId, text2) {
|
|
9438
|
+
const current2 = getNote(ctx, noteId);
|
|
9439
|
+
assertOpen(current2, "edit");
|
|
9440
|
+
const body = cleanText(text2);
|
|
9441
|
+
ctx.db.update(testNotes).set({ text: body, updatedAt: Date.now() }).where(eq14(testNotes.id, noteId)).run();
|
|
9442
|
+
emit(ctx, current2.featureId, {
|
|
9443
|
+
type: "note.edited",
|
|
9444
|
+
message: "note edited",
|
|
9445
|
+
data: { noteId }
|
|
9446
|
+
});
|
|
9447
|
+
renderTestNotes(ctx, getFeatureRow(ctx, current2.featureId));
|
|
9448
|
+
return getNote(ctx, noteId);
|
|
9449
|
+
}
|
|
9450
|
+
function deleteNote(ctx, noteId) {
|
|
9451
|
+
const current2 = getNote(ctx, noteId);
|
|
9452
|
+
assertOpen(current2, "delete");
|
|
9453
|
+
ctx.db.delete(testNotes).where(eq14(testNotes.id, noteId)).run();
|
|
9454
|
+
emit(ctx, current2.featureId, {
|
|
9455
|
+
type: "note.deleted",
|
|
9456
|
+
message: "note deleted",
|
|
9457
|
+
data: { noteId }
|
|
9458
|
+
});
|
|
9459
|
+
renderTestNotes(ctx, getFeatureRow(ctx, current2.featureId));
|
|
9460
|
+
}
|
|
9461
|
+
function toggleNote(ctx, noteId) {
|
|
9462
|
+
const current2 = getNote(ctx, noteId);
|
|
9463
|
+
if (current2.status === "promoted") {
|
|
9464
|
+
throw new InvalidInputError(`cannot toggle note ${noteId} \u2014 it is promoted, and promoted notes are frozen`);
|
|
9465
|
+
}
|
|
9466
|
+
const status = current2.status === "open" ? "done" : "open";
|
|
9467
|
+
ctx.db.update(testNotes).set({ status, updatedAt: Date.now() }).where(eq14(testNotes.id, noteId)).run();
|
|
9468
|
+
emit(ctx, current2.featureId, {
|
|
9469
|
+
type: "note.toggled",
|
|
9470
|
+
message: `note ${current2.status} \u2192 ${status}`,
|
|
9471
|
+
data: { noteId, from: current2.status, to: status }
|
|
9472
|
+
});
|
|
9473
|
+
renderTestNotes(ctx, getFeatureRow(ctx, current2.featureId));
|
|
9474
|
+
return getNote(ctx, noteId);
|
|
9475
|
+
}
|
|
9476
|
+
function promotionTicket(feature, note) {
|
|
9477
|
+
const firstLine = note.text.split(`
|
|
9478
|
+
`)[0].trim();
|
|
9479
|
+
const docs = featureDocsRel(feature.slug);
|
|
9480
|
+
return {
|
|
9481
|
+
title: firstLine.length <= TITLE_MAX ? firstLine : `${firstLine.slice(0, TITLE_MAX - 1).trimEnd()}\u2026`,
|
|
9482
|
+
goal: note.text,
|
|
9483
|
+
context: [
|
|
9484
|
+
`Found during lap ${note.lap} test drive of ${feature.slug}.`,
|
|
9485
|
+
`Read ${docs}/spec.md and ${docs}/decisions.md for what this feature is meant to do.`
|
|
9486
|
+
].join(`
|
|
9487
|
+
|
|
9488
|
+
`),
|
|
9489
|
+
acceptanceCriteria: [`The noted behavior no longer reproduces: ${note.text}`],
|
|
9490
|
+
seams: [],
|
|
9491
|
+
blockedBy: []
|
|
9492
|
+
};
|
|
9493
|
+
}
|
|
9494
|
+
function promoteNote(ctx, noteId) {
|
|
9495
|
+
const current2 = getNote(ctx, noteId);
|
|
9496
|
+
assertOpen(current2, "promote");
|
|
9497
|
+
const feature = getFeatureRow(ctx, current2.featureId);
|
|
9498
|
+
const [ticket] = storeTickets(ctx, current2.featureId, [promotionTicket(feature, current2)]);
|
|
9499
|
+
ctx.db.update(testNotes).set({ status: "promoted", ticketId: ticket.id, updatedAt: Date.now() }).where(eq14(testNotes.id, noteId)).run();
|
|
9500
|
+
emit(ctx, current2.featureId, {
|
|
9501
|
+
type: "note.promoted",
|
|
9502
|
+
message: `note promoted to ticket ${ticket.seq}`,
|
|
9503
|
+
ticketId: ticket.id,
|
|
9504
|
+
data: { noteId, seq: ticket.seq }
|
|
9505
|
+
});
|
|
9506
|
+
renderTestNotes(ctx, feature);
|
|
9507
|
+
return { note: getNote(ctx, noteId), ticket };
|
|
9508
|
+
}
|
|
9509
|
+
function noteLine(ctx, note) {
|
|
9510
|
+
if (note.status === "open")
|
|
9511
|
+
return `- [ ] ${note.text}`;
|
|
9512
|
+
const ticket = note.ticketId ? ` (\u2192 ticket ${getTicket(ctx, note.ticketId).seq})` : "";
|
|
9513
|
+
return `- [x] ${note.text}${ticket}`;
|
|
9514
|
+
}
|
|
9515
|
+
function renderTestNotes(ctx, feature) {
|
|
9516
|
+
const notes = listByFeature3(ctx, feature.id);
|
|
9517
|
+
const laps = [...new Set(notes.map((n) => n.lap))].sort((a, b) => a - b);
|
|
9518
|
+
const lines = ["# Test notes"];
|
|
9519
|
+
for (const lap of laps) {
|
|
9520
|
+
lines.push("", `## Lap ${lap}`, "");
|
|
9521
|
+
for (const note of notes.filter((n) => n.lap === lap))
|
|
9522
|
+
lines.push(noteLine(ctx, note));
|
|
9523
|
+
}
|
|
9524
|
+
const path = featureDocPath(projectForFeature(ctx, feature), feature, "test-notes.md");
|
|
9525
|
+
mkdirSync9(dirname10(path), { recursive: true });
|
|
9526
|
+
writeFileSync5(path, `${lines.join(`
|
|
9527
|
+
`)}
|
|
9528
|
+
`, "utf8");
|
|
9529
|
+
}
|
|
9530
|
+
var TITLE_MAX = 60;
|
|
9531
|
+
var init_test_notes = __esm(() => {
|
|
9532
|
+
init_src();
|
|
9533
|
+
init_paths();
|
|
9534
|
+
init_schema();
|
|
9535
|
+
init_errors();
|
|
9536
|
+
init_events();
|
|
9537
|
+
init_feature_docs();
|
|
9538
|
+
init_repo();
|
|
9539
|
+
init_tickets();
|
|
9540
|
+
});
|
|
9541
|
+
|
|
9542
|
+
// src/trpc/routers/test-notes.ts
|
|
9350
9543
|
import * as z12 from "zod";
|
|
9544
|
+
var testNotesRouter;
|
|
9545
|
+
var init_test_notes2 = __esm(() => {
|
|
9546
|
+
init_test_notes();
|
|
9547
|
+
init_context();
|
|
9548
|
+
testNotesRouter = router({
|
|
9549
|
+
list: publicProcedure.input(z12.object({ featureId: z12.string() })).query(({ ctx, input }) => listByFeature3(ctx, input.featureId)),
|
|
9550
|
+
add: publicProcedure.input(z12.object({ featureId: z12.string(), text: z12.string().min(1) })).mutation(({ ctx, input }) => addNote(ctx, input.featureId, input.text)),
|
|
9551
|
+
edit: publicProcedure.input(z12.object({ noteId: z12.string(), text: z12.string().min(1) })).mutation(({ ctx, input }) => editNote(ctx, input.noteId, input.text)),
|
|
9552
|
+
remove: publicProcedure.input(z12.object({ noteId: z12.string() })).mutation(({ ctx, input }) => deleteNote(ctx, input.noteId)),
|
|
9553
|
+
toggle: publicProcedure.input(z12.object({ noteId: z12.string() })).mutation(({ ctx, input }) => toggleNote(ctx, input.noteId)),
|
|
9554
|
+
promote: publicProcedure.input(z12.object({ noteId: z12.string() })).mutation(({ ctx, input }) => promoteNote(ctx, input.noteId))
|
|
9555
|
+
});
|
|
9556
|
+
});
|
|
9557
|
+
|
|
9558
|
+
// src/trpc/routers/ticket.ts
|
|
9559
|
+
import * as z13 from "zod";
|
|
9351
9560
|
var ticketRouter;
|
|
9352
9561
|
var init_ticket = __esm(() => {
|
|
9353
9562
|
init_features();
|
|
@@ -9356,8 +9565,8 @@ var init_ticket = __esm(() => {
|
|
|
9356
9565
|
init_ticket_burner();
|
|
9357
9566
|
init_context();
|
|
9358
9567
|
ticketRouter = router({
|
|
9359
|
-
retry: publicProcedure.input(
|
|
9360
|
-
stop: publicProcedure.input(
|
|
9568
|
+
retry: publicProcedure.input(z13.object({ ticketId: z13.string(), fresh: z13.boolean().optional() })).mutation(({ ctx, input }) => retryTicket(ctx, input.ticketId, { fresh: input.fresh })),
|
|
9569
|
+
stop: publicProcedure.input(z13.object({ ticketId: z13.string() })).mutation(({ ctx, input }) => {
|
|
9361
9570
|
if (stopTicketRun(input.ticketId))
|
|
9362
9571
|
return { stopped: true, swept: false };
|
|
9363
9572
|
const ticket = getTicket(ctx, input.ticketId);
|
|
@@ -9367,13 +9576,13 @@ var init_ticket = __esm(() => {
|
|
|
9367
9576
|
}
|
|
9368
9577
|
return { stopped: false, swept: false };
|
|
9369
9578
|
}),
|
|
9370
|
-
cancel: publicProcedure.input(
|
|
9371
|
-
edit: publicProcedure.input(
|
|
9372
|
-
ticketId:
|
|
9373
|
-
title:
|
|
9374
|
-
goal:
|
|
9375
|
-
context:
|
|
9376
|
-
acceptanceCriteria:
|
|
9579
|
+
cancel: publicProcedure.input(z13.object({ ticketId: z13.string(), reason: z13.string().optional() })).mutation(({ ctx, input }) => cancelTicket(ctx, input.ticketId, input.reason)),
|
|
9580
|
+
edit: publicProcedure.input(z13.object({
|
|
9581
|
+
ticketId: z13.string(),
|
|
9582
|
+
title: z13.string().min(1).optional(),
|
|
9583
|
+
goal: z13.string().min(1).optional(),
|
|
9584
|
+
context: z13.string().optional(),
|
|
9585
|
+
acceptanceCriteria: z13.array(z13.string().min(1)).optional()
|
|
9377
9586
|
})).mutation(({ ctx, input }) => {
|
|
9378
9587
|
const { ticketId, ...patch } = input;
|
|
9379
9588
|
return editTicket(ctx, ticketId, patch);
|
|
@@ -9393,12 +9602,14 @@ var init_router = __esm(() => {
|
|
|
9393
9602
|
init_settings2();
|
|
9394
9603
|
init_setup2();
|
|
9395
9604
|
init_system();
|
|
9605
|
+
init_test_notes2();
|
|
9396
9606
|
init_ticket();
|
|
9397
9607
|
appRouter = router({
|
|
9398
9608
|
project: projectRouter,
|
|
9399
9609
|
feature: featureRouter,
|
|
9400
9610
|
run: runRouter,
|
|
9401
9611
|
ticket: ticketRouter,
|
|
9612
|
+
notes: testNotesRouter,
|
|
9402
9613
|
events: eventsRouter,
|
|
9403
9614
|
docs: docsRouter,
|
|
9404
9615
|
settings: settingsRouter,
|
|
@@ -9408,14 +9619,14 @@ var init_router = __esm(() => {
|
|
|
9408
9619
|
});
|
|
9409
9620
|
|
|
9410
9621
|
// src/workflows/reconcile-runs.ts
|
|
9411
|
-
import { eq as
|
|
9622
|
+
import { eq as eq15 } from "drizzle-orm";
|
|
9412
9623
|
async function reconcileStaleRuns(ctx) {
|
|
9413
|
-
const stale = ctx.db.select().from(runs).where(
|
|
9624
|
+
const stale = ctx.db.select().from(runs).where(eq15(runs.status, "running")).all().map(rowToRun);
|
|
9414
9625
|
const reconciled = [];
|
|
9415
9626
|
for (const run3 of stale) {
|
|
9416
9627
|
if (isRunActive(run3.id))
|
|
9417
9628
|
continue;
|
|
9418
|
-
ctx.db.update(runs).set({ status: "failed", endedAt: Date.now(), summary: "orphaned by server restart" }).where(
|
|
9629
|
+
ctx.db.update(runs).set({ status: "failed", endedAt: Date.now(), summary: "orphaned by server restart" }).where(eq15(runs.id, run3.id)).run();
|
|
9419
9630
|
const released = releaseForSession(ctx, run3.id);
|
|
9420
9631
|
const swept = workflowClaimsFeatureBranch(run3.workflow) ? sweepOrphanedBurning(ctx, run3.featureId, "orphaned by server restart \u2014 retry to resume its commits") : [];
|
|
9421
9632
|
if (workflowClaimsFeatureBranch(run3.workflow)) {
|
|
@@ -9645,7 +9856,7 @@ var init_cli = __esm(() => {
|
|
|
9645
9856
|
// src/bin/runcastle.ts
|
|
9646
9857
|
init_asset_paths();
|
|
9647
9858
|
init_version();
|
|
9648
|
-
import { dirname as
|
|
9859
|
+
import { dirname as dirname11, resolve as resolve11 } from "path";
|
|
9649
9860
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
9650
9861
|
function parseCommand(argv) {
|
|
9651
9862
|
const [first, ...rest] = argv;
|
|
@@ -9670,7 +9881,7 @@ Usage:
|
|
|
9670
9881
|
runcastle --help Show this help
|
|
9671
9882
|
`;
|
|
9672
9883
|
async function main(argv) {
|
|
9673
|
-
applyInstalledAssetEnv(resolve11(
|
|
9884
|
+
applyInstalledAssetEnv(resolve11(dirname11(fileURLToPath8(import.meta.url)), ".."));
|
|
9674
9885
|
const { command, args } = parseCommand(argv);
|
|
9675
9886
|
switch (command) {
|
|
9676
9887
|
case "version":
|