@staff0rd/assist 0.170.3 → 0.171.1
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 +560 -223
- package/package.json +3 -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.171.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -38,6 +38,7 @@ var package_default = {
|
|
|
38
38
|
url: "https://github.com/staff0rd/assist"
|
|
39
39
|
},
|
|
40
40
|
dependencies: {
|
|
41
|
+
"better-sqlite3": "^12.8.0",
|
|
41
42
|
chalk: "^5.6.2",
|
|
42
43
|
commander: "^14.0.2",
|
|
43
44
|
diff: "^8.0.2",
|
|
@@ -59,6 +60,7 @@ var package_default = {
|
|
|
59
60
|
"@semantic-release/changelog": "^6.0.3",
|
|
60
61
|
"@semantic-release/exec": "^7.1.0",
|
|
61
62
|
"@semantic-release/git": "^10.0.1",
|
|
63
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
62
64
|
"@types/node": "^24.10.1",
|
|
63
65
|
"@types/node-notifier": "^8.0.5",
|
|
64
66
|
"@types/react": "^19.2.14",
|
|
@@ -97,14 +99,210 @@ async function exitOnCancel(promise) {
|
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
// src/commands/backlog/acquireLock.ts
|
|
100
|
-
import { existsSync as existsSync2, readFileSync as
|
|
101
|
-
import { join as
|
|
102
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
103
|
+
import { join as join4 } from "path";
|
|
102
104
|
|
|
103
105
|
// src/commands/backlog/shared.ts
|
|
104
|
-
import {
|
|
105
|
-
import { join } from "path";
|
|
106
|
+
import { join as join3 } from "path";
|
|
106
107
|
import chalk from "chalk";
|
|
107
|
-
|
|
108
|
+
|
|
109
|
+
// src/commands/backlog/deleteItemRelations.ts
|
|
110
|
+
function deleteItemRelations(db, itemId) {
|
|
111
|
+
db.prepare("DELETE FROM plan_tasks WHERE item_id = ?").run(itemId);
|
|
112
|
+
db.prepare("DELETE FROM plan_phases WHERE item_id = ?").run(itemId);
|
|
113
|
+
db.prepare("DELETE FROM comments WHERE item_id = ?").run(itemId);
|
|
114
|
+
db.prepare("DELETE FROM links WHERE item_id = ?").run(itemId);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/commands/backlog/deleteItem.ts
|
|
118
|
+
function deleteItem(db, id) {
|
|
119
|
+
const del2 = db.transaction(() => {
|
|
120
|
+
deleteItemRelations(db, id);
|
|
121
|
+
const result = db.prepare("DELETE FROM items WHERE id = ?").run(id);
|
|
122
|
+
return result.changes > 0;
|
|
123
|
+
});
|
|
124
|
+
return del2();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/commands/backlog/exportToJsonl.ts
|
|
128
|
+
import { statSync, writeFileSync } from "fs";
|
|
129
|
+
import { join } from "path";
|
|
130
|
+
|
|
131
|
+
// src/commands/backlog/loadComments.ts
|
|
132
|
+
function loadComments(db, itemId) {
|
|
133
|
+
const rows = db.prepare(
|
|
134
|
+
"SELECT text, phase, timestamp, type FROM comments WHERE item_id = ? ORDER BY idx"
|
|
135
|
+
).all(itemId);
|
|
136
|
+
return rows.map((r) => {
|
|
137
|
+
const c = {
|
|
138
|
+
text: r.text,
|
|
139
|
+
timestamp: r.timestamp,
|
|
140
|
+
type: r.type
|
|
141
|
+
};
|
|
142
|
+
if (r.phase != null) c.phase = r.phase;
|
|
143
|
+
return c;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/commands/backlog/loadPlan.ts
|
|
148
|
+
function toPhase(db, itemId, p) {
|
|
149
|
+
const tasks = db.prepare(
|
|
150
|
+
"SELECT task, verify FROM plan_tasks WHERE item_id = ? AND phase_idx = ? ORDER BY idx"
|
|
151
|
+
).all(itemId, p.idx);
|
|
152
|
+
const phase = {
|
|
153
|
+
name: p.name,
|
|
154
|
+
tasks: tasks.map((t) => ({
|
|
155
|
+
task: t.task,
|
|
156
|
+
...t.verify != null ? { verify: t.verify } : {}
|
|
157
|
+
}))
|
|
158
|
+
};
|
|
159
|
+
if (p.manual_checks) {
|
|
160
|
+
phase.manualChecks = JSON.parse(p.manual_checks);
|
|
161
|
+
}
|
|
162
|
+
return phase;
|
|
163
|
+
}
|
|
164
|
+
function loadPlan(db, itemId) {
|
|
165
|
+
const phases = db.prepare(
|
|
166
|
+
"SELECT idx, name, manual_checks FROM plan_phases WHERE item_id = ? ORDER BY idx"
|
|
167
|
+
).all(itemId);
|
|
168
|
+
if (phases.length === 0) return void 0;
|
|
169
|
+
return phases.map((p) => toPhase(db, itemId, p));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/commands/backlog/loadAllItems.ts
|
|
173
|
+
function loadLinks(db, itemId) {
|
|
174
|
+
return db.prepare("SELECT type, target_id as targetId FROM links WHERE item_id = ?").all(itemId);
|
|
175
|
+
}
|
|
176
|
+
function rowToItem(db, row) {
|
|
177
|
+
const comments2 = loadComments(db, row.id);
|
|
178
|
+
const links = loadLinks(db, row.id);
|
|
179
|
+
const plan2 = loadPlan(db, row.id);
|
|
180
|
+
const item = {
|
|
181
|
+
id: row.id,
|
|
182
|
+
type: row.type,
|
|
183
|
+
name: row.name,
|
|
184
|
+
acceptanceCriteria: JSON.parse(row.acceptance_criteria),
|
|
185
|
+
status: row.status
|
|
186
|
+
};
|
|
187
|
+
if (row.description != null) item.description = row.description;
|
|
188
|
+
if (row.current_phase != null) item.currentPhase = row.current_phase;
|
|
189
|
+
if (comments2.length > 0) item.comments = comments2;
|
|
190
|
+
if (links && links.length > 0) item.links = links;
|
|
191
|
+
if (plan2) item.plan = plan2;
|
|
192
|
+
return item;
|
|
193
|
+
}
|
|
194
|
+
function loadAllItems(db) {
|
|
195
|
+
const rows = db.prepare("SELECT * FROM items ORDER BY id").all();
|
|
196
|
+
return rows.map((row) => rowToItem(db, row));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/commands/backlog/exportToJsonl.ts
|
|
200
|
+
function getJsonlPath(dir) {
|
|
201
|
+
return join(dir, ".assist", "backlog.jsonl");
|
|
202
|
+
}
|
|
203
|
+
function exportToJsonl(db, dir) {
|
|
204
|
+
const jsonlPath = getJsonlPath(dir);
|
|
205
|
+
const items = loadAllItems(db);
|
|
206
|
+
const lines = items.map((item) => JSON.stringify(item));
|
|
207
|
+
writeFileSync(jsonlPath, lines.length > 0 ? `${lines.join("\n")}
|
|
208
|
+
` : "");
|
|
209
|
+
const mtimeMs = statSync(jsonlPath).mtimeMs;
|
|
210
|
+
db.prepare(
|
|
211
|
+
"INSERT INTO metadata (key, value) VALUES ('jsonl_last_import_ms', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
212
|
+
).run(String(mtimeMs));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/commands/backlog/importFromJsonlIfNeeded.ts
|
|
216
|
+
import { readFileSync, statSync as statSync2 } from "fs";
|
|
217
|
+
|
|
218
|
+
// src/commands/backlog/insertItemRelations.ts
|
|
219
|
+
function insertComments(db, item) {
|
|
220
|
+
if (!item.comments) return;
|
|
221
|
+
const stmt = db.prepare(
|
|
222
|
+
"INSERT INTO comments (item_id, idx, text, phase, timestamp, type) VALUES (?, ?, ?, ?, ?, ?)"
|
|
223
|
+
);
|
|
224
|
+
for (let i = 0; i < item.comments.length; i++) {
|
|
225
|
+
const c = item.comments[i];
|
|
226
|
+
stmt.run(item.id, i, c.text, c.phase ?? null, c.timestamp, c.type);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function insertLinks(db, item) {
|
|
230
|
+
if (!item.links) return;
|
|
231
|
+
const stmt = db.prepare(
|
|
232
|
+
"INSERT INTO links (item_id, type, target_id) VALUES (?, ?, ?)"
|
|
233
|
+
);
|
|
234
|
+
for (const l of item.links) {
|
|
235
|
+
stmt.run(item.id, l.type, l.targetId);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function insertPlan(db, item) {
|
|
239
|
+
if (!item.plan) return;
|
|
240
|
+
const phaseStmt = db.prepare(
|
|
241
|
+
"INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
|
|
242
|
+
);
|
|
243
|
+
const taskStmt = db.prepare(
|
|
244
|
+
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task, verify) VALUES (?, ?, ?, ?, ?)"
|
|
245
|
+
);
|
|
246
|
+
for (let pi = 0; pi < item.plan.length; pi++) {
|
|
247
|
+
const phase = item.plan[pi];
|
|
248
|
+
phaseStmt.run(
|
|
249
|
+
item.id,
|
|
250
|
+
pi,
|
|
251
|
+
phase.name,
|
|
252
|
+
phase.manualChecks ? JSON.stringify(phase.manualChecks) : null
|
|
253
|
+
);
|
|
254
|
+
for (let ti = 0; ti < phase.tasks.length; ti++) {
|
|
255
|
+
const task = phase.tasks[ti];
|
|
256
|
+
taskStmt.run(item.id, pi, ti, task.task, task.verify ?? null);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function insertItemRelations(db, item) {
|
|
261
|
+
insertComments(db, item);
|
|
262
|
+
insertLinks(db, item);
|
|
263
|
+
insertPlan(db, item);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/commands/backlog/saveAllItems.ts
|
|
267
|
+
function upsertItem(db, item) {
|
|
268
|
+
db.prepare(
|
|
269
|
+
`INSERT INTO items (id, type, name, description, acceptance_criteria, status, current_phase)
|
|
270
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
271
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
272
|
+
type = excluded.type,
|
|
273
|
+
name = excluded.name,
|
|
274
|
+
description = excluded.description,
|
|
275
|
+
acceptance_criteria = excluded.acceptance_criteria,
|
|
276
|
+
status = excluded.status,
|
|
277
|
+
current_phase = excluded.current_phase`
|
|
278
|
+
).run(
|
|
279
|
+
item.id,
|
|
280
|
+
item.type,
|
|
281
|
+
item.name,
|
|
282
|
+
item.description ?? null,
|
|
283
|
+
JSON.stringify(item.acceptanceCriteria),
|
|
284
|
+
item.status,
|
|
285
|
+
item.currentPhase ?? null
|
|
286
|
+
);
|
|
287
|
+
deleteItemRelations(db, item.id);
|
|
288
|
+
insertItemRelations(db, item);
|
|
289
|
+
}
|
|
290
|
+
function saveAllItems(db, items) {
|
|
291
|
+
const save = db.transaction(() => {
|
|
292
|
+
const existingIds = db.prepare("SELECT id FROM items").all();
|
|
293
|
+
const newIds = new Set(items.map((i) => i.id));
|
|
294
|
+
for (const { id } of existingIds) {
|
|
295
|
+
if (!newIds.has(id)) {
|
|
296
|
+
deleteItemRelations(db, id);
|
|
297
|
+
db.prepare("DELETE FROM items WHERE id = ?").run(id);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
for (const item of items) {
|
|
301
|
+
upsertItem(db, item);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
save();
|
|
305
|
+
}
|
|
108
306
|
|
|
109
307
|
// src/commands/backlog/types.ts
|
|
110
308
|
import { z } from "zod";
|
|
@@ -145,6 +343,143 @@ var backlogItemSchema = z.strictObject({
|
|
|
145
343
|
});
|
|
146
344
|
var backlogFileSchema = z.array(backlogItemSchema);
|
|
147
345
|
|
|
346
|
+
// src/commands/backlog/importFromJsonlIfNeeded.ts
|
|
347
|
+
function getLastImportMs(db) {
|
|
348
|
+
const row = db.prepare("SELECT value FROM metadata WHERE key = 'jsonl_last_import_ms'").get();
|
|
349
|
+
return row ? Number(row.value) : 0;
|
|
350
|
+
}
|
|
351
|
+
function setLastImportMs(db, ms) {
|
|
352
|
+
db.prepare(
|
|
353
|
+
"INSERT INTO metadata (key, value) VALUES ('jsonl_last_import_ms', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
354
|
+
).run(String(ms));
|
|
355
|
+
}
|
|
356
|
+
function importFromJsonlIfNeeded(db, dir) {
|
|
357
|
+
const jsonlPath = getJsonlPath(dir);
|
|
358
|
+
let stat;
|
|
359
|
+
try {
|
|
360
|
+
stat = statSync2(jsonlPath);
|
|
361
|
+
} catch {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const fileMtimeMs = stat.mtimeMs;
|
|
365
|
+
const lastImportMs = getLastImportMs(db);
|
|
366
|
+
if (fileMtimeMs <= lastImportMs) return;
|
|
367
|
+
const content = readFileSync(jsonlPath, "utf-8").trim();
|
|
368
|
+
if (content.length === 0) {
|
|
369
|
+
setLastImportMs(db, fileMtimeMs);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const items = content.split("\n").map((line) => {
|
|
373
|
+
const parsed = JSON.parse(line);
|
|
374
|
+
return backlogItemSchema.parse(parsed);
|
|
375
|
+
});
|
|
376
|
+
saveAllItems(db, items);
|
|
377
|
+
setLastImportMs(db, fileMtimeMs);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/commands/backlog/migrateYamlIfNeeded.ts
|
|
381
|
+
import { existsSync, readFileSync as readFileSync2, renameSync } from "fs";
|
|
382
|
+
import { parse as parseYaml } from "yaml";
|
|
383
|
+
function migrateYamlIfNeeded(db, yamlPath) {
|
|
384
|
+
if (!existsSync(yamlPath)) return false;
|
|
385
|
+
const existing = db.prepare("SELECT COUNT(*) as count FROM items").get();
|
|
386
|
+
if (existing.count > 0) return false;
|
|
387
|
+
const content = readFileSync2(yamlPath, "utf-8");
|
|
388
|
+
const raw = parseYaml(content) || [];
|
|
389
|
+
const items = backlogFileSchema.parse(raw);
|
|
390
|
+
if (items.length > 0) {
|
|
391
|
+
saveAllItems(db, items);
|
|
392
|
+
renameSync(yamlPath, `${yamlPath}.bak`);
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/commands/backlog/openDb.ts
|
|
399
|
+
import { mkdirSync } from "fs";
|
|
400
|
+
import { join as join2 } from "path";
|
|
401
|
+
import Database from "better-sqlite3";
|
|
402
|
+
var _db;
|
|
403
|
+
function getDbPath(dir) {
|
|
404
|
+
return join2(dir, ".assist", "backlog.db");
|
|
405
|
+
}
|
|
406
|
+
function initSchema(db) {
|
|
407
|
+
db.exec(`
|
|
408
|
+
CREATE TABLE IF NOT EXISTS items (
|
|
409
|
+
id INTEGER PRIMARY KEY,
|
|
410
|
+
type TEXT NOT NULL DEFAULT 'story',
|
|
411
|
+
name TEXT NOT NULL,
|
|
412
|
+
description TEXT,
|
|
413
|
+
acceptance_criteria TEXT NOT NULL DEFAULT '[]',
|
|
414
|
+
status TEXT NOT NULL DEFAULT 'todo',
|
|
415
|
+
current_phase INTEGER
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
CREATE TABLE IF NOT EXISTS comments (
|
|
419
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
420
|
+
idx INTEGER NOT NULL,
|
|
421
|
+
text TEXT NOT NULL,
|
|
422
|
+
phase INTEGER,
|
|
423
|
+
timestamp TEXT NOT NULL,
|
|
424
|
+
type TEXT NOT NULL DEFAULT 'comment',
|
|
425
|
+
PRIMARY KEY (item_id, idx)
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
CREATE TABLE IF NOT EXISTS links (
|
|
429
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
430
|
+
type TEXT NOT NULL,
|
|
431
|
+
target_id INTEGER NOT NULL,
|
|
432
|
+
PRIMARY KEY (item_id, type, target_id)
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
CREATE TABLE IF NOT EXISTS plan_phases (
|
|
436
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
437
|
+
idx INTEGER NOT NULL,
|
|
438
|
+
name TEXT NOT NULL,
|
|
439
|
+
manual_checks TEXT,
|
|
440
|
+
PRIMARY KEY (item_id, idx)
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
CREATE TABLE IF NOT EXISTS plan_tasks (
|
|
444
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
445
|
+
phase_idx INTEGER NOT NULL,
|
|
446
|
+
idx INTEGER NOT NULL,
|
|
447
|
+
task TEXT NOT NULL,
|
|
448
|
+
verify TEXT,
|
|
449
|
+
PRIMARY KEY (item_id, phase_idx, idx),
|
|
450
|
+
FOREIGN KEY (item_id, phase_idx) REFERENCES plan_phases(item_id, idx) ON DELETE CASCADE
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
CREATE TABLE IF NOT EXISTS metadata (
|
|
454
|
+
key TEXT PRIMARY KEY,
|
|
455
|
+
value TEXT NOT NULL
|
|
456
|
+
);
|
|
457
|
+
`);
|
|
458
|
+
}
|
|
459
|
+
function openDb(dir) {
|
|
460
|
+
if (_db) return _db;
|
|
461
|
+
const dbPath = getDbPath(dir);
|
|
462
|
+
mkdirSync(join2(dir, ".assist"), { recursive: true });
|
|
463
|
+
const db = new Database(dbPath);
|
|
464
|
+
db.pragma("journal_mode = WAL");
|
|
465
|
+
db.pragma("foreign_keys = ON");
|
|
466
|
+
initSchema(db);
|
|
467
|
+
_db = db;
|
|
468
|
+
return db;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/commands/backlog/updateCurrentPhase.ts
|
|
472
|
+
function updateCurrentPhase(db, id, phase) {
|
|
473
|
+
const result = db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(phase, id);
|
|
474
|
+
return result.changes > 0;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// src/commands/backlog/updateStatus.ts
|
|
478
|
+
function updateStatus(db, id, status2) {
|
|
479
|
+
const result = db.prepare("UPDATE items SET status = ? WHERE id = ?").run(status2, id);
|
|
480
|
+
return result.changes > 0;
|
|
481
|
+
}
|
|
482
|
+
|
|
148
483
|
// src/commands/backlog/shared.ts
|
|
149
484
|
var _backlogDir;
|
|
150
485
|
function setBacklogDir(dir) {
|
|
@@ -154,33 +489,29 @@ function getBacklogDir() {
|
|
|
154
489
|
return _backlogDir ?? process.cwd();
|
|
155
490
|
}
|
|
156
491
|
function getBacklogPath() {
|
|
157
|
-
return
|
|
492
|
+
return join3(getBacklogDir(), "assist.backlog.yml");
|
|
493
|
+
}
|
|
494
|
+
function getDb() {
|
|
495
|
+
const dir = getBacklogDir();
|
|
496
|
+
const db = openDb(dir);
|
|
497
|
+
const migrated = migrateYamlIfNeeded(db, getBacklogPath());
|
|
498
|
+
if (migrated) exportToJsonl(db, dir);
|
|
499
|
+
return db;
|
|
158
500
|
}
|
|
159
501
|
function loadBacklog() {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
const content = readFileSync(backlogPath, "utf-8");
|
|
165
|
-
const raw = parseYaml(content) || [];
|
|
166
|
-
return backlogFileSchema.parse(raw);
|
|
502
|
+
const db = getDb();
|
|
503
|
+
importFromJsonlIfNeeded(db, getBacklogDir());
|
|
504
|
+
return loadAllItems(db);
|
|
167
505
|
}
|
|
168
506
|
function saveBacklog(items) {
|
|
169
|
-
const
|
|
170
|
-
|
|
507
|
+
const db = getDb();
|
|
508
|
+
saveAllItems(db, items);
|
|
509
|
+
exportToJsonl(db, getBacklogDir());
|
|
171
510
|
}
|
|
172
511
|
function findItem(items, id) {
|
|
173
512
|
return items.find((item) => item.id === id);
|
|
174
513
|
}
|
|
175
514
|
function loadAndFindItem(id) {
|
|
176
|
-
if (!existsSync(getBacklogPath())) {
|
|
177
|
-
console.log(
|
|
178
|
-
chalk.yellow(
|
|
179
|
-
"No backlog found. Run 'assist backlog init' to create one."
|
|
180
|
-
)
|
|
181
|
-
);
|
|
182
|
-
return void 0;
|
|
183
|
-
}
|
|
184
515
|
const items = loadBacklog();
|
|
185
516
|
const item = findItem(items, Number.parseInt(id, 10));
|
|
186
517
|
if (!item) {
|
|
@@ -192,20 +523,24 @@ function loadAndFindItem(id) {
|
|
|
192
523
|
function setStatus(id, status2) {
|
|
193
524
|
const result = loadAndFindItem(id);
|
|
194
525
|
if (!result) return void 0;
|
|
195
|
-
|
|
196
|
-
|
|
526
|
+
const db = getDb();
|
|
527
|
+
updateStatus(db, result.item.id, status2);
|
|
528
|
+
exportToJsonl(db, getBacklogDir());
|
|
197
529
|
return result.item.name;
|
|
198
530
|
}
|
|
199
531
|
function setCurrentPhase(id, phase) {
|
|
200
532
|
const result = loadAndFindItem(id);
|
|
201
533
|
if (!result) return;
|
|
202
|
-
|
|
203
|
-
|
|
534
|
+
const db = getDb();
|
|
535
|
+
updateCurrentPhase(db, result.item.id, phase);
|
|
536
|
+
exportToJsonl(db, getBacklogDir());
|
|
204
537
|
}
|
|
205
538
|
function removeItem(id) {
|
|
206
539
|
const result = loadAndFindItem(id);
|
|
207
540
|
if (!result) return void 0;
|
|
208
|
-
|
|
541
|
+
const db = getDb();
|
|
542
|
+
deleteItem(db, result.item.id);
|
|
543
|
+
exportToJsonl(db, getBacklogDir());
|
|
209
544
|
return result.item.name;
|
|
210
545
|
}
|
|
211
546
|
function getNextId(items) {
|
|
@@ -215,7 +550,7 @@ function getNextId(items) {
|
|
|
215
550
|
|
|
216
551
|
// src/commands/backlog/acquireLock.ts
|
|
217
552
|
function getLockPath(itemId) {
|
|
218
|
-
return
|
|
553
|
+
return join4(getBacklogDir(), `.assist-lock-${itemId}.json`);
|
|
219
554
|
}
|
|
220
555
|
function isProcessAlive(pid) {
|
|
221
556
|
try {
|
|
@@ -229,7 +564,7 @@ function isLockedByOther(itemId) {
|
|
|
229
564
|
const lockPath = getLockPath(itemId);
|
|
230
565
|
if (!existsSync2(lockPath)) return false;
|
|
231
566
|
try {
|
|
232
|
-
const lock = JSON.parse(
|
|
567
|
+
const lock = JSON.parse(readFileSync3(lockPath, "utf-8"));
|
|
233
568
|
if (lock.pid === process.pid) return false;
|
|
234
569
|
return isProcessAlive(lock.pid);
|
|
235
570
|
} catch {
|
|
@@ -438,10 +773,10 @@ async function handleIncompletePhase() {
|
|
|
438
773
|
|
|
439
774
|
// src/commands/backlog/writeSignal.ts
|
|
440
775
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
441
|
-
import { join as
|
|
776
|
+
import { join as join5 } from "path";
|
|
442
777
|
var SIGNAL_FILE = ".assist-signal.json";
|
|
443
778
|
function getSignalPath() {
|
|
444
|
-
return
|
|
779
|
+
return join5(getBacklogDir(), SIGNAL_FILE);
|
|
445
780
|
}
|
|
446
781
|
function writeSignal(event, data) {
|
|
447
782
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
@@ -489,12 +824,12 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
489
824
|
import { existsSync as existsSync5, unwatchFile, watchFile } from "fs";
|
|
490
825
|
|
|
491
826
|
// src/commands/backlog/readSignal.ts
|
|
492
|
-
import { existsSync as existsSync4, readFileSync as
|
|
827
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
493
828
|
function readSignal() {
|
|
494
829
|
const path50 = getSignalPath();
|
|
495
830
|
if (!existsSync4(path50)) return void 0;
|
|
496
831
|
try {
|
|
497
|
-
return JSON.parse(
|
|
832
|
+
return JSON.parse(readFileSync4(path50, "utf-8"));
|
|
498
833
|
} catch {
|
|
499
834
|
return void 0;
|
|
500
835
|
}
|
|
@@ -862,11 +1197,11 @@ function printComments(item) {
|
|
|
862
1197
|
|
|
863
1198
|
// src/shared/web.ts
|
|
864
1199
|
import { exec } from "child_process";
|
|
865
|
-
import { readFileSync as
|
|
1200
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
866
1201
|
import {
|
|
867
1202
|
createServer
|
|
868
1203
|
} from "http";
|
|
869
|
-
import { dirname, join as
|
|
1204
|
+
import { dirname, join as join6 } from "path";
|
|
870
1205
|
import { fileURLToPath } from "url";
|
|
871
1206
|
import chalk14 from "chalk";
|
|
872
1207
|
function respondJson(res, status2, data) {
|
|
@@ -878,7 +1213,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
|
|
|
878
1213
|
let cache;
|
|
879
1214
|
return (_req, res) => {
|
|
880
1215
|
if (!cache) {
|
|
881
|
-
cache =
|
|
1216
|
+
cache = readFileSync5(join6(dir, bundlePath), "utf-8");
|
|
882
1217
|
}
|
|
883
1218
|
res.writeHead(200, { "Content-Type": "application/javascript" });
|
|
884
1219
|
res.end(cache);
|
|
@@ -991,7 +1326,7 @@ async function createItem(req, res) {
|
|
|
991
1326
|
saveBacklog(items);
|
|
992
1327
|
respondJson(res, 201, newItem);
|
|
993
1328
|
}
|
|
994
|
-
function
|
|
1329
|
+
function deleteItem2(res, id) {
|
|
995
1330
|
const result = findItemOr404(res, id);
|
|
996
1331
|
if (!result) return;
|
|
997
1332
|
saveBacklog(result.items.filter((i) => i.id !== id));
|
|
@@ -1033,7 +1368,7 @@ var itemRoutes = {
|
|
|
1033
1368
|
GET: (_req, res, id) => getItemById(res, id),
|
|
1034
1369
|
PUT: (req, res, id) => updateItem(req, res, id),
|
|
1035
1370
|
PATCH: (req, res, id) => patchItemStatus(req, res, id),
|
|
1036
|
-
DELETE: (_req, res, id) =>
|
|
1371
|
+
DELETE: (_req, res, id) => deleteItem2(res, id)
|
|
1037
1372
|
};
|
|
1038
1373
|
var baseHandler = createRouteHandler(routes);
|
|
1039
1374
|
async function handleRequest(req, res, port) {
|
|
@@ -1080,19 +1415,19 @@ async function launchMode(slashCommand) {
|
|
|
1080
1415
|
import { execSync } from "child_process";
|
|
1081
1416
|
|
|
1082
1417
|
// src/shared/loadConfig.ts
|
|
1083
|
-
import { existsSync as existsSync7, readFileSync as
|
|
1418
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
1084
1419
|
import { homedir } from "os";
|
|
1085
|
-
import { basename, dirname as dirname2, join as
|
|
1420
|
+
import { basename, dirname as dirname2, join as join7 } from "path";
|
|
1086
1421
|
import chalk16 from "chalk";
|
|
1087
|
-
import { stringify as
|
|
1422
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
1088
1423
|
|
|
1089
1424
|
// src/shared/loadRawYaml.ts
|
|
1090
|
-
import { existsSync as existsSync6, readFileSync as
|
|
1425
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
1091
1426
|
import { parse as parseYaml2 } from "yaml";
|
|
1092
1427
|
function loadRawYaml(path50) {
|
|
1093
1428
|
if (!existsSync6(path50)) return {};
|
|
1094
1429
|
try {
|
|
1095
|
-
const content =
|
|
1430
|
+
const content = readFileSync6(path50, "utf-8");
|
|
1096
1431
|
return parseYaml2(content) || {};
|
|
1097
1432
|
} catch {
|
|
1098
1433
|
return {};
|
|
@@ -1222,9 +1557,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1222
1557
|
function findConfigUp(startDir) {
|
|
1223
1558
|
let current = startDir;
|
|
1224
1559
|
while (current !== dirname2(current)) {
|
|
1225
|
-
const claudePath =
|
|
1560
|
+
const claudePath = join7(current, ".claude", "assist.yml");
|
|
1226
1561
|
if (existsSync7(claudePath)) return claudePath;
|
|
1227
|
-
const rootPath =
|
|
1562
|
+
const rootPath = join7(current, "assist.yml");
|
|
1228
1563
|
if (existsSync7(rootPath)) return rootPath;
|
|
1229
1564
|
current = dirname2(current);
|
|
1230
1565
|
}
|
|
@@ -1233,10 +1568,10 @@ function findConfigUp(startDir) {
|
|
|
1233
1568
|
function getConfigPath() {
|
|
1234
1569
|
const found = findConfigUp(process.cwd());
|
|
1235
1570
|
if (found) return found;
|
|
1236
|
-
return
|
|
1571
|
+
return join7(process.cwd(), "assist.yml");
|
|
1237
1572
|
}
|
|
1238
1573
|
function getGlobalConfigPath() {
|
|
1239
|
-
return
|
|
1574
|
+
return join7(homedir(), ".assist.yml");
|
|
1240
1575
|
}
|
|
1241
1576
|
function loadConfig() {
|
|
1242
1577
|
const globalRaw = loadRawYaml(getGlobalConfigPath());
|
|
@@ -1251,21 +1586,21 @@ function loadGlobalConfigRaw() {
|
|
|
1251
1586
|
return loadRawYaml(getGlobalConfigPath());
|
|
1252
1587
|
}
|
|
1253
1588
|
function saveGlobalConfig(config) {
|
|
1254
|
-
writeFileSync4(getGlobalConfigPath(),
|
|
1589
|
+
writeFileSync4(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
|
|
1255
1590
|
}
|
|
1256
1591
|
function saveConfig(config) {
|
|
1257
1592
|
const configPath = getConfigPath();
|
|
1258
|
-
writeFileSync4(configPath,
|
|
1593
|
+
writeFileSync4(configPath, stringifyYaml(config, { lineWidth: 0 }));
|
|
1259
1594
|
}
|
|
1260
1595
|
function getRepoName() {
|
|
1261
1596
|
const config = loadConfig();
|
|
1262
1597
|
if (config.devlog?.name) {
|
|
1263
1598
|
return config.devlog.name;
|
|
1264
1599
|
}
|
|
1265
|
-
const packageJsonPath =
|
|
1600
|
+
const packageJsonPath = join7(process.cwd(), "package.json");
|
|
1266
1601
|
if (existsSync7(packageJsonPath)) {
|
|
1267
1602
|
try {
|
|
1268
|
-
const content =
|
|
1603
|
+
const content = readFileSync7(packageJsonPath, "utf-8");
|
|
1269
1604
|
const pkg = JSON.parse(content);
|
|
1270
1605
|
if (pkg.name) {
|
|
1271
1606
|
return pkg.name;
|
|
@@ -1369,7 +1704,7 @@ function commit(args) {
|
|
|
1369
1704
|
|
|
1370
1705
|
// src/commands/config/index.ts
|
|
1371
1706
|
import chalk17 from "chalk";
|
|
1372
|
-
import { stringify as
|
|
1707
|
+
import { stringify as stringifyYaml2 } from "yaml";
|
|
1373
1708
|
|
|
1374
1709
|
// src/commands/config/setNestedValue.ts
|
|
1375
1710
|
function isPlainObject(val) {
|
|
@@ -1476,7 +1811,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
1476
1811
|
}
|
|
1477
1812
|
function configList() {
|
|
1478
1813
|
const config = loadConfig();
|
|
1479
|
-
console.log(
|
|
1814
|
+
console.log(stringifyYaml2(config, { lineWidth: 0 }).trimEnd());
|
|
1480
1815
|
}
|
|
1481
1816
|
|
|
1482
1817
|
// src/commands/config/configGet.ts
|
|
@@ -1714,17 +2049,17 @@ import * as path3 from "path";
|
|
|
1714
2049
|
import chalk25 from "chalk";
|
|
1715
2050
|
|
|
1716
2051
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1717
|
-
import { existsSync as existsSync9, readFileSync as
|
|
1718
|
-
import { join as
|
|
2052
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
2053
|
+
import { join as join9 } from "path";
|
|
1719
2054
|
import chalk24 from "chalk";
|
|
1720
2055
|
function loadKnipConfig(knipJsonPath) {
|
|
1721
2056
|
if (existsSync9(knipJsonPath)) {
|
|
1722
|
-
return JSON.parse(
|
|
2057
|
+
return JSON.parse(readFileSync9(knipJsonPath, "utf-8"));
|
|
1723
2058
|
}
|
|
1724
2059
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
1725
2060
|
}
|
|
1726
2061
|
function addToKnipIgnoreBinaries(cwd, binary) {
|
|
1727
|
-
const knipJsonPath =
|
|
2062
|
+
const knipJsonPath = join9(cwd, "knip.json");
|
|
1728
2063
|
try {
|
|
1729
2064
|
const knipConfig = loadKnipConfig(knipJsonPath);
|
|
1730
2065
|
const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
|
|
@@ -1772,8 +2107,8 @@ import chalk29 from "chalk";
|
|
|
1772
2107
|
|
|
1773
2108
|
// src/commands/lint/init.ts
|
|
1774
2109
|
import { execSync as execSync5 } from "child_process";
|
|
1775
|
-
import { existsSync as existsSync12, readFileSync as
|
|
1776
|
-
import { dirname as dirname7, join as
|
|
2110
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
2111
|
+
import { dirname as dirname7, join as join10 } from "path";
|
|
1777
2112
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1778
2113
|
import chalk28 from "chalk";
|
|
1779
2114
|
|
|
@@ -1798,7 +2133,7 @@ async function promptConfirm(message, initial = true) {
|
|
|
1798
2133
|
|
|
1799
2134
|
// src/shared/removeEslint/index.ts
|
|
1800
2135
|
import { execSync as execSync4 } from "child_process";
|
|
1801
|
-
import { existsSync as existsSync11, readFileSync as
|
|
2136
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
|
|
1802
2137
|
|
|
1803
2138
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
1804
2139
|
import { existsSync as existsSync10, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -1842,7 +2177,7 @@ function removeEslintFromPackageJson(options2) {
|
|
|
1842
2177
|
if (!existsSync11(packageJsonPath)) {
|
|
1843
2178
|
return false;
|
|
1844
2179
|
}
|
|
1845
|
-
const packageJson = JSON.parse(
|
|
2180
|
+
const packageJson = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
1846
2181
|
let modified = false;
|
|
1847
2182
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
1848
2183
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -1920,9 +2255,9 @@ async function init() {
|
|
|
1920
2255
|
console.log("No biome.json found, skipping linter config");
|
|
1921
2256
|
return;
|
|
1922
2257
|
}
|
|
1923
|
-
const linterConfigPath =
|
|
1924
|
-
const linterConfig = JSON.parse(
|
|
1925
|
-
const biomeConfig = JSON.parse(
|
|
2258
|
+
const linterConfigPath = join10(__dirname2, "commands/lint/biome.linter.json");
|
|
2259
|
+
const linterConfig = JSON.parse(readFileSync11(linterConfigPath, "utf-8"));
|
|
2260
|
+
const biomeConfig = JSON.parse(readFileSync11(biomeConfigPath, "utf-8"));
|
|
1926
2261
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
1927
2262
|
`;
|
|
1928
2263
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -2980,7 +3315,7 @@ function initPackageJson(name) {
|
|
|
2980
3315
|
}
|
|
2981
3316
|
|
|
2982
3317
|
// src/commands/new/registerNew/newCli/writeCliTemplate.ts
|
|
2983
|
-
import { mkdirSync as
|
|
3318
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync11 } from "fs";
|
|
2984
3319
|
function writeCliTemplate(name) {
|
|
2985
3320
|
console.log("Writing tsconfig.json...");
|
|
2986
3321
|
writeFileSync11(
|
|
@@ -3021,7 +3356,7 @@ export default defineConfig({
|
|
|
3021
3356
|
`
|
|
3022
3357
|
);
|
|
3023
3358
|
console.log("Writing src/index.ts...");
|
|
3024
|
-
|
|
3359
|
+
mkdirSync3("src", { recursive: true });
|
|
3025
3360
|
writeFileSync11(
|
|
3026
3361
|
"src/index.ts",
|
|
3027
3362
|
`#!/usr/bin/env node
|
|
@@ -3050,7 +3385,7 @@ async function newCli() {
|
|
|
3050
3385
|
|
|
3051
3386
|
// src/commands/new/registerNew/newProject.ts
|
|
3052
3387
|
import { execSync as execSync13 } from "child_process";
|
|
3053
|
-
import { existsSync as existsSync16, readFileSync as
|
|
3388
|
+
import { existsSync as existsSync16, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
3054
3389
|
|
|
3055
3390
|
// src/commands/deploy/init/index.ts
|
|
3056
3391
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -3058,8 +3393,8 @@ import chalk40 from "chalk";
|
|
|
3058
3393
|
import enquirer5 from "enquirer";
|
|
3059
3394
|
|
|
3060
3395
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3061
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
3062
|
-
import { dirname as dirname13, join as
|
|
3396
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
3397
|
+
import { dirname as dirname13, join as join13 } from "path";
|
|
3063
3398
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3064
3399
|
import chalk39 from "chalk";
|
|
3065
3400
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
@@ -3068,23 +3403,23 @@ function getExistingSiteId() {
|
|
|
3068
3403
|
if (!existsSync15(WORKFLOW_PATH)) {
|
|
3069
3404
|
return null;
|
|
3070
3405
|
}
|
|
3071
|
-
const content =
|
|
3406
|
+
const content = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3072
3407
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
3073
3408
|
return match ? match[1] : null;
|
|
3074
3409
|
}
|
|
3075
3410
|
function getTemplateContent(siteId) {
|
|
3076
|
-
const templatePath =
|
|
3077
|
-
const template =
|
|
3411
|
+
const templatePath = join13(__dirname3, "commands/deploy/build.yml");
|
|
3412
|
+
const template = readFileSync13(templatePath, "utf-8");
|
|
3078
3413
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
3079
3414
|
}
|
|
3080
3415
|
async function updateWorkflow(siteId) {
|
|
3081
3416
|
const newContent = getTemplateContent(siteId);
|
|
3082
3417
|
const workflowDir = ".github/workflows";
|
|
3083
3418
|
if (!existsSync15(workflowDir)) {
|
|
3084
|
-
|
|
3419
|
+
mkdirSync4(workflowDir, { recursive: true });
|
|
3085
3420
|
}
|
|
3086
3421
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3087
|
-
const oldContent =
|
|
3422
|
+
const oldContent = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3088
3423
|
if (oldContent === newContent) {
|
|
3089
3424
|
console.log(chalk39.green("build.yml is already up to date"));
|
|
3090
3425
|
return;
|
|
@@ -3182,7 +3517,7 @@ function addViteBaseConfig() {
|
|
|
3182
3517
|
console.log("No vite.config.ts found, skipping base config");
|
|
3183
3518
|
return;
|
|
3184
3519
|
}
|
|
3185
|
-
const content =
|
|
3520
|
+
const content = readFileSync14(viteConfigPath, "utf-8");
|
|
3186
3521
|
if (content.includes("base:")) {
|
|
3187
3522
|
console.log("vite.config.ts already has base config");
|
|
3188
3523
|
return;
|
|
@@ -3365,12 +3700,13 @@ import chalk45 from "chalk";
|
|
|
3365
3700
|
|
|
3366
3701
|
// src/commands/backlog/commitBacklog.ts
|
|
3367
3702
|
import { execSync as execSync14 } from "child_process";
|
|
3703
|
+
import { join as join14 } from "path";
|
|
3368
3704
|
import chalk43 from "chalk";
|
|
3369
3705
|
function commitBacklog(id, name) {
|
|
3370
3706
|
try {
|
|
3371
|
-
const
|
|
3707
|
+
const jsonlPath = join14(getBacklogDir(), ".assist", "backlog.jsonl");
|
|
3372
3708
|
const message = `chore: add backlog item #${id} \u2014 ${name}`;
|
|
3373
|
-
execSync14(`git add ${shellQuote(
|
|
3709
|
+
execSync14(`git add ${shellQuote(jsonlPath)}`, { stdio: "ignore" });
|
|
3374
3710
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3375
3711
|
} catch {
|
|
3376
3712
|
console.log(chalk43.yellow("Warning: could not auto-commit backlog file."));
|
|
@@ -3378,7 +3714,7 @@ function commitBacklog(id, name) {
|
|
|
3378
3714
|
}
|
|
3379
3715
|
|
|
3380
3716
|
// src/commands/backlog/add/parseItemFile.ts
|
|
3381
|
-
import { existsSync as existsSync17, readFileSync as
|
|
3717
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
3382
3718
|
import chalk44 from "chalk";
|
|
3383
3719
|
import { ZodError } from "zod";
|
|
3384
3720
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
@@ -3390,7 +3726,7 @@ function readJsonFile(filePath) {
|
|
|
3390
3726
|
}
|
|
3391
3727
|
let raw;
|
|
3392
3728
|
try {
|
|
3393
|
-
raw =
|
|
3729
|
+
raw = readFileSync15(filePath, "utf-8");
|
|
3394
3730
|
} catch {
|
|
3395
3731
|
console.log(chalk44.red(`Failed to read file: ${filePath}`));
|
|
3396
3732
|
process.exitCode = 1;
|
|
@@ -3428,9 +3764,9 @@ function parseItemFile(filePath) {
|
|
|
3428
3764
|
|
|
3429
3765
|
// src/commands/backlog/add/shared.ts
|
|
3430
3766
|
import { spawnSync } from "child_process";
|
|
3431
|
-
import { mkdtempSync, readFileSync as
|
|
3767
|
+
import { mkdtempSync, readFileSync as readFileSync16, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
|
|
3432
3768
|
import { tmpdir } from "os";
|
|
3433
|
-
import { join as
|
|
3769
|
+
import { join as join15 } from "path";
|
|
3434
3770
|
import enquirer6 from "enquirer";
|
|
3435
3771
|
async function promptType() {
|
|
3436
3772
|
const { type } = await enquirer6.prompt({
|
|
@@ -3470,15 +3806,15 @@ async function promptDescription() {
|
|
|
3470
3806
|
}
|
|
3471
3807
|
function openEditor() {
|
|
3472
3808
|
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
3473
|
-
const dir = mkdtempSync(
|
|
3474
|
-
const filePath =
|
|
3809
|
+
const dir = mkdtempSync(join15(tmpdir(), "assist-"));
|
|
3810
|
+
const filePath = join15(dir, "description.md");
|
|
3475
3811
|
writeFileSync14(filePath, "");
|
|
3476
3812
|
const result = spawnSync(editor, [filePath], { stdio: "inherit" });
|
|
3477
3813
|
if (result.status !== 0) {
|
|
3478
3814
|
unlinkSync4(filePath);
|
|
3479
3815
|
return void 0;
|
|
3480
3816
|
}
|
|
3481
|
-
const content =
|
|
3817
|
+
const content = readFileSync16(filePath, "utf-8").trim();
|
|
3482
3818
|
unlinkSync4(filePath);
|
|
3483
3819
|
return content || void 0;
|
|
3484
3820
|
}
|
|
@@ -3870,7 +4206,7 @@ function extractGraphqlQuery(args) {
|
|
|
3870
4206
|
}
|
|
3871
4207
|
|
|
3872
4208
|
// src/shared/loadCliReads.ts
|
|
3873
|
-
import { existsSync as existsSync21, readFileSync as
|
|
4209
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
3874
4210
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
3875
4211
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3876
4212
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -3880,7 +4216,7 @@ function packageRoot() {
|
|
|
3880
4216
|
}
|
|
3881
4217
|
function readLines(path50) {
|
|
3882
4218
|
if (!existsSync21(path50)) return [];
|
|
3883
|
-
return
|
|
4219
|
+
return readFileSync17(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3884
4220
|
}
|
|
3885
4221
|
var cachedReads;
|
|
3886
4222
|
var cachedWrites;
|
|
@@ -3926,14 +4262,14 @@ function findCliWrite(command) {
|
|
|
3926
4262
|
}
|
|
3927
4263
|
|
|
3928
4264
|
// src/shared/readSettingsPerms.ts
|
|
3929
|
-
import { existsSync as existsSync22, readFileSync as
|
|
4265
|
+
import { existsSync as existsSync22, readFileSync as readFileSync18 } from "fs";
|
|
3930
4266
|
import { homedir as homedir3 } from "os";
|
|
3931
|
-
import { join as
|
|
4267
|
+
import { join as join16 } from "path";
|
|
3932
4268
|
function readSettingsPerms(key) {
|
|
3933
4269
|
const paths = [
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
4270
|
+
join16(homedir3(), ".claude", "settings.json"),
|
|
4271
|
+
join16(process.cwd(), ".claude", "settings.json"),
|
|
4272
|
+
join16(process.cwd(), ".claude", "settings.local.json")
|
|
3937
4273
|
];
|
|
3938
4274
|
const entries = [];
|
|
3939
4275
|
for (const p of paths) {
|
|
@@ -3944,7 +4280,7 @@ function readSettingsPerms(key) {
|
|
|
3944
4280
|
function readPermissionArray(filePath, key) {
|
|
3945
4281
|
if (!existsSync22(filePath)) return [];
|
|
3946
4282
|
try {
|
|
3947
|
-
const data = JSON.parse(
|
|
4283
|
+
const data = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
3948
4284
|
const arr = data?.permissions?.[key];
|
|
3949
4285
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
3950
4286
|
} catch {
|
|
@@ -4229,9 +4565,9 @@ function denyRemove(pattern2) {
|
|
|
4229
4565
|
}
|
|
4230
4566
|
|
|
4231
4567
|
// src/commands/permitCliReads/index.ts
|
|
4232
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
4568
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
|
|
4233
4569
|
import { homedir as homedir4 } from "os";
|
|
4234
|
-
import { join as
|
|
4570
|
+
import { join as join17 } from "path";
|
|
4235
4571
|
|
|
4236
4572
|
// src/shared/getInstallDir.ts
|
|
4237
4573
|
import { execSync as execSync15 } from "child_process";
|
|
@@ -4533,16 +4869,16 @@ function updateSettings(cli, commands) {
|
|
|
4533
4869
|
// src/commands/permitCliReads/index.ts
|
|
4534
4870
|
function logPath(cli) {
|
|
4535
4871
|
const safeName = cli.replace(/\s+/g, "-");
|
|
4536
|
-
return
|
|
4872
|
+
return join17(homedir4(), ".assist", `cli-discover-${safeName}.log`);
|
|
4537
4873
|
}
|
|
4538
4874
|
function readCache(cli) {
|
|
4539
4875
|
const path50 = logPath(cli);
|
|
4540
4876
|
if (!existsSync23(path50)) return void 0;
|
|
4541
|
-
return
|
|
4877
|
+
return readFileSync19(path50, "utf-8");
|
|
4542
4878
|
}
|
|
4543
4879
|
function writeCache(cli, output) {
|
|
4544
|
-
const dir =
|
|
4545
|
-
|
|
4880
|
+
const dir = join17(homedir4(), ".assist");
|
|
4881
|
+
mkdirSync5(dir, { recursive: true });
|
|
4546
4882
|
writeFileSync16(logPath(cli), output);
|
|
4547
4883
|
}
|
|
4548
4884
|
async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
@@ -5090,7 +5426,7 @@ function registerComplexity(program2) {
|
|
|
5090
5426
|
}
|
|
5091
5427
|
|
|
5092
5428
|
// src/commands/deploy/redirect.ts
|
|
5093
|
-
import { existsSync as existsSync24, readFileSync as
|
|
5429
|
+
import { existsSync as existsSync24, readFileSync as readFileSync20, writeFileSync as writeFileSync17 } from "fs";
|
|
5094
5430
|
import chalk64 from "chalk";
|
|
5095
5431
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5096
5432
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -5103,7 +5439,7 @@ function redirect() {
|
|
|
5103
5439
|
console.log(chalk64.yellow("No index.html found"));
|
|
5104
5440
|
return;
|
|
5105
5441
|
}
|
|
5106
|
-
const content =
|
|
5442
|
+
const content = readFileSync20(indexPath, "utf-8");
|
|
5107
5443
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5108
5444
|
console.log(chalk64.dim("Trailing slash script already present"));
|
|
5109
5445
|
return;
|
|
@@ -5131,10 +5467,10 @@ import { basename as basename3 } from "path";
|
|
|
5131
5467
|
|
|
5132
5468
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
5133
5469
|
import { homedir as homedir5 } from "os";
|
|
5134
|
-
import { join as
|
|
5135
|
-
var BLOG_REPO_ROOT =
|
|
5470
|
+
import { join as join18 } from "path";
|
|
5471
|
+
var BLOG_REPO_ROOT = join18(homedir5(), "git/blog");
|
|
5136
5472
|
function loadBlogSkipDays(repoName) {
|
|
5137
|
-
const config = loadRawYaml(
|
|
5473
|
+
const config = loadRawYaml(join18(BLOG_REPO_ROOT, "assist.yml"));
|
|
5138
5474
|
const devlog = config.devlog;
|
|
5139
5475
|
const skip2 = devlog?.skip;
|
|
5140
5476
|
return new Set(skip2?.[repoName] ?? []);
|
|
@@ -5145,9 +5481,9 @@ import { execSync as execSync17 } from "child_process";
|
|
|
5145
5481
|
import chalk65 from "chalk";
|
|
5146
5482
|
|
|
5147
5483
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
5148
|
-
import { readdirSync, readFileSync as
|
|
5149
|
-
import { join as
|
|
5150
|
-
var DEVLOG_DIR =
|
|
5484
|
+
import { readdirSync, readFileSync as readFileSync21 } from "fs";
|
|
5485
|
+
import { join as join19 } from "path";
|
|
5486
|
+
var DEVLOG_DIR = join19(BLOG_REPO_ROOT, "src/content/devlog");
|
|
5151
5487
|
function extractFrontmatter(content) {
|
|
5152
5488
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5153
5489
|
return fm?.[1] ?? null;
|
|
@@ -5175,7 +5511,7 @@ function readDevlogFiles(callback) {
|
|
|
5175
5511
|
try {
|
|
5176
5512
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
5177
5513
|
for (const file of files) {
|
|
5178
|
-
const content =
|
|
5514
|
+
const content = readFileSync21(join19(DEVLOG_DIR, file), "utf-8");
|
|
5179
5515
|
const parsed = parseFrontmatter(content, file);
|
|
5180
5516
|
if (parsed) callback(parsed);
|
|
5181
5517
|
}
|
|
@@ -5354,7 +5690,8 @@ function getLastVersionInfo(repoName, config) {
|
|
|
5354
5690
|
const gitInfo = getLastVersionInfoFromGit();
|
|
5355
5691
|
if (gitInfo) return { date: lastDate, version: gitInfo.version };
|
|
5356
5692
|
}
|
|
5357
|
-
const
|
|
5693
|
+
const dayEntries = entries.get(lastDate);
|
|
5694
|
+
const lastVersion = dayEntries?.[dayEntries.length - 1]?.version;
|
|
5358
5695
|
return lastVersion ? { date: lastDate, version: lastVersion } : null;
|
|
5359
5696
|
}
|
|
5360
5697
|
function cleanVersion(version2) {
|
|
@@ -5561,11 +5898,11 @@ function repos(options2) {
|
|
|
5561
5898
|
|
|
5562
5899
|
// src/commands/devlog/skip.ts
|
|
5563
5900
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5564
|
-
import { join as
|
|
5901
|
+
import { join as join20 } from "path";
|
|
5565
5902
|
import chalk70 from "chalk";
|
|
5566
|
-
import { stringify as
|
|
5903
|
+
import { stringify as stringifyYaml3 } from "yaml";
|
|
5567
5904
|
function getBlogConfigPath() {
|
|
5568
|
-
return
|
|
5905
|
+
return join20(BLOG_REPO_ROOT, "assist.yml");
|
|
5569
5906
|
}
|
|
5570
5907
|
function skip(date) {
|
|
5571
5908
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -5589,7 +5926,7 @@ function skip(date) {
|
|
|
5589
5926
|
skip2[repoName] = skipDays;
|
|
5590
5927
|
devlog.skip = skip2;
|
|
5591
5928
|
config.devlog = devlog;
|
|
5592
|
-
writeFileSync18(configPath,
|
|
5929
|
+
writeFileSync18(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
5593
5930
|
console.log(chalk70.green(`Added ${date} to skip list for ${repoName}`));
|
|
5594
5931
|
}
|
|
5595
5932
|
|
|
@@ -5626,7 +5963,7 @@ function registerDevlog(program2) {
|
|
|
5626
5963
|
|
|
5627
5964
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5628
5965
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5629
|
-
import { join as
|
|
5966
|
+
import { join as join21 } from "path";
|
|
5630
5967
|
import chalk72 from "chalk";
|
|
5631
5968
|
|
|
5632
5969
|
// src/shared/findRepoRoot.ts
|
|
@@ -5654,7 +5991,7 @@ function isLockedDll(debugDir) {
|
|
|
5654
5991
|
}
|
|
5655
5992
|
for (const file of files) {
|
|
5656
5993
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
5657
|
-
const dllPath =
|
|
5994
|
+
const dllPath = join21(debugDir, file);
|
|
5658
5995
|
try {
|
|
5659
5996
|
const fd = openSync(dllPath, "r+");
|
|
5660
5997
|
closeSync(fd);
|
|
@@ -5672,13 +6009,13 @@ function findFirstLockedDll(dir) {
|
|
|
5672
6009
|
return null;
|
|
5673
6010
|
}
|
|
5674
6011
|
if (entries.includes("bin")) {
|
|
5675
|
-
const locked = isLockedDll(
|
|
6012
|
+
const locked = isLockedDll(join21(dir, "bin", "Debug"));
|
|
5676
6013
|
if (locked) return locked;
|
|
5677
6014
|
}
|
|
5678
6015
|
for (const entry of entries) {
|
|
5679
6016
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
5680
6017
|
continue;
|
|
5681
|
-
const found = findFirstLockedDll(
|
|
6018
|
+
const found = findFirstLockedDll(join21(dir, entry));
|
|
5682
6019
|
if (found) return found;
|
|
5683
6020
|
}
|
|
5684
6021
|
return null;
|
|
@@ -5701,11 +6038,11 @@ async function checkBuildLocksCommand() {
|
|
|
5701
6038
|
}
|
|
5702
6039
|
|
|
5703
6040
|
// src/commands/dotnet/buildTree.ts
|
|
5704
|
-
import { readFileSync as
|
|
6041
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
5705
6042
|
import path22 from "path";
|
|
5706
6043
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
5707
6044
|
function getProjectRefs(csprojPath) {
|
|
5708
|
-
const content =
|
|
6045
|
+
const content = readFileSync22(csprojPath, "utf-8");
|
|
5709
6046
|
const refs = [];
|
|
5710
6047
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
5711
6048
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -5722,7 +6059,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
5722
6059
|
for (const ref of getProjectRefs(abs)) {
|
|
5723
6060
|
const childAbs = path22.resolve(dir, ref);
|
|
5724
6061
|
try {
|
|
5725
|
-
|
|
6062
|
+
readFileSync22(childAbs);
|
|
5726
6063
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
5727
6064
|
} catch {
|
|
5728
6065
|
node.children.push({
|
|
@@ -5747,7 +6084,7 @@ function collectAllDeps(node) {
|
|
|
5747
6084
|
}
|
|
5748
6085
|
|
|
5749
6086
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
5750
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
6087
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync23, statSync as statSync3 } from "fs";
|
|
5751
6088
|
import path23 from "path";
|
|
5752
6089
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
5753
6090
|
if (depth > maxDepth) return [];
|
|
@@ -5763,7 +6100,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
|
5763
6100
|
continue;
|
|
5764
6101
|
const full = path23.join(dir, entry);
|
|
5765
6102
|
try {
|
|
5766
|
-
const stat =
|
|
6103
|
+
const stat = statSync3(full);
|
|
5767
6104
|
if (stat.isFile() && entry.endsWith(".sln")) {
|
|
5768
6105
|
results.push(full);
|
|
5769
6106
|
} else if (stat.isDirectory()) {
|
|
@@ -5782,7 +6119,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
5782
6119
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
5783
6120
|
for (const sln of slnFiles) {
|
|
5784
6121
|
try {
|
|
5785
|
-
const content =
|
|
6122
|
+
const content = readFileSync23(sln, "utf-8");
|
|
5786
6123
|
if (pattern2.test(content)) {
|
|
5787
6124
|
matches.push(path23.relative(repoRoot, sln));
|
|
5788
6125
|
}
|
|
@@ -6025,11 +6362,11 @@ import chalk78 from "chalk";
|
|
|
6025
6362
|
|
|
6026
6363
|
// src/commands/dotnet/findSolution.ts
|
|
6027
6364
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6028
|
-
import { dirname as dirname16, join as
|
|
6365
|
+
import { dirname as dirname16, join as join22 } from "path";
|
|
6029
6366
|
import chalk77 from "chalk";
|
|
6030
6367
|
function findSlnInDir(dir) {
|
|
6031
6368
|
try {
|
|
6032
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
6369
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join22(dir, f));
|
|
6033
6370
|
} catch {
|
|
6034
6371
|
return [];
|
|
6035
6372
|
}
|
|
@@ -6100,7 +6437,7 @@ function parseInspectReport(json) {
|
|
|
6100
6437
|
|
|
6101
6438
|
// src/commands/dotnet/runInspectCode.ts
|
|
6102
6439
|
import { execSync as execSync23 } from "child_process";
|
|
6103
|
-
import { existsSync as existsSync28, readFileSync as
|
|
6440
|
+
import { existsSync as existsSync28, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
6104
6441
|
import { tmpdir as tmpdir2 } from "os";
|
|
6105
6442
|
import path26 from "path";
|
|
6106
6443
|
import chalk79 from "chalk";
|
|
@@ -6135,7 +6472,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6135
6472
|
console.error(chalk79.red("Report file not generated"));
|
|
6136
6473
|
process.exit(1);
|
|
6137
6474
|
}
|
|
6138
|
-
const xml =
|
|
6475
|
+
const xml = readFileSync24(reportPath, "utf-8");
|
|
6139
6476
|
unlinkSync5(reportPath);
|
|
6140
6477
|
return xml;
|
|
6141
6478
|
}
|
|
@@ -6363,20 +6700,20 @@ function acceptanceCriteria(issueKey) {
|
|
|
6363
6700
|
import { execSync as execSync26 } from "child_process";
|
|
6364
6701
|
|
|
6365
6702
|
// src/shared/loadJson.ts
|
|
6366
|
-
import { existsSync as existsSync29, mkdirSync as
|
|
6703
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync19 } from "fs";
|
|
6367
6704
|
import { homedir as homedir6 } from "os";
|
|
6368
|
-
import { join as
|
|
6705
|
+
import { join as join23 } from "path";
|
|
6369
6706
|
function getStoreDir() {
|
|
6370
|
-
return
|
|
6707
|
+
return join23(homedir6(), ".assist");
|
|
6371
6708
|
}
|
|
6372
6709
|
function getStorePath(filename) {
|
|
6373
|
-
return
|
|
6710
|
+
return join23(getStoreDir(), filename);
|
|
6374
6711
|
}
|
|
6375
6712
|
function loadJson(filename) {
|
|
6376
6713
|
const path50 = getStorePath(filename);
|
|
6377
6714
|
if (existsSync29(path50)) {
|
|
6378
6715
|
try {
|
|
6379
|
-
return JSON.parse(
|
|
6716
|
+
return JSON.parse(readFileSync25(path50, "utf-8"));
|
|
6380
6717
|
} catch {
|
|
6381
6718
|
return {};
|
|
6382
6719
|
}
|
|
@@ -6386,7 +6723,7 @@ function loadJson(filename) {
|
|
|
6386
6723
|
function saveJson(filename, data) {
|
|
6387
6724
|
const dir = getStoreDir();
|
|
6388
6725
|
if (!existsSync29(dir)) {
|
|
6389
|
-
|
|
6726
|
+
mkdirSync6(dir, { recursive: true });
|
|
6390
6727
|
}
|
|
6391
6728
|
writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
6392
6729
|
}
|
|
@@ -6702,7 +7039,7 @@ function registerNews(program2) {
|
|
|
6702
7039
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
6703
7040
|
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync20 } from "fs";
|
|
6704
7041
|
import { tmpdir as tmpdir3 } from "os";
|
|
6705
|
-
import { join as
|
|
7042
|
+
import { join as join24 } from "path";
|
|
6706
7043
|
|
|
6707
7044
|
// src/commands/prs/shared.ts
|
|
6708
7045
|
import { execSync as execSync27 } from "child_process";
|
|
@@ -6774,7 +7111,7 @@ function comment2(path50, line, body) {
|
|
|
6774
7111
|
validateLine(line);
|
|
6775
7112
|
try {
|
|
6776
7113
|
const prId = getCurrentPrNodeId();
|
|
6777
|
-
const queryFile =
|
|
7114
|
+
const queryFile = join24(tmpdir3(), `gh-query-${Date.now()}.graphql`);
|
|
6778
7115
|
writeFileSync20(queryFile, MUTATION);
|
|
6779
7116
|
try {
|
|
6780
7117
|
const result = spawnSync2(
|
|
@@ -6819,21 +7156,21 @@ import { execSync as execSync29 } from "child_process";
|
|
|
6819
7156
|
import { execSync as execSync28 } from "child_process";
|
|
6820
7157
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
|
|
6821
7158
|
import { tmpdir as tmpdir4 } from "os";
|
|
6822
|
-
import { join as
|
|
7159
|
+
import { join as join26 } from "path";
|
|
6823
7160
|
|
|
6824
7161
|
// src/commands/prs/loadCommentsCache.ts
|
|
6825
|
-
import { existsSync as existsSync30, readFileSync as
|
|
6826
|
-
import { join as
|
|
7162
|
+
import { existsSync as existsSync30, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
|
|
7163
|
+
import { join as join25 } from "path";
|
|
6827
7164
|
import { parse as parse2 } from "yaml";
|
|
6828
7165
|
function getCachePath(prNumber) {
|
|
6829
|
-
return
|
|
7166
|
+
return join25(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
6830
7167
|
}
|
|
6831
7168
|
function loadCommentsCache(prNumber) {
|
|
6832
7169
|
const cachePath = getCachePath(prNumber);
|
|
6833
7170
|
if (!existsSync30(cachePath)) {
|
|
6834
7171
|
return null;
|
|
6835
7172
|
}
|
|
6836
|
-
const content =
|
|
7173
|
+
const content = readFileSync26(cachePath, "utf-8");
|
|
6837
7174
|
return parse2(content);
|
|
6838
7175
|
}
|
|
6839
7176
|
function deleteCommentsCache(prNumber) {
|
|
@@ -6853,7 +7190,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
6853
7190
|
}
|
|
6854
7191
|
function resolveThread(threadId) {
|
|
6855
7192
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
6856
|
-
const queryFile =
|
|
7193
|
+
const queryFile = join26(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
6857
7194
|
writeFileSync21(queryFile, mutation);
|
|
6858
7195
|
try {
|
|
6859
7196
|
execSync28(
|
|
@@ -6935,18 +7272,18 @@ function fixed(commentId, sha) {
|
|
|
6935
7272
|
}
|
|
6936
7273
|
|
|
6937
7274
|
// src/commands/prs/listComments/index.ts
|
|
6938
|
-
import { existsSync as existsSync31, mkdirSync as
|
|
6939
|
-
import { join as
|
|
7275
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync7, writeFileSync as writeFileSync23 } from "fs";
|
|
7276
|
+
import { join as join28 } from "path";
|
|
6940
7277
|
import { stringify } from "yaml";
|
|
6941
7278
|
|
|
6942
7279
|
// src/commands/prs/fetchThreadIds.ts
|
|
6943
7280
|
import { execSync as execSync30 } from "child_process";
|
|
6944
7281
|
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync22 } from "fs";
|
|
6945
7282
|
import { tmpdir as tmpdir5 } from "os";
|
|
6946
|
-
import { join as
|
|
7283
|
+
import { join as join27 } from "path";
|
|
6947
7284
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
6948
7285
|
function fetchThreadIds(org, repo, prNumber) {
|
|
6949
|
-
const queryFile =
|
|
7286
|
+
const queryFile = join27(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
6950
7287
|
writeFileSync22(queryFile, THREAD_QUERY);
|
|
6951
7288
|
try {
|
|
6952
7289
|
const result = execSync30(
|
|
@@ -7060,16 +7397,16 @@ function printComments2(result) {
|
|
|
7060
7397
|
|
|
7061
7398
|
// src/commands/prs/listComments/index.ts
|
|
7062
7399
|
function writeCommentsCache(prNumber, comments2) {
|
|
7063
|
-
const assistDir =
|
|
7400
|
+
const assistDir = join28(process.cwd(), ".assist");
|
|
7064
7401
|
if (!existsSync31(assistDir)) {
|
|
7065
|
-
|
|
7402
|
+
mkdirSync7(assistDir, { recursive: true });
|
|
7066
7403
|
}
|
|
7067
7404
|
const cacheData = {
|
|
7068
7405
|
prNumber,
|
|
7069
7406
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7070
7407
|
comments: comments2
|
|
7071
7408
|
};
|
|
7072
|
-
const cachePath =
|
|
7409
|
+
const cachePath = join28(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
7073
7410
|
writeFileSync23(cachePath, stringify(cacheData));
|
|
7074
7411
|
}
|
|
7075
7412
|
function handleKnownErrors(error) {
|
|
@@ -7102,7 +7439,7 @@ async function listComments() {
|
|
|
7102
7439
|
];
|
|
7103
7440
|
updateCache(prNumber, allComments);
|
|
7104
7441
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
7105
|
-
const cachePath = hasLineComments ?
|
|
7442
|
+
const cachePath = hasLineComments ? join28(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
7106
7443
|
return { comments: allComments, cachePath };
|
|
7107
7444
|
} catch (error) {
|
|
7108
7445
|
const handled = handleKnownErrors(error);
|
|
@@ -9496,8 +9833,8 @@ function registerSeq(program2) {
|
|
|
9496
9833
|
}
|
|
9497
9834
|
|
|
9498
9835
|
// src/commands/transcript/shared.ts
|
|
9499
|
-
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as
|
|
9500
|
-
import { basename as basename4, join as
|
|
9836
|
+
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
9837
|
+
import { basename as basename4, join as join29, relative } from "path";
|
|
9501
9838
|
import * as readline2 from "readline";
|
|
9502
9839
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
9503
9840
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -9515,8 +9852,8 @@ function collectFiles(dir, extension) {
|
|
|
9515
9852
|
if (!existsSync32(dir)) return [];
|
|
9516
9853
|
const results = [];
|
|
9517
9854
|
for (const entry of readdirSync5(dir)) {
|
|
9518
|
-
const fullPath =
|
|
9519
|
-
if (
|
|
9855
|
+
const fullPath = join29(dir, entry);
|
|
9856
|
+
if (statSync4(fullPath).isDirectory()) {
|
|
9520
9857
|
results.push(...collectFiles(fullPath, extension));
|
|
9521
9858
|
} else if (entry.endsWith(extension)) {
|
|
9522
9859
|
results.push(fullPath);
|
|
@@ -9612,11 +9949,11 @@ async function configure() {
|
|
|
9612
9949
|
import { existsSync as existsSync34 } from "fs";
|
|
9613
9950
|
|
|
9614
9951
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9615
|
-
import { dirname as dirname18, join as
|
|
9952
|
+
import { dirname as dirname18, join as join31 } from "path";
|
|
9616
9953
|
|
|
9617
9954
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
9618
|
-
import { renameSync } from "fs";
|
|
9619
|
-
import { join as
|
|
9955
|
+
import { renameSync as renameSync2 } from "fs";
|
|
9956
|
+
import { join as join30 } from "path";
|
|
9620
9957
|
async function resolveDate(rl, choice) {
|
|
9621
9958
|
if (choice === "1") return getDatePrefix(0);
|
|
9622
9959
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -9631,7 +9968,7 @@ async function resolveDate(rl, choice) {
|
|
|
9631
9968
|
}
|
|
9632
9969
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
9633
9970
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
9634
|
-
|
|
9971
|
+
renameSync2(join30(vttDir, vttFile), join30(vttDir, newFilename));
|
|
9635
9972
|
console.log(`Renamed to: ${newFilename}`);
|
|
9636
9973
|
return newFilename;
|
|
9637
9974
|
}
|
|
@@ -9665,12 +10002,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9665
10002
|
const vttFileDir = dirname18(vttFile.absolutePath);
|
|
9666
10003
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
9667
10004
|
if (newFilename) {
|
|
9668
|
-
const newRelativePath =
|
|
10005
|
+
const newRelativePath = join31(
|
|
9669
10006
|
dirname18(vttFile.relativePath),
|
|
9670
10007
|
newFilename
|
|
9671
10008
|
);
|
|
9672
10009
|
vttFiles[i] = {
|
|
9673
|
-
absolutePath:
|
|
10010
|
+
absolutePath: join31(vttFileDir, newFilename),
|
|
9674
10011
|
relativePath: newRelativePath,
|
|
9675
10012
|
filename: newFilename
|
|
9676
10013
|
};
|
|
@@ -9683,8 +10020,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9683
10020
|
}
|
|
9684
10021
|
|
|
9685
10022
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
9686
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
9687
|
-
import { basename as basename5, dirname as dirname19, join as
|
|
10023
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync24 } from "fs";
|
|
10024
|
+
import { basename as basename5, dirname as dirname19, join as join32 } from "path";
|
|
9688
10025
|
|
|
9689
10026
|
// src/commands/transcript/cleanText.ts
|
|
9690
10027
|
function cleanText(text) {
|
|
@@ -9894,22 +10231,22 @@ function toMdFilename(vttFilename) {
|
|
|
9894
10231
|
return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
9895
10232
|
}
|
|
9896
10233
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
9897
|
-
return relativeDir === "." ? transcriptsDir :
|
|
10234
|
+
return relativeDir === "." ? transcriptsDir : join32(transcriptsDir, relativeDir);
|
|
9898
10235
|
}
|
|
9899
10236
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
9900
10237
|
const mdFile = toMdFilename(vttFile.filename);
|
|
9901
10238
|
const relativeDir = dirname19(vttFile.relativePath);
|
|
9902
10239
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
9903
|
-
const outputPath =
|
|
10240
|
+
const outputPath = join32(outputDir, mdFile);
|
|
9904
10241
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
9905
10242
|
}
|
|
9906
10243
|
function logSkipped(relativeDir, mdFile) {
|
|
9907
|
-
console.log(`Skipping (already exists): ${
|
|
10244
|
+
console.log(`Skipping (already exists): ${join32(relativeDir, mdFile)}`);
|
|
9908
10245
|
return "skipped";
|
|
9909
10246
|
}
|
|
9910
10247
|
function ensureDirectory(dir, label2) {
|
|
9911
10248
|
if (!existsSync33(dir)) {
|
|
9912
|
-
|
|
10249
|
+
mkdirSync8(dir, { recursive: true });
|
|
9913
10250
|
console.log(`Created ${label2}: ${dir}`);
|
|
9914
10251
|
}
|
|
9915
10252
|
}
|
|
@@ -9931,7 +10268,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
9931
10268
|
}
|
|
9932
10269
|
function readAndParseCues(inputPath) {
|
|
9933
10270
|
console.log(`Reading: ${inputPath}`);
|
|
9934
|
-
return processCues(
|
|
10271
|
+
return processCues(readFileSync27(inputPath, "utf-8"));
|
|
9935
10272
|
}
|
|
9936
10273
|
function writeFormatted(outputPath, content) {
|
|
9937
10274
|
writeFileSync24(outputPath, content, "utf-8");
|
|
@@ -10003,17 +10340,17 @@ async function format() {
|
|
|
10003
10340
|
|
|
10004
10341
|
// src/commands/transcript/summarise/index.ts
|
|
10005
10342
|
import { existsSync as existsSync36 } from "fs";
|
|
10006
|
-
import { basename as basename6, dirname as dirname21, join as
|
|
10343
|
+
import { basename as basename6, dirname as dirname21, join as join34, relative as relative2 } from "path";
|
|
10007
10344
|
|
|
10008
10345
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10009
10346
|
import {
|
|
10010
10347
|
existsSync as existsSync35,
|
|
10011
|
-
mkdirSync as
|
|
10012
|
-
readFileSync as
|
|
10013
|
-
renameSync as
|
|
10348
|
+
mkdirSync as mkdirSync9,
|
|
10349
|
+
readFileSync as readFileSync28,
|
|
10350
|
+
renameSync as renameSync3,
|
|
10014
10351
|
rmSync
|
|
10015
10352
|
} from "fs";
|
|
10016
|
-
import { dirname as dirname20, join as
|
|
10353
|
+
import { dirname as dirname20, join as join33 } from "path";
|
|
10017
10354
|
|
|
10018
10355
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10019
10356
|
import chalk118 from "chalk";
|
|
@@ -10042,7 +10379,7 @@ function validateStagedContent(filename, content) {
|
|
|
10042
10379
|
}
|
|
10043
10380
|
|
|
10044
10381
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10045
|
-
var STAGING_DIR =
|
|
10382
|
+
var STAGING_DIR = join33(process.cwd(), ".assist", "transcript");
|
|
10046
10383
|
function processStagedFile() {
|
|
10047
10384
|
if (!existsSync35(STAGING_DIR)) {
|
|
10048
10385
|
return false;
|
|
@@ -10053,7 +10390,7 @@ function processStagedFile() {
|
|
|
10053
10390
|
}
|
|
10054
10391
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10055
10392
|
const stagedFile = stagedFiles[0];
|
|
10056
|
-
const content =
|
|
10393
|
+
const content = readFileSync28(stagedFile.absolutePath, "utf-8");
|
|
10057
10394
|
validateStagedContent(stagedFile.filename, content);
|
|
10058
10395
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
10059
10396
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -10066,12 +10403,12 @@ function processStagedFile() {
|
|
|
10066
10403
|
);
|
|
10067
10404
|
process.exit(1);
|
|
10068
10405
|
}
|
|
10069
|
-
const destPath =
|
|
10406
|
+
const destPath = join33(summaryDir, matchingTranscript.relativePath);
|
|
10070
10407
|
const destDir = dirname20(destPath);
|
|
10071
10408
|
if (!existsSync35(destDir)) {
|
|
10072
|
-
|
|
10409
|
+
mkdirSync9(destDir, { recursive: true });
|
|
10073
10410
|
}
|
|
10074
|
-
|
|
10411
|
+
renameSync3(stagedFile.absolutePath, destPath);
|
|
10075
10412
|
const remaining = findMdFilesRecursive(STAGING_DIR);
|
|
10076
10413
|
if (remaining.length === 0) {
|
|
10077
10414
|
rmSync(STAGING_DIR, { recursive: true });
|
|
@@ -10082,7 +10419,7 @@ function processStagedFile() {
|
|
|
10082
10419
|
// src/commands/transcript/summarise/index.ts
|
|
10083
10420
|
function buildRelativeKey(relativePath, baseName) {
|
|
10084
10421
|
const relDir = dirname21(relativePath);
|
|
10085
|
-
return relDir === "." ? baseName :
|
|
10422
|
+
return relDir === "." ? baseName : join34(relDir, baseName);
|
|
10086
10423
|
}
|
|
10087
10424
|
function buildSummaryIndex(summaryDir) {
|
|
10088
10425
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -10116,8 +10453,8 @@ function summarise2() {
|
|
|
10116
10453
|
}
|
|
10117
10454
|
const next3 = missing[0];
|
|
10118
10455
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
10119
|
-
const outputPath =
|
|
10120
|
-
const summaryFileDir =
|
|
10456
|
+
const outputPath = join34(STAGING_DIR, outputFilename);
|
|
10457
|
+
const summaryFileDir = join34(summaryDir, dirname21(next3.relativePath));
|
|
10121
10458
|
const relativeTranscriptPath = encodeURI(
|
|
10122
10459
|
relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
10123
10460
|
);
|
|
@@ -10163,50 +10500,50 @@ function registerVerify(program2) {
|
|
|
10163
10500
|
|
|
10164
10501
|
// src/commands/voice/devices.ts
|
|
10165
10502
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10166
|
-
import { join as
|
|
10503
|
+
import { join as join36 } from "path";
|
|
10167
10504
|
|
|
10168
10505
|
// src/commands/voice/shared.ts
|
|
10169
10506
|
import { homedir as homedir7 } from "os";
|
|
10170
|
-
import { dirname as dirname22, join as
|
|
10507
|
+
import { dirname as dirname22, join as join35 } from "path";
|
|
10171
10508
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
10172
10509
|
var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
|
|
10173
|
-
var VOICE_DIR =
|
|
10510
|
+
var VOICE_DIR = join35(homedir7(), ".assist", "voice");
|
|
10174
10511
|
var voicePaths = {
|
|
10175
10512
|
dir: VOICE_DIR,
|
|
10176
|
-
pid:
|
|
10177
|
-
log:
|
|
10178
|
-
venv:
|
|
10179
|
-
lock:
|
|
10513
|
+
pid: join35(VOICE_DIR, "voice.pid"),
|
|
10514
|
+
log: join35(VOICE_DIR, "voice.log"),
|
|
10515
|
+
venv: join35(VOICE_DIR, ".venv"),
|
|
10516
|
+
lock: join35(VOICE_DIR, "voice.lock")
|
|
10180
10517
|
};
|
|
10181
10518
|
function getPythonDir() {
|
|
10182
|
-
return
|
|
10519
|
+
return join35(__dirname6, "commands", "voice", "python");
|
|
10183
10520
|
}
|
|
10184
10521
|
function getVenvPython() {
|
|
10185
|
-
return process.platform === "win32" ?
|
|
10522
|
+
return process.platform === "win32" ? join35(voicePaths.venv, "Scripts", "python.exe") : join35(voicePaths.venv, "bin", "python");
|
|
10186
10523
|
}
|
|
10187
10524
|
function getLockDir() {
|
|
10188
10525
|
const config = loadConfig();
|
|
10189
10526
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
10190
10527
|
}
|
|
10191
10528
|
function getLockFile() {
|
|
10192
|
-
return
|
|
10529
|
+
return join35(getLockDir(), "voice.lock");
|
|
10193
10530
|
}
|
|
10194
10531
|
|
|
10195
10532
|
// src/commands/voice/devices.ts
|
|
10196
10533
|
function devices() {
|
|
10197
|
-
const script =
|
|
10534
|
+
const script = join36(getPythonDir(), "list_devices.py");
|
|
10198
10535
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
10199
10536
|
}
|
|
10200
10537
|
|
|
10201
10538
|
// src/commands/voice/logs.ts
|
|
10202
|
-
import { existsSync as existsSync37, readFileSync as
|
|
10539
|
+
import { existsSync as existsSync37, readFileSync as readFileSync29 } from "fs";
|
|
10203
10540
|
function logs(options2) {
|
|
10204
10541
|
if (!existsSync37(voicePaths.log)) {
|
|
10205
10542
|
console.log("No voice log file found");
|
|
10206
10543
|
return;
|
|
10207
10544
|
}
|
|
10208
10545
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
10209
|
-
const content =
|
|
10546
|
+
const content = readFileSync29(voicePaths.log, "utf-8").trim();
|
|
10210
10547
|
if (!content) {
|
|
10211
10548
|
console.log("Voice log is empty");
|
|
10212
10549
|
return;
|
|
@@ -10228,13 +10565,13 @@ function logs(options2) {
|
|
|
10228
10565
|
|
|
10229
10566
|
// src/commands/voice/setup.ts
|
|
10230
10567
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
10231
|
-
import { mkdirSync as
|
|
10232
|
-
import { join as
|
|
10568
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
10569
|
+
import { join as join38 } from "path";
|
|
10233
10570
|
|
|
10234
10571
|
// src/commands/voice/checkLockFile.ts
|
|
10235
10572
|
import { execSync as execSync37 } from "child_process";
|
|
10236
|
-
import { existsSync as existsSync38, mkdirSync as
|
|
10237
|
-
import { join as
|
|
10573
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync25 } from "fs";
|
|
10574
|
+
import { join as join37 } from "path";
|
|
10238
10575
|
function isProcessAlive2(pid) {
|
|
10239
10576
|
try {
|
|
10240
10577
|
process.kill(pid, 0);
|
|
@@ -10247,7 +10584,7 @@ function checkLockFile() {
|
|
|
10247
10584
|
const lockFile = getLockFile();
|
|
10248
10585
|
if (!existsSync38(lockFile)) return;
|
|
10249
10586
|
try {
|
|
10250
|
-
const lock = JSON.parse(
|
|
10587
|
+
const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
|
|
10251
10588
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
10252
10589
|
console.error(
|
|
10253
10590
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -10271,7 +10608,7 @@ function bootstrapVenv() {
|
|
|
10271
10608
|
}
|
|
10272
10609
|
function writeLockFile(pid) {
|
|
10273
10610
|
const lockFile = getLockFile();
|
|
10274
|
-
|
|
10611
|
+
mkdirSync10(join37(lockFile, ".."), { recursive: true });
|
|
10275
10612
|
writeFileSync25(
|
|
10276
10613
|
lockFile,
|
|
10277
10614
|
JSON.stringify({
|
|
@@ -10284,10 +10621,10 @@ function writeLockFile(pid) {
|
|
|
10284
10621
|
|
|
10285
10622
|
// src/commands/voice/setup.ts
|
|
10286
10623
|
function setup() {
|
|
10287
|
-
|
|
10624
|
+
mkdirSync11(voicePaths.dir, { recursive: true });
|
|
10288
10625
|
bootstrapVenv();
|
|
10289
10626
|
console.log("\nDownloading models...\n");
|
|
10290
|
-
const script =
|
|
10627
|
+
const script = join38(getPythonDir(), "setup_models.py");
|
|
10291
10628
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
10292
10629
|
stdio: "inherit",
|
|
10293
10630
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -10300,8 +10637,8 @@ function setup() {
|
|
|
10300
10637
|
|
|
10301
10638
|
// src/commands/voice/start.ts
|
|
10302
10639
|
import { spawn as spawn5 } from "child_process";
|
|
10303
|
-
import { mkdirSync as
|
|
10304
|
-
import { join as
|
|
10640
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
10641
|
+
import { join as join39 } from "path";
|
|
10305
10642
|
|
|
10306
10643
|
// src/commands/voice/buildDaemonEnv.ts
|
|
10307
10644
|
function buildDaemonEnv(options2) {
|
|
@@ -10334,12 +10671,12 @@ function spawnBackground(python, script, env) {
|
|
|
10334
10671
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
10335
10672
|
}
|
|
10336
10673
|
function start2(options2) {
|
|
10337
|
-
|
|
10674
|
+
mkdirSync12(voicePaths.dir, { recursive: true });
|
|
10338
10675
|
checkLockFile();
|
|
10339
10676
|
bootstrapVenv();
|
|
10340
10677
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
10341
10678
|
const env = buildDaemonEnv({ debug });
|
|
10342
|
-
const script =
|
|
10679
|
+
const script = join39(getPythonDir(), "voice_daemon.py");
|
|
10343
10680
|
const python = getVenvPython();
|
|
10344
10681
|
if (options2.foreground) {
|
|
10345
10682
|
spawnForeground(python, script, env);
|
|
@@ -10349,7 +10686,7 @@ function start2(options2) {
|
|
|
10349
10686
|
}
|
|
10350
10687
|
|
|
10351
10688
|
// src/commands/voice/status.ts
|
|
10352
|
-
import { existsSync as existsSync39, readFileSync as
|
|
10689
|
+
import { existsSync as existsSync39, readFileSync as readFileSync31 } from "fs";
|
|
10353
10690
|
function isProcessAlive3(pid) {
|
|
10354
10691
|
try {
|
|
10355
10692
|
process.kill(pid, 0);
|
|
@@ -10360,7 +10697,7 @@ function isProcessAlive3(pid) {
|
|
|
10360
10697
|
}
|
|
10361
10698
|
function readRecentLogs(count) {
|
|
10362
10699
|
if (!existsSync39(voicePaths.log)) return [];
|
|
10363
|
-
const lines =
|
|
10700
|
+
const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
|
|
10364
10701
|
return lines.slice(-count);
|
|
10365
10702
|
}
|
|
10366
10703
|
function status() {
|
|
@@ -10368,7 +10705,7 @@ function status() {
|
|
|
10368
10705
|
console.log("Voice daemon: not running (no PID file)");
|
|
10369
10706
|
return;
|
|
10370
10707
|
}
|
|
10371
|
-
const pid = Number.parseInt(
|
|
10708
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10372
10709
|
const alive = isProcessAlive3(pid);
|
|
10373
10710
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10374
10711
|
const recent = readRecentLogs(5);
|
|
@@ -10387,13 +10724,13 @@ function status() {
|
|
|
10387
10724
|
}
|
|
10388
10725
|
|
|
10389
10726
|
// src/commands/voice/stop.ts
|
|
10390
|
-
import { existsSync as existsSync40, readFileSync as
|
|
10727
|
+
import { existsSync as existsSync40, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
|
|
10391
10728
|
function stop() {
|
|
10392
10729
|
if (!existsSync40(voicePaths.pid)) {
|
|
10393
10730
|
console.log("Voice daemon is not running (no PID file)");
|
|
10394
10731
|
return;
|
|
10395
10732
|
}
|
|
10396
|
-
const pid = Number.parseInt(
|
|
10733
|
+
const pid = Number.parseInt(readFileSync32(voicePaths.pid, "utf-8").trim(), 10);
|
|
10397
10734
|
try {
|
|
10398
10735
|
process.kill(pid, "SIGTERM");
|
|
10399
10736
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10627,15 +10964,15 @@ async function auth() {
|
|
|
10627
10964
|
}
|
|
10628
10965
|
|
|
10629
10966
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10630
|
-
import { readFileSync as
|
|
10631
|
-
import { join as
|
|
10967
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
10968
|
+
import { join as join40 } from "path";
|
|
10632
10969
|
async function showClaudeCodeIcon() {
|
|
10633
10970
|
const appData = process.env.APPDATA;
|
|
10634
10971
|
if (!appData) return;
|
|
10635
|
-
const portFile =
|
|
10972
|
+
const portFile = join40(appData, "Roam", "roam-local-api.port");
|
|
10636
10973
|
let port;
|
|
10637
10974
|
try {
|
|
10638
|
-
port =
|
|
10975
|
+
port = readFileSync33(portFile, "utf-8").trim();
|
|
10639
10976
|
} catch {
|
|
10640
10977
|
return;
|
|
10641
10978
|
}
|
|
@@ -10706,8 +11043,8 @@ Done in ${elapsed}`);
|
|
|
10706
11043
|
}
|
|
10707
11044
|
|
|
10708
11045
|
// src/commands/run/add.ts
|
|
10709
|
-
import { mkdirSync as
|
|
10710
|
-
import { join as
|
|
11046
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync27 } from "fs";
|
|
11047
|
+
import { join as join41 } from "path";
|
|
10711
11048
|
function findAddIndex() {
|
|
10712
11049
|
const addIndex = process.argv.indexOf("add");
|
|
10713
11050
|
if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
|
|
@@ -10753,15 +11090,15 @@ function saveNewRunConfig(name, command, args) {
|
|
|
10753
11090
|
saveConfig(config);
|
|
10754
11091
|
}
|
|
10755
11092
|
function createCommandFile(name) {
|
|
10756
|
-
const dir =
|
|
10757
|
-
|
|
11093
|
+
const dir = join41(".claude", "commands");
|
|
11094
|
+
mkdirSync13(dir, { recursive: true });
|
|
10758
11095
|
const content = `---
|
|
10759
11096
|
description: Run ${name}
|
|
10760
11097
|
---
|
|
10761
11098
|
|
|
10762
11099
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
10763
11100
|
`;
|
|
10764
|
-
const filePath =
|
|
11101
|
+
const filePath = join41(dir, `${name}.md`);
|
|
10765
11102
|
writeFileSync27(filePath, content);
|
|
10766
11103
|
console.log(`Created command file: ${filePath}`);
|
|
10767
11104
|
}
|
|
@@ -10832,9 +11169,9 @@ function run3(name, args) {
|
|
|
10832
11169
|
|
|
10833
11170
|
// src/commands/screenshot/index.ts
|
|
10834
11171
|
import { execSync as execSync40 } from "child_process";
|
|
10835
|
-
import { existsSync as existsSync41, mkdirSync as
|
|
11172
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10836
11173
|
import { tmpdir as tmpdir6 } from "os";
|
|
10837
|
-
import { join as
|
|
11174
|
+
import { join as join42, resolve as resolve5 } from "path";
|
|
10838
11175
|
import chalk120 from "chalk";
|
|
10839
11176
|
|
|
10840
11177
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -10965,13 +11302,13 @@ Write-Output $OutputPath
|
|
|
10965
11302
|
// src/commands/screenshot/index.ts
|
|
10966
11303
|
function buildOutputPath(outputDir, processName) {
|
|
10967
11304
|
if (!existsSync41(outputDir)) {
|
|
10968
|
-
|
|
11305
|
+
mkdirSync14(outputDir, { recursive: true });
|
|
10969
11306
|
}
|
|
10970
11307
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10971
11308
|
return resolve5(outputDir, `${processName}-${timestamp}.png`);
|
|
10972
11309
|
}
|
|
10973
11310
|
function runPowerShellScript(processName, outputPath) {
|
|
10974
|
-
const scriptPath =
|
|
11311
|
+
const scriptPath = join42(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
10975
11312
|
writeFileSync28(scriptPath, captureWindowPs1, "utf-8");
|
|
10976
11313
|
try {
|
|
10977
11314
|
execSync40(
|