@staff0rd/assist 0.172.3 → 0.173.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/README.md +2 -1
- package/allowed.cli-writes +1 -0
- package/claude/commands/bug.md +2 -13
- package/claude/commands/draft.md +8 -21
- package/dist/allowed.cli-writes +1 -0
- package/dist/commands/backlog/web/bundle.js +75 -60
- package/dist/index.js +207 -207
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.173.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -76,6 +76,7 @@ var package_default = {
|
|
|
76
76
|
marked: "^15.0.12",
|
|
77
77
|
react: "^19.2.4",
|
|
78
78
|
"react-dom": "^19.2.4",
|
|
79
|
+
"react-router": "^7.14.0",
|
|
79
80
|
"semantic-release": "^25.0.2",
|
|
80
81
|
tsup: "^8.5.1",
|
|
81
82
|
vitest: "^4.0.18"
|
|
@@ -148,14 +149,11 @@ function loadComments(db, itemId) {
|
|
|
148
149
|
// src/commands/backlog/loadPlan.ts
|
|
149
150
|
function toPhase(db, itemId, p) {
|
|
150
151
|
const tasks = db.prepare(
|
|
151
|
-
"SELECT task
|
|
152
|
+
"SELECT task FROM plan_tasks WHERE item_id = ? AND phase_idx = ? ORDER BY idx"
|
|
152
153
|
).all(itemId, p.idx);
|
|
153
154
|
const phase = {
|
|
154
155
|
name: p.name,
|
|
155
|
-
tasks: tasks.map((t) => ({
|
|
156
|
-
task: t.task,
|
|
157
|
-
...t.verify != null ? { verify: t.verify } : {}
|
|
158
|
-
}))
|
|
156
|
+
tasks: tasks.map((t) => ({ task: t.task }))
|
|
159
157
|
};
|
|
160
158
|
if (p.manual_checks) {
|
|
161
159
|
phase.manualChecks = JSON.parse(p.manual_checks);
|
|
@@ -242,7 +240,7 @@ function insertPlan(db, item) {
|
|
|
242
240
|
"INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
|
|
243
241
|
);
|
|
244
242
|
const taskStmt = db.prepare(
|
|
245
|
-
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task
|
|
243
|
+
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task) VALUES (?, ?, ?, ?)"
|
|
246
244
|
);
|
|
247
245
|
for (let pi = 0; pi < item.plan.length; pi++) {
|
|
248
246
|
const phase = item.plan[pi];
|
|
@@ -254,7 +252,7 @@ function insertPlan(db, item) {
|
|
|
254
252
|
);
|
|
255
253
|
for (let ti = 0; ti < phase.tasks.length; ti++) {
|
|
256
254
|
const task = phase.tasks[ti];
|
|
257
|
-
taskStmt.run(item.id, pi, ti, task.task
|
|
255
|
+
taskStmt.run(item.id, pi, ti, task.task);
|
|
258
256
|
}
|
|
259
257
|
}
|
|
260
258
|
}
|
|
@@ -310,8 +308,7 @@ import { z } from "zod";
|
|
|
310
308
|
var backlogStatusSchema = z.enum(["todo", "in-progress", "done", "wontdo"]);
|
|
311
309
|
var backlogTypeSchema = z.enum(["story", "bug"]);
|
|
312
310
|
var planTaskSchema = z.strictObject({
|
|
313
|
-
task: z.string()
|
|
314
|
-
verify: z.string().optional()
|
|
311
|
+
task: z.string()
|
|
315
312
|
});
|
|
316
313
|
var planPhaseSchema = z.strictObject({
|
|
317
314
|
name: z.string(),
|
|
@@ -446,7 +443,6 @@ function initSchema(db) {
|
|
|
446
443
|
phase_idx INTEGER NOT NULL,
|
|
447
444
|
idx INTEGER NOT NULL,
|
|
448
445
|
task TEXT NOT NULL,
|
|
449
|
-
verify TEXT,
|
|
450
446
|
PRIMARY KEY (item_id, phase_idx, idx),
|
|
451
447
|
FOREIGN KEY (item_id, phase_idx) REFERENCES plan_phases(item_id, idx) ON DELETE CASCADE
|
|
452
448
|
);
|
|
@@ -618,9 +614,17 @@ function phaseLabel(item) {
|
|
|
618
614
|
` (phase ${(item.currentPhase ?? 0) + 1}/${item.plan.length})`
|
|
619
615
|
);
|
|
620
616
|
}
|
|
621
|
-
function
|
|
617
|
+
function isBlocked(item, items) {
|
|
618
|
+
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
619
|
+
return deps2.some((dep) => {
|
|
620
|
+
const target = items.find((i) => i.id === dep.targetId);
|
|
621
|
+
return target !== void 0 && target.status !== "done";
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
function dependencyLabel(item, items) {
|
|
622
625
|
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
623
626
|
if (deps2.length === 0) return "";
|
|
627
|
+
if (isBlocked(item, items)) return chalk2.red(" [blocked]");
|
|
624
628
|
return chalk2.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
|
|
625
629
|
}
|
|
626
630
|
function printVerboseDetails(item) {
|
|
@@ -698,11 +702,7 @@ function buildManualCheckLines(manualChecks) {
|
|
|
698
702
|
return [];
|
|
699
703
|
}
|
|
700
704
|
function formatTasks(phase) {
|
|
701
|
-
return phase.tasks.map((t) => {
|
|
702
|
-
let line = `- ${t.task}`;
|
|
703
|
-
if (t.verify) line += ` (verify: ${t.verify})`;
|
|
704
|
-
return line;
|
|
705
|
-
}).join("\n");
|
|
705
|
+
return phase.tasks.map((t) => `- ${t.task}`).join("\n");
|
|
706
706
|
}
|
|
707
707
|
|
|
708
708
|
// src/commands/backlog/buildReviewPrompt.ts
|
|
@@ -980,41 +980,51 @@ async function runReview(item, plan2, spawnOptions) {
|
|
|
980
980
|
// src/commands/backlog/next.ts
|
|
981
981
|
function findResumable(items) {
|
|
982
982
|
return items.find(
|
|
983
|
-
(i) => i.status === "in-progress" && i.plan && !isLockedByOther(i.id)
|
|
983
|
+
(i) => i.status === "in-progress" && i.plan && !isLockedByOther(i.id) && !isBlocked(i, items)
|
|
984
984
|
);
|
|
985
985
|
}
|
|
986
|
-
|
|
987
|
-
const
|
|
986
|
+
function toChoice(item, items) {
|
|
987
|
+
const name = `${typeLabel(item.type)} #${item.id}: ${item.name}`;
|
|
988
|
+
return isBlocked(item, items) ? { name, disabled: chalk7.red("[blocked]") } : { name };
|
|
989
|
+
}
|
|
990
|
+
async function selectItem(todo, items) {
|
|
988
991
|
const { selected } = await exitOnCancel(
|
|
989
992
|
enquirer2.prompt({
|
|
990
993
|
type: "select",
|
|
991
994
|
name: "selected",
|
|
992
995
|
message: "Choose a backlog item to start:",
|
|
993
|
-
choices
|
|
996
|
+
choices: todo.map((i) => toChoice(i, items))
|
|
994
997
|
})
|
|
995
998
|
);
|
|
996
999
|
return selected.match(/#(\d+)/)?.[1] ?? "";
|
|
997
1000
|
}
|
|
1001
|
+
async function pickItem(items) {
|
|
1002
|
+
const resumable = findResumable(items);
|
|
1003
|
+
if (resumable) {
|
|
1004
|
+
console.log(
|
|
1005
|
+
chalk7.bold(
|
|
1006
|
+
`Resuming in-progress item #${resumable.id}: ${resumable.name}`
|
|
1007
|
+
)
|
|
1008
|
+
);
|
|
1009
|
+
return String(resumable.id);
|
|
1010
|
+
}
|
|
1011
|
+
const todo = items.filter((i) => i.status === "todo");
|
|
1012
|
+
if (todo.length === 0) {
|
|
1013
|
+
console.log(chalk7.green("All backlog items complete."));
|
|
1014
|
+
return void 0;
|
|
1015
|
+
}
|
|
1016
|
+
if (todo.every((i) => isBlocked(i, items))) {
|
|
1017
|
+
console.log(
|
|
1018
|
+
chalk7.yellow("All remaining todo items are blocked by dependencies.")
|
|
1019
|
+
);
|
|
1020
|
+
return void 0;
|
|
1021
|
+
}
|
|
1022
|
+
return selectItem(todo, items);
|
|
1023
|
+
}
|
|
998
1024
|
async function next(options2) {
|
|
999
1025
|
while (true) {
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1002
|
-
if (inProgress) {
|
|
1003
|
-
console.log(
|
|
1004
|
-
chalk7.bold(
|
|
1005
|
-
`Resuming in-progress item #${inProgress.id}: ${inProgress.name}`
|
|
1006
|
-
)
|
|
1007
|
-
);
|
|
1008
|
-
const completed2 = await run(String(inProgress.id), options2);
|
|
1009
|
-
if (!completed2) return;
|
|
1010
|
-
continue;
|
|
1011
|
-
}
|
|
1012
|
-
const todo = items.filter((i) => i.status === "todo");
|
|
1013
|
-
if (todo.length === 0) {
|
|
1014
|
-
console.log(chalk7.green("All backlog items complete."));
|
|
1015
|
-
return;
|
|
1016
|
-
}
|
|
1017
|
-
const id = await selectItem(todo);
|
|
1026
|
+
const id = await pickItem(loadBacklog());
|
|
1027
|
+
if (id === void 0) return;
|
|
1018
1028
|
const completed = await run(id, options2);
|
|
1019
1029
|
if (!completed) return;
|
|
1020
1030
|
}
|
|
@@ -1082,9 +1092,6 @@ function plan(id) {
|
|
|
1082
1092
|
console.log(`${chalk9.bold(`Phase ${i + 1}:`)} ${phase.name}`);
|
|
1083
1093
|
for (const task of phase.tasks) {
|
|
1084
1094
|
console.log(` - ${task.task}`);
|
|
1085
|
-
if (task.verify) {
|
|
1086
|
-
console.log(` ${chalk9.dim(`verify: ${task.verify}`)}`);
|
|
1087
|
-
}
|
|
1088
1095
|
}
|
|
1089
1096
|
console.log();
|
|
1090
1097
|
}
|
|
@@ -1130,9 +1137,6 @@ import chalk12 from "chalk";
|
|
|
1130
1137
|
function printPhaseTasks(phase) {
|
|
1131
1138
|
for (const task of phase.tasks) {
|
|
1132
1139
|
console.log(` - ${task.task}`);
|
|
1133
|
-
if (task.verify) {
|
|
1134
|
-
console.log(` ${chalk12.dim(`verify: ${task.verify}`)}`);
|
|
1135
|
-
}
|
|
1136
1140
|
}
|
|
1137
1141
|
if (phase.manualChecks && phase.manualChecks.length > 0) {
|
|
1138
1142
|
console.log(` ${chalk12.dim("Manual checks:")}`);
|
|
@@ -1376,18 +1380,28 @@ var itemRoutes = {
|
|
|
1376
1380
|
PATCH: (req, res, id) => patchItemStatus(req, res, id),
|
|
1377
1381
|
DELETE: (_req, res, id) => deleteItem2(res, id)
|
|
1378
1382
|
};
|
|
1383
|
+
var serveHtml = createHtmlHandler(getHtml);
|
|
1379
1384
|
var baseHandler = createRouteHandler(routes);
|
|
1385
|
+
async function handleItemRoute(req, res, pathname) {
|
|
1386
|
+
const match = pathname.match(/^\/api\/items\/(\d+)$/);
|
|
1387
|
+
if (!match) return false;
|
|
1388
|
+
const handler = itemRoutes[req.method ?? "GET"];
|
|
1389
|
+
if (!handler) return false;
|
|
1390
|
+
await handler(req, res, Number.parseInt(match[1], 10));
|
|
1391
|
+
return true;
|
|
1392
|
+
}
|
|
1380
1393
|
async function handleRequest(req, res, port) {
|
|
1381
1394
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
1382
1395
|
const method = req.method ?? "GET";
|
|
1383
1396
|
const pathname = url.pathname;
|
|
1384
|
-
|
|
1385
|
-
if (
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1397
|
+
if (await handleItemRoute(req, res, pathname)) return;
|
|
1398
|
+
if (routes[`${method} ${pathname}`]) {
|
|
1399
|
+
await baseHandler(req, res, port);
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (method === "GET" && !pathname.startsWith("/api/")) {
|
|
1403
|
+
await serveHtml(req, res);
|
|
1404
|
+
return;
|
|
1391
1405
|
}
|
|
1392
1406
|
await baseHandler(req, res, port);
|
|
1393
1407
|
}
|
|
@@ -3701,7 +3715,7 @@ function registerCommentCommands(cmd) {
|
|
|
3701
3715
|
}
|
|
3702
3716
|
|
|
3703
3717
|
// src/commands/backlog/add/index.ts
|
|
3704
|
-
import
|
|
3718
|
+
import chalk44 from "chalk";
|
|
3705
3719
|
|
|
3706
3720
|
// src/commands/backlog/commitBacklog.ts
|
|
3707
3721
|
import { execSync as execSync14 } from "child_process";
|
|
@@ -3718,58 +3732,9 @@ function commitBacklog(id, name) {
|
|
|
3718
3732
|
}
|
|
3719
3733
|
}
|
|
3720
3734
|
|
|
3721
|
-
// src/commands/backlog/add/parseItemFile.ts
|
|
3722
|
-
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
|
|
3723
|
-
import chalk44 from "chalk";
|
|
3724
|
-
import { ZodError } from "zod";
|
|
3725
|
-
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
3726
|
-
function readJsonFile(filePath) {
|
|
3727
|
-
if (!existsSync18(filePath)) {
|
|
3728
|
-
console.log(chalk44.red(`File not found: ${filePath}`));
|
|
3729
|
-
process.exitCode = 1;
|
|
3730
|
-
return void 0;
|
|
3731
|
-
}
|
|
3732
|
-
let raw;
|
|
3733
|
-
try {
|
|
3734
|
-
raw = readFileSync15(filePath, "utf-8");
|
|
3735
|
-
} catch {
|
|
3736
|
-
console.log(chalk44.red(`Failed to read file: ${filePath}`));
|
|
3737
|
-
process.exitCode = 1;
|
|
3738
|
-
return void 0;
|
|
3739
|
-
}
|
|
3740
|
-
try {
|
|
3741
|
-
return JSON.parse(raw);
|
|
3742
|
-
} catch {
|
|
3743
|
-
console.log(chalk44.red(`Invalid JSON in file: ${filePath}`));
|
|
3744
|
-
process.exitCode = 1;
|
|
3745
|
-
return void 0;
|
|
3746
|
-
}
|
|
3747
|
-
}
|
|
3748
|
-
function formatZodError(err) {
|
|
3749
|
-
if (err instanceof ZodError) {
|
|
3750
|
-
console.log(chalk44.red("Invalid backlog item schema:"));
|
|
3751
|
-
for (const issue of err.issues) {
|
|
3752
|
-
console.log(chalk44.red(` - ${issue.path.join(".")}: ${issue.message}`));
|
|
3753
|
-
}
|
|
3754
|
-
} else {
|
|
3755
|
-
console.log(chalk44.red("Invalid backlog item schema."));
|
|
3756
|
-
}
|
|
3757
|
-
}
|
|
3758
|
-
function parseItemFile(filePath) {
|
|
3759
|
-
const parsed = readJsonFile(filePath);
|
|
3760
|
-
if (parsed === void 0) return void 0;
|
|
3761
|
-
try {
|
|
3762
|
-
return addItemSchema.parse(parsed);
|
|
3763
|
-
} catch (err) {
|
|
3764
|
-
formatZodError(err);
|
|
3765
|
-
process.exitCode = 1;
|
|
3766
|
-
return void 0;
|
|
3767
|
-
}
|
|
3768
|
-
}
|
|
3769
|
-
|
|
3770
3735
|
// src/commands/backlog/add/shared.ts
|
|
3771
3736
|
import { spawnSync } from "child_process";
|
|
3772
|
-
import { mkdtempSync, readFileSync as
|
|
3737
|
+
import { mkdtempSync, readFileSync as readFileSync15, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
|
|
3773
3738
|
import { tmpdir } from "os";
|
|
3774
3739
|
import { join as join15 } from "path";
|
|
3775
3740
|
import enquirer6 from "enquirer";
|
|
@@ -3819,7 +3784,7 @@ function openEditor() {
|
|
|
3819
3784
|
unlinkSync4(filePath);
|
|
3820
3785
|
return void 0;
|
|
3821
3786
|
}
|
|
3822
|
-
const content =
|
|
3787
|
+
const content = readFileSync15(filePath, "utf-8").trim();
|
|
3823
3788
|
unlinkSync4(filePath);
|
|
3824
3789
|
return content || void 0;
|
|
3825
3790
|
}
|
|
@@ -3838,49 +3803,70 @@ async function promptAcceptanceCriteria() {
|
|
|
3838
3803
|
}
|
|
3839
3804
|
|
|
3840
3805
|
// src/commands/backlog/add/index.ts
|
|
3841
|
-
function
|
|
3842
|
-
const
|
|
3843
|
-
|
|
3844
|
-
const
|
|
3845
|
-
const
|
|
3846
|
-
items.push({ ...data, id, status: "todo" });
|
|
3847
|
-
saveBacklog(items);
|
|
3848
|
-
commitBacklog(id, data.name);
|
|
3849
|
-
console.log(chalk45.green(`Added item #${id}: ${data.name}`));
|
|
3850
|
-
}
|
|
3851
|
-
async function addInteractive() {
|
|
3852
|
-
const type = await promptType();
|
|
3853
|
-
const name = await promptName();
|
|
3854
|
-
const description = await promptDescription();
|
|
3855
|
-
const acceptanceCriteria2 = await promptAcceptanceCriteria();
|
|
3806
|
+
async function addFromOptions(options2) {
|
|
3807
|
+
const type = options2.type ?? await promptType();
|
|
3808
|
+
const name = options2.name ?? await promptName();
|
|
3809
|
+
const description = options2.desc ?? await promptDescription();
|
|
3810
|
+
const acceptanceCriteria2 = options2.ac ?? await promptAcceptanceCriteria();
|
|
3856
3811
|
const items = loadBacklog();
|
|
3857
3812
|
const id = getNextId(items);
|
|
3858
3813
|
items.push({
|
|
3859
3814
|
id,
|
|
3860
3815
|
type,
|
|
3861
3816
|
name,
|
|
3862
|
-
description,
|
|
3817
|
+
description: description || void 0,
|
|
3863
3818
|
acceptanceCriteria: acceptanceCriteria2,
|
|
3864
3819
|
status: "todo"
|
|
3865
3820
|
});
|
|
3866
3821
|
saveBacklog(items);
|
|
3867
3822
|
commitBacklog(id, name);
|
|
3868
|
-
console.log(
|
|
3823
|
+
console.log(chalk44.green(`Added item #${id}: ${name}`));
|
|
3869
3824
|
}
|
|
3870
3825
|
async function add(options2) {
|
|
3871
3826
|
if (!backlogExists()) {
|
|
3872
3827
|
console.log(
|
|
3873
|
-
|
|
3828
|
+
chalk44.yellow(
|
|
3874
3829
|
"No backlog found. Run 'assist backlog init' to create one."
|
|
3875
3830
|
)
|
|
3876
3831
|
);
|
|
3877
3832
|
return;
|
|
3878
3833
|
}
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3834
|
+
await addFromOptions(options2);
|
|
3835
|
+
}
|
|
3836
|
+
|
|
3837
|
+
// src/commands/backlog/addPhase.ts
|
|
3838
|
+
import chalk45 from "chalk";
|
|
3839
|
+
function addPhase(id, name, options2) {
|
|
3840
|
+
const result = loadAndFindItem(id);
|
|
3841
|
+
if (!result) return;
|
|
3842
|
+
const tasks = options2.task ?? [];
|
|
3843
|
+
if (tasks.length === 0) {
|
|
3844
|
+
console.log(chalk45.red("At least one --task is required."));
|
|
3845
|
+
process.exitCode = 1;
|
|
3846
|
+
return;
|
|
3883
3847
|
}
|
|
3848
|
+
const dir = getBacklogDir();
|
|
3849
|
+
const db = openDb(dir);
|
|
3850
|
+
const itemId = result.item.id;
|
|
3851
|
+
const existing = db.prepare("SELECT COUNT(*) as cnt FROM plan_phases WHERE item_id = ?").get(itemId);
|
|
3852
|
+
const phaseIdx = existing.cnt;
|
|
3853
|
+
const manualChecks = options2.manualCheck && options2.manualCheck.length > 0 ? JSON.stringify(options2.manualCheck) : null;
|
|
3854
|
+
db.prepare(
|
|
3855
|
+
"INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
|
|
3856
|
+
).run(itemId, phaseIdx, name, manualChecks);
|
|
3857
|
+
const taskStmt = db.prepare(
|
|
3858
|
+
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task) VALUES (?, ?, ?, ?)"
|
|
3859
|
+
);
|
|
3860
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
3861
|
+
taskStmt.run(itemId, phaseIdx, i, tasks[i]);
|
|
3862
|
+
}
|
|
3863
|
+
exportToJsonl(db, dir);
|
|
3864
|
+
commitBacklog(itemId, result.item.name);
|
|
3865
|
+
console.log(
|
|
3866
|
+
chalk45.green(
|
|
3867
|
+
`Added phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
3868
|
+
)
|
|
3869
|
+
);
|
|
3884
3870
|
}
|
|
3885
3871
|
|
|
3886
3872
|
// src/commands/backlog/init/index.ts
|
|
@@ -3911,14 +3897,15 @@ async function list2(options2) {
|
|
|
3911
3897
|
);
|
|
3912
3898
|
return;
|
|
3913
3899
|
}
|
|
3914
|
-
const
|
|
3900
|
+
const allItems = loadBacklog();
|
|
3901
|
+
const items = filterItems(allItems, options2);
|
|
3915
3902
|
if (items.length === 0) {
|
|
3916
3903
|
console.log(chalk47.dim("Backlog is empty."));
|
|
3917
3904
|
return;
|
|
3918
3905
|
}
|
|
3919
3906
|
for (const item of items) {
|
|
3920
3907
|
console.log(
|
|
3921
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item)}`
|
|
3908
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk47.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
3922
3909
|
);
|
|
3923
3910
|
if (options2.verbose) {
|
|
3924
3911
|
printVerboseDetails(item);
|
|
@@ -3933,7 +3920,11 @@ function registerItemCommands(cmd) {
|
|
|
3933
3920
|
"--status <type>",
|
|
3934
3921
|
"Filter by status (todo, in-progress, done, wontdo)"
|
|
3935
3922
|
).option("-a, --all", "Include done/wontdo items").option("-v, --verbose", "Show all item details").action(list2);
|
|
3936
|
-
cmd.command("add").description("Add a new backlog item").option("--
|
|
3923
|
+
cmd.command("add").description("Add a new backlog item").option("--name <name>", "Item name").option("--type <type>", "Item type (story or bug)").option("--desc <description>", "Item description").option("--ac <criterion...>", "Acceptance criteria (repeatable)").action(add);
|
|
3924
|
+
cmd.command("add-phase <id> <name>").description("Add a phase to an existing backlog item").option("--task <task...>", "Task description (repeatable)").option(
|
|
3925
|
+
"--manual-check <check...>",
|
|
3926
|
+
"Manual check description (repeatable)"
|
|
3927
|
+
).action(addPhase);
|
|
3937
3928
|
}
|
|
3938
3929
|
|
|
3939
3930
|
// src/commands/backlog/link.ts
|
|
@@ -4227,7 +4218,7 @@ function extractGraphqlQuery(args) {
|
|
|
4227
4218
|
}
|
|
4228
4219
|
|
|
4229
4220
|
// src/shared/loadCliReads.ts
|
|
4230
|
-
import { existsSync as
|
|
4221
|
+
import { existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
|
|
4231
4222
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
4232
4223
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
4233
4224
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -4236,8 +4227,8 @@ function packageRoot() {
|
|
|
4236
4227
|
return __dirname4;
|
|
4237
4228
|
}
|
|
4238
4229
|
function readLines(path50) {
|
|
4239
|
-
if (!
|
|
4240
|
-
return
|
|
4230
|
+
if (!existsSync18(path50)) return [];
|
|
4231
|
+
return readFileSync16(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
4241
4232
|
}
|
|
4242
4233
|
var cachedReads;
|
|
4243
4234
|
var cachedWrites;
|
|
@@ -4283,7 +4274,7 @@ function findCliWrite(command) {
|
|
|
4283
4274
|
}
|
|
4284
4275
|
|
|
4285
4276
|
// src/shared/readSettingsPerms.ts
|
|
4286
|
-
import { existsSync as
|
|
4277
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
|
|
4287
4278
|
import { homedir as homedir3 } from "os";
|
|
4288
4279
|
import { join as join16 } from "path";
|
|
4289
4280
|
function readSettingsPerms(key) {
|
|
@@ -4299,9 +4290,9 @@ function readSettingsPerms(key) {
|
|
|
4299
4290
|
return entries;
|
|
4300
4291
|
}
|
|
4301
4292
|
function readPermissionArray(filePath, key) {
|
|
4302
|
-
if (!
|
|
4293
|
+
if (!existsSync19(filePath)) return [];
|
|
4303
4294
|
try {
|
|
4304
|
-
const data = JSON.parse(
|
|
4295
|
+
const data = JSON.parse(readFileSync17(filePath, "utf-8"));
|
|
4305
4296
|
const arr = data?.permissions?.[key];
|
|
4306
4297
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
4307
4298
|
} catch {
|
|
@@ -4392,6 +4383,18 @@ function matchesConfigDeny(command) {
|
|
|
4392
4383
|
|
|
4393
4384
|
// src/shared/splitCompound.ts
|
|
4394
4385
|
import { parse } from "shell-quote";
|
|
4386
|
+
|
|
4387
|
+
// src/shared/hasUnquotedBackticks.ts
|
|
4388
|
+
var QUOTED_OR_BACKTICK_RE = /\\.|'[^']*'|"[^"]*"|(`)/g;
|
|
4389
|
+
function hasUnquotedBackticks(command) {
|
|
4390
|
+
QUOTED_OR_BACKTICK_RE.lastIndex = 0;
|
|
4391
|
+
for (let m = QUOTED_OR_BACKTICK_RE.exec(command); m !== null; m = QUOTED_OR_BACKTICK_RE.exec(command)) {
|
|
4392
|
+
if (m[1] !== void 0) return true;
|
|
4393
|
+
}
|
|
4394
|
+
return false;
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
// src/shared/splitCompound.ts
|
|
4395
4398
|
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
4396
4399
|
var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
|
|
4397
4400
|
var FD_REDIRECT_RE = /\d+>&\d+/g;
|
|
@@ -4407,12 +4410,9 @@ function splitCompound(command) {
|
|
|
4407
4410
|
function tokenizeCommand(command) {
|
|
4408
4411
|
const trimmed = command.trim().replace(FD_DEVNULL_RE, "").replace(FD_REDIRECT_RE, "");
|
|
4409
4412
|
if (!trimmed) return void 0;
|
|
4413
|
+
if (hasUnquotedBackticks(trimmed)) return void 0;
|
|
4410
4414
|
try {
|
|
4411
|
-
|
|
4412
|
-
const hasBacktick = tokens.some(
|
|
4413
|
-
(t) => typeof t === "string" && /`.+`/.test(t)
|
|
4414
|
-
);
|
|
4415
|
-
return hasBacktick ? void 0 : tokens;
|
|
4415
|
+
return parse(trimmed);
|
|
4416
4416
|
} catch {
|
|
4417
4417
|
return void 0;
|
|
4418
4418
|
}
|
|
@@ -4586,7 +4586,7 @@ function denyRemove(pattern2) {
|
|
|
4586
4586
|
}
|
|
4587
4587
|
|
|
4588
4588
|
// src/commands/permitCliReads/index.ts
|
|
4589
|
-
import { existsSync as
|
|
4589
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync5, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
4590
4590
|
import { homedir as homedir4 } from "os";
|
|
4591
4591
|
import { join as join17 } from "path";
|
|
4592
4592
|
|
|
@@ -4894,8 +4894,8 @@ function logPath(cli) {
|
|
|
4894
4894
|
}
|
|
4895
4895
|
function readCache(cli) {
|
|
4896
4896
|
const path50 = logPath(cli);
|
|
4897
|
-
if (!
|
|
4898
|
-
return
|
|
4897
|
+
if (!existsSync20(path50)) return void 0;
|
|
4898
|
+
return readFileSync18(path50, "utf-8");
|
|
4899
4899
|
}
|
|
4900
4900
|
function writeCache(cli, output) {
|
|
4901
4901
|
const dir = join17(homedir4(), ".assist");
|
|
@@ -5447,7 +5447,7 @@ function registerComplexity(program2) {
|
|
|
5447
5447
|
}
|
|
5448
5448
|
|
|
5449
5449
|
// src/commands/deploy/redirect.ts
|
|
5450
|
-
import { existsSync as
|
|
5450
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
5451
5451
|
import chalk65 from "chalk";
|
|
5452
5452
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5453
5453
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -5456,11 +5456,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
5456
5456
|
</script>`;
|
|
5457
5457
|
function redirect() {
|
|
5458
5458
|
const indexPath = "index.html";
|
|
5459
|
-
if (!
|
|
5459
|
+
if (!existsSync21(indexPath)) {
|
|
5460
5460
|
console.log(chalk65.yellow("No index.html found"));
|
|
5461
5461
|
return;
|
|
5462
5462
|
}
|
|
5463
|
-
const content =
|
|
5463
|
+
const content = readFileSync19(indexPath, "utf-8");
|
|
5464
5464
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5465
5465
|
console.log(chalk65.dim("Trailing slash script already present"));
|
|
5466
5466
|
return;
|
|
@@ -5502,7 +5502,7 @@ import { execSync as execSync17 } from "child_process";
|
|
|
5502
5502
|
import chalk66 from "chalk";
|
|
5503
5503
|
|
|
5504
5504
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
5505
|
-
import { readdirSync, readFileSync as
|
|
5505
|
+
import { readdirSync, readFileSync as readFileSync20 } from "fs";
|
|
5506
5506
|
import { join as join19 } from "path";
|
|
5507
5507
|
var DEVLOG_DIR = join19(BLOG_REPO_ROOT, "src/content/devlog");
|
|
5508
5508
|
function extractFrontmatter(content) {
|
|
@@ -5532,7 +5532,7 @@ function readDevlogFiles(callback) {
|
|
|
5532
5532
|
try {
|
|
5533
5533
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
5534
5534
|
for (const file of files) {
|
|
5535
|
-
const content =
|
|
5535
|
+
const content = readFileSync20(join19(DEVLOG_DIR, file), "utf-8");
|
|
5536
5536
|
const parsed = parseFrontmatter(content, file);
|
|
5537
5537
|
if (parsed) callback(parsed);
|
|
5538
5538
|
}
|
|
@@ -5988,12 +5988,12 @@ import { join as join21 } from "path";
|
|
|
5988
5988
|
import chalk73 from "chalk";
|
|
5989
5989
|
|
|
5990
5990
|
// src/shared/findRepoRoot.ts
|
|
5991
|
-
import { existsSync as
|
|
5991
|
+
import { existsSync as existsSync22 } from "fs";
|
|
5992
5992
|
import path21 from "path";
|
|
5993
5993
|
function findRepoRoot(dir) {
|
|
5994
5994
|
let current = dir;
|
|
5995
5995
|
while (current !== path21.dirname(current)) {
|
|
5996
|
-
if (
|
|
5996
|
+
if (existsSync22(path21.join(current, ".git"))) {
|
|
5997
5997
|
return current;
|
|
5998
5998
|
}
|
|
5999
5999
|
current = path21.dirname(current);
|
|
@@ -6059,11 +6059,11 @@ async function checkBuildLocksCommand() {
|
|
|
6059
6059
|
}
|
|
6060
6060
|
|
|
6061
6061
|
// src/commands/dotnet/buildTree.ts
|
|
6062
|
-
import { readFileSync as
|
|
6062
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
6063
6063
|
import path22 from "path";
|
|
6064
6064
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
6065
6065
|
function getProjectRefs(csprojPath) {
|
|
6066
|
-
const content =
|
|
6066
|
+
const content = readFileSync21(csprojPath, "utf-8");
|
|
6067
6067
|
const refs = [];
|
|
6068
6068
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
6069
6069
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -6080,7 +6080,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
6080
6080
|
for (const ref of getProjectRefs(abs)) {
|
|
6081
6081
|
const childAbs = path22.resolve(dir, ref);
|
|
6082
6082
|
try {
|
|
6083
|
-
|
|
6083
|
+
readFileSync21(childAbs);
|
|
6084
6084
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
6085
6085
|
} catch {
|
|
6086
6086
|
node.children.push({
|
|
@@ -6105,7 +6105,7 @@ function collectAllDeps(node) {
|
|
|
6105
6105
|
}
|
|
6106
6106
|
|
|
6107
6107
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
6108
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
6108
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync22, statSync as statSync3 } from "fs";
|
|
6109
6109
|
import path23 from "path";
|
|
6110
6110
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
6111
6111
|
if (depth > maxDepth) return [];
|
|
@@ -6140,7 +6140,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
6140
6140
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
6141
6141
|
for (const sln of slnFiles) {
|
|
6142
6142
|
try {
|
|
6143
|
-
const content =
|
|
6143
|
+
const content = readFileSync22(sln, "utf-8");
|
|
6144
6144
|
if (pattern2.test(content)) {
|
|
6145
6145
|
matches.push(path23.relative(repoRoot, sln));
|
|
6146
6146
|
}
|
|
@@ -6204,12 +6204,12 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6204
6204
|
}
|
|
6205
6205
|
|
|
6206
6206
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6207
|
-
import { existsSync as
|
|
6207
|
+
import { existsSync as existsSync23 } from "fs";
|
|
6208
6208
|
import path24 from "path";
|
|
6209
6209
|
import chalk75 from "chalk";
|
|
6210
6210
|
function resolveCsproj(csprojPath) {
|
|
6211
6211
|
const resolved = path24.resolve(csprojPath);
|
|
6212
|
-
if (!
|
|
6212
|
+
if (!existsSync23(resolved)) {
|
|
6213
6213
|
console.error(chalk75.red(`File not found: ${resolved}`));
|
|
6214
6214
|
process.exit(1);
|
|
6215
6215
|
}
|
|
@@ -6377,7 +6377,7 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
6377
6377
|
}
|
|
6378
6378
|
|
|
6379
6379
|
// src/commands/dotnet/resolveSolution.ts
|
|
6380
|
-
import { existsSync as
|
|
6380
|
+
import { existsSync as existsSync24 } from "fs";
|
|
6381
6381
|
import path25 from "path";
|
|
6382
6382
|
import chalk79 from "chalk";
|
|
6383
6383
|
|
|
@@ -6418,7 +6418,7 @@ function findSolution() {
|
|
|
6418
6418
|
function resolveSolution(sln) {
|
|
6419
6419
|
if (sln) {
|
|
6420
6420
|
const resolved = path25.resolve(sln);
|
|
6421
|
-
if (!
|
|
6421
|
+
if (!existsSync24(resolved)) {
|
|
6422
6422
|
console.error(chalk79.red(`Solution file not found: ${resolved}`));
|
|
6423
6423
|
process.exit(1);
|
|
6424
6424
|
}
|
|
@@ -6458,7 +6458,7 @@ function parseInspectReport(json) {
|
|
|
6458
6458
|
|
|
6459
6459
|
// src/commands/dotnet/runInspectCode.ts
|
|
6460
6460
|
import { execSync as execSync23 } from "child_process";
|
|
6461
|
-
import { existsSync as
|
|
6461
|
+
import { existsSync as existsSync25, readFileSync as readFileSync23, unlinkSync as unlinkSync5 } from "fs";
|
|
6462
6462
|
import { tmpdir as tmpdir2 } from "os";
|
|
6463
6463
|
import path26 from "path";
|
|
6464
6464
|
import chalk80 from "chalk";
|
|
@@ -6489,11 +6489,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6489
6489
|
console.error(chalk80.red("jb inspectcode failed"));
|
|
6490
6490
|
process.exit(1);
|
|
6491
6491
|
}
|
|
6492
|
-
if (!
|
|
6492
|
+
if (!existsSync25(reportPath)) {
|
|
6493
6493
|
console.error(chalk80.red("Report file not generated"));
|
|
6494
6494
|
process.exit(1);
|
|
6495
6495
|
}
|
|
6496
|
-
const xml =
|
|
6496
|
+
const xml = readFileSync23(reportPath, "utf-8");
|
|
6497
6497
|
unlinkSync5(reportPath);
|
|
6498
6498
|
return xml;
|
|
6499
6499
|
}
|
|
@@ -6721,7 +6721,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
6721
6721
|
import { execSync as execSync26 } from "child_process";
|
|
6722
6722
|
|
|
6723
6723
|
// src/shared/loadJson.ts
|
|
6724
|
-
import { existsSync as
|
|
6724
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync6, readFileSync as readFileSync24, writeFileSync as writeFileSync19 } from "fs";
|
|
6725
6725
|
import { homedir as homedir6 } from "os";
|
|
6726
6726
|
import { join as join23 } from "path";
|
|
6727
6727
|
function getStoreDir() {
|
|
@@ -6732,9 +6732,9 @@ function getStorePath(filename) {
|
|
|
6732
6732
|
}
|
|
6733
6733
|
function loadJson(filename) {
|
|
6734
6734
|
const path50 = getStorePath(filename);
|
|
6735
|
-
if (
|
|
6735
|
+
if (existsSync26(path50)) {
|
|
6736
6736
|
try {
|
|
6737
|
-
return JSON.parse(
|
|
6737
|
+
return JSON.parse(readFileSync24(path50, "utf-8"));
|
|
6738
6738
|
} catch {
|
|
6739
6739
|
return {};
|
|
6740
6740
|
}
|
|
@@ -6743,7 +6743,7 @@ function loadJson(filename) {
|
|
|
6743
6743
|
}
|
|
6744
6744
|
function saveJson(filename, data) {
|
|
6745
6745
|
const dir = getStoreDir();
|
|
6746
|
-
if (!
|
|
6746
|
+
if (!existsSync26(dir)) {
|
|
6747
6747
|
mkdirSync6(dir, { recursive: true });
|
|
6748
6748
|
}
|
|
6749
6749
|
writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -7180,7 +7180,7 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
7180
7180
|
import { join as join26 } from "path";
|
|
7181
7181
|
|
|
7182
7182
|
// src/commands/prs/loadCommentsCache.ts
|
|
7183
|
-
import { existsSync as
|
|
7183
|
+
import { existsSync as existsSync27, readFileSync as readFileSync25, unlinkSync as unlinkSync7 } from "fs";
|
|
7184
7184
|
import { join as join25 } from "path";
|
|
7185
7185
|
import { parse as parse2 } from "yaml";
|
|
7186
7186
|
function getCachePath(prNumber) {
|
|
@@ -7188,15 +7188,15 @@ function getCachePath(prNumber) {
|
|
|
7188
7188
|
}
|
|
7189
7189
|
function loadCommentsCache(prNumber) {
|
|
7190
7190
|
const cachePath = getCachePath(prNumber);
|
|
7191
|
-
if (!
|
|
7191
|
+
if (!existsSync27(cachePath)) {
|
|
7192
7192
|
return null;
|
|
7193
7193
|
}
|
|
7194
|
-
const content =
|
|
7194
|
+
const content = readFileSync25(cachePath, "utf-8");
|
|
7195
7195
|
return parse2(content);
|
|
7196
7196
|
}
|
|
7197
7197
|
function deleteCommentsCache(prNumber) {
|
|
7198
7198
|
const cachePath = getCachePath(prNumber);
|
|
7199
|
-
if (
|
|
7199
|
+
if (existsSync27(cachePath)) {
|
|
7200
7200
|
unlinkSync7(cachePath);
|
|
7201
7201
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
7202
7202
|
}
|
|
@@ -7293,7 +7293,7 @@ function fixed(commentId, sha) {
|
|
|
7293
7293
|
}
|
|
7294
7294
|
|
|
7295
7295
|
// src/commands/prs/listComments/index.ts
|
|
7296
|
-
import { existsSync as
|
|
7296
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync7, writeFileSync as writeFileSync23 } from "fs";
|
|
7297
7297
|
import { join as join28 } from "path";
|
|
7298
7298
|
import { stringify } from "yaml";
|
|
7299
7299
|
|
|
@@ -7419,7 +7419,7 @@ function printComments2(result) {
|
|
|
7419
7419
|
// src/commands/prs/listComments/index.ts
|
|
7420
7420
|
function writeCommentsCache(prNumber, comments2) {
|
|
7421
7421
|
const assistDir = join28(process.cwd(), ".assist");
|
|
7422
|
-
if (!
|
|
7422
|
+
if (!existsSync28(assistDir)) {
|
|
7423
7423
|
mkdirSync7(assistDir, { recursive: true });
|
|
7424
7424
|
}
|
|
7425
7425
|
const cacheData = {
|
|
@@ -9854,7 +9854,7 @@ function registerSeq(program2) {
|
|
|
9854
9854
|
}
|
|
9855
9855
|
|
|
9856
9856
|
// src/commands/transcript/shared.ts
|
|
9857
|
-
import { existsSync as
|
|
9857
|
+
import { existsSync as existsSync29, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
9858
9858
|
import { basename as basename4, join as join29, relative } from "path";
|
|
9859
9859
|
import * as readline2 from "readline";
|
|
9860
9860
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -9870,7 +9870,7 @@ function isValidDatePrefix(filename) {
|
|
|
9870
9870
|
return DATE_PREFIX_REGEX.test(filename);
|
|
9871
9871
|
}
|
|
9872
9872
|
function collectFiles(dir, extension) {
|
|
9873
|
-
if (!
|
|
9873
|
+
if (!existsSync29(dir)) return [];
|
|
9874
9874
|
const results = [];
|
|
9875
9875
|
for (const entry of readdirSync5(dir)) {
|
|
9876
9876
|
const fullPath = join29(dir, entry);
|
|
@@ -9967,7 +9967,7 @@ async function configure() {
|
|
|
9967
9967
|
}
|
|
9968
9968
|
|
|
9969
9969
|
// src/commands/transcript/format/index.ts
|
|
9970
|
-
import { existsSync as
|
|
9970
|
+
import { existsSync as existsSync31 } from "fs";
|
|
9971
9971
|
|
|
9972
9972
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9973
9973
|
import { dirname as dirname18, join as join31 } from "path";
|
|
@@ -10041,7 +10041,7 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10041
10041
|
}
|
|
10042
10042
|
|
|
10043
10043
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
10044
|
-
import { existsSync as
|
|
10044
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync26, writeFileSync as writeFileSync24 } from "fs";
|
|
10045
10045
|
import { basename as basename5, dirname as dirname19, join as join32 } from "path";
|
|
10046
10046
|
|
|
10047
10047
|
// src/commands/transcript/cleanText.ts
|
|
@@ -10266,7 +10266,7 @@ function logSkipped(relativeDir, mdFile) {
|
|
|
10266
10266
|
return "skipped";
|
|
10267
10267
|
}
|
|
10268
10268
|
function ensureDirectory(dir, label2) {
|
|
10269
|
-
if (!
|
|
10269
|
+
if (!existsSync30(dir)) {
|
|
10270
10270
|
mkdirSync8(dir, { recursive: true });
|
|
10271
10271
|
console.log(`Created ${label2}: ${dir}`);
|
|
10272
10272
|
}
|
|
@@ -10289,7 +10289,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
10289
10289
|
}
|
|
10290
10290
|
function readAndParseCues(inputPath) {
|
|
10291
10291
|
console.log(`Reading: ${inputPath}`);
|
|
10292
|
-
return processCues(
|
|
10292
|
+
return processCues(readFileSync26(inputPath, "utf-8"));
|
|
10293
10293
|
}
|
|
10294
10294
|
function writeFormatted(outputPath, content) {
|
|
10295
10295
|
writeFileSync24(outputPath, content, "utf-8");
|
|
@@ -10302,7 +10302,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
10302
10302
|
logReduction(cues.length, chatMessages.length);
|
|
10303
10303
|
}
|
|
10304
10304
|
function tryProcessVtt(vttFile, paths) {
|
|
10305
|
-
if (
|
|
10305
|
+
if (existsSync30(paths.outputPath))
|
|
10306
10306
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
10307
10307
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
10308
10308
|
return "processed";
|
|
@@ -10328,7 +10328,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
10328
10328
|
logSummary(counts);
|
|
10329
10329
|
}
|
|
10330
10330
|
function requireVttDir(vttDir) {
|
|
10331
|
-
if (!
|
|
10331
|
+
if (!existsSync31(vttDir)) {
|
|
10332
10332
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
10333
10333
|
process.exit(1);
|
|
10334
10334
|
}
|
|
@@ -10360,14 +10360,14 @@ async function format() {
|
|
|
10360
10360
|
}
|
|
10361
10361
|
|
|
10362
10362
|
// src/commands/transcript/summarise/index.ts
|
|
10363
|
-
import { existsSync as
|
|
10363
|
+
import { existsSync as existsSync33 } from "fs";
|
|
10364
10364
|
import { basename as basename6, dirname as dirname21, join as join34, relative as relative2 } from "path";
|
|
10365
10365
|
|
|
10366
10366
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10367
10367
|
import {
|
|
10368
|
-
existsSync as
|
|
10368
|
+
existsSync as existsSync32,
|
|
10369
10369
|
mkdirSync as mkdirSync9,
|
|
10370
|
-
readFileSync as
|
|
10370
|
+
readFileSync as readFileSync27,
|
|
10371
10371
|
renameSync as renameSync3,
|
|
10372
10372
|
rmSync
|
|
10373
10373
|
} from "fs";
|
|
@@ -10402,7 +10402,7 @@ function validateStagedContent(filename, content) {
|
|
|
10402
10402
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10403
10403
|
var STAGING_DIR = join33(process.cwd(), ".assist", "transcript");
|
|
10404
10404
|
function processStagedFile() {
|
|
10405
|
-
if (!
|
|
10405
|
+
if (!existsSync32(STAGING_DIR)) {
|
|
10406
10406
|
return false;
|
|
10407
10407
|
}
|
|
10408
10408
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -10411,7 +10411,7 @@ function processStagedFile() {
|
|
|
10411
10411
|
}
|
|
10412
10412
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10413
10413
|
const stagedFile = stagedFiles[0];
|
|
10414
|
-
const content =
|
|
10414
|
+
const content = readFileSync27(stagedFile.absolutePath, "utf-8");
|
|
10415
10415
|
validateStagedContent(stagedFile.filename, content);
|
|
10416
10416
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
10417
10417
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -10426,7 +10426,7 @@ function processStagedFile() {
|
|
|
10426
10426
|
}
|
|
10427
10427
|
const destPath = join33(summaryDir, matchingTranscript.relativePath);
|
|
10428
10428
|
const destDir = dirname20(destPath);
|
|
10429
|
-
if (!
|
|
10429
|
+
if (!existsSync32(destDir)) {
|
|
10430
10430
|
mkdirSync9(destDir, { recursive: true });
|
|
10431
10431
|
}
|
|
10432
10432
|
renameSync3(stagedFile.absolutePath, destPath);
|
|
@@ -10453,7 +10453,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
10453
10453
|
function summarise2() {
|
|
10454
10454
|
processStagedFile();
|
|
10455
10455
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10456
|
-
if (!
|
|
10456
|
+
if (!existsSync33(transcriptsDir)) {
|
|
10457
10457
|
console.log("No transcripts directory found.");
|
|
10458
10458
|
return;
|
|
10459
10459
|
}
|
|
@@ -10557,14 +10557,14 @@ function devices() {
|
|
|
10557
10557
|
}
|
|
10558
10558
|
|
|
10559
10559
|
// src/commands/voice/logs.ts
|
|
10560
|
-
import { existsSync as
|
|
10560
|
+
import { existsSync as existsSync34, readFileSync as readFileSync28 } from "fs";
|
|
10561
10561
|
function logs(options2) {
|
|
10562
|
-
if (!
|
|
10562
|
+
if (!existsSync34(voicePaths.log)) {
|
|
10563
10563
|
console.log("No voice log file found");
|
|
10564
10564
|
return;
|
|
10565
10565
|
}
|
|
10566
10566
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
10567
|
-
const content =
|
|
10567
|
+
const content = readFileSync28(voicePaths.log, "utf-8").trim();
|
|
10568
10568
|
if (!content) {
|
|
10569
10569
|
console.log("Voice log is empty");
|
|
10570
10570
|
return;
|
|
@@ -10591,7 +10591,7 @@ import { join as join38 } from "path";
|
|
|
10591
10591
|
|
|
10592
10592
|
// src/commands/voice/checkLockFile.ts
|
|
10593
10593
|
import { execSync as execSync37 } from "child_process";
|
|
10594
|
-
import { existsSync as
|
|
10594
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync10, readFileSync as readFileSync29, writeFileSync as writeFileSync25 } from "fs";
|
|
10595
10595
|
import { join as join37 } from "path";
|
|
10596
10596
|
function isProcessAlive2(pid) {
|
|
10597
10597
|
try {
|
|
@@ -10603,9 +10603,9 @@ function isProcessAlive2(pid) {
|
|
|
10603
10603
|
}
|
|
10604
10604
|
function checkLockFile() {
|
|
10605
10605
|
const lockFile = getLockFile();
|
|
10606
|
-
if (!
|
|
10606
|
+
if (!existsSync35(lockFile)) return;
|
|
10607
10607
|
try {
|
|
10608
|
-
const lock = JSON.parse(
|
|
10608
|
+
const lock = JSON.parse(readFileSync29(lockFile, "utf-8"));
|
|
10609
10609
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
10610
10610
|
console.error(
|
|
10611
10611
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -10616,7 +10616,7 @@ function checkLockFile() {
|
|
|
10616
10616
|
}
|
|
10617
10617
|
}
|
|
10618
10618
|
function bootstrapVenv() {
|
|
10619
|
-
if (
|
|
10619
|
+
if (existsSync35(getVenvPython())) return;
|
|
10620
10620
|
console.log("Setting up Python environment...");
|
|
10621
10621
|
const pythonDir = getPythonDir();
|
|
10622
10622
|
execSync37(
|
|
@@ -10707,7 +10707,7 @@ function start2(options2) {
|
|
|
10707
10707
|
}
|
|
10708
10708
|
|
|
10709
10709
|
// src/commands/voice/status.ts
|
|
10710
|
-
import { existsSync as
|
|
10710
|
+
import { existsSync as existsSync36, readFileSync as readFileSync30 } from "fs";
|
|
10711
10711
|
function isProcessAlive3(pid) {
|
|
10712
10712
|
try {
|
|
10713
10713
|
process.kill(pid, 0);
|
|
@@ -10717,16 +10717,16 @@ function isProcessAlive3(pid) {
|
|
|
10717
10717
|
}
|
|
10718
10718
|
}
|
|
10719
10719
|
function readRecentLogs(count) {
|
|
10720
|
-
if (!
|
|
10721
|
-
const lines =
|
|
10720
|
+
if (!existsSync36(voicePaths.log)) return [];
|
|
10721
|
+
const lines = readFileSync30(voicePaths.log, "utf-8").trim().split("\n");
|
|
10722
10722
|
return lines.slice(-count);
|
|
10723
10723
|
}
|
|
10724
10724
|
function status() {
|
|
10725
|
-
if (!
|
|
10725
|
+
if (!existsSync36(voicePaths.pid)) {
|
|
10726
10726
|
console.log("Voice daemon: not running (no PID file)");
|
|
10727
10727
|
return;
|
|
10728
10728
|
}
|
|
10729
|
-
const pid = Number.parseInt(
|
|
10729
|
+
const pid = Number.parseInt(readFileSync30(voicePaths.pid, "utf-8").trim(), 10);
|
|
10730
10730
|
const alive = isProcessAlive3(pid);
|
|
10731
10731
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10732
10732
|
const recent = readRecentLogs(5);
|
|
@@ -10745,13 +10745,13 @@ function status() {
|
|
|
10745
10745
|
}
|
|
10746
10746
|
|
|
10747
10747
|
// src/commands/voice/stop.ts
|
|
10748
|
-
import { existsSync as
|
|
10748
|
+
import { existsSync as existsSync37, readFileSync as readFileSync31, unlinkSync as unlinkSync10 } from "fs";
|
|
10749
10749
|
function stop() {
|
|
10750
|
-
if (!
|
|
10750
|
+
if (!existsSync37(voicePaths.pid)) {
|
|
10751
10751
|
console.log("Voice daemon is not running (no PID file)");
|
|
10752
10752
|
return;
|
|
10753
10753
|
}
|
|
10754
|
-
const pid = Number.parseInt(
|
|
10754
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10755
10755
|
try {
|
|
10756
10756
|
process.kill(pid, "SIGTERM");
|
|
10757
10757
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10764,7 +10764,7 @@ function stop() {
|
|
|
10764
10764
|
}
|
|
10765
10765
|
try {
|
|
10766
10766
|
const lockFile = getLockFile();
|
|
10767
|
-
if (
|
|
10767
|
+
if (existsSync37(lockFile)) unlinkSync10(lockFile);
|
|
10768
10768
|
} catch {
|
|
10769
10769
|
}
|
|
10770
10770
|
console.log("Voice daemon stopped");
|
|
@@ -10985,7 +10985,7 @@ async function auth() {
|
|
|
10985
10985
|
}
|
|
10986
10986
|
|
|
10987
10987
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10988
|
-
import { readFileSync as
|
|
10988
|
+
import { readFileSync as readFileSync32 } from "fs";
|
|
10989
10989
|
import { join as join40 } from "path";
|
|
10990
10990
|
async function showClaudeCodeIcon() {
|
|
10991
10991
|
const appData = process.env.APPDATA;
|
|
@@ -10993,7 +10993,7 @@ async function showClaudeCodeIcon() {
|
|
|
10993
10993
|
const portFile = join40(appData, "Roam", "roam-local-api.port");
|
|
10994
10994
|
let port;
|
|
10995
10995
|
try {
|
|
10996
|
-
port =
|
|
10996
|
+
port = readFileSync32(portFile, "utf-8").trim();
|
|
10997
10997
|
} catch {
|
|
10998
10998
|
return;
|
|
10999
10999
|
}
|
|
@@ -11190,7 +11190,7 @@ function run3(name, args) {
|
|
|
11190
11190
|
|
|
11191
11191
|
// src/commands/screenshot/index.ts
|
|
11192
11192
|
import { execSync as execSync40 } from "child_process";
|
|
11193
|
-
import { existsSync as
|
|
11193
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
11194
11194
|
import { tmpdir as tmpdir6 } from "os";
|
|
11195
11195
|
import { join as join42, resolve as resolve5 } from "path";
|
|
11196
11196
|
import chalk121 from "chalk";
|
|
@@ -11322,7 +11322,7 @@ Write-Output $OutputPath
|
|
|
11322
11322
|
|
|
11323
11323
|
// src/commands/screenshot/index.ts
|
|
11324
11324
|
function buildOutputPath(outputDir, processName) {
|
|
11325
|
-
if (!
|
|
11325
|
+
if (!existsSync38(outputDir)) {
|
|
11326
11326
|
mkdirSync14(outputDir, { recursive: true });
|
|
11327
11327
|
}
|
|
11328
11328
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|