@staff0rd/assist 0.170.3 → 0.171.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/dist/index.js +549 -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.0",
|
|
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,199 @@ 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/loadPlan.ts
|
|
132
|
+
function toPhase(db, itemId, p) {
|
|
133
|
+
const tasks = db.prepare(
|
|
134
|
+
"SELECT task, verify FROM plan_tasks WHERE item_id = ? AND phase_idx = ? ORDER BY idx"
|
|
135
|
+
).all(itemId, p.idx);
|
|
136
|
+
const phase = {
|
|
137
|
+
name: p.name,
|
|
138
|
+
tasks: tasks.map((t) => ({
|
|
139
|
+
task: t.task,
|
|
140
|
+
...t.verify != null ? { verify: t.verify } : {}
|
|
141
|
+
}))
|
|
142
|
+
};
|
|
143
|
+
if (p.manual_checks) {
|
|
144
|
+
phase.manualChecks = JSON.parse(p.manual_checks);
|
|
145
|
+
}
|
|
146
|
+
return phase;
|
|
147
|
+
}
|
|
148
|
+
function loadPlan(db, itemId) {
|
|
149
|
+
const phases = db.prepare(
|
|
150
|
+
"SELECT idx, name, manual_checks FROM plan_phases WHERE item_id = ? ORDER BY idx"
|
|
151
|
+
).all(itemId);
|
|
152
|
+
if (phases.length === 0) return void 0;
|
|
153
|
+
return phases.map((p) => toPhase(db, itemId, p));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/commands/backlog/loadAllItems.ts
|
|
157
|
+
function loadComments(db, itemId) {
|
|
158
|
+
return db.prepare(
|
|
159
|
+
"SELECT text, phase, timestamp, type FROM comments WHERE item_id = ? ORDER BY idx"
|
|
160
|
+
).all(itemId);
|
|
161
|
+
}
|
|
162
|
+
function loadLinks(db, itemId) {
|
|
163
|
+
return db.prepare("SELECT type, target_id as targetId FROM links WHERE item_id = ?").all(itemId);
|
|
164
|
+
}
|
|
165
|
+
function rowToItem(db, row) {
|
|
166
|
+
const comments2 = loadComments(db, row.id);
|
|
167
|
+
const links = loadLinks(db, row.id);
|
|
168
|
+
const plan2 = loadPlan(db, row.id);
|
|
169
|
+
const item = {
|
|
170
|
+
id: row.id,
|
|
171
|
+
type: row.type,
|
|
172
|
+
name: row.name,
|
|
173
|
+
acceptanceCriteria: JSON.parse(row.acceptance_criteria),
|
|
174
|
+
status: row.status
|
|
175
|
+
};
|
|
176
|
+
if (row.description != null) item.description = row.description;
|
|
177
|
+
if (row.current_phase != null) item.currentPhase = row.current_phase;
|
|
178
|
+
if (comments2.length > 0) item.comments = comments2;
|
|
179
|
+
if (links && links.length > 0) item.links = links;
|
|
180
|
+
if (plan2) item.plan = plan2;
|
|
181
|
+
return item;
|
|
182
|
+
}
|
|
183
|
+
function loadAllItems(db) {
|
|
184
|
+
const rows = db.prepare("SELECT * FROM items ORDER BY id").all();
|
|
185
|
+
return rows.map((row) => rowToItem(db, row));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/commands/backlog/exportToJsonl.ts
|
|
189
|
+
function getJsonlPath(dir) {
|
|
190
|
+
return join(dir, ".assist", "backlog.jsonl");
|
|
191
|
+
}
|
|
192
|
+
function exportToJsonl(db, dir) {
|
|
193
|
+
const jsonlPath = getJsonlPath(dir);
|
|
194
|
+
const items = loadAllItems(db);
|
|
195
|
+
const lines = items.map((item) => JSON.stringify(item));
|
|
196
|
+
writeFileSync(jsonlPath, lines.length > 0 ? `${lines.join("\n")}
|
|
197
|
+
` : "");
|
|
198
|
+
const mtimeMs = statSync(jsonlPath).mtimeMs;
|
|
199
|
+
db.prepare(
|
|
200
|
+
"INSERT INTO metadata (key, value) VALUES ('jsonl_last_import_ms', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
201
|
+
).run(String(mtimeMs));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/commands/backlog/importFromJsonlIfNeeded.ts
|
|
205
|
+
import { readFileSync, statSync as statSync2 } from "fs";
|
|
206
|
+
|
|
207
|
+
// src/commands/backlog/insertItemRelations.ts
|
|
208
|
+
function insertComments(db, item) {
|
|
209
|
+
if (!item.comments) return;
|
|
210
|
+
const stmt = db.prepare(
|
|
211
|
+
"INSERT INTO comments (item_id, idx, text, phase, timestamp, type) VALUES (?, ?, ?, ?, ?, ?)"
|
|
212
|
+
);
|
|
213
|
+
for (let i = 0; i < item.comments.length; i++) {
|
|
214
|
+
const c = item.comments[i];
|
|
215
|
+
stmt.run(item.id, i, c.text, c.phase ?? null, c.timestamp, c.type);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function insertLinks(db, item) {
|
|
219
|
+
if (!item.links) return;
|
|
220
|
+
const stmt = db.prepare(
|
|
221
|
+
"INSERT INTO links (item_id, type, target_id) VALUES (?, ?, ?)"
|
|
222
|
+
);
|
|
223
|
+
for (const l of item.links) {
|
|
224
|
+
stmt.run(item.id, l.type, l.targetId);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function insertPlan(db, item) {
|
|
228
|
+
if (!item.plan) return;
|
|
229
|
+
const phaseStmt = db.prepare(
|
|
230
|
+
"INSERT INTO plan_phases (item_id, idx, name, manual_checks) VALUES (?, ?, ?, ?)"
|
|
231
|
+
);
|
|
232
|
+
const taskStmt = db.prepare(
|
|
233
|
+
"INSERT INTO plan_tasks (item_id, phase_idx, idx, task, verify) VALUES (?, ?, ?, ?, ?)"
|
|
234
|
+
);
|
|
235
|
+
for (let pi = 0; pi < item.plan.length; pi++) {
|
|
236
|
+
const phase = item.plan[pi];
|
|
237
|
+
phaseStmt.run(
|
|
238
|
+
item.id,
|
|
239
|
+
pi,
|
|
240
|
+
phase.name,
|
|
241
|
+
phase.manualChecks ? JSON.stringify(phase.manualChecks) : null
|
|
242
|
+
);
|
|
243
|
+
for (let ti = 0; ti < phase.tasks.length; ti++) {
|
|
244
|
+
const task = phase.tasks[ti];
|
|
245
|
+
taskStmt.run(item.id, pi, ti, task.task, task.verify ?? null);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function insertItemRelations(db, item) {
|
|
250
|
+
insertComments(db, item);
|
|
251
|
+
insertLinks(db, item);
|
|
252
|
+
insertPlan(db, item);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/commands/backlog/saveAllItems.ts
|
|
256
|
+
function upsertItem(db, item) {
|
|
257
|
+
db.prepare(
|
|
258
|
+
`INSERT INTO items (id, type, name, description, acceptance_criteria, status, current_phase)
|
|
259
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
260
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
261
|
+
type = excluded.type,
|
|
262
|
+
name = excluded.name,
|
|
263
|
+
description = excluded.description,
|
|
264
|
+
acceptance_criteria = excluded.acceptance_criteria,
|
|
265
|
+
status = excluded.status,
|
|
266
|
+
current_phase = excluded.current_phase`
|
|
267
|
+
).run(
|
|
268
|
+
item.id,
|
|
269
|
+
item.type,
|
|
270
|
+
item.name,
|
|
271
|
+
item.description ?? null,
|
|
272
|
+
JSON.stringify(item.acceptanceCriteria),
|
|
273
|
+
item.status,
|
|
274
|
+
item.currentPhase ?? null
|
|
275
|
+
);
|
|
276
|
+
deleteItemRelations(db, item.id);
|
|
277
|
+
insertItemRelations(db, item);
|
|
278
|
+
}
|
|
279
|
+
function saveAllItems(db, items) {
|
|
280
|
+
const save = db.transaction(() => {
|
|
281
|
+
const existingIds = db.prepare("SELECT id FROM items").all();
|
|
282
|
+
const newIds = new Set(items.map((i) => i.id));
|
|
283
|
+
for (const { id } of existingIds) {
|
|
284
|
+
if (!newIds.has(id)) {
|
|
285
|
+
deleteItemRelations(db, id);
|
|
286
|
+
db.prepare("DELETE FROM items WHERE id = ?").run(id);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
for (const item of items) {
|
|
290
|
+
upsertItem(db, item);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
save();
|
|
294
|
+
}
|
|
108
295
|
|
|
109
296
|
// src/commands/backlog/types.ts
|
|
110
297
|
import { z } from "zod";
|
|
@@ -145,6 +332,143 @@ var backlogItemSchema = z.strictObject({
|
|
|
145
332
|
});
|
|
146
333
|
var backlogFileSchema = z.array(backlogItemSchema);
|
|
147
334
|
|
|
335
|
+
// src/commands/backlog/importFromJsonlIfNeeded.ts
|
|
336
|
+
function getLastImportMs(db) {
|
|
337
|
+
const row = db.prepare("SELECT value FROM metadata WHERE key = 'jsonl_last_import_ms'").get();
|
|
338
|
+
return row ? Number(row.value) : 0;
|
|
339
|
+
}
|
|
340
|
+
function setLastImportMs(db, ms) {
|
|
341
|
+
db.prepare(
|
|
342
|
+
"INSERT INTO metadata (key, value) VALUES ('jsonl_last_import_ms', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
343
|
+
).run(String(ms));
|
|
344
|
+
}
|
|
345
|
+
function importFromJsonlIfNeeded(db, dir) {
|
|
346
|
+
const jsonlPath = getJsonlPath(dir);
|
|
347
|
+
let stat;
|
|
348
|
+
try {
|
|
349
|
+
stat = statSync2(jsonlPath);
|
|
350
|
+
} catch {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const fileMtimeMs = stat.mtimeMs;
|
|
354
|
+
const lastImportMs = getLastImportMs(db);
|
|
355
|
+
if (fileMtimeMs <= lastImportMs) return;
|
|
356
|
+
const content = readFileSync(jsonlPath, "utf-8").trim();
|
|
357
|
+
if (content.length === 0) {
|
|
358
|
+
setLastImportMs(db, fileMtimeMs);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const items = content.split("\n").map((line) => {
|
|
362
|
+
const parsed = JSON.parse(line);
|
|
363
|
+
return backlogItemSchema.parse(parsed);
|
|
364
|
+
});
|
|
365
|
+
saveAllItems(db, items);
|
|
366
|
+
setLastImportMs(db, fileMtimeMs);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// src/commands/backlog/migrateYamlIfNeeded.ts
|
|
370
|
+
import { existsSync, readFileSync as readFileSync2, renameSync } from "fs";
|
|
371
|
+
import { parse as parseYaml } from "yaml";
|
|
372
|
+
function migrateYamlIfNeeded(db, yamlPath) {
|
|
373
|
+
if (!existsSync(yamlPath)) return false;
|
|
374
|
+
const existing = db.prepare("SELECT COUNT(*) as count FROM items").get();
|
|
375
|
+
if (existing.count > 0) return false;
|
|
376
|
+
const content = readFileSync2(yamlPath, "utf-8");
|
|
377
|
+
const raw = parseYaml(content) || [];
|
|
378
|
+
const items = backlogFileSchema.parse(raw);
|
|
379
|
+
if (items.length > 0) {
|
|
380
|
+
saveAllItems(db, items);
|
|
381
|
+
renameSync(yamlPath, `${yamlPath}.bak`);
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/commands/backlog/openDb.ts
|
|
388
|
+
import { mkdirSync } from "fs";
|
|
389
|
+
import { join as join2 } from "path";
|
|
390
|
+
import Database from "better-sqlite3";
|
|
391
|
+
var _db;
|
|
392
|
+
function getDbPath(dir) {
|
|
393
|
+
return join2(dir, ".assist", "backlog.db");
|
|
394
|
+
}
|
|
395
|
+
function initSchema(db) {
|
|
396
|
+
db.exec(`
|
|
397
|
+
CREATE TABLE IF NOT EXISTS items (
|
|
398
|
+
id INTEGER PRIMARY KEY,
|
|
399
|
+
type TEXT NOT NULL DEFAULT 'story',
|
|
400
|
+
name TEXT NOT NULL,
|
|
401
|
+
description TEXT,
|
|
402
|
+
acceptance_criteria TEXT NOT NULL DEFAULT '[]',
|
|
403
|
+
status TEXT NOT NULL DEFAULT 'todo',
|
|
404
|
+
current_phase INTEGER
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
CREATE TABLE IF NOT EXISTS comments (
|
|
408
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
409
|
+
idx INTEGER NOT NULL,
|
|
410
|
+
text TEXT NOT NULL,
|
|
411
|
+
phase INTEGER,
|
|
412
|
+
timestamp TEXT NOT NULL,
|
|
413
|
+
type TEXT NOT NULL DEFAULT 'comment',
|
|
414
|
+
PRIMARY KEY (item_id, idx)
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
CREATE TABLE IF NOT EXISTS links (
|
|
418
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
419
|
+
type TEXT NOT NULL,
|
|
420
|
+
target_id INTEGER NOT NULL,
|
|
421
|
+
PRIMARY KEY (item_id, type, target_id)
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
CREATE TABLE IF NOT EXISTS plan_phases (
|
|
425
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
426
|
+
idx INTEGER NOT NULL,
|
|
427
|
+
name TEXT NOT NULL,
|
|
428
|
+
manual_checks TEXT,
|
|
429
|
+
PRIMARY KEY (item_id, idx)
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
CREATE TABLE IF NOT EXISTS plan_tasks (
|
|
433
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
434
|
+
phase_idx INTEGER NOT NULL,
|
|
435
|
+
idx INTEGER NOT NULL,
|
|
436
|
+
task TEXT NOT NULL,
|
|
437
|
+
verify TEXT,
|
|
438
|
+
PRIMARY KEY (item_id, phase_idx, idx),
|
|
439
|
+
FOREIGN KEY (item_id, phase_idx) REFERENCES plan_phases(item_id, idx) ON DELETE CASCADE
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
CREATE TABLE IF NOT EXISTS metadata (
|
|
443
|
+
key TEXT PRIMARY KEY,
|
|
444
|
+
value TEXT NOT NULL
|
|
445
|
+
);
|
|
446
|
+
`);
|
|
447
|
+
}
|
|
448
|
+
function openDb(dir) {
|
|
449
|
+
if (_db) return _db;
|
|
450
|
+
const dbPath = getDbPath(dir);
|
|
451
|
+
mkdirSync(join2(dir, ".assist"), { recursive: true });
|
|
452
|
+
const db = new Database(dbPath);
|
|
453
|
+
db.pragma("journal_mode = WAL");
|
|
454
|
+
db.pragma("foreign_keys = ON");
|
|
455
|
+
initSchema(db);
|
|
456
|
+
_db = db;
|
|
457
|
+
return db;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// src/commands/backlog/updateCurrentPhase.ts
|
|
461
|
+
function updateCurrentPhase(db, id, phase) {
|
|
462
|
+
const result = db.prepare("UPDATE items SET current_phase = ? WHERE id = ?").run(phase, id);
|
|
463
|
+
return result.changes > 0;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/commands/backlog/updateStatus.ts
|
|
467
|
+
function updateStatus(db, id, status2) {
|
|
468
|
+
const result = db.prepare("UPDATE items SET status = ? WHERE id = ?").run(status2, id);
|
|
469
|
+
return result.changes > 0;
|
|
470
|
+
}
|
|
471
|
+
|
|
148
472
|
// src/commands/backlog/shared.ts
|
|
149
473
|
var _backlogDir;
|
|
150
474
|
function setBacklogDir(dir) {
|
|
@@ -154,33 +478,29 @@ function getBacklogDir() {
|
|
|
154
478
|
return _backlogDir ?? process.cwd();
|
|
155
479
|
}
|
|
156
480
|
function getBacklogPath() {
|
|
157
|
-
return
|
|
481
|
+
return join3(getBacklogDir(), "assist.backlog.yml");
|
|
482
|
+
}
|
|
483
|
+
function getDb() {
|
|
484
|
+
const dir = getBacklogDir();
|
|
485
|
+
const db = openDb(dir);
|
|
486
|
+
const migrated = migrateYamlIfNeeded(db, getBacklogPath());
|
|
487
|
+
if (migrated) exportToJsonl(db, dir);
|
|
488
|
+
return db;
|
|
158
489
|
}
|
|
159
490
|
function loadBacklog() {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
const content = readFileSync(backlogPath, "utf-8");
|
|
165
|
-
const raw = parseYaml(content) || [];
|
|
166
|
-
return backlogFileSchema.parse(raw);
|
|
491
|
+
const db = getDb();
|
|
492
|
+
importFromJsonlIfNeeded(db, getBacklogDir());
|
|
493
|
+
return loadAllItems(db);
|
|
167
494
|
}
|
|
168
495
|
function saveBacklog(items) {
|
|
169
|
-
const
|
|
170
|
-
|
|
496
|
+
const db = getDb();
|
|
497
|
+
saveAllItems(db, items);
|
|
498
|
+
exportToJsonl(db, getBacklogDir());
|
|
171
499
|
}
|
|
172
500
|
function findItem(items, id) {
|
|
173
501
|
return items.find((item) => item.id === id);
|
|
174
502
|
}
|
|
175
503
|
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
504
|
const items = loadBacklog();
|
|
185
505
|
const item = findItem(items, Number.parseInt(id, 10));
|
|
186
506
|
if (!item) {
|
|
@@ -192,20 +512,24 @@ function loadAndFindItem(id) {
|
|
|
192
512
|
function setStatus(id, status2) {
|
|
193
513
|
const result = loadAndFindItem(id);
|
|
194
514
|
if (!result) return void 0;
|
|
195
|
-
|
|
196
|
-
|
|
515
|
+
const db = getDb();
|
|
516
|
+
updateStatus(db, result.item.id, status2);
|
|
517
|
+
exportToJsonl(db, getBacklogDir());
|
|
197
518
|
return result.item.name;
|
|
198
519
|
}
|
|
199
520
|
function setCurrentPhase(id, phase) {
|
|
200
521
|
const result = loadAndFindItem(id);
|
|
201
522
|
if (!result) return;
|
|
202
|
-
|
|
203
|
-
|
|
523
|
+
const db = getDb();
|
|
524
|
+
updateCurrentPhase(db, result.item.id, phase);
|
|
525
|
+
exportToJsonl(db, getBacklogDir());
|
|
204
526
|
}
|
|
205
527
|
function removeItem(id) {
|
|
206
528
|
const result = loadAndFindItem(id);
|
|
207
529
|
if (!result) return void 0;
|
|
208
|
-
|
|
530
|
+
const db = getDb();
|
|
531
|
+
deleteItem(db, result.item.id);
|
|
532
|
+
exportToJsonl(db, getBacklogDir());
|
|
209
533
|
return result.item.name;
|
|
210
534
|
}
|
|
211
535
|
function getNextId(items) {
|
|
@@ -215,7 +539,7 @@ function getNextId(items) {
|
|
|
215
539
|
|
|
216
540
|
// src/commands/backlog/acquireLock.ts
|
|
217
541
|
function getLockPath(itemId) {
|
|
218
|
-
return
|
|
542
|
+
return join4(getBacklogDir(), `.assist-lock-${itemId}.json`);
|
|
219
543
|
}
|
|
220
544
|
function isProcessAlive(pid) {
|
|
221
545
|
try {
|
|
@@ -229,7 +553,7 @@ function isLockedByOther(itemId) {
|
|
|
229
553
|
const lockPath = getLockPath(itemId);
|
|
230
554
|
if (!existsSync2(lockPath)) return false;
|
|
231
555
|
try {
|
|
232
|
-
const lock = JSON.parse(
|
|
556
|
+
const lock = JSON.parse(readFileSync3(lockPath, "utf-8"));
|
|
233
557
|
if (lock.pid === process.pid) return false;
|
|
234
558
|
return isProcessAlive(lock.pid);
|
|
235
559
|
} catch {
|
|
@@ -438,10 +762,10 @@ async function handleIncompletePhase() {
|
|
|
438
762
|
|
|
439
763
|
// src/commands/backlog/writeSignal.ts
|
|
440
764
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
441
|
-
import { join as
|
|
765
|
+
import { join as join5 } from "path";
|
|
442
766
|
var SIGNAL_FILE = ".assist-signal.json";
|
|
443
767
|
function getSignalPath() {
|
|
444
|
-
return
|
|
768
|
+
return join5(getBacklogDir(), SIGNAL_FILE);
|
|
445
769
|
}
|
|
446
770
|
function writeSignal(event, data) {
|
|
447
771
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
@@ -489,12 +813,12 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
489
813
|
import { existsSync as existsSync5, unwatchFile, watchFile } from "fs";
|
|
490
814
|
|
|
491
815
|
// src/commands/backlog/readSignal.ts
|
|
492
|
-
import { existsSync as existsSync4, readFileSync as
|
|
816
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
493
817
|
function readSignal() {
|
|
494
818
|
const path50 = getSignalPath();
|
|
495
819
|
if (!existsSync4(path50)) return void 0;
|
|
496
820
|
try {
|
|
497
|
-
return JSON.parse(
|
|
821
|
+
return JSON.parse(readFileSync4(path50, "utf-8"));
|
|
498
822
|
} catch {
|
|
499
823
|
return void 0;
|
|
500
824
|
}
|
|
@@ -862,11 +1186,11 @@ function printComments(item) {
|
|
|
862
1186
|
|
|
863
1187
|
// src/shared/web.ts
|
|
864
1188
|
import { exec } from "child_process";
|
|
865
|
-
import { readFileSync as
|
|
1189
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
866
1190
|
import {
|
|
867
1191
|
createServer
|
|
868
1192
|
} from "http";
|
|
869
|
-
import { dirname, join as
|
|
1193
|
+
import { dirname, join as join6 } from "path";
|
|
870
1194
|
import { fileURLToPath } from "url";
|
|
871
1195
|
import chalk14 from "chalk";
|
|
872
1196
|
function respondJson(res, status2, data) {
|
|
@@ -878,7 +1202,7 @@ function createBundleHandler(importMetaUrl, bundlePath) {
|
|
|
878
1202
|
let cache;
|
|
879
1203
|
return (_req, res) => {
|
|
880
1204
|
if (!cache) {
|
|
881
|
-
cache =
|
|
1205
|
+
cache = readFileSync5(join6(dir, bundlePath), "utf-8");
|
|
882
1206
|
}
|
|
883
1207
|
res.writeHead(200, { "Content-Type": "application/javascript" });
|
|
884
1208
|
res.end(cache);
|
|
@@ -991,7 +1315,7 @@ async function createItem(req, res) {
|
|
|
991
1315
|
saveBacklog(items);
|
|
992
1316
|
respondJson(res, 201, newItem);
|
|
993
1317
|
}
|
|
994
|
-
function
|
|
1318
|
+
function deleteItem2(res, id) {
|
|
995
1319
|
const result = findItemOr404(res, id);
|
|
996
1320
|
if (!result) return;
|
|
997
1321
|
saveBacklog(result.items.filter((i) => i.id !== id));
|
|
@@ -1033,7 +1357,7 @@ var itemRoutes = {
|
|
|
1033
1357
|
GET: (_req, res, id) => getItemById(res, id),
|
|
1034
1358
|
PUT: (req, res, id) => updateItem(req, res, id),
|
|
1035
1359
|
PATCH: (req, res, id) => patchItemStatus(req, res, id),
|
|
1036
|
-
DELETE: (_req, res, id) =>
|
|
1360
|
+
DELETE: (_req, res, id) => deleteItem2(res, id)
|
|
1037
1361
|
};
|
|
1038
1362
|
var baseHandler = createRouteHandler(routes);
|
|
1039
1363
|
async function handleRequest(req, res, port) {
|
|
@@ -1080,19 +1404,19 @@ async function launchMode(slashCommand) {
|
|
|
1080
1404
|
import { execSync } from "child_process";
|
|
1081
1405
|
|
|
1082
1406
|
// src/shared/loadConfig.ts
|
|
1083
|
-
import { existsSync as existsSync7, readFileSync as
|
|
1407
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
1084
1408
|
import { homedir } from "os";
|
|
1085
|
-
import { basename, dirname as dirname2, join as
|
|
1409
|
+
import { basename, dirname as dirname2, join as join7 } from "path";
|
|
1086
1410
|
import chalk16 from "chalk";
|
|
1087
|
-
import { stringify as
|
|
1411
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
1088
1412
|
|
|
1089
1413
|
// src/shared/loadRawYaml.ts
|
|
1090
|
-
import { existsSync as existsSync6, readFileSync as
|
|
1414
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
1091
1415
|
import { parse as parseYaml2 } from "yaml";
|
|
1092
1416
|
function loadRawYaml(path50) {
|
|
1093
1417
|
if (!existsSync6(path50)) return {};
|
|
1094
1418
|
try {
|
|
1095
|
-
const content =
|
|
1419
|
+
const content = readFileSync6(path50, "utf-8");
|
|
1096
1420
|
return parseYaml2(content) || {};
|
|
1097
1421
|
} catch {
|
|
1098
1422
|
return {};
|
|
@@ -1222,9 +1546,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
1222
1546
|
function findConfigUp(startDir) {
|
|
1223
1547
|
let current = startDir;
|
|
1224
1548
|
while (current !== dirname2(current)) {
|
|
1225
|
-
const claudePath =
|
|
1549
|
+
const claudePath = join7(current, ".claude", "assist.yml");
|
|
1226
1550
|
if (existsSync7(claudePath)) return claudePath;
|
|
1227
|
-
const rootPath =
|
|
1551
|
+
const rootPath = join7(current, "assist.yml");
|
|
1228
1552
|
if (existsSync7(rootPath)) return rootPath;
|
|
1229
1553
|
current = dirname2(current);
|
|
1230
1554
|
}
|
|
@@ -1233,10 +1557,10 @@ function findConfigUp(startDir) {
|
|
|
1233
1557
|
function getConfigPath() {
|
|
1234
1558
|
const found = findConfigUp(process.cwd());
|
|
1235
1559
|
if (found) return found;
|
|
1236
|
-
return
|
|
1560
|
+
return join7(process.cwd(), "assist.yml");
|
|
1237
1561
|
}
|
|
1238
1562
|
function getGlobalConfigPath() {
|
|
1239
|
-
return
|
|
1563
|
+
return join7(homedir(), ".assist.yml");
|
|
1240
1564
|
}
|
|
1241
1565
|
function loadConfig() {
|
|
1242
1566
|
const globalRaw = loadRawYaml(getGlobalConfigPath());
|
|
@@ -1251,21 +1575,21 @@ function loadGlobalConfigRaw() {
|
|
|
1251
1575
|
return loadRawYaml(getGlobalConfigPath());
|
|
1252
1576
|
}
|
|
1253
1577
|
function saveGlobalConfig(config) {
|
|
1254
|
-
writeFileSync4(getGlobalConfigPath(),
|
|
1578
|
+
writeFileSync4(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
|
|
1255
1579
|
}
|
|
1256
1580
|
function saveConfig(config) {
|
|
1257
1581
|
const configPath = getConfigPath();
|
|
1258
|
-
writeFileSync4(configPath,
|
|
1582
|
+
writeFileSync4(configPath, stringifyYaml(config, { lineWidth: 0 }));
|
|
1259
1583
|
}
|
|
1260
1584
|
function getRepoName() {
|
|
1261
1585
|
const config = loadConfig();
|
|
1262
1586
|
if (config.devlog?.name) {
|
|
1263
1587
|
return config.devlog.name;
|
|
1264
1588
|
}
|
|
1265
|
-
const packageJsonPath =
|
|
1589
|
+
const packageJsonPath = join7(process.cwd(), "package.json");
|
|
1266
1590
|
if (existsSync7(packageJsonPath)) {
|
|
1267
1591
|
try {
|
|
1268
|
-
const content =
|
|
1592
|
+
const content = readFileSync7(packageJsonPath, "utf-8");
|
|
1269
1593
|
const pkg = JSON.parse(content);
|
|
1270
1594
|
if (pkg.name) {
|
|
1271
1595
|
return pkg.name;
|
|
@@ -1369,7 +1693,7 @@ function commit(args) {
|
|
|
1369
1693
|
|
|
1370
1694
|
// src/commands/config/index.ts
|
|
1371
1695
|
import chalk17 from "chalk";
|
|
1372
|
-
import { stringify as
|
|
1696
|
+
import { stringify as stringifyYaml2 } from "yaml";
|
|
1373
1697
|
|
|
1374
1698
|
// src/commands/config/setNestedValue.ts
|
|
1375
1699
|
function isPlainObject(val) {
|
|
@@ -1476,7 +1800,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
1476
1800
|
}
|
|
1477
1801
|
function configList() {
|
|
1478
1802
|
const config = loadConfig();
|
|
1479
|
-
console.log(
|
|
1803
|
+
console.log(stringifyYaml2(config, { lineWidth: 0 }).trimEnd());
|
|
1480
1804
|
}
|
|
1481
1805
|
|
|
1482
1806
|
// src/commands/config/configGet.ts
|
|
@@ -1714,17 +2038,17 @@ import * as path3 from "path";
|
|
|
1714
2038
|
import chalk25 from "chalk";
|
|
1715
2039
|
|
|
1716
2040
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
1717
|
-
import { existsSync as existsSync9, readFileSync as
|
|
1718
|
-
import { join as
|
|
2041
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
2042
|
+
import { join as join9 } from "path";
|
|
1719
2043
|
import chalk24 from "chalk";
|
|
1720
2044
|
function loadKnipConfig(knipJsonPath) {
|
|
1721
2045
|
if (existsSync9(knipJsonPath)) {
|
|
1722
|
-
return JSON.parse(
|
|
2046
|
+
return JSON.parse(readFileSync9(knipJsonPath, "utf-8"));
|
|
1723
2047
|
}
|
|
1724
2048
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
1725
2049
|
}
|
|
1726
2050
|
function addToKnipIgnoreBinaries(cwd, binary) {
|
|
1727
|
-
const knipJsonPath =
|
|
2051
|
+
const knipJsonPath = join9(cwd, "knip.json");
|
|
1728
2052
|
try {
|
|
1729
2053
|
const knipConfig = loadKnipConfig(knipJsonPath);
|
|
1730
2054
|
const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
|
|
@@ -1772,8 +2096,8 @@ import chalk29 from "chalk";
|
|
|
1772
2096
|
|
|
1773
2097
|
// src/commands/lint/init.ts
|
|
1774
2098
|
import { execSync as execSync5 } from "child_process";
|
|
1775
|
-
import { existsSync as existsSync12, readFileSync as
|
|
1776
|
-
import { dirname as dirname7, join as
|
|
2099
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
2100
|
+
import { dirname as dirname7, join as join10 } from "path";
|
|
1777
2101
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1778
2102
|
import chalk28 from "chalk";
|
|
1779
2103
|
|
|
@@ -1798,7 +2122,7 @@ async function promptConfirm(message, initial = true) {
|
|
|
1798
2122
|
|
|
1799
2123
|
// src/shared/removeEslint/index.ts
|
|
1800
2124
|
import { execSync as execSync4 } from "child_process";
|
|
1801
|
-
import { existsSync as existsSync11, readFileSync as
|
|
2125
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
|
|
1802
2126
|
|
|
1803
2127
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
1804
2128
|
import { existsSync as existsSync10, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -1842,7 +2166,7 @@ function removeEslintFromPackageJson(options2) {
|
|
|
1842
2166
|
if (!existsSync11(packageJsonPath)) {
|
|
1843
2167
|
return false;
|
|
1844
2168
|
}
|
|
1845
|
-
const packageJson = JSON.parse(
|
|
2169
|
+
const packageJson = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
1846
2170
|
let modified = false;
|
|
1847
2171
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
1848
2172
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -1920,9 +2244,9 @@ async function init() {
|
|
|
1920
2244
|
console.log("No biome.json found, skipping linter config");
|
|
1921
2245
|
return;
|
|
1922
2246
|
}
|
|
1923
|
-
const linterConfigPath =
|
|
1924
|
-
const linterConfig = JSON.parse(
|
|
1925
|
-
const biomeConfig = JSON.parse(
|
|
2247
|
+
const linterConfigPath = join10(__dirname2, "commands/lint/biome.linter.json");
|
|
2248
|
+
const linterConfig = JSON.parse(readFileSync11(linterConfigPath, "utf-8"));
|
|
2249
|
+
const biomeConfig = JSON.parse(readFileSync11(biomeConfigPath, "utf-8"));
|
|
1926
2250
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
1927
2251
|
`;
|
|
1928
2252
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -2980,7 +3304,7 @@ function initPackageJson(name) {
|
|
|
2980
3304
|
}
|
|
2981
3305
|
|
|
2982
3306
|
// src/commands/new/registerNew/newCli/writeCliTemplate.ts
|
|
2983
|
-
import { mkdirSync as
|
|
3307
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync11 } from "fs";
|
|
2984
3308
|
function writeCliTemplate(name) {
|
|
2985
3309
|
console.log("Writing tsconfig.json...");
|
|
2986
3310
|
writeFileSync11(
|
|
@@ -3021,7 +3345,7 @@ export default defineConfig({
|
|
|
3021
3345
|
`
|
|
3022
3346
|
);
|
|
3023
3347
|
console.log("Writing src/index.ts...");
|
|
3024
|
-
|
|
3348
|
+
mkdirSync3("src", { recursive: true });
|
|
3025
3349
|
writeFileSync11(
|
|
3026
3350
|
"src/index.ts",
|
|
3027
3351
|
`#!/usr/bin/env node
|
|
@@ -3050,7 +3374,7 @@ async function newCli() {
|
|
|
3050
3374
|
|
|
3051
3375
|
// src/commands/new/registerNew/newProject.ts
|
|
3052
3376
|
import { execSync as execSync13 } from "child_process";
|
|
3053
|
-
import { existsSync as existsSync16, readFileSync as
|
|
3377
|
+
import { existsSync as existsSync16, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
3054
3378
|
|
|
3055
3379
|
// src/commands/deploy/init/index.ts
|
|
3056
3380
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -3058,8 +3382,8 @@ import chalk40 from "chalk";
|
|
|
3058
3382
|
import enquirer5 from "enquirer";
|
|
3059
3383
|
|
|
3060
3384
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3061
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
3062
|
-
import { dirname as dirname13, join as
|
|
3385
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
3386
|
+
import { dirname as dirname13, join as join13 } from "path";
|
|
3063
3387
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3064
3388
|
import chalk39 from "chalk";
|
|
3065
3389
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
@@ -3068,23 +3392,23 @@ function getExistingSiteId() {
|
|
|
3068
3392
|
if (!existsSync15(WORKFLOW_PATH)) {
|
|
3069
3393
|
return null;
|
|
3070
3394
|
}
|
|
3071
|
-
const content =
|
|
3395
|
+
const content = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3072
3396
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
3073
3397
|
return match ? match[1] : null;
|
|
3074
3398
|
}
|
|
3075
3399
|
function getTemplateContent(siteId) {
|
|
3076
|
-
const templatePath =
|
|
3077
|
-
const template =
|
|
3400
|
+
const templatePath = join13(__dirname3, "commands/deploy/build.yml");
|
|
3401
|
+
const template = readFileSync13(templatePath, "utf-8");
|
|
3078
3402
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
3079
3403
|
}
|
|
3080
3404
|
async function updateWorkflow(siteId) {
|
|
3081
3405
|
const newContent = getTemplateContent(siteId);
|
|
3082
3406
|
const workflowDir = ".github/workflows";
|
|
3083
3407
|
if (!existsSync15(workflowDir)) {
|
|
3084
|
-
|
|
3408
|
+
mkdirSync4(workflowDir, { recursive: true });
|
|
3085
3409
|
}
|
|
3086
3410
|
if (existsSync15(WORKFLOW_PATH)) {
|
|
3087
|
-
const oldContent =
|
|
3411
|
+
const oldContent = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3088
3412
|
if (oldContent === newContent) {
|
|
3089
3413
|
console.log(chalk39.green("build.yml is already up to date"));
|
|
3090
3414
|
return;
|
|
@@ -3182,7 +3506,7 @@ function addViteBaseConfig() {
|
|
|
3182
3506
|
console.log("No vite.config.ts found, skipping base config");
|
|
3183
3507
|
return;
|
|
3184
3508
|
}
|
|
3185
|
-
const content =
|
|
3509
|
+
const content = readFileSync14(viteConfigPath, "utf-8");
|
|
3186
3510
|
if (content.includes("base:")) {
|
|
3187
3511
|
console.log("vite.config.ts already has base config");
|
|
3188
3512
|
return;
|
|
@@ -3365,12 +3689,13 @@ import chalk45 from "chalk";
|
|
|
3365
3689
|
|
|
3366
3690
|
// src/commands/backlog/commitBacklog.ts
|
|
3367
3691
|
import { execSync as execSync14 } from "child_process";
|
|
3692
|
+
import { join as join14 } from "path";
|
|
3368
3693
|
import chalk43 from "chalk";
|
|
3369
3694
|
function commitBacklog(id, name) {
|
|
3370
3695
|
try {
|
|
3371
|
-
const
|
|
3696
|
+
const jsonlPath = join14(getBacklogDir(), ".assist", "backlog.jsonl");
|
|
3372
3697
|
const message = `chore: add backlog item #${id} \u2014 ${name}`;
|
|
3373
|
-
execSync14(`git add ${shellQuote(
|
|
3698
|
+
execSync14(`git add ${shellQuote(jsonlPath)}`, { stdio: "ignore" });
|
|
3374
3699
|
execSync14(`git commit -m ${shellQuote(message)}`, { stdio: "ignore" });
|
|
3375
3700
|
} catch {
|
|
3376
3701
|
console.log(chalk43.yellow("Warning: could not auto-commit backlog file."));
|
|
@@ -3378,7 +3703,7 @@ function commitBacklog(id, name) {
|
|
|
3378
3703
|
}
|
|
3379
3704
|
|
|
3380
3705
|
// src/commands/backlog/add/parseItemFile.ts
|
|
3381
|
-
import { existsSync as existsSync17, readFileSync as
|
|
3706
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
3382
3707
|
import chalk44 from "chalk";
|
|
3383
3708
|
import { ZodError } from "zod";
|
|
3384
3709
|
var addItemSchema = backlogItemSchema.omit({ id: true, status: true });
|
|
@@ -3390,7 +3715,7 @@ function readJsonFile(filePath) {
|
|
|
3390
3715
|
}
|
|
3391
3716
|
let raw;
|
|
3392
3717
|
try {
|
|
3393
|
-
raw =
|
|
3718
|
+
raw = readFileSync15(filePath, "utf-8");
|
|
3394
3719
|
} catch {
|
|
3395
3720
|
console.log(chalk44.red(`Failed to read file: ${filePath}`));
|
|
3396
3721
|
process.exitCode = 1;
|
|
@@ -3428,9 +3753,9 @@ function parseItemFile(filePath) {
|
|
|
3428
3753
|
|
|
3429
3754
|
// src/commands/backlog/add/shared.ts
|
|
3430
3755
|
import { spawnSync } from "child_process";
|
|
3431
|
-
import { mkdtempSync, readFileSync as
|
|
3756
|
+
import { mkdtempSync, readFileSync as readFileSync16, unlinkSync as unlinkSync4, writeFileSync as writeFileSync14 } from "fs";
|
|
3432
3757
|
import { tmpdir } from "os";
|
|
3433
|
-
import { join as
|
|
3758
|
+
import { join as join15 } from "path";
|
|
3434
3759
|
import enquirer6 from "enquirer";
|
|
3435
3760
|
async function promptType() {
|
|
3436
3761
|
const { type } = await enquirer6.prompt({
|
|
@@ -3470,15 +3795,15 @@ async function promptDescription() {
|
|
|
3470
3795
|
}
|
|
3471
3796
|
function openEditor() {
|
|
3472
3797
|
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
3473
|
-
const dir = mkdtempSync(
|
|
3474
|
-
const filePath =
|
|
3798
|
+
const dir = mkdtempSync(join15(tmpdir(), "assist-"));
|
|
3799
|
+
const filePath = join15(dir, "description.md");
|
|
3475
3800
|
writeFileSync14(filePath, "");
|
|
3476
3801
|
const result = spawnSync(editor, [filePath], { stdio: "inherit" });
|
|
3477
3802
|
if (result.status !== 0) {
|
|
3478
3803
|
unlinkSync4(filePath);
|
|
3479
3804
|
return void 0;
|
|
3480
3805
|
}
|
|
3481
|
-
const content =
|
|
3806
|
+
const content = readFileSync16(filePath, "utf-8").trim();
|
|
3482
3807
|
unlinkSync4(filePath);
|
|
3483
3808
|
return content || void 0;
|
|
3484
3809
|
}
|
|
@@ -3870,7 +4195,7 @@ function extractGraphqlQuery(args) {
|
|
|
3870
4195
|
}
|
|
3871
4196
|
|
|
3872
4197
|
// src/shared/loadCliReads.ts
|
|
3873
|
-
import { existsSync as existsSync21, readFileSync as
|
|
4198
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
3874
4199
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
3875
4200
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3876
4201
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -3880,7 +4205,7 @@ function packageRoot() {
|
|
|
3880
4205
|
}
|
|
3881
4206
|
function readLines(path50) {
|
|
3882
4207
|
if (!existsSync21(path50)) return [];
|
|
3883
|
-
return
|
|
4208
|
+
return readFileSync17(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
3884
4209
|
}
|
|
3885
4210
|
var cachedReads;
|
|
3886
4211
|
var cachedWrites;
|
|
@@ -3926,14 +4251,14 @@ function findCliWrite(command) {
|
|
|
3926
4251
|
}
|
|
3927
4252
|
|
|
3928
4253
|
// src/shared/readSettingsPerms.ts
|
|
3929
|
-
import { existsSync as existsSync22, readFileSync as
|
|
4254
|
+
import { existsSync as existsSync22, readFileSync as readFileSync18 } from "fs";
|
|
3930
4255
|
import { homedir as homedir3 } from "os";
|
|
3931
|
-
import { join as
|
|
4256
|
+
import { join as join16 } from "path";
|
|
3932
4257
|
function readSettingsPerms(key) {
|
|
3933
4258
|
const paths = [
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
4259
|
+
join16(homedir3(), ".claude", "settings.json"),
|
|
4260
|
+
join16(process.cwd(), ".claude", "settings.json"),
|
|
4261
|
+
join16(process.cwd(), ".claude", "settings.local.json")
|
|
3937
4262
|
];
|
|
3938
4263
|
const entries = [];
|
|
3939
4264
|
for (const p of paths) {
|
|
@@ -3944,7 +4269,7 @@ function readSettingsPerms(key) {
|
|
|
3944
4269
|
function readPermissionArray(filePath, key) {
|
|
3945
4270
|
if (!existsSync22(filePath)) return [];
|
|
3946
4271
|
try {
|
|
3947
|
-
const data = JSON.parse(
|
|
4272
|
+
const data = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
3948
4273
|
const arr = data?.permissions?.[key];
|
|
3949
4274
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
3950
4275
|
} catch {
|
|
@@ -4229,9 +4554,9 @@ function denyRemove(pattern2) {
|
|
|
4229
4554
|
}
|
|
4230
4555
|
|
|
4231
4556
|
// src/commands/permitCliReads/index.ts
|
|
4232
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
4557
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
|
|
4233
4558
|
import { homedir as homedir4 } from "os";
|
|
4234
|
-
import { join as
|
|
4559
|
+
import { join as join17 } from "path";
|
|
4235
4560
|
|
|
4236
4561
|
// src/shared/getInstallDir.ts
|
|
4237
4562
|
import { execSync as execSync15 } from "child_process";
|
|
@@ -4533,16 +4858,16 @@ function updateSettings(cli, commands) {
|
|
|
4533
4858
|
// src/commands/permitCliReads/index.ts
|
|
4534
4859
|
function logPath(cli) {
|
|
4535
4860
|
const safeName = cli.replace(/\s+/g, "-");
|
|
4536
|
-
return
|
|
4861
|
+
return join17(homedir4(), ".assist", `cli-discover-${safeName}.log`);
|
|
4537
4862
|
}
|
|
4538
4863
|
function readCache(cli) {
|
|
4539
4864
|
const path50 = logPath(cli);
|
|
4540
4865
|
if (!existsSync23(path50)) return void 0;
|
|
4541
|
-
return
|
|
4866
|
+
return readFileSync19(path50, "utf-8");
|
|
4542
4867
|
}
|
|
4543
4868
|
function writeCache(cli, output) {
|
|
4544
|
-
const dir =
|
|
4545
|
-
|
|
4869
|
+
const dir = join17(homedir4(), ".assist");
|
|
4870
|
+
mkdirSync5(dir, { recursive: true });
|
|
4546
4871
|
writeFileSync16(logPath(cli), output);
|
|
4547
4872
|
}
|
|
4548
4873
|
async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
@@ -5090,7 +5415,7 @@ function registerComplexity(program2) {
|
|
|
5090
5415
|
}
|
|
5091
5416
|
|
|
5092
5417
|
// src/commands/deploy/redirect.ts
|
|
5093
|
-
import { existsSync as existsSync24, readFileSync as
|
|
5418
|
+
import { existsSync as existsSync24, readFileSync as readFileSync20, writeFileSync as writeFileSync17 } from "fs";
|
|
5094
5419
|
import chalk64 from "chalk";
|
|
5095
5420
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5096
5421
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -5103,7 +5428,7 @@ function redirect() {
|
|
|
5103
5428
|
console.log(chalk64.yellow("No index.html found"));
|
|
5104
5429
|
return;
|
|
5105
5430
|
}
|
|
5106
|
-
const content =
|
|
5431
|
+
const content = readFileSync20(indexPath, "utf-8");
|
|
5107
5432
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5108
5433
|
console.log(chalk64.dim("Trailing slash script already present"));
|
|
5109
5434
|
return;
|
|
@@ -5131,10 +5456,10 @@ import { basename as basename3 } from "path";
|
|
|
5131
5456
|
|
|
5132
5457
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
5133
5458
|
import { homedir as homedir5 } from "os";
|
|
5134
|
-
import { join as
|
|
5135
|
-
var BLOG_REPO_ROOT =
|
|
5459
|
+
import { join as join18 } from "path";
|
|
5460
|
+
var BLOG_REPO_ROOT = join18(homedir5(), "git/blog");
|
|
5136
5461
|
function loadBlogSkipDays(repoName) {
|
|
5137
|
-
const config = loadRawYaml(
|
|
5462
|
+
const config = loadRawYaml(join18(BLOG_REPO_ROOT, "assist.yml"));
|
|
5138
5463
|
const devlog = config.devlog;
|
|
5139
5464
|
const skip2 = devlog?.skip;
|
|
5140
5465
|
return new Set(skip2?.[repoName] ?? []);
|
|
@@ -5145,9 +5470,9 @@ import { execSync as execSync17 } from "child_process";
|
|
|
5145
5470
|
import chalk65 from "chalk";
|
|
5146
5471
|
|
|
5147
5472
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
5148
|
-
import { readdirSync, readFileSync as
|
|
5149
|
-
import { join as
|
|
5150
|
-
var DEVLOG_DIR =
|
|
5473
|
+
import { readdirSync, readFileSync as readFileSync21 } from "fs";
|
|
5474
|
+
import { join as join19 } from "path";
|
|
5475
|
+
var DEVLOG_DIR = join19(BLOG_REPO_ROOT, "src/content/devlog");
|
|
5151
5476
|
function extractFrontmatter(content) {
|
|
5152
5477
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5153
5478
|
return fm?.[1] ?? null;
|
|
@@ -5175,7 +5500,7 @@ function readDevlogFiles(callback) {
|
|
|
5175
5500
|
try {
|
|
5176
5501
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
5177
5502
|
for (const file of files) {
|
|
5178
|
-
const content =
|
|
5503
|
+
const content = readFileSync21(join19(DEVLOG_DIR, file), "utf-8");
|
|
5179
5504
|
const parsed = parseFrontmatter(content, file);
|
|
5180
5505
|
if (parsed) callback(parsed);
|
|
5181
5506
|
}
|
|
@@ -5354,7 +5679,8 @@ function getLastVersionInfo(repoName, config) {
|
|
|
5354
5679
|
const gitInfo = getLastVersionInfoFromGit();
|
|
5355
5680
|
if (gitInfo) return { date: lastDate, version: gitInfo.version };
|
|
5356
5681
|
}
|
|
5357
|
-
const
|
|
5682
|
+
const dayEntries = entries.get(lastDate);
|
|
5683
|
+
const lastVersion = dayEntries?.[dayEntries.length - 1]?.version;
|
|
5358
5684
|
return lastVersion ? { date: lastDate, version: lastVersion } : null;
|
|
5359
5685
|
}
|
|
5360
5686
|
function cleanVersion(version2) {
|
|
@@ -5561,11 +5887,11 @@ function repos(options2) {
|
|
|
5561
5887
|
|
|
5562
5888
|
// src/commands/devlog/skip.ts
|
|
5563
5889
|
import { writeFileSync as writeFileSync18 } from "fs";
|
|
5564
|
-
import { join as
|
|
5890
|
+
import { join as join20 } from "path";
|
|
5565
5891
|
import chalk70 from "chalk";
|
|
5566
|
-
import { stringify as
|
|
5892
|
+
import { stringify as stringifyYaml3 } from "yaml";
|
|
5567
5893
|
function getBlogConfigPath() {
|
|
5568
|
-
return
|
|
5894
|
+
return join20(BLOG_REPO_ROOT, "assist.yml");
|
|
5569
5895
|
}
|
|
5570
5896
|
function skip(date) {
|
|
5571
5897
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -5589,7 +5915,7 @@ function skip(date) {
|
|
|
5589
5915
|
skip2[repoName] = skipDays;
|
|
5590
5916
|
devlog.skip = skip2;
|
|
5591
5917
|
config.devlog = devlog;
|
|
5592
|
-
writeFileSync18(configPath,
|
|
5918
|
+
writeFileSync18(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
5593
5919
|
console.log(chalk70.green(`Added ${date} to skip list for ${repoName}`));
|
|
5594
5920
|
}
|
|
5595
5921
|
|
|
@@ -5626,7 +5952,7 @@ function registerDevlog(program2) {
|
|
|
5626
5952
|
|
|
5627
5953
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
5628
5954
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
5629
|
-
import { join as
|
|
5955
|
+
import { join as join21 } from "path";
|
|
5630
5956
|
import chalk72 from "chalk";
|
|
5631
5957
|
|
|
5632
5958
|
// src/shared/findRepoRoot.ts
|
|
@@ -5654,7 +5980,7 @@ function isLockedDll(debugDir) {
|
|
|
5654
5980
|
}
|
|
5655
5981
|
for (const file of files) {
|
|
5656
5982
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
5657
|
-
const dllPath =
|
|
5983
|
+
const dllPath = join21(debugDir, file);
|
|
5658
5984
|
try {
|
|
5659
5985
|
const fd = openSync(dllPath, "r+");
|
|
5660
5986
|
closeSync(fd);
|
|
@@ -5672,13 +5998,13 @@ function findFirstLockedDll(dir) {
|
|
|
5672
5998
|
return null;
|
|
5673
5999
|
}
|
|
5674
6000
|
if (entries.includes("bin")) {
|
|
5675
|
-
const locked = isLockedDll(
|
|
6001
|
+
const locked = isLockedDll(join21(dir, "bin", "Debug"));
|
|
5676
6002
|
if (locked) return locked;
|
|
5677
6003
|
}
|
|
5678
6004
|
for (const entry of entries) {
|
|
5679
6005
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
5680
6006
|
continue;
|
|
5681
|
-
const found = findFirstLockedDll(
|
|
6007
|
+
const found = findFirstLockedDll(join21(dir, entry));
|
|
5682
6008
|
if (found) return found;
|
|
5683
6009
|
}
|
|
5684
6010
|
return null;
|
|
@@ -5701,11 +6027,11 @@ async function checkBuildLocksCommand() {
|
|
|
5701
6027
|
}
|
|
5702
6028
|
|
|
5703
6029
|
// src/commands/dotnet/buildTree.ts
|
|
5704
|
-
import { readFileSync as
|
|
6030
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
5705
6031
|
import path22 from "path";
|
|
5706
6032
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
5707
6033
|
function getProjectRefs(csprojPath) {
|
|
5708
|
-
const content =
|
|
6034
|
+
const content = readFileSync22(csprojPath, "utf-8");
|
|
5709
6035
|
const refs = [];
|
|
5710
6036
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
5711
6037
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -5722,7 +6048,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
5722
6048
|
for (const ref of getProjectRefs(abs)) {
|
|
5723
6049
|
const childAbs = path22.resolve(dir, ref);
|
|
5724
6050
|
try {
|
|
5725
|
-
|
|
6051
|
+
readFileSync22(childAbs);
|
|
5726
6052
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
5727
6053
|
} catch {
|
|
5728
6054
|
node.children.push({
|
|
@@ -5747,7 +6073,7 @@ function collectAllDeps(node) {
|
|
|
5747
6073
|
}
|
|
5748
6074
|
|
|
5749
6075
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
5750
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
6076
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync23, statSync as statSync3 } from "fs";
|
|
5751
6077
|
import path23 from "path";
|
|
5752
6078
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
5753
6079
|
if (depth > maxDepth) return [];
|
|
@@ -5763,7 +6089,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
|
5763
6089
|
continue;
|
|
5764
6090
|
const full = path23.join(dir, entry);
|
|
5765
6091
|
try {
|
|
5766
|
-
const stat =
|
|
6092
|
+
const stat = statSync3(full);
|
|
5767
6093
|
if (stat.isFile() && entry.endsWith(".sln")) {
|
|
5768
6094
|
results.push(full);
|
|
5769
6095
|
} else if (stat.isDirectory()) {
|
|
@@ -5782,7 +6108,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
5782
6108
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
5783
6109
|
for (const sln of slnFiles) {
|
|
5784
6110
|
try {
|
|
5785
|
-
const content =
|
|
6111
|
+
const content = readFileSync23(sln, "utf-8");
|
|
5786
6112
|
if (pattern2.test(content)) {
|
|
5787
6113
|
matches.push(path23.relative(repoRoot, sln));
|
|
5788
6114
|
}
|
|
@@ -6025,11 +6351,11 @@ import chalk78 from "chalk";
|
|
|
6025
6351
|
|
|
6026
6352
|
// src/commands/dotnet/findSolution.ts
|
|
6027
6353
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6028
|
-
import { dirname as dirname16, join as
|
|
6354
|
+
import { dirname as dirname16, join as join22 } from "path";
|
|
6029
6355
|
import chalk77 from "chalk";
|
|
6030
6356
|
function findSlnInDir(dir) {
|
|
6031
6357
|
try {
|
|
6032
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
6358
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join22(dir, f));
|
|
6033
6359
|
} catch {
|
|
6034
6360
|
return [];
|
|
6035
6361
|
}
|
|
@@ -6100,7 +6426,7 @@ function parseInspectReport(json) {
|
|
|
6100
6426
|
|
|
6101
6427
|
// src/commands/dotnet/runInspectCode.ts
|
|
6102
6428
|
import { execSync as execSync23 } from "child_process";
|
|
6103
|
-
import { existsSync as existsSync28, readFileSync as
|
|
6429
|
+
import { existsSync as existsSync28, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
6104
6430
|
import { tmpdir as tmpdir2 } from "os";
|
|
6105
6431
|
import path26 from "path";
|
|
6106
6432
|
import chalk79 from "chalk";
|
|
@@ -6135,7 +6461,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6135
6461
|
console.error(chalk79.red("Report file not generated"));
|
|
6136
6462
|
process.exit(1);
|
|
6137
6463
|
}
|
|
6138
|
-
const xml =
|
|
6464
|
+
const xml = readFileSync24(reportPath, "utf-8");
|
|
6139
6465
|
unlinkSync5(reportPath);
|
|
6140
6466
|
return xml;
|
|
6141
6467
|
}
|
|
@@ -6363,20 +6689,20 @@ function acceptanceCriteria(issueKey) {
|
|
|
6363
6689
|
import { execSync as execSync26 } from "child_process";
|
|
6364
6690
|
|
|
6365
6691
|
// src/shared/loadJson.ts
|
|
6366
|
-
import { existsSync as existsSync29, mkdirSync as
|
|
6692
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync19 } from "fs";
|
|
6367
6693
|
import { homedir as homedir6 } from "os";
|
|
6368
|
-
import { join as
|
|
6694
|
+
import { join as join23 } from "path";
|
|
6369
6695
|
function getStoreDir() {
|
|
6370
|
-
return
|
|
6696
|
+
return join23(homedir6(), ".assist");
|
|
6371
6697
|
}
|
|
6372
6698
|
function getStorePath(filename) {
|
|
6373
|
-
return
|
|
6699
|
+
return join23(getStoreDir(), filename);
|
|
6374
6700
|
}
|
|
6375
6701
|
function loadJson(filename) {
|
|
6376
6702
|
const path50 = getStorePath(filename);
|
|
6377
6703
|
if (existsSync29(path50)) {
|
|
6378
6704
|
try {
|
|
6379
|
-
return JSON.parse(
|
|
6705
|
+
return JSON.parse(readFileSync25(path50, "utf-8"));
|
|
6380
6706
|
} catch {
|
|
6381
6707
|
return {};
|
|
6382
6708
|
}
|
|
@@ -6386,7 +6712,7 @@ function loadJson(filename) {
|
|
|
6386
6712
|
function saveJson(filename, data) {
|
|
6387
6713
|
const dir = getStoreDir();
|
|
6388
6714
|
if (!existsSync29(dir)) {
|
|
6389
|
-
|
|
6715
|
+
mkdirSync6(dir, { recursive: true });
|
|
6390
6716
|
}
|
|
6391
6717
|
writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
6392
6718
|
}
|
|
@@ -6702,7 +7028,7 @@ function registerNews(program2) {
|
|
|
6702
7028
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
6703
7029
|
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync20 } from "fs";
|
|
6704
7030
|
import { tmpdir as tmpdir3 } from "os";
|
|
6705
|
-
import { join as
|
|
7031
|
+
import { join as join24 } from "path";
|
|
6706
7032
|
|
|
6707
7033
|
// src/commands/prs/shared.ts
|
|
6708
7034
|
import { execSync as execSync27 } from "child_process";
|
|
@@ -6774,7 +7100,7 @@ function comment2(path50, line, body) {
|
|
|
6774
7100
|
validateLine(line);
|
|
6775
7101
|
try {
|
|
6776
7102
|
const prId = getCurrentPrNodeId();
|
|
6777
|
-
const queryFile =
|
|
7103
|
+
const queryFile = join24(tmpdir3(), `gh-query-${Date.now()}.graphql`);
|
|
6778
7104
|
writeFileSync20(queryFile, MUTATION);
|
|
6779
7105
|
try {
|
|
6780
7106
|
const result = spawnSync2(
|
|
@@ -6819,21 +7145,21 @@ import { execSync as execSync29 } from "child_process";
|
|
|
6819
7145
|
import { execSync as execSync28 } from "child_process";
|
|
6820
7146
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "fs";
|
|
6821
7147
|
import { tmpdir as tmpdir4 } from "os";
|
|
6822
|
-
import { join as
|
|
7148
|
+
import { join as join26 } from "path";
|
|
6823
7149
|
|
|
6824
7150
|
// src/commands/prs/loadCommentsCache.ts
|
|
6825
|
-
import { existsSync as existsSync30, readFileSync as
|
|
6826
|
-
import { join as
|
|
7151
|
+
import { existsSync as existsSync30, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
|
|
7152
|
+
import { join as join25 } from "path";
|
|
6827
7153
|
import { parse as parse2 } from "yaml";
|
|
6828
7154
|
function getCachePath(prNumber) {
|
|
6829
|
-
return
|
|
7155
|
+
return join25(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
6830
7156
|
}
|
|
6831
7157
|
function loadCommentsCache(prNumber) {
|
|
6832
7158
|
const cachePath = getCachePath(prNumber);
|
|
6833
7159
|
if (!existsSync30(cachePath)) {
|
|
6834
7160
|
return null;
|
|
6835
7161
|
}
|
|
6836
|
-
const content =
|
|
7162
|
+
const content = readFileSync26(cachePath, "utf-8");
|
|
6837
7163
|
return parse2(content);
|
|
6838
7164
|
}
|
|
6839
7165
|
function deleteCommentsCache(prNumber) {
|
|
@@ -6853,7 +7179,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
6853
7179
|
}
|
|
6854
7180
|
function resolveThread(threadId) {
|
|
6855
7181
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
6856
|
-
const queryFile =
|
|
7182
|
+
const queryFile = join26(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
6857
7183
|
writeFileSync21(queryFile, mutation);
|
|
6858
7184
|
try {
|
|
6859
7185
|
execSync28(
|
|
@@ -6935,18 +7261,18 @@ function fixed(commentId, sha) {
|
|
|
6935
7261
|
}
|
|
6936
7262
|
|
|
6937
7263
|
// src/commands/prs/listComments/index.ts
|
|
6938
|
-
import { existsSync as existsSync31, mkdirSync as
|
|
6939
|
-
import { join as
|
|
7264
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync7, writeFileSync as writeFileSync23 } from "fs";
|
|
7265
|
+
import { join as join28 } from "path";
|
|
6940
7266
|
import { stringify } from "yaml";
|
|
6941
7267
|
|
|
6942
7268
|
// src/commands/prs/fetchThreadIds.ts
|
|
6943
7269
|
import { execSync as execSync30 } from "child_process";
|
|
6944
7270
|
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync22 } from "fs";
|
|
6945
7271
|
import { tmpdir as tmpdir5 } from "os";
|
|
6946
|
-
import { join as
|
|
7272
|
+
import { join as join27 } from "path";
|
|
6947
7273
|
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
7274
|
function fetchThreadIds(org, repo, prNumber) {
|
|
6949
|
-
const queryFile =
|
|
7275
|
+
const queryFile = join27(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
6950
7276
|
writeFileSync22(queryFile, THREAD_QUERY);
|
|
6951
7277
|
try {
|
|
6952
7278
|
const result = execSync30(
|
|
@@ -7060,16 +7386,16 @@ function printComments2(result) {
|
|
|
7060
7386
|
|
|
7061
7387
|
// src/commands/prs/listComments/index.ts
|
|
7062
7388
|
function writeCommentsCache(prNumber, comments2) {
|
|
7063
|
-
const assistDir =
|
|
7389
|
+
const assistDir = join28(process.cwd(), ".assist");
|
|
7064
7390
|
if (!existsSync31(assistDir)) {
|
|
7065
|
-
|
|
7391
|
+
mkdirSync7(assistDir, { recursive: true });
|
|
7066
7392
|
}
|
|
7067
7393
|
const cacheData = {
|
|
7068
7394
|
prNumber,
|
|
7069
7395
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7070
7396
|
comments: comments2
|
|
7071
7397
|
};
|
|
7072
|
-
const cachePath =
|
|
7398
|
+
const cachePath = join28(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
7073
7399
|
writeFileSync23(cachePath, stringify(cacheData));
|
|
7074
7400
|
}
|
|
7075
7401
|
function handleKnownErrors(error) {
|
|
@@ -7102,7 +7428,7 @@ async function listComments() {
|
|
|
7102
7428
|
];
|
|
7103
7429
|
updateCache(prNumber, allComments);
|
|
7104
7430
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
7105
|
-
const cachePath = hasLineComments ?
|
|
7431
|
+
const cachePath = hasLineComments ? join28(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
7106
7432
|
return { comments: allComments, cachePath };
|
|
7107
7433
|
} catch (error) {
|
|
7108
7434
|
const handled = handleKnownErrors(error);
|
|
@@ -9496,8 +9822,8 @@ function registerSeq(program2) {
|
|
|
9496
9822
|
}
|
|
9497
9823
|
|
|
9498
9824
|
// src/commands/transcript/shared.ts
|
|
9499
|
-
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as
|
|
9500
|
-
import { basename as basename4, join as
|
|
9825
|
+
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
9826
|
+
import { basename as basename4, join as join29, relative } from "path";
|
|
9501
9827
|
import * as readline2 from "readline";
|
|
9502
9828
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
9503
9829
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -9515,8 +9841,8 @@ function collectFiles(dir, extension) {
|
|
|
9515
9841
|
if (!existsSync32(dir)) return [];
|
|
9516
9842
|
const results = [];
|
|
9517
9843
|
for (const entry of readdirSync5(dir)) {
|
|
9518
|
-
const fullPath =
|
|
9519
|
-
if (
|
|
9844
|
+
const fullPath = join29(dir, entry);
|
|
9845
|
+
if (statSync4(fullPath).isDirectory()) {
|
|
9520
9846
|
results.push(...collectFiles(fullPath, extension));
|
|
9521
9847
|
} else if (entry.endsWith(extension)) {
|
|
9522
9848
|
results.push(fullPath);
|
|
@@ -9612,11 +9938,11 @@ async function configure() {
|
|
|
9612
9938
|
import { existsSync as existsSync34 } from "fs";
|
|
9613
9939
|
|
|
9614
9940
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9615
|
-
import { dirname as dirname18, join as
|
|
9941
|
+
import { dirname as dirname18, join as join31 } from "path";
|
|
9616
9942
|
|
|
9617
9943
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
9618
|
-
import { renameSync } from "fs";
|
|
9619
|
-
import { join as
|
|
9944
|
+
import { renameSync as renameSync2 } from "fs";
|
|
9945
|
+
import { join as join30 } from "path";
|
|
9620
9946
|
async function resolveDate(rl, choice) {
|
|
9621
9947
|
if (choice === "1") return getDatePrefix(0);
|
|
9622
9948
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -9631,7 +9957,7 @@ async function resolveDate(rl, choice) {
|
|
|
9631
9957
|
}
|
|
9632
9958
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
9633
9959
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
9634
|
-
|
|
9960
|
+
renameSync2(join30(vttDir, vttFile), join30(vttDir, newFilename));
|
|
9635
9961
|
console.log(`Renamed to: ${newFilename}`);
|
|
9636
9962
|
return newFilename;
|
|
9637
9963
|
}
|
|
@@ -9665,12 +9991,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9665
9991
|
const vttFileDir = dirname18(vttFile.absolutePath);
|
|
9666
9992
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
9667
9993
|
if (newFilename) {
|
|
9668
|
-
const newRelativePath =
|
|
9994
|
+
const newRelativePath = join31(
|
|
9669
9995
|
dirname18(vttFile.relativePath),
|
|
9670
9996
|
newFilename
|
|
9671
9997
|
);
|
|
9672
9998
|
vttFiles[i] = {
|
|
9673
|
-
absolutePath:
|
|
9999
|
+
absolutePath: join31(vttFileDir, newFilename),
|
|
9674
10000
|
relativePath: newRelativePath,
|
|
9675
10001
|
filename: newFilename
|
|
9676
10002
|
};
|
|
@@ -9683,8 +10009,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9683
10009
|
}
|
|
9684
10010
|
|
|
9685
10011
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
9686
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
9687
|
-
import { basename as basename5, dirname as dirname19, join as
|
|
10012
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync24 } from "fs";
|
|
10013
|
+
import { basename as basename5, dirname as dirname19, join as join32 } from "path";
|
|
9688
10014
|
|
|
9689
10015
|
// src/commands/transcript/cleanText.ts
|
|
9690
10016
|
function cleanText(text) {
|
|
@@ -9894,22 +10220,22 @@ function toMdFilename(vttFilename) {
|
|
|
9894
10220
|
return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
9895
10221
|
}
|
|
9896
10222
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
9897
|
-
return relativeDir === "." ? transcriptsDir :
|
|
10223
|
+
return relativeDir === "." ? transcriptsDir : join32(transcriptsDir, relativeDir);
|
|
9898
10224
|
}
|
|
9899
10225
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
9900
10226
|
const mdFile = toMdFilename(vttFile.filename);
|
|
9901
10227
|
const relativeDir = dirname19(vttFile.relativePath);
|
|
9902
10228
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
9903
|
-
const outputPath =
|
|
10229
|
+
const outputPath = join32(outputDir, mdFile);
|
|
9904
10230
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
9905
10231
|
}
|
|
9906
10232
|
function logSkipped(relativeDir, mdFile) {
|
|
9907
|
-
console.log(`Skipping (already exists): ${
|
|
10233
|
+
console.log(`Skipping (already exists): ${join32(relativeDir, mdFile)}`);
|
|
9908
10234
|
return "skipped";
|
|
9909
10235
|
}
|
|
9910
10236
|
function ensureDirectory(dir, label2) {
|
|
9911
10237
|
if (!existsSync33(dir)) {
|
|
9912
|
-
|
|
10238
|
+
mkdirSync8(dir, { recursive: true });
|
|
9913
10239
|
console.log(`Created ${label2}: ${dir}`);
|
|
9914
10240
|
}
|
|
9915
10241
|
}
|
|
@@ -9931,7 +10257,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
9931
10257
|
}
|
|
9932
10258
|
function readAndParseCues(inputPath) {
|
|
9933
10259
|
console.log(`Reading: ${inputPath}`);
|
|
9934
|
-
return processCues(
|
|
10260
|
+
return processCues(readFileSync27(inputPath, "utf-8"));
|
|
9935
10261
|
}
|
|
9936
10262
|
function writeFormatted(outputPath, content) {
|
|
9937
10263
|
writeFileSync24(outputPath, content, "utf-8");
|
|
@@ -10003,17 +10329,17 @@ async function format() {
|
|
|
10003
10329
|
|
|
10004
10330
|
// src/commands/transcript/summarise/index.ts
|
|
10005
10331
|
import { existsSync as existsSync36 } from "fs";
|
|
10006
|
-
import { basename as basename6, dirname as dirname21, join as
|
|
10332
|
+
import { basename as basename6, dirname as dirname21, join as join34, relative as relative2 } from "path";
|
|
10007
10333
|
|
|
10008
10334
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10009
10335
|
import {
|
|
10010
10336
|
existsSync as existsSync35,
|
|
10011
|
-
mkdirSync as
|
|
10012
|
-
readFileSync as
|
|
10013
|
-
renameSync as
|
|
10337
|
+
mkdirSync as mkdirSync9,
|
|
10338
|
+
readFileSync as readFileSync28,
|
|
10339
|
+
renameSync as renameSync3,
|
|
10014
10340
|
rmSync
|
|
10015
10341
|
} from "fs";
|
|
10016
|
-
import { dirname as dirname20, join as
|
|
10342
|
+
import { dirname as dirname20, join as join33 } from "path";
|
|
10017
10343
|
|
|
10018
10344
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10019
10345
|
import chalk118 from "chalk";
|
|
@@ -10042,7 +10368,7 @@ function validateStagedContent(filename, content) {
|
|
|
10042
10368
|
}
|
|
10043
10369
|
|
|
10044
10370
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10045
|
-
var STAGING_DIR =
|
|
10371
|
+
var STAGING_DIR = join33(process.cwd(), ".assist", "transcript");
|
|
10046
10372
|
function processStagedFile() {
|
|
10047
10373
|
if (!existsSync35(STAGING_DIR)) {
|
|
10048
10374
|
return false;
|
|
@@ -10053,7 +10379,7 @@ function processStagedFile() {
|
|
|
10053
10379
|
}
|
|
10054
10380
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10055
10381
|
const stagedFile = stagedFiles[0];
|
|
10056
|
-
const content =
|
|
10382
|
+
const content = readFileSync28(stagedFile.absolutePath, "utf-8");
|
|
10057
10383
|
validateStagedContent(stagedFile.filename, content);
|
|
10058
10384
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
10059
10385
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -10066,12 +10392,12 @@ function processStagedFile() {
|
|
|
10066
10392
|
);
|
|
10067
10393
|
process.exit(1);
|
|
10068
10394
|
}
|
|
10069
|
-
const destPath =
|
|
10395
|
+
const destPath = join33(summaryDir, matchingTranscript.relativePath);
|
|
10070
10396
|
const destDir = dirname20(destPath);
|
|
10071
10397
|
if (!existsSync35(destDir)) {
|
|
10072
|
-
|
|
10398
|
+
mkdirSync9(destDir, { recursive: true });
|
|
10073
10399
|
}
|
|
10074
|
-
|
|
10400
|
+
renameSync3(stagedFile.absolutePath, destPath);
|
|
10075
10401
|
const remaining = findMdFilesRecursive(STAGING_DIR);
|
|
10076
10402
|
if (remaining.length === 0) {
|
|
10077
10403
|
rmSync(STAGING_DIR, { recursive: true });
|
|
@@ -10082,7 +10408,7 @@ function processStagedFile() {
|
|
|
10082
10408
|
// src/commands/transcript/summarise/index.ts
|
|
10083
10409
|
function buildRelativeKey(relativePath, baseName) {
|
|
10084
10410
|
const relDir = dirname21(relativePath);
|
|
10085
|
-
return relDir === "." ? baseName :
|
|
10411
|
+
return relDir === "." ? baseName : join34(relDir, baseName);
|
|
10086
10412
|
}
|
|
10087
10413
|
function buildSummaryIndex(summaryDir) {
|
|
10088
10414
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -10116,8 +10442,8 @@ function summarise2() {
|
|
|
10116
10442
|
}
|
|
10117
10443
|
const next3 = missing[0];
|
|
10118
10444
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
10119
|
-
const outputPath =
|
|
10120
|
-
const summaryFileDir =
|
|
10445
|
+
const outputPath = join34(STAGING_DIR, outputFilename);
|
|
10446
|
+
const summaryFileDir = join34(summaryDir, dirname21(next3.relativePath));
|
|
10121
10447
|
const relativeTranscriptPath = encodeURI(
|
|
10122
10448
|
relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
10123
10449
|
);
|
|
@@ -10163,50 +10489,50 @@ function registerVerify(program2) {
|
|
|
10163
10489
|
|
|
10164
10490
|
// src/commands/voice/devices.ts
|
|
10165
10491
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10166
|
-
import { join as
|
|
10492
|
+
import { join as join36 } from "path";
|
|
10167
10493
|
|
|
10168
10494
|
// src/commands/voice/shared.ts
|
|
10169
10495
|
import { homedir as homedir7 } from "os";
|
|
10170
|
-
import { dirname as dirname22, join as
|
|
10496
|
+
import { dirname as dirname22, join as join35 } from "path";
|
|
10171
10497
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
10172
10498
|
var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
|
|
10173
|
-
var VOICE_DIR =
|
|
10499
|
+
var VOICE_DIR = join35(homedir7(), ".assist", "voice");
|
|
10174
10500
|
var voicePaths = {
|
|
10175
10501
|
dir: VOICE_DIR,
|
|
10176
|
-
pid:
|
|
10177
|
-
log:
|
|
10178
|
-
venv:
|
|
10179
|
-
lock:
|
|
10502
|
+
pid: join35(VOICE_DIR, "voice.pid"),
|
|
10503
|
+
log: join35(VOICE_DIR, "voice.log"),
|
|
10504
|
+
venv: join35(VOICE_DIR, ".venv"),
|
|
10505
|
+
lock: join35(VOICE_DIR, "voice.lock")
|
|
10180
10506
|
};
|
|
10181
10507
|
function getPythonDir() {
|
|
10182
|
-
return
|
|
10508
|
+
return join35(__dirname6, "commands", "voice", "python");
|
|
10183
10509
|
}
|
|
10184
10510
|
function getVenvPython() {
|
|
10185
|
-
return process.platform === "win32" ?
|
|
10511
|
+
return process.platform === "win32" ? join35(voicePaths.venv, "Scripts", "python.exe") : join35(voicePaths.venv, "bin", "python");
|
|
10186
10512
|
}
|
|
10187
10513
|
function getLockDir() {
|
|
10188
10514
|
const config = loadConfig();
|
|
10189
10515
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
10190
10516
|
}
|
|
10191
10517
|
function getLockFile() {
|
|
10192
|
-
return
|
|
10518
|
+
return join35(getLockDir(), "voice.lock");
|
|
10193
10519
|
}
|
|
10194
10520
|
|
|
10195
10521
|
// src/commands/voice/devices.ts
|
|
10196
10522
|
function devices() {
|
|
10197
|
-
const script =
|
|
10523
|
+
const script = join36(getPythonDir(), "list_devices.py");
|
|
10198
10524
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
10199
10525
|
}
|
|
10200
10526
|
|
|
10201
10527
|
// src/commands/voice/logs.ts
|
|
10202
|
-
import { existsSync as existsSync37, readFileSync as
|
|
10528
|
+
import { existsSync as existsSync37, readFileSync as readFileSync29 } from "fs";
|
|
10203
10529
|
function logs(options2) {
|
|
10204
10530
|
if (!existsSync37(voicePaths.log)) {
|
|
10205
10531
|
console.log("No voice log file found");
|
|
10206
10532
|
return;
|
|
10207
10533
|
}
|
|
10208
10534
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
10209
|
-
const content =
|
|
10535
|
+
const content = readFileSync29(voicePaths.log, "utf-8").trim();
|
|
10210
10536
|
if (!content) {
|
|
10211
10537
|
console.log("Voice log is empty");
|
|
10212
10538
|
return;
|
|
@@ -10228,13 +10554,13 @@ function logs(options2) {
|
|
|
10228
10554
|
|
|
10229
10555
|
// src/commands/voice/setup.ts
|
|
10230
10556
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
10231
|
-
import { mkdirSync as
|
|
10232
|
-
import { join as
|
|
10557
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
10558
|
+
import { join as join38 } from "path";
|
|
10233
10559
|
|
|
10234
10560
|
// src/commands/voice/checkLockFile.ts
|
|
10235
10561
|
import { execSync as execSync37 } from "child_process";
|
|
10236
|
-
import { existsSync as existsSync38, mkdirSync as
|
|
10237
|
-
import { join as
|
|
10562
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync25 } from "fs";
|
|
10563
|
+
import { join as join37 } from "path";
|
|
10238
10564
|
function isProcessAlive2(pid) {
|
|
10239
10565
|
try {
|
|
10240
10566
|
process.kill(pid, 0);
|
|
@@ -10247,7 +10573,7 @@ function checkLockFile() {
|
|
|
10247
10573
|
const lockFile = getLockFile();
|
|
10248
10574
|
if (!existsSync38(lockFile)) return;
|
|
10249
10575
|
try {
|
|
10250
|
-
const lock = JSON.parse(
|
|
10576
|
+
const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
|
|
10251
10577
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
10252
10578
|
console.error(
|
|
10253
10579
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -10271,7 +10597,7 @@ function bootstrapVenv() {
|
|
|
10271
10597
|
}
|
|
10272
10598
|
function writeLockFile(pid) {
|
|
10273
10599
|
const lockFile = getLockFile();
|
|
10274
|
-
|
|
10600
|
+
mkdirSync10(join37(lockFile, ".."), { recursive: true });
|
|
10275
10601
|
writeFileSync25(
|
|
10276
10602
|
lockFile,
|
|
10277
10603
|
JSON.stringify({
|
|
@@ -10284,10 +10610,10 @@ function writeLockFile(pid) {
|
|
|
10284
10610
|
|
|
10285
10611
|
// src/commands/voice/setup.ts
|
|
10286
10612
|
function setup() {
|
|
10287
|
-
|
|
10613
|
+
mkdirSync11(voicePaths.dir, { recursive: true });
|
|
10288
10614
|
bootstrapVenv();
|
|
10289
10615
|
console.log("\nDownloading models...\n");
|
|
10290
|
-
const script =
|
|
10616
|
+
const script = join38(getPythonDir(), "setup_models.py");
|
|
10291
10617
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
10292
10618
|
stdio: "inherit",
|
|
10293
10619
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -10300,8 +10626,8 @@ function setup() {
|
|
|
10300
10626
|
|
|
10301
10627
|
// src/commands/voice/start.ts
|
|
10302
10628
|
import { spawn as spawn5 } from "child_process";
|
|
10303
|
-
import { mkdirSync as
|
|
10304
|
-
import { join as
|
|
10629
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
10630
|
+
import { join as join39 } from "path";
|
|
10305
10631
|
|
|
10306
10632
|
// src/commands/voice/buildDaemonEnv.ts
|
|
10307
10633
|
function buildDaemonEnv(options2) {
|
|
@@ -10334,12 +10660,12 @@ function spawnBackground(python, script, env) {
|
|
|
10334
10660
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
10335
10661
|
}
|
|
10336
10662
|
function start2(options2) {
|
|
10337
|
-
|
|
10663
|
+
mkdirSync12(voicePaths.dir, { recursive: true });
|
|
10338
10664
|
checkLockFile();
|
|
10339
10665
|
bootstrapVenv();
|
|
10340
10666
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
10341
10667
|
const env = buildDaemonEnv({ debug });
|
|
10342
|
-
const script =
|
|
10668
|
+
const script = join39(getPythonDir(), "voice_daemon.py");
|
|
10343
10669
|
const python = getVenvPython();
|
|
10344
10670
|
if (options2.foreground) {
|
|
10345
10671
|
spawnForeground(python, script, env);
|
|
@@ -10349,7 +10675,7 @@ function start2(options2) {
|
|
|
10349
10675
|
}
|
|
10350
10676
|
|
|
10351
10677
|
// src/commands/voice/status.ts
|
|
10352
|
-
import { existsSync as existsSync39, readFileSync as
|
|
10678
|
+
import { existsSync as existsSync39, readFileSync as readFileSync31 } from "fs";
|
|
10353
10679
|
function isProcessAlive3(pid) {
|
|
10354
10680
|
try {
|
|
10355
10681
|
process.kill(pid, 0);
|
|
@@ -10360,7 +10686,7 @@ function isProcessAlive3(pid) {
|
|
|
10360
10686
|
}
|
|
10361
10687
|
function readRecentLogs(count) {
|
|
10362
10688
|
if (!existsSync39(voicePaths.log)) return [];
|
|
10363
|
-
const lines =
|
|
10689
|
+
const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
|
|
10364
10690
|
return lines.slice(-count);
|
|
10365
10691
|
}
|
|
10366
10692
|
function status() {
|
|
@@ -10368,7 +10694,7 @@ function status() {
|
|
|
10368
10694
|
console.log("Voice daemon: not running (no PID file)");
|
|
10369
10695
|
return;
|
|
10370
10696
|
}
|
|
10371
|
-
const pid = Number.parseInt(
|
|
10697
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10372
10698
|
const alive = isProcessAlive3(pid);
|
|
10373
10699
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10374
10700
|
const recent = readRecentLogs(5);
|
|
@@ -10387,13 +10713,13 @@ function status() {
|
|
|
10387
10713
|
}
|
|
10388
10714
|
|
|
10389
10715
|
// src/commands/voice/stop.ts
|
|
10390
|
-
import { existsSync as existsSync40, readFileSync as
|
|
10716
|
+
import { existsSync as existsSync40, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
|
|
10391
10717
|
function stop() {
|
|
10392
10718
|
if (!existsSync40(voicePaths.pid)) {
|
|
10393
10719
|
console.log("Voice daemon is not running (no PID file)");
|
|
10394
10720
|
return;
|
|
10395
10721
|
}
|
|
10396
|
-
const pid = Number.parseInt(
|
|
10722
|
+
const pid = Number.parseInt(readFileSync32(voicePaths.pid, "utf-8").trim(), 10);
|
|
10397
10723
|
try {
|
|
10398
10724
|
process.kill(pid, "SIGTERM");
|
|
10399
10725
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10627,15 +10953,15 @@ async function auth() {
|
|
|
10627
10953
|
}
|
|
10628
10954
|
|
|
10629
10955
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10630
|
-
import { readFileSync as
|
|
10631
|
-
import { join as
|
|
10956
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
10957
|
+
import { join as join40 } from "path";
|
|
10632
10958
|
async function showClaudeCodeIcon() {
|
|
10633
10959
|
const appData = process.env.APPDATA;
|
|
10634
10960
|
if (!appData) return;
|
|
10635
|
-
const portFile =
|
|
10961
|
+
const portFile = join40(appData, "Roam", "roam-local-api.port");
|
|
10636
10962
|
let port;
|
|
10637
10963
|
try {
|
|
10638
|
-
port =
|
|
10964
|
+
port = readFileSync33(portFile, "utf-8").trim();
|
|
10639
10965
|
} catch {
|
|
10640
10966
|
return;
|
|
10641
10967
|
}
|
|
@@ -10706,8 +11032,8 @@ Done in ${elapsed}`);
|
|
|
10706
11032
|
}
|
|
10707
11033
|
|
|
10708
11034
|
// src/commands/run/add.ts
|
|
10709
|
-
import { mkdirSync as
|
|
10710
|
-
import { join as
|
|
11035
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync27 } from "fs";
|
|
11036
|
+
import { join as join41 } from "path";
|
|
10711
11037
|
function findAddIndex() {
|
|
10712
11038
|
const addIndex = process.argv.indexOf("add");
|
|
10713
11039
|
if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
|
|
@@ -10753,15 +11079,15 @@ function saveNewRunConfig(name, command, args) {
|
|
|
10753
11079
|
saveConfig(config);
|
|
10754
11080
|
}
|
|
10755
11081
|
function createCommandFile(name) {
|
|
10756
|
-
const dir =
|
|
10757
|
-
|
|
11082
|
+
const dir = join41(".claude", "commands");
|
|
11083
|
+
mkdirSync13(dir, { recursive: true });
|
|
10758
11084
|
const content = `---
|
|
10759
11085
|
description: Run ${name}
|
|
10760
11086
|
---
|
|
10761
11087
|
|
|
10762
11088
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
10763
11089
|
`;
|
|
10764
|
-
const filePath =
|
|
11090
|
+
const filePath = join41(dir, `${name}.md`);
|
|
10765
11091
|
writeFileSync27(filePath, content);
|
|
10766
11092
|
console.log(`Created command file: ${filePath}`);
|
|
10767
11093
|
}
|
|
@@ -10832,9 +11158,9 @@ function run3(name, args) {
|
|
|
10832
11158
|
|
|
10833
11159
|
// src/commands/screenshot/index.ts
|
|
10834
11160
|
import { execSync as execSync40 } from "child_process";
|
|
10835
|
-
import { existsSync as existsSync41, mkdirSync as
|
|
11161
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10836
11162
|
import { tmpdir as tmpdir6 } from "os";
|
|
10837
|
-
import { join as
|
|
11163
|
+
import { join as join42, resolve as resolve5 } from "path";
|
|
10838
11164
|
import chalk120 from "chalk";
|
|
10839
11165
|
|
|
10840
11166
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -10965,13 +11291,13 @@ Write-Output $OutputPath
|
|
|
10965
11291
|
// src/commands/screenshot/index.ts
|
|
10966
11292
|
function buildOutputPath(outputDir, processName) {
|
|
10967
11293
|
if (!existsSync41(outputDir)) {
|
|
10968
|
-
|
|
11294
|
+
mkdirSync14(outputDir, { recursive: true });
|
|
10969
11295
|
}
|
|
10970
11296
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10971
11297
|
return resolve5(outputDir, `${processName}-${timestamp}.png`);
|
|
10972
11298
|
}
|
|
10973
11299
|
function runPowerShellScript(processName, outputPath) {
|
|
10974
|
-
const scriptPath =
|
|
11300
|
+
const scriptPath = join42(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
10975
11301
|
writeFileSync28(scriptPath, captureWindowPs1, "utf-8");
|
|
10976
11302
|
try {
|
|
10977
11303
|
execSync40(
|