@staff0rd/assist 0.170.2 → 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 +641 -294
- 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);
|
|
@@ -7996,7 +8322,7 @@ function isNameReferencedInSource(sourceFile, name) {
|
|
|
7996
8322
|
}
|
|
7997
8323
|
async function applyExtraction(functionName, sourceFile, destPath, plan2, project) {
|
|
7998
8324
|
project.createSourceFile(destPath, plan2.destContent, { overwrite: false });
|
|
7999
|
-
for (const fn of [plan2.target, ...plan2.
|
|
8325
|
+
for (const fn of [plan2.target, ...plan2.functionsToRemove]) {
|
|
8000
8326
|
fn.remove();
|
|
8001
8327
|
}
|
|
8002
8328
|
for (const stmt of plan2.statementsToRemove) {
|
|
@@ -8033,7 +8359,7 @@ async function applyExtraction(functionName, sourceFile, destPath, plan2, projec
|
|
|
8033
8359
|
|
|
8034
8360
|
// src/commands/refactor/extract/collectDependencies.ts
|
|
8035
8361
|
import {
|
|
8036
|
-
SyntaxKind as
|
|
8362
|
+
SyntaxKind as SyntaxKind7
|
|
8037
8363
|
} from "ts-morph";
|
|
8038
8364
|
|
|
8039
8365
|
// src/commands/refactor/extract/collectPrivateFunctions.ts
|
|
@@ -8072,6 +8398,41 @@ function collectPrivateFunctions(target, fnMap) {
|
|
|
8072
8398
|
});
|
|
8073
8399
|
}
|
|
8074
8400
|
|
|
8401
|
+
// src/commands/refactor/extract/collectPrivateStatements.ts
|
|
8402
|
+
import { SyntaxKind as SyntaxKind5 } from "ts-morph";
|
|
8403
|
+
function getReferencedIdentifiers(fn) {
|
|
8404
|
+
const names = /* @__PURE__ */ new Set();
|
|
8405
|
+
for (const id of fn.getDescendantsOfKind(SyntaxKind5.Identifier)) {
|
|
8406
|
+
names.add(id.getText());
|
|
8407
|
+
}
|
|
8408
|
+
return names;
|
|
8409
|
+
}
|
|
8410
|
+
function collectPrivateStatements(functions, stmtMap) {
|
|
8411
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8412
|
+
for (const fn of functions) {
|
|
8413
|
+
for (const name of getReferencedIdentifiers(fn)) {
|
|
8414
|
+
const stmt = stmtMap.get(name);
|
|
8415
|
+
if (stmt) seen.add(stmt);
|
|
8416
|
+
}
|
|
8417
|
+
}
|
|
8418
|
+
return [...seen];
|
|
8419
|
+
}
|
|
8420
|
+
|
|
8421
|
+
// src/commands/refactor/extract/getFunctionMap.ts
|
|
8422
|
+
import {
|
|
8423
|
+
SyntaxKind as SyntaxKind6
|
|
8424
|
+
} from "ts-morph";
|
|
8425
|
+
function getFunctionMap(sourceFile) {
|
|
8426
|
+
const map = /* @__PURE__ */ new Map();
|
|
8427
|
+
for (const fn of sourceFile.getDescendantsOfKind(
|
|
8428
|
+
SyntaxKind6.FunctionDeclaration
|
|
8429
|
+
)) {
|
|
8430
|
+
const name = fn.getName();
|
|
8431
|
+
if (name) map.set(name, fn);
|
|
8432
|
+
}
|
|
8433
|
+
return map;
|
|
8434
|
+
}
|
|
8435
|
+
|
|
8075
8436
|
// src/commands/refactor/extract/getPrivateStatementMap.ts
|
|
8076
8437
|
function getPrivateStatementMap(sourceFile) {
|
|
8077
8438
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -8089,73 +8450,61 @@ function getPrivateStatementMap(sourceFile) {
|
|
|
8089
8450
|
}
|
|
8090
8451
|
|
|
8091
8452
|
// src/commands/refactor/extract/collectDependencies.ts
|
|
8092
|
-
function
|
|
8093
|
-
|
|
8094
|
-
for (const id of fn.getDescendantsOfKind(SyntaxKind5.Identifier)) {
|
|
8095
|
-
names.add(id.getText());
|
|
8096
|
-
}
|
|
8097
|
-
return names;
|
|
8098
|
-
}
|
|
8099
|
-
function getFunctionMap(sourceFile) {
|
|
8100
|
-
const map = /* @__PURE__ */ new Map();
|
|
8101
|
-
for (const fn of sourceFile.getDescendantsOfKind(
|
|
8102
|
-
SyntaxKind5.FunctionDeclaration
|
|
8103
|
-
)) {
|
|
8104
|
-
const name = fn.getName();
|
|
8105
|
-
if (name) map.set(name, fn);
|
|
8106
|
-
}
|
|
8107
|
-
return map;
|
|
8453
|
+
function getRemainingFunctions(sourceFile, extracted) {
|
|
8454
|
+
return sourceFile.getDescendantsOfKind(SyntaxKind7.FunctionDeclaration).filter((fn) => !extracted.has(fn));
|
|
8108
8455
|
}
|
|
8109
|
-
function
|
|
8110
|
-
const
|
|
8111
|
-
for (const fn of
|
|
8112
|
-
for (const
|
|
8113
|
-
|
|
8114
|
-
if (stmt) seen.add(stmt);
|
|
8456
|
+
function collectFnsUsedByRemaining(remaining, fnMap) {
|
|
8457
|
+
const used = /* @__PURE__ */ new Set();
|
|
8458
|
+
for (const fn of remaining) {
|
|
8459
|
+
for (const dep of collectPrivateFunctions(fn, fnMap)) {
|
|
8460
|
+
used.add(dep);
|
|
8115
8461
|
}
|
|
8116
8462
|
}
|
|
8117
|
-
return
|
|
8118
|
-
}
|
|
8119
|
-
function getRemainingFunctions(sourceFile, extracted) {
|
|
8120
|
-
return sourceFile.getDescendantsOfKind(SyntaxKind5.FunctionDeclaration).filter((fn) => !extracted.has(fn));
|
|
8463
|
+
return used;
|
|
8121
8464
|
}
|
|
8122
8465
|
function collectDependencies(target, sourceFile) {
|
|
8123
8466
|
const fnMap = getFunctionMap(sourceFile);
|
|
8124
8467
|
const depFunctions = collectPrivateFunctions(target, fnMap);
|
|
8125
8468
|
const allExtracted = [target, ...depFunctions];
|
|
8126
8469
|
const stmtMap = getPrivateStatementMap(sourceFile);
|
|
8127
|
-
const
|
|
8128
|
-
const
|
|
8129
|
-
const
|
|
8130
|
-
const
|
|
8131
|
-
const
|
|
8470
|
+
const stmtsToCopy = collectPrivateStatements(allExtracted, stmtMap);
|
|
8471
|
+
const remaining = getRemainingFunctions(sourceFile, new Set(allExtracted));
|
|
8472
|
+
const fnsUsedByRemaining = collectFnsUsedByRemaining(remaining, fnMap);
|
|
8473
|
+
const fnsToRemove = depFunctions.filter((fn) => !fnsUsedByRemaining.has(fn));
|
|
8474
|
+
const staysInSource = [
|
|
8475
|
+
...remaining,
|
|
8476
|
+
...depFunctions.filter((fn) => fnsUsedByRemaining.has(fn))
|
|
8477
|
+
];
|
|
8478
|
+
const stmtsToRemove = stmtsToCopy.filter(
|
|
8479
|
+
(s) => !new Set(collectPrivateStatements(staysInSource, stmtMap)).has(s)
|
|
8480
|
+
);
|
|
8132
8481
|
return {
|
|
8133
|
-
functions: depFunctions,
|
|
8134
|
-
statements: { toCopy, toRemove }
|
|
8482
|
+
functions: { toCopy: depFunctions, toRemove: fnsToRemove },
|
|
8483
|
+
statements: { toCopy: stmtsToCopy, toRemove: stmtsToRemove }
|
|
8135
8484
|
};
|
|
8136
8485
|
}
|
|
8137
8486
|
|
|
8138
8487
|
// src/commands/refactor/extract/findFunction.ts
|
|
8139
8488
|
import {
|
|
8140
|
-
SyntaxKind as
|
|
8489
|
+
SyntaxKind as SyntaxKind8
|
|
8141
8490
|
} from "ts-morph";
|
|
8142
8491
|
function findFunction(sourceFile, functionName) {
|
|
8143
|
-
return sourceFile.getDescendantsOfKind(
|
|
8492
|
+
return sourceFile.getDescendantsOfKind(SyntaxKind8.FunctionDeclaration).find((fn) => fn.getName() === functionName);
|
|
8144
8493
|
}
|
|
8145
8494
|
|
|
8146
8495
|
// src/commands/refactor/extract/getExportedDependencyNames.ts
|
|
8147
|
-
import { SyntaxKind as
|
|
8496
|
+
import { SyntaxKind as SyntaxKind9 } from "ts-morph";
|
|
8148
8497
|
function getExportedDependencyNames(target, sourceFile) {
|
|
8149
8498
|
const calledNames = /* @__PURE__ */ new Set();
|
|
8150
|
-
for (const call of target.getDescendantsOfKind(
|
|
8499
|
+
for (const call of target.getDescendantsOfKind(SyntaxKind9.CallExpression)) {
|
|
8151
8500
|
const expr = call.getExpression();
|
|
8152
|
-
if (expr.getKind() ===
|
|
8501
|
+
if (expr.getKind() === SyntaxKind9.Identifier) {
|
|
8153
8502
|
calledNames.add(expr.getText());
|
|
8154
8503
|
}
|
|
8155
8504
|
}
|
|
8156
8505
|
const exported = [];
|
|
8157
8506
|
for (const fn of sourceFile.getDescendantsOfKind(
|
|
8158
|
-
|
|
8507
|
+
SyntaxKind9.FunctionDeclaration
|
|
8159
8508
|
)) {
|
|
8160
8509
|
const name = fn.getName();
|
|
8161
8510
|
if (name && calledNames.has(name) && fn.isExported()) {
|
|
@@ -8166,9 +8515,9 @@ function getExportedDependencyNames(target, sourceFile) {
|
|
|
8166
8515
|
}
|
|
8167
8516
|
|
|
8168
8517
|
// src/commands/refactor/extract/getStatementNames.ts
|
|
8169
|
-
import { SyntaxKind as
|
|
8518
|
+
import { SyntaxKind as SyntaxKind10 } from "ts-morph";
|
|
8170
8519
|
function getStatementNames(node) {
|
|
8171
|
-
if (node.getKind() ===
|
|
8520
|
+
if (node.getKind() === SyntaxKind10.VariableStatement) {
|
|
8172
8521
|
const stmt = node;
|
|
8173
8522
|
return stmt.getDeclarations().map((d) => d.getName());
|
|
8174
8523
|
}
|
|
@@ -8178,7 +8527,7 @@ function getStatementNames(node) {
|
|
|
8178
8527
|
|
|
8179
8528
|
// src/commands/refactor/extract/resolveImports.ts
|
|
8180
8529
|
import {
|
|
8181
|
-
SyntaxKind as
|
|
8530
|
+
SyntaxKind as SyntaxKind11
|
|
8182
8531
|
} from "ts-morph";
|
|
8183
8532
|
|
|
8184
8533
|
// src/commands/refactor/extract/matchImport.ts
|
|
@@ -8222,7 +8571,7 @@ function matchImport(importDecl, neededNames) {
|
|
|
8222
8571
|
function getReferencedNames(nodes) {
|
|
8223
8572
|
const names = /* @__PURE__ */ new Set();
|
|
8224
8573
|
for (const node of nodes) {
|
|
8225
|
-
for (const id of node.getDescendantsOfKind(
|
|
8574
|
+
for (const id of node.getDescendantsOfKind(SyntaxKind11.Identifier)) {
|
|
8226
8575
|
names.add(id.getText());
|
|
8227
8576
|
}
|
|
8228
8577
|
}
|
|
@@ -8237,7 +8586,7 @@ function getLocallyDeclaredNames(functions) {
|
|
|
8237
8586
|
names.add(param.getName());
|
|
8238
8587
|
}
|
|
8239
8588
|
for (const varDecl of fn.getDescendantsOfKind(
|
|
8240
|
-
|
|
8589
|
+
SyntaxKind11.VariableDeclaration
|
|
8241
8590
|
)) {
|
|
8242
8591
|
names.add(varDecl.getName());
|
|
8243
8592
|
}
|
|
@@ -8274,26 +8623,24 @@ function extractTexts(target, allFunctions, statements) {
|
|
|
8274
8623
|
function analyseTarget(sourceFile, functionName) {
|
|
8275
8624
|
const target = findFunction(sourceFile, functionName);
|
|
8276
8625
|
if (!target) throw new Error(`Function "${functionName}" not found`);
|
|
8277
|
-
const { functions
|
|
8278
|
-
|
|
8279
|
-
sourceFile
|
|
8280
|
-
);
|
|
8281
|
-
const all = [target, ...dependencies];
|
|
8626
|
+
const { functions, statements } = collectDependencies(target, sourceFile);
|
|
8627
|
+
const all = [target, ...functions.toCopy];
|
|
8282
8628
|
return {
|
|
8283
8629
|
target,
|
|
8284
|
-
dependencies,
|
|
8630
|
+
dependencies: functions.toCopy,
|
|
8631
|
+
functionsToRemove: functions.toRemove,
|
|
8285
8632
|
statementsToCopy: statements.toCopy,
|
|
8286
8633
|
statementsToRemove: statements.toRemove,
|
|
8287
8634
|
imports: resolveImports(
|
|
8288
8635
|
target,
|
|
8289
|
-
|
|
8636
|
+
functions.toCopy,
|
|
8290
8637
|
sourceFile,
|
|
8291
8638
|
statements.toCopy
|
|
8292
8639
|
),
|
|
8293
8640
|
exportedDeps: getExportedDependencyNames(target, sourceFile),
|
|
8294
8641
|
extractedNames: [
|
|
8295
8642
|
...statements.toRemove.flatMap(getStatementNames),
|
|
8296
|
-
...
|
|
8643
|
+
...[target, ...functions.toRemove].map((fn) => fn.getName()).filter(Boolean)
|
|
8297
8644
|
],
|
|
8298
8645
|
functionTexts: extractTexts(target, all, statements.toCopy)
|
|
8299
8646
|
};
|
|
@@ -8394,16 +8741,16 @@ function rewriteImportPaths(imports, sourcePath, destPath) {
|
|
|
8394
8741
|
}
|
|
8395
8742
|
|
|
8396
8743
|
// src/commands/refactor/extract/sourceReferencesName.ts
|
|
8397
|
-
import { SyntaxKind as
|
|
8744
|
+
import { SyntaxKind as SyntaxKind12 } from "ts-morph";
|
|
8398
8745
|
var DECLARATION_KINDS = /* @__PURE__ */ new Set([
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8746
|
+
SyntaxKind12.FunctionDeclaration,
|
|
8747
|
+
SyntaxKind12.ImportSpecifier,
|
|
8748
|
+
SyntaxKind12.ExportSpecifier
|
|
8402
8749
|
]);
|
|
8403
8750
|
function isInsideExtractedFunction(node, extracted) {
|
|
8404
8751
|
let current = node;
|
|
8405
8752
|
while (current) {
|
|
8406
|
-
if (current.getKind() !==
|
|
8753
|
+
if (current.getKind() !== SyntaxKind12.FunctionDeclaration) {
|
|
8407
8754
|
current = current.getParent();
|
|
8408
8755
|
continue;
|
|
8409
8756
|
}
|
|
@@ -8415,7 +8762,7 @@ function isInsideExtractedFunction(node, extracted) {
|
|
|
8415
8762
|
}
|
|
8416
8763
|
function sourceReferencesName(sourceFile, functionName, extractedNames) {
|
|
8417
8764
|
const extracted = new Set(extractedNames);
|
|
8418
|
-
for (const id of sourceFile.getDescendantsOfKind(
|
|
8765
|
+
for (const id of sourceFile.getDescendantsOfKind(SyntaxKind12.Identifier)) {
|
|
8419
8766
|
if (id.getText() !== functionName) continue;
|
|
8420
8767
|
const parent = id.getParent();
|
|
8421
8768
|
if (!parent || DECLARATION_KINDS.has(parent.getKind())) continue;
|
|
@@ -8620,24 +8967,24 @@ import chalk107 from "chalk";
|
|
|
8620
8967
|
import { Project as Project3 } from "ts-morph";
|
|
8621
8968
|
|
|
8622
8969
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
8623
|
-
import { SyntaxKind as
|
|
8970
|
+
import { SyntaxKind as SyntaxKind13 } from "ts-morph";
|
|
8624
8971
|
var declarationKinds = [
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8972
|
+
SyntaxKind13.VariableDeclaration,
|
|
8973
|
+
SyntaxKind13.FunctionDeclaration,
|
|
8974
|
+
SyntaxKind13.ClassDeclaration,
|
|
8975
|
+
SyntaxKind13.InterfaceDeclaration,
|
|
8976
|
+
SyntaxKind13.TypeAliasDeclaration,
|
|
8977
|
+
SyntaxKind13.EnumDeclaration,
|
|
8978
|
+
SyntaxKind13.PropertyDeclaration,
|
|
8979
|
+
SyntaxKind13.MethodDeclaration,
|
|
8980
|
+
SyntaxKind13.Parameter
|
|
8634
8981
|
];
|
|
8635
8982
|
function isDeclaration(identifier) {
|
|
8636
8983
|
const parent = identifier.getParent();
|
|
8637
8984
|
return parent !== void 0 && declarationKinds.includes(parent.getKind());
|
|
8638
8985
|
}
|
|
8639
8986
|
function findSymbol(sourceFile, symbolName) {
|
|
8640
|
-
for (const id of sourceFile.getDescendantsOfKind(
|
|
8987
|
+
for (const id of sourceFile.getDescendantsOfKind(SyntaxKind13.Identifier)) {
|
|
8641
8988
|
if (id.getText() === symbolName && isDeclaration(id)) return id;
|
|
8642
8989
|
}
|
|
8643
8990
|
return void 0;
|
|
@@ -9475,8 +9822,8 @@ function registerSeq(program2) {
|
|
|
9475
9822
|
}
|
|
9476
9823
|
|
|
9477
9824
|
// src/commands/transcript/shared.ts
|
|
9478
|
-
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as
|
|
9479
|
-
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";
|
|
9480
9827
|
import * as readline2 from "readline";
|
|
9481
9828
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
9482
9829
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -9494,8 +9841,8 @@ function collectFiles(dir, extension) {
|
|
|
9494
9841
|
if (!existsSync32(dir)) return [];
|
|
9495
9842
|
const results = [];
|
|
9496
9843
|
for (const entry of readdirSync5(dir)) {
|
|
9497
|
-
const fullPath =
|
|
9498
|
-
if (
|
|
9844
|
+
const fullPath = join29(dir, entry);
|
|
9845
|
+
if (statSync4(fullPath).isDirectory()) {
|
|
9499
9846
|
results.push(...collectFiles(fullPath, extension));
|
|
9500
9847
|
} else if (entry.endsWith(extension)) {
|
|
9501
9848
|
results.push(fullPath);
|
|
@@ -9591,11 +9938,11 @@ async function configure() {
|
|
|
9591
9938
|
import { existsSync as existsSync34 } from "fs";
|
|
9592
9939
|
|
|
9593
9940
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
9594
|
-
import { dirname as dirname18, join as
|
|
9941
|
+
import { dirname as dirname18, join as join31 } from "path";
|
|
9595
9942
|
|
|
9596
9943
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
9597
|
-
import { renameSync } from "fs";
|
|
9598
|
-
import { join as
|
|
9944
|
+
import { renameSync as renameSync2 } from "fs";
|
|
9945
|
+
import { join as join30 } from "path";
|
|
9599
9946
|
async function resolveDate(rl, choice) {
|
|
9600
9947
|
if (choice === "1") return getDatePrefix(0);
|
|
9601
9948
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -9610,7 +9957,7 @@ async function resolveDate(rl, choice) {
|
|
|
9610
9957
|
}
|
|
9611
9958
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
9612
9959
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
9613
|
-
|
|
9960
|
+
renameSync2(join30(vttDir, vttFile), join30(vttDir, newFilename));
|
|
9614
9961
|
console.log(`Renamed to: ${newFilename}`);
|
|
9615
9962
|
return newFilename;
|
|
9616
9963
|
}
|
|
@@ -9644,12 +9991,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9644
9991
|
const vttFileDir = dirname18(vttFile.absolutePath);
|
|
9645
9992
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
9646
9993
|
if (newFilename) {
|
|
9647
|
-
const newRelativePath =
|
|
9994
|
+
const newRelativePath = join31(
|
|
9648
9995
|
dirname18(vttFile.relativePath),
|
|
9649
9996
|
newFilename
|
|
9650
9997
|
);
|
|
9651
9998
|
vttFiles[i] = {
|
|
9652
|
-
absolutePath:
|
|
9999
|
+
absolutePath: join31(vttFileDir, newFilename),
|
|
9653
10000
|
relativePath: newRelativePath,
|
|
9654
10001
|
filename: newFilename
|
|
9655
10002
|
};
|
|
@@ -9662,8 +10009,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
9662
10009
|
}
|
|
9663
10010
|
|
|
9664
10011
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
9665
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
9666
|
-
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";
|
|
9667
10014
|
|
|
9668
10015
|
// src/commands/transcript/cleanText.ts
|
|
9669
10016
|
function cleanText(text) {
|
|
@@ -9873,22 +10220,22 @@ function toMdFilename(vttFilename) {
|
|
|
9873
10220
|
return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
9874
10221
|
}
|
|
9875
10222
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
9876
|
-
return relativeDir === "." ? transcriptsDir :
|
|
10223
|
+
return relativeDir === "." ? transcriptsDir : join32(transcriptsDir, relativeDir);
|
|
9877
10224
|
}
|
|
9878
10225
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
9879
10226
|
const mdFile = toMdFilename(vttFile.filename);
|
|
9880
10227
|
const relativeDir = dirname19(vttFile.relativePath);
|
|
9881
10228
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
9882
|
-
const outputPath =
|
|
10229
|
+
const outputPath = join32(outputDir, mdFile);
|
|
9883
10230
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
9884
10231
|
}
|
|
9885
10232
|
function logSkipped(relativeDir, mdFile) {
|
|
9886
|
-
console.log(`Skipping (already exists): ${
|
|
10233
|
+
console.log(`Skipping (already exists): ${join32(relativeDir, mdFile)}`);
|
|
9887
10234
|
return "skipped";
|
|
9888
10235
|
}
|
|
9889
10236
|
function ensureDirectory(dir, label2) {
|
|
9890
10237
|
if (!existsSync33(dir)) {
|
|
9891
|
-
|
|
10238
|
+
mkdirSync8(dir, { recursive: true });
|
|
9892
10239
|
console.log(`Created ${label2}: ${dir}`);
|
|
9893
10240
|
}
|
|
9894
10241
|
}
|
|
@@ -9910,7 +10257,7 @@ function logReduction(cueCount, messageCount) {
|
|
|
9910
10257
|
}
|
|
9911
10258
|
function readAndParseCues(inputPath) {
|
|
9912
10259
|
console.log(`Reading: ${inputPath}`);
|
|
9913
|
-
return processCues(
|
|
10260
|
+
return processCues(readFileSync27(inputPath, "utf-8"));
|
|
9914
10261
|
}
|
|
9915
10262
|
function writeFormatted(outputPath, content) {
|
|
9916
10263
|
writeFileSync24(outputPath, content, "utf-8");
|
|
@@ -9982,17 +10329,17 @@ async function format() {
|
|
|
9982
10329
|
|
|
9983
10330
|
// src/commands/transcript/summarise/index.ts
|
|
9984
10331
|
import { existsSync as existsSync36 } from "fs";
|
|
9985
|
-
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";
|
|
9986
10333
|
|
|
9987
10334
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
9988
10335
|
import {
|
|
9989
10336
|
existsSync as existsSync35,
|
|
9990
|
-
mkdirSync as
|
|
9991
|
-
readFileSync as
|
|
9992
|
-
renameSync as
|
|
10337
|
+
mkdirSync as mkdirSync9,
|
|
10338
|
+
readFileSync as readFileSync28,
|
|
10339
|
+
renameSync as renameSync3,
|
|
9993
10340
|
rmSync
|
|
9994
10341
|
} from "fs";
|
|
9995
|
-
import { dirname as dirname20, join as
|
|
10342
|
+
import { dirname as dirname20, join as join33 } from "path";
|
|
9996
10343
|
|
|
9997
10344
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
9998
10345
|
import chalk118 from "chalk";
|
|
@@ -10021,7 +10368,7 @@ function validateStagedContent(filename, content) {
|
|
|
10021
10368
|
}
|
|
10022
10369
|
|
|
10023
10370
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10024
|
-
var STAGING_DIR =
|
|
10371
|
+
var STAGING_DIR = join33(process.cwd(), ".assist", "transcript");
|
|
10025
10372
|
function processStagedFile() {
|
|
10026
10373
|
if (!existsSync35(STAGING_DIR)) {
|
|
10027
10374
|
return false;
|
|
@@ -10032,7 +10379,7 @@ function processStagedFile() {
|
|
|
10032
10379
|
}
|
|
10033
10380
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10034
10381
|
const stagedFile = stagedFiles[0];
|
|
10035
|
-
const content =
|
|
10382
|
+
const content = readFileSync28(stagedFile.absolutePath, "utf-8");
|
|
10036
10383
|
validateStagedContent(stagedFile.filename, content);
|
|
10037
10384
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
10038
10385
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -10045,12 +10392,12 @@ function processStagedFile() {
|
|
|
10045
10392
|
);
|
|
10046
10393
|
process.exit(1);
|
|
10047
10394
|
}
|
|
10048
|
-
const destPath =
|
|
10395
|
+
const destPath = join33(summaryDir, matchingTranscript.relativePath);
|
|
10049
10396
|
const destDir = dirname20(destPath);
|
|
10050
10397
|
if (!existsSync35(destDir)) {
|
|
10051
|
-
|
|
10398
|
+
mkdirSync9(destDir, { recursive: true });
|
|
10052
10399
|
}
|
|
10053
|
-
|
|
10400
|
+
renameSync3(stagedFile.absolutePath, destPath);
|
|
10054
10401
|
const remaining = findMdFilesRecursive(STAGING_DIR);
|
|
10055
10402
|
if (remaining.length === 0) {
|
|
10056
10403
|
rmSync(STAGING_DIR, { recursive: true });
|
|
@@ -10061,7 +10408,7 @@ function processStagedFile() {
|
|
|
10061
10408
|
// src/commands/transcript/summarise/index.ts
|
|
10062
10409
|
function buildRelativeKey(relativePath, baseName) {
|
|
10063
10410
|
const relDir = dirname21(relativePath);
|
|
10064
|
-
return relDir === "." ? baseName :
|
|
10411
|
+
return relDir === "." ? baseName : join34(relDir, baseName);
|
|
10065
10412
|
}
|
|
10066
10413
|
function buildSummaryIndex(summaryDir) {
|
|
10067
10414
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -10095,8 +10442,8 @@ function summarise2() {
|
|
|
10095
10442
|
}
|
|
10096
10443
|
const next3 = missing[0];
|
|
10097
10444
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
10098
|
-
const outputPath =
|
|
10099
|
-
const summaryFileDir =
|
|
10445
|
+
const outputPath = join34(STAGING_DIR, outputFilename);
|
|
10446
|
+
const summaryFileDir = join34(summaryDir, dirname21(next3.relativePath));
|
|
10100
10447
|
const relativeTranscriptPath = encodeURI(
|
|
10101
10448
|
relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
10102
10449
|
);
|
|
@@ -10142,50 +10489,50 @@ function registerVerify(program2) {
|
|
|
10142
10489
|
|
|
10143
10490
|
// src/commands/voice/devices.ts
|
|
10144
10491
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10145
|
-
import { join as
|
|
10492
|
+
import { join as join36 } from "path";
|
|
10146
10493
|
|
|
10147
10494
|
// src/commands/voice/shared.ts
|
|
10148
10495
|
import { homedir as homedir7 } from "os";
|
|
10149
|
-
import { dirname as dirname22, join as
|
|
10496
|
+
import { dirname as dirname22, join as join35 } from "path";
|
|
10150
10497
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
10151
10498
|
var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
|
|
10152
|
-
var VOICE_DIR =
|
|
10499
|
+
var VOICE_DIR = join35(homedir7(), ".assist", "voice");
|
|
10153
10500
|
var voicePaths = {
|
|
10154
10501
|
dir: VOICE_DIR,
|
|
10155
|
-
pid:
|
|
10156
|
-
log:
|
|
10157
|
-
venv:
|
|
10158
|
-
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")
|
|
10159
10506
|
};
|
|
10160
10507
|
function getPythonDir() {
|
|
10161
|
-
return
|
|
10508
|
+
return join35(__dirname6, "commands", "voice", "python");
|
|
10162
10509
|
}
|
|
10163
10510
|
function getVenvPython() {
|
|
10164
|
-
return process.platform === "win32" ?
|
|
10511
|
+
return process.platform === "win32" ? join35(voicePaths.venv, "Scripts", "python.exe") : join35(voicePaths.venv, "bin", "python");
|
|
10165
10512
|
}
|
|
10166
10513
|
function getLockDir() {
|
|
10167
10514
|
const config = loadConfig();
|
|
10168
10515
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
10169
10516
|
}
|
|
10170
10517
|
function getLockFile() {
|
|
10171
|
-
return
|
|
10518
|
+
return join35(getLockDir(), "voice.lock");
|
|
10172
10519
|
}
|
|
10173
10520
|
|
|
10174
10521
|
// src/commands/voice/devices.ts
|
|
10175
10522
|
function devices() {
|
|
10176
|
-
const script =
|
|
10523
|
+
const script = join36(getPythonDir(), "list_devices.py");
|
|
10177
10524
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
10178
10525
|
}
|
|
10179
10526
|
|
|
10180
10527
|
// src/commands/voice/logs.ts
|
|
10181
|
-
import { existsSync as existsSync37, readFileSync as
|
|
10528
|
+
import { existsSync as existsSync37, readFileSync as readFileSync29 } from "fs";
|
|
10182
10529
|
function logs(options2) {
|
|
10183
10530
|
if (!existsSync37(voicePaths.log)) {
|
|
10184
10531
|
console.log("No voice log file found");
|
|
10185
10532
|
return;
|
|
10186
10533
|
}
|
|
10187
10534
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
10188
|
-
const content =
|
|
10535
|
+
const content = readFileSync29(voicePaths.log, "utf-8").trim();
|
|
10189
10536
|
if (!content) {
|
|
10190
10537
|
console.log("Voice log is empty");
|
|
10191
10538
|
return;
|
|
@@ -10207,13 +10554,13 @@ function logs(options2) {
|
|
|
10207
10554
|
|
|
10208
10555
|
// src/commands/voice/setup.ts
|
|
10209
10556
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
10210
|
-
import { mkdirSync as
|
|
10211
|
-
import { join as
|
|
10557
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
10558
|
+
import { join as join38 } from "path";
|
|
10212
10559
|
|
|
10213
10560
|
// src/commands/voice/checkLockFile.ts
|
|
10214
10561
|
import { execSync as execSync37 } from "child_process";
|
|
10215
|
-
import { existsSync as existsSync38, mkdirSync as
|
|
10216
|
-
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";
|
|
10217
10564
|
function isProcessAlive2(pid) {
|
|
10218
10565
|
try {
|
|
10219
10566
|
process.kill(pid, 0);
|
|
@@ -10226,7 +10573,7 @@ function checkLockFile() {
|
|
|
10226
10573
|
const lockFile = getLockFile();
|
|
10227
10574
|
if (!existsSync38(lockFile)) return;
|
|
10228
10575
|
try {
|
|
10229
|
-
const lock = JSON.parse(
|
|
10576
|
+
const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
|
|
10230
10577
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
10231
10578
|
console.error(
|
|
10232
10579
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -10250,7 +10597,7 @@ function bootstrapVenv() {
|
|
|
10250
10597
|
}
|
|
10251
10598
|
function writeLockFile(pid) {
|
|
10252
10599
|
const lockFile = getLockFile();
|
|
10253
|
-
|
|
10600
|
+
mkdirSync10(join37(lockFile, ".."), { recursive: true });
|
|
10254
10601
|
writeFileSync25(
|
|
10255
10602
|
lockFile,
|
|
10256
10603
|
JSON.stringify({
|
|
@@ -10263,10 +10610,10 @@ function writeLockFile(pid) {
|
|
|
10263
10610
|
|
|
10264
10611
|
// src/commands/voice/setup.ts
|
|
10265
10612
|
function setup() {
|
|
10266
|
-
|
|
10613
|
+
mkdirSync11(voicePaths.dir, { recursive: true });
|
|
10267
10614
|
bootstrapVenv();
|
|
10268
10615
|
console.log("\nDownloading models...\n");
|
|
10269
|
-
const script =
|
|
10616
|
+
const script = join38(getPythonDir(), "setup_models.py");
|
|
10270
10617
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
10271
10618
|
stdio: "inherit",
|
|
10272
10619
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -10279,8 +10626,8 @@ function setup() {
|
|
|
10279
10626
|
|
|
10280
10627
|
// src/commands/voice/start.ts
|
|
10281
10628
|
import { spawn as spawn5 } from "child_process";
|
|
10282
|
-
import { mkdirSync as
|
|
10283
|
-
import { join as
|
|
10629
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync26 } from "fs";
|
|
10630
|
+
import { join as join39 } from "path";
|
|
10284
10631
|
|
|
10285
10632
|
// src/commands/voice/buildDaemonEnv.ts
|
|
10286
10633
|
function buildDaemonEnv(options2) {
|
|
@@ -10313,12 +10660,12 @@ function spawnBackground(python, script, env) {
|
|
|
10313
10660
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
10314
10661
|
}
|
|
10315
10662
|
function start2(options2) {
|
|
10316
|
-
|
|
10663
|
+
mkdirSync12(voicePaths.dir, { recursive: true });
|
|
10317
10664
|
checkLockFile();
|
|
10318
10665
|
bootstrapVenv();
|
|
10319
10666
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
10320
10667
|
const env = buildDaemonEnv({ debug });
|
|
10321
|
-
const script =
|
|
10668
|
+
const script = join39(getPythonDir(), "voice_daemon.py");
|
|
10322
10669
|
const python = getVenvPython();
|
|
10323
10670
|
if (options2.foreground) {
|
|
10324
10671
|
spawnForeground(python, script, env);
|
|
@@ -10328,7 +10675,7 @@ function start2(options2) {
|
|
|
10328
10675
|
}
|
|
10329
10676
|
|
|
10330
10677
|
// src/commands/voice/status.ts
|
|
10331
|
-
import { existsSync as existsSync39, readFileSync as
|
|
10678
|
+
import { existsSync as existsSync39, readFileSync as readFileSync31 } from "fs";
|
|
10332
10679
|
function isProcessAlive3(pid) {
|
|
10333
10680
|
try {
|
|
10334
10681
|
process.kill(pid, 0);
|
|
@@ -10339,7 +10686,7 @@ function isProcessAlive3(pid) {
|
|
|
10339
10686
|
}
|
|
10340
10687
|
function readRecentLogs(count) {
|
|
10341
10688
|
if (!existsSync39(voicePaths.log)) return [];
|
|
10342
|
-
const lines =
|
|
10689
|
+
const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
|
|
10343
10690
|
return lines.slice(-count);
|
|
10344
10691
|
}
|
|
10345
10692
|
function status() {
|
|
@@ -10347,7 +10694,7 @@ function status() {
|
|
|
10347
10694
|
console.log("Voice daemon: not running (no PID file)");
|
|
10348
10695
|
return;
|
|
10349
10696
|
}
|
|
10350
|
-
const pid = Number.parseInt(
|
|
10697
|
+
const pid = Number.parseInt(readFileSync31(voicePaths.pid, "utf-8").trim(), 10);
|
|
10351
10698
|
const alive = isProcessAlive3(pid);
|
|
10352
10699
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
10353
10700
|
const recent = readRecentLogs(5);
|
|
@@ -10366,13 +10713,13 @@ function status() {
|
|
|
10366
10713
|
}
|
|
10367
10714
|
|
|
10368
10715
|
// src/commands/voice/stop.ts
|
|
10369
|
-
import { existsSync as existsSync40, readFileSync as
|
|
10716
|
+
import { existsSync as existsSync40, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
|
|
10370
10717
|
function stop() {
|
|
10371
10718
|
if (!existsSync40(voicePaths.pid)) {
|
|
10372
10719
|
console.log("Voice daemon is not running (no PID file)");
|
|
10373
10720
|
return;
|
|
10374
10721
|
}
|
|
10375
|
-
const pid = Number.parseInt(
|
|
10722
|
+
const pid = Number.parseInt(readFileSync32(voicePaths.pid, "utf-8").trim(), 10);
|
|
10376
10723
|
try {
|
|
10377
10724
|
process.kill(pid, "SIGTERM");
|
|
10378
10725
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -10606,15 +10953,15 @@ async function auth() {
|
|
|
10606
10953
|
}
|
|
10607
10954
|
|
|
10608
10955
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
10609
|
-
import { readFileSync as
|
|
10610
|
-
import { join as
|
|
10956
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
10957
|
+
import { join as join40 } from "path";
|
|
10611
10958
|
async function showClaudeCodeIcon() {
|
|
10612
10959
|
const appData = process.env.APPDATA;
|
|
10613
10960
|
if (!appData) return;
|
|
10614
|
-
const portFile =
|
|
10961
|
+
const portFile = join40(appData, "Roam", "roam-local-api.port");
|
|
10615
10962
|
let port;
|
|
10616
10963
|
try {
|
|
10617
|
-
port =
|
|
10964
|
+
port = readFileSync33(portFile, "utf-8").trim();
|
|
10618
10965
|
} catch {
|
|
10619
10966
|
return;
|
|
10620
10967
|
}
|
|
@@ -10685,8 +11032,8 @@ Done in ${elapsed}`);
|
|
|
10685
11032
|
}
|
|
10686
11033
|
|
|
10687
11034
|
// src/commands/run/add.ts
|
|
10688
|
-
import { mkdirSync as
|
|
10689
|
-
import { join as
|
|
11035
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync27 } from "fs";
|
|
11036
|
+
import { join as join41 } from "path";
|
|
10690
11037
|
function findAddIndex() {
|
|
10691
11038
|
const addIndex = process.argv.indexOf("add");
|
|
10692
11039
|
if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
|
|
@@ -10732,15 +11079,15 @@ function saveNewRunConfig(name, command, args) {
|
|
|
10732
11079
|
saveConfig(config);
|
|
10733
11080
|
}
|
|
10734
11081
|
function createCommandFile(name) {
|
|
10735
|
-
const dir =
|
|
10736
|
-
|
|
11082
|
+
const dir = join41(".claude", "commands");
|
|
11083
|
+
mkdirSync13(dir, { recursive: true });
|
|
10737
11084
|
const content = `---
|
|
10738
11085
|
description: Run ${name}
|
|
10739
11086
|
---
|
|
10740
11087
|
|
|
10741
11088
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
10742
11089
|
`;
|
|
10743
|
-
const filePath =
|
|
11090
|
+
const filePath = join41(dir, `${name}.md`);
|
|
10744
11091
|
writeFileSync27(filePath, content);
|
|
10745
11092
|
console.log(`Created command file: ${filePath}`);
|
|
10746
11093
|
}
|
|
@@ -10811,9 +11158,9 @@ function run3(name, args) {
|
|
|
10811
11158
|
|
|
10812
11159
|
// src/commands/screenshot/index.ts
|
|
10813
11160
|
import { execSync as execSync40 } from "child_process";
|
|
10814
|
-
import { existsSync as existsSync41, mkdirSync as
|
|
11161
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
|
|
10815
11162
|
import { tmpdir as tmpdir6 } from "os";
|
|
10816
|
-
import { join as
|
|
11163
|
+
import { join as join42, resolve as resolve5 } from "path";
|
|
10817
11164
|
import chalk120 from "chalk";
|
|
10818
11165
|
|
|
10819
11166
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -10944,13 +11291,13 @@ Write-Output $OutputPath
|
|
|
10944
11291
|
// src/commands/screenshot/index.ts
|
|
10945
11292
|
function buildOutputPath(outputDir, processName) {
|
|
10946
11293
|
if (!existsSync41(outputDir)) {
|
|
10947
|
-
|
|
11294
|
+
mkdirSync14(outputDir, { recursive: true });
|
|
10948
11295
|
}
|
|
10949
11296
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10950
11297
|
return resolve5(outputDir, `${processName}-${timestamp}.png`);
|
|
10951
11298
|
}
|
|
10952
11299
|
function runPowerShellScript(processName, outputPath) {
|
|
10953
|
-
const scriptPath =
|
|
11300
|
+
const scriptPath = join42(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
10954
11301
|
writeFileSync28(scriptPath, captureWindowPs1, "utf-8");
|
|
10955
11302
|
try {
|
|
10956
11303
|
execSync40(
|