@staff0rd/assist 0.294.1 → 0.296.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/commands/sessions/web/bundle.js +66 -66
- package/dist/index.js +793 -705
- package/package.json +1 -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.296.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -384,6 +384,7 @@ import {
|
|
|
384
384
|
|
|
385
385
|
// src/commands/backlog/backlogSchema.ts
|
|
386
386
|
import {
|
|
387
|
+
boolean,
|
|
387
388
|
foreignKey,
|
|
388
389
|
index,
|
|
389
390
|
integer,
|
|
@@ -401,7 +402,8 @@ var items = pgTable(
|
|
|
401
402
|
description: text(),
|
|
402
403
|
acceptanceCriteria: text("acceptance_criteria").notNull().default("[]"),
|
|
403
404
|
status: text().notNull().default("todo"),
|
|
404
|
-
currentPhase: integer("current_phase")
|
|
405
|
+
currentPhase: integer("current_phase"),
|
|
406
|
+
starred: boolean().notNull().default(false)
|
|
405
407
|
},
|
|
406
408
|
(t) => [index("items_origin_idx").on(t.origin)]
|
|
407
409
|
);
|
|
@@ -482,9 +484,13 @@ var SCHEMA = `
|
|
|
482
484
|
description TEXT,
|
|
483
485
|
acceptance_criteria TEXT NOT NULL DEFAULT '[]',
|
|
484
486
|
status TEXT NOT NULL DEFAULT 'todo',
|
|
485
|
-
current_phase INTEGER
|
|
487
|
+
current_phase INTEGER,
|
|
488
|
+
starred BOOLEAN NOT NULL DEFAULT false
|
|
486
489
|
);
|
|
487
490
|
|
|
491
|
+
-- Backfill the column on databases created before it was introduced.
|
|
492
|
+
ALTER TABLE items ADD COLUMN IF NOT EXISTS starred BOOLEAN NOT NULL DEFAULT false;
|
|
493
|
+
|
|
488
494
|
CREATE INDEX IF NOT EXISTS items_origin_idx ON items (origin);
|
|
489
495
|
|
|
490
496
|
CREATE TABLE IF NOT EXISTS comments (
|
|
@@ -2988,6 +2994,9 @@ function statusIcon(status2) {
|
|
|
2988
2994
|
return chalk27.dim("[-]");
|
|
2989
2995
|
}
|
|
2990
2996
|
}
|
|
2997
|
+
function starMarker(item) {
|
|
2998
|
+
return item.starred ? `${chalk27.yellow("\u2605")} ` : "";
|
|
2999
|
+
}
|
|
2991
3000
|
function typeLabel(type) {
|
|
2992
3001
|
switch (type) {
|
|
2993
3002
|
case "bug":
|
|
@@ -3093,8 +3102,8 @@ import chalk31 from "chalk";
|
|
|
3093
3102
|
|
|
3094
3103
|
// src/commands/backlog/deleteItem.ts
|
|
3095
3104
|
import { eq } from "drizzle-orm";
|
|
3096
|
-
async function deleteItem(orm,
|
|
3097
|
-
const [row] = await orm.delete(items).where(eq(items.id,
|
|
3105
|
+
async function deleteItem(orm, id2) {
|
|
3106
|
+
const [row] = await orm.delete(items).where(eq(items.id, id2)).returning({ name: items.name });
|
|
3098
3107
|
return row?.name;
|
|
3099
3108
|
}
|
|
3100
3109
|
|
|
@@ -3146,7 +3155,8 @@ function itemColumns(item, origin) {
|
|
|
3146
3155
|
description: item.description ?? null,
|
|
3147
3156
|
acceptanceCriteria: JSON.stringify(item.acceptanceCriteria),
|
|
3148
3157
|
status: item.status,
|
|
3149
|
-
currentPhase: item.currentPhase ?? null
|
|
3158
|
+
currentPhase: item.currentPhase ?? null,
|
|
3159
|
+
starred: item.starred
|
|
3150
3160
|
};
|
|
3151
3161
|
}
|
|
3152
3162
|
|
|
@@ -3321,22 +3331,23 @@ function baseItem(row) {
|
|
|
3321
3331
|
name: row.name,
|
|
3322
3332
|
acceptanceCriteria: JSON.parse(row.acceptanceCriteria),
|
|
3323
3333
|
status: row.status,
|
|
3334
|
+
starred: row.starred,
|
|
3324
3335
|
origin: row.origin
|
|
3325
3336
|
};
|
|
3326
3337
|
assignOptionalColumns(item, row);
|
|
3327
3338
|
return item;
|
|
3328
3339
|
}
|
|
3329
|
-
function attachComments(item, rel,
|
|
3330
|
-
const comments3 = (rel.comments.get(
|
|
3340
|
+
function attachComments(item, rel, id2) {
|
|
3341
|
+
const comments3 = (rel.comments.get(id2) ?? []).map(rowToComment);
|
|
3331
3342
|
if (comments3.length > 0) item.comments = comments3;
|
|
3332
3343
|
}
|
|
3333
|
-
function attachLinks(item, rel,
|
|
3334
|
-
const links2 = (rel.links.get(
|
|
3344
|
+
function attachLinks(item, rel, id2) {
|
|
3345
|
+
const links2 = (rel.links.get(id2) ?? []).map(rowToLink);
|
|
3335
3346
|
if (links2.length > 0) item.links = links2;
|
|
3336
3347
|
}
|
|
3337
|
-
function attachPlan(item, rel,
|
|
3338
|
-
const phases = rel.phases.get(
|
|
3339
|
-
if (phases.length > 0) item.plan = buildPlan(phases, rel.tasks.get(
|
|
3348
|
+
function attachPlan(item, rel, id2) {
|
|
3349
|
+
const phases = rel.phases.get(id2) ?? [];
|
|
3350
|
+
if (phases.length > 0) item.plan = buildPlan(phases, rel.tasks.get(id2) ?? []);
|
|
3340
3351
|
}
|
|
3341
3352
|
function rowToItem(row, rel) {
|
|
3342
3353
|
const item = baseItem(row);
|
|
@@ -3394,6 +3405,7 @@ var backlogItemSchema = z3.strictObject({
|
|
|
3394
3405
|
acceptanceCriteria: z3.array(z3.string()),
|
|
3395
3406
|
plan: z3.array(planPhaseSchema).optional(),
|
|
3396
3407
|
currentPhase: z3.number().optional(),
|
|
3408
|
+
starred: z3.boolean().default(false),
|
|
3397
3409
|
status: backlogStatusSchema,
|
|
3398
3410
|
comments: z3.array(backlogCommentSchema).optional(),
|
|
3399
3411
|
links: z3.array(backlogLinkSchema).optional(),
|
|
@@ -3530,10 +3542,10 @@ function getCurrentOrigin(cwd) {
|
|
|
3530
3542
|
|
|
3531
3543
|
// src/commands/backlog/loadItem.ts
|
|
3532
3544
|
import { eq as eq3 } from "drizzle-orm";
|
|
3533
|
-
async function loadItem(orm,
|
|
3534
|
-
const [row] = await orm.select().from(items).where(eq3(items.id,
|
|
3545
|
+
async function loadItem(orm, id2) {
|
|
3546
|
+
const [row] = await orm.select().from(items).where(eq3(items.id, id2));
|
|
3535
3547
|
if (!row) return void 0;
|
|
3536
|
-
const rel = await loadRelations(orm, [
|
|
3548
|
+
const rel = await loadRelations(orm, [id2]);
|
|
3537
3549
|
return rowToItem(row, rel);
|
|
3538
3550
|
}
|
|
3539
3551
|
|
|
@@ -3564,14 +3576,14 @@ async function searchItemIds(orm, query, origin) {
|
|
|
3564
3576
|
|
|
3565
3577
|
// src/commands/backlog/updateCurrentPhase.ts
|
|
3566
3578
|
import { eq as eq7 } from "drizzle-orm";
|
|
3567
|
-
async function updateCurrentPhase(orm,
|
|
3568
|
-
await orm.update(items).set({ currentPhase: phase }).where(eq7(items.id,
|
|
3579
|
+
async function updateCurrentPhase(orm, id2, phase) {
|
|
3580
|
+
await orm.update(items).set({ currentPhase: phase }).where(eq7(items.id, id2));
|
|
3569
3581
|
}
|
|
3570
3582
|
|
|
3571
3583
|
// src/commands/backlog/updateStatus.ts
|
|
3572
3584
|
import { eq as eq8 } from "drizzle-orm";
|
|
3573
|
-
async function updateStatus(orm,
|
|
3574
|
-
const [row] = await orm.update(items).set({ status: status2 }).where(eq8(items.id,
|
|
3585
|
+
async function updateStatus(orm, id2, status2) {
|
|
3586
|
+
const [row] = await orm.update(items).set({ status: status2 }).where(eq8(items.id, id2)).returning({ name: items.name });
|
|
3575
3587
|
return row?.name;
|
|
3576
3588
|
}
|
|
3577
3589
|
|
|
@@ -3603,35 +3615,35 @@ async function searchBacklog(query) {
|
|
|
3603
3615
|
const allItems = await loadAllItems(orm, origin);
|
|
3604
3616
|
return allItems.filter((item) => ids.includes(item.id));
|
|
3605
3617
|
}
|
|
3606
|
-
async function findOneItem(
|
|
3607
|
-
const numId = Number.parseInt(
|
|
3618
|
+
async function findOneItem(id2) {
|
|
3619
|
+
const numId = Number.parseInt(id2, 10);
|
|
3608
3620
|
const { orm } = await getReady();
|
|
3609
3621
|
const item = Number.isNaN(numId) ? void 0 : await loadItem(orm, numId);
|
|
3610
3622
|
if (!item) {
|
|
3611
|
-
console.log(chalk31.red(`Item #${
|
|
3623
|
+
console.log(chalk31.red(`Item #${id2} not found.`));
|
|
3612
3624
|
return void 0;
|
|
3613
3625
|
}
|
|
3614
3626
|
return { orm, item };
|
|
3615
3627
|
}
|
|
3616
|
-
async function setStatus(
|
|
3628
|
+
async function setStatus(id2, status2) {
|
|
3617
3629
|
const { orm } = await getReady();
|
|
3618
|
-
const name = await updateStatus(orm, Number.parseInt(
|
|
3619
|
-
if (name === void 0) console.log(chalk31.red(`Item #${
|
|
3630
|
+
const name = await updateStatus(orm, Number.parseInt(id2, 10), status2);
|
|
3631
|
+
if (name === void 0) console.log(chalk31.red(`Item #${id2} not found.`));
|
|
3620
3632
|
return name;
|
|
3621
3633
|
}
|
|
3622
|
-
async function setCurrentPhase(
|
|
3634
|
+
async function setCurrentPhase(id2, phase) {
|
|
3623
3635
|
const { orm } = await getReady();
|
|
3624
|
-
await updateCurrentPhase(orm, Number.parseInt(
|
|
3636
|
+
await updateCurrentPhase(orm, Number.parseInt(id2, 10), phase);
|
|
3625
3637
|
}
|
|
3626
|
-
async function removeItem(
|
|
3638
|
+
async function removeItem(id2) {
|
|
3627
3639
|
const { orm } = await getReady();
|
|
3628
|
-
const name = await deleteItem(orm, Number.parseInt(
|
|
3629
|
-
if (name === void 0) console.log(chalk31.red(`Item #${
|
|
3640
|
+
const name = await deleteItem(orm, Number.parseInt(id2, 10));
|
|
3641
|
+
if (name === void 0) console.log(chalk31.red(`Item #${id2} not found.`));
|
|
3630
3642
|
return name;
|
|
3631
3643
|
}
|
|
3632
3644
|
|
|
3633
3645
|
// src/commands/backlog/handleReviewResult.ts
|
|
3634
|
-
async function handleReviewResult(
|
|
3646
|
+
async function handleReviewResult(id2, review2) {
|
|
3635
3647
|
if (review2.kind === "fail" || review2.kind === "abort")
|
|
3636
3648
|
return { kind: "stop", success: false };
|
|
3637
3649
|
if (review2.kind === "paused") return { kind: "stop", success: true };
|
|
@@ -3641,12 +3653,12 @@ async function handleReviewResult(id, review2) {
|
|
|
3641
3653
|
startPhase: review2.targetPhase,
|
|
3642
3654
|
plan: review2.plan
|
|
3643
3655
|
};
|
|
3644
|
-
await ensureDone(
|
|
3656
|
+
await ensureDone(id2);
|
|
3645
3657
|
return { kind: "stop", success: true };
|
|
3646
3658
|
}
|
|
3647
|
-
async function ensureDone(
|
|
3659
|
+
async function ensureDone(id2) {
|
|
3648
3660
|
try {
|
|
3649
|
-
await setStatus(
|
|
3661
|
+
await setStatus(id2, "done");
|
|
3650
3662
|
} catch {
|
|
3651
3663
|
}
|
|
3652
3664
|
}
|
|
@@ -3668,20 +3680,20 @@ function resolvePlan(item) {
|
|
|
3668
3680
|
}
|
|
3669
3681
|
|
|
3670
3682
|
// src/commands/backlog/prepareRun.ts
|
|
3671
|
-
async function prepareRun(
|
|
3672
|
-
const found = await findOneItem(
|
|
3683
|
+
async function prepareRun(id2) {
|
|
3684
|
+
const found = await findOneItem(id2);
|
|
3673
3685
|
if (!found) return void 0;
|
|
3674
3686
|
const { item } = found;
|
|
3675
3687
|
const plan2 = resolvePlan(item);
|
|
3676
3688
|
const startPhase = (item.currentPhase ?? 1) - 1;
|
|
3677
3689
|
if (item.status === "done") {
|
|
3678
|
-
console.log(chalk32.green(`Already done: #${
|
|
3690
|
+
console.log(chalk32.green(`Already done: #${id2}: ${item.name}`));
|
|
3679
3691
|
return void 0;
|
|
3680
3692
|
}
|
|
3681
3693
|
if (startPhase > plan2.length) {
|
|
3682
|
-
await setStatus(
|
|
3694
|
+
await setStatus(id2, "done");
|
|
3683
3695
|
console.log(
|
|
3684
|
-
chalk32.green(`All phases already complete for #${
|
|
3696
|
+
chalk32.green(`All phases already complete for #${id2}: ${item.name}`)
|
|
3685
3697
|
);
|
|
3686
3698
|
return void 0;
|
|
3687
3699
|
}
|
|
@@ -3770,10 +3782,10 @@ function buildCommentLines(comments3) {
|
|
|
3770
3782
|
return ["", "Comments:", ...comments3.map(formatPromptComment)];
|
|
3771
3783
|
}
|
|
3772
3784
|
function formatPromptComment(entry) {
|
|
3773
|
-
const
|
|
3785
|
+
const id2 = entry.id !== void 0 ? `#${entry.id} ` : "";
|
|
3774
3786
|
const tag = entry.type === "summary" ? "[summary]" : "[comment]";
|
|
3775
3787
|
const phase = entry.phase !== void 0 ? ` (phase ${entry.phase})` : "";
|
|
3776
|
-
return `${
|
|
3788
|
+
return `${id2}${tag}${phase} ${entry.timestamp}
|
|
3777
3789
|
${entry.text}`;
|
|
3778
3790
|
}
|
|
3779
3791
|
|
|
@@ -4005,8 +4017,8 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4005
4017
|
}
|
|
4006
4018
|
|
|
4007
4019
|
// src/commands/backlog/reloadPlan.ts
|
|
4008
|
-
async function reloadPlan(
|
|
4009
|
-
const found = await findOneItem(String(
|
|
4020
|
+
async function reloadPlan(id2) {
|
|
4021
|
+
const found = await findOneItem(String(id2));
|
|
4010
4022
|
if (!found) return void 0;
|
|
4011
4023
|
return resolvePlan(found.item);
|
|
4012
4024
|
}
|
|
@@ -4073,15 +4085,15 @@ async function runOnce(item, startPhase, plan2, spawnOptions) {
|
|
|
4073
4085
|
}
|
|
4074
4086
|
|
|
4075
4087
|
// src/commands/backlog/run.ts
|
|
4076
|
-
async function run2(
|
|
4088
|
+
async function run2(id2, spawnOptions) {
|
|
4077
4089
|
if (blockedByHandover()) return false;
|
|
4078
|
-
const prepared = await prepareRun(
|
|
4090
|
+
const prepared = await prepareRun(id2);
|
|
4079
4091
|
if (!prepared) return false;
|
|
4080
|
-
await setStatus(
|
|
4081
|
-
logProgress(
|
|
4082
|
-
return runPrepared(
|
|
4092
|
+
await setStatus(id2, "in-progress");
|
|
4093
|
+
logProgress(id2, prepared);
|
|
4094
|
+
return runPrepared(id2, prepared, spawnOptions);
|
|
4083
4095
|
}
|
|
4084
|
-
async function runPrepared(
|
|
4096
|
+
async function runPrepared(id2, prepared, spawnOptions) {
|
|
4085
4097
|
const { item } = prepared;
|
|
4086
4098
|
let { plan: plan2, startPhase } = prepared;
|
|
4087
4099
|
acquireLock(item.id);
|
|
@@ -4089,7 +4101,7 @@ async function runPrepared(id, prepared, spawnOptions) {
|
|
|
4089
4101
|
while (true) {
|
|
4090
4102
|
const review2 = await runOnce(item, startPhase, plan2, spawnOptions);
|
|
4091
4103
|
spawnOptions = withoutResumeSession(spawnOptions);
|
|
4092
|
-
const outcome = await handleReviewResult(
|
|
4104
|
+
const outcome = await handleReviewResult(id2, review2);
|
|
4093
4105
|
if (outcome.kind === "stop") return outcome.success;
|
|
4094
4106
|
startPhase = outcome.startPhase;
|
|
4095
4107
|
plan2 = outcome.plan;
|
|
@@ -4098,8 +4110,8 @@ async function runPrepared(id, prepared, spawnOptions) {
|
|
|
4098
4110
|
releaseLock(item.id);
|
|
4099
4111
|
}
|
|
4100
4112
|
}
|
|
4101
|
-
function logProgress(
|
|
4102
|
-
console.log(chalk35.bold(`Running plan for #${
|
|
4113
|
+
function logProgress(id2, { plan: plan2, startPhase, item }) {
|
|
4114
|
+
console.log(chalk35.bold(`Running plan for #${id2}: ${item.name}`));
|
|
4103
4115
|
const totalPhases = plan2.length + 1;
|
|
4104
4116
|
if (startPhase > 0) {
|
|
4105
4117
|
const phaseNumber = startPhase + 1;
|
|
@@ -4157,11 +4169,11 @@ async function next(options2, startId) {
|
|
|
4157
4169
|
let pendingId = startId;
|
|
4158
4170
|
let firstPick = true;
|
|
4159
4171
|
while (true) {
|
|
4160
|
-
const
|
|
4172
|
+
const id2 = pendingId ?? await pickItem(await loadBacklog(), firstPick);
|
|
4161
4173
|
pendingId = void 0;
|
|
4162
4174
|
firstPick = false;
|
|
4163
|
-
if (
|
|
4164
|
-
const completed = await run2(
|
|
4175
|
+
if (id2 === void 0) return;
|
|
4176
|
+
const completed = await run2(id2, options2);
|
|
4165
4177
|
if (!completed || options2?.once) return;
|
|
4166
4178
|
}
|
|
4167
4179
|
}
|
|
@@ -4184,16 +4196,16 @@ async function appendComment(orm, itemId, text3, opts = {}) {
|
|
|
4184
4196
|
|
|
4185
4197
|
// src/commands/backlog/getItemStatus.ts
|
|
4186
4198
|
import { eq as eq9 } from "drizzle-orm";
|
|
4187
|
-
async function getItemStatus(orm,
|
|
4188
|
-
const [row] = await orm.select({ status: items.status }).from(items).where(eq9(items.id,
|
|
4199
|
+
async function getItemStatus(orm, id2) {
|
|
4200
|
+
const [row] = await orm.select({ status: items.status }).from(items).where(eq9(items.id, id2));
|
|
4189
4201
|
return row?.status;
|
|
4190
4202
|
}
|
|
4191
4203
|
|
|
4192
4204
|
// src/commands/backlog/phaseDone.ts
|
|
4193
|
-
async function phaseDone(
|
|
4205
|
+
async function phaseDone(id2, phase, summary) {
|
|
4194
4206
|
const phaseNumber = Number.parseInt(phase, 10);
|
|
4195
4207
|
const phaseIndex = phaseNumber - 1;
|
|
4196
|
-
const itemId = Number.parseInt(
|
|
4208
|
+
const itemId = Number.parseInt(id2, 10);
|
|
4197
4209
|
writeSignal("phase-done", {
|
|
4198
4210
|
itemId,
|
|
4199
4211
|
phaseIndex,
|
|
@@ -4202,27 +4214,27 @@ async function phaseDone(id, phase, summary) {
|
|
|
4202
4214
|
const { orm } = await getReady();
|
|
4203
4215
|
const status2 = await getItemStatus(orm, itemId);
|
|
4204
4216
|
if (status2 === void 0) {
|
|
4205
|
-
console.log(chalk37.red(`Item #${
|
|
4217
|
+
console.log(chalk37.red(`Item #${id2} not found.`));
|
|
4206
4218
|
return;
|
|
4207
4219
|
}
|
|
4208
4220
|
if (status2 === "done") {
|
|
4209
|
-
console.log(chalk37.dim(`Item #${
|
|
4221
|
+
console.log(chalk37.dim(`Item #${id2} already done, skipping phase advance.`));
|
|
4210
4222
|
return;
|
|
4211
4223
|
}
|
|
4212
4224
|
await appendComment(orm, itemId, summary, {
|
|
4213
4225
|
phase: phaseNumber,
|
|
4214
4226
|
type: "summary"
|
|
4215
4227
|
});
|
|
4216
|
-
await setCurrentPhase(
|
|
4228
|
+
await setCurrentPhase(id2, phaseNumber + 1);
|
|
4217
4229
|
console.log(
|
|
4218
|
-
chalk37.green(`Phase ${phaseNumber} of item #${
|
|
4230
|
+
chalk37.green(`Phase ${phaseNumber} of item #${id2} marked as complete.`)
|
|
4219
4231
|
);
|
|
4220
4232
|
}
|
|
4221
4233
|
|
|
4222
4234
|
// src/commands/backlog/plan.ts
|
|
4223
4235
|
import chalk38 from "chalk";
|
|
4224
|
-
async function plan(
|
|
4225
|
-
const found = await findOneItem(
|
|
4236
|
+
async function plan(id2) {
|
|
4237
|
+
const found = await findOneItem(id2);
|
|
4226
4238
|
if (!found) return;
|
|
4227
4239
|
const { item } = found;
|
|
4228
4240
|
if (!item.plan || item.plan.length === 0) {
|
|
@@ -4246,11 +4258,11 @@ import chalk42 from "chalk";
|
|
|
4246
4258
|
// src/commands/backlog/formatComment.ts
|
|
4247
4259
|
import chalk39 from "chalk";
|
|
4248
4260
|
function formatComment(entry) {
|
|
4249
|
-
const
|
|
4261
|
+
const id2 = entry.id !== void 0 ? chalk39.dim(`#${entry.id} `) : "";
|
|
4250
4262
|
const tag = entry.type === "summary" ? chalk39.magenta("[summary]") : chalk39.cyan("[comment]");
|
|
4251
4263
|
const phase = entry.phase !== void 0 ? chalk39.dim(` (phase ${entry.phase})`) : "";
|
|
4252
4264
|
const time = chalk39.dim(entry.timestamp);
|
|
4253
|
-
return `${
|
|
4265
|
+
return `${id2}${tag}${phase} ${time}
|
|
4254
4266
|
${entry.text}`;
|
|
4255
4267
|
}
|
|
4256
4268
|
|
|
@@ -4343,8 +4355,8 @@ function printAcceptanceCriteria(criteria) {
|
|
|
4343
4355
|
}
|
|
4344
4356
|
console.log();
|
|
4345
4357
|
}
|
|
4346
|
-
async function show(
|
|
4347
|
-
const found = await findOneItem(
|
|
4358
|
+
async function show(id2) {
|
|
4359
|
+
const found = await findOneItem(id2);
|
|
4348
4360
|
if (!found) process.exit(1);
|
|
4349
4361
|
const { orm, item } = found;
|
|
4350
4362
|
printHeader(item);
|
|
@@ -4457,10 +4469,10 @@ function parseRoute(req, port) {
|
|
|
4457
4469
|
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
4458
4470
|
return { method: req.method ?? "GET", pathname: url.pathname };
|
|
4459
4471
|
}
|
|
4460
|
-
function createRouteHandler(
|
|
4472
|
+
function createRouteHandler(routes3) {
|
|
4461
4473
|
return async (req, res, port) => {
|
|
4462
4474
|
const { method, pathname } = parseRoute(req, port);
|
|
4463
|
-
const handler =
|
|
4475
|
+
const handler = routes3[`${method} ${pathname}`];
|
|
4464
4476
|
if (handler) {
|
|
4465
4477
|
await handler(req, res);
|
|
4466
4478
|
return;
|
|
@@ -4622,12 +4634,12 @@ function createBundleHandler(importMetaUrl, bundlePath) {
|
|
|
4622
4634
|
}
|
|
4623
4635
|
|
|
4624
4636
|
// src/shared/createFallbackHandler.ts
|
|
4625
|
-
function createFallbackHandler(
|
|
4626
|
-
const baseHandler = createRouteHandler(
|
|
4637
|
+
function createFallbackHandler(routes3, htmlHandler2, extra) {
|
|
4638
|
+
const baseHandler = createRouteHandler(routes3);
|
|
4627
4639
|
return async (req, res, port) => {
|
|
4628
4640
|
const { method, pathname } = parseRoute(req, port);
|
|
4629
4641
|
if (extra && await extra(req, res, pathname)) return;
|
|
4630
|
-
if (
|
|
4642
|
+
if (routes3[`${method} ${pathname}`]) {
|
|
4631
4643
|
await baseHandler(req, res, port);
|
|
4632
4644
|
return;
|
|
4633
4645
|
}
|
|
@@ -4650,14 +4662,16 @@ async function loadItemSummaries(orm, origin) {
|
|
|
4650
4662
|
origin: items.origin,
|
|
4651
4663
|
type: items.type,
|
|
4652
4664
|
name: items.name,
|
|
4653
|
-
status: items.status
|
|
4665
|
+
status: items.status,
|
|
4666
|
+
starred: items.starred
|
|
4654
4667
|
}).from(items).where(origin === void 0 ? void 0 : eq10(items.origin, origin)).orderBy(asc5(items.id));
|
|
4655
4668
|
return rows.map((row) => ({
|
|
4656
4669
|
id: row.id,
|
|
4657
4670
|
origin: row.origin,
|
|
4658
4671
|
type: row.type,
|
|
4659
4672
|
name: row.name,
|
|
4660
|
-
status: row.status
|
|
4673
|
+
status: row.status,
|
|
4674
|
+
starred: row.starred
|
|
4661
4675
|
}));
|
|
4662
4676
|
}
|
|
4663
4677
|
|
|
@@ -4691,8 +4705,32 @@ async function getBacklogExists(req, res) {
|
|
|
4691
4705
|
respondJson(res, 200, { exists: await backlogHasItems() });
|
|
4692
4706
|
}
|
|
4693
4707
|
|
|
4694
|
-
// src/commands/backlog/
|
|
4708
|
+
// src/commands/backlog/deleteComment.ts
|
|
4709
|
+
import { and as and2, eq as eq12 } from "drizzle-orm";
|
|
4710
|
+
async function deleteComment(orm, itemId, commentId) {
|
|
4711
|
+
const [row] = await orm.select({ type: comments.type }).from(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4712
|
+
if (!row) return "not-found";
|
|
4713
|
+
if (row.type === "summary") return "is-summary";
|
|
4714
|
+
await orm.delete(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4715
|
+
return "deleted";
|
|
4716
|
+
}
|
|
4717
|
+
|
|
4718
|
+
// src/commands/backlog/updateStarred.ts
|
|
4695
4719
|
import { eq as eq13 } from "drizzle-orm";
|
|
4720
|
+
async function updateStarred(orm, id2, starred) {
|
|
4721
|
+
const [row] = await orm.update(items).set({ starred }).where(eq13(items.id, id2)).returning({ name: items.name });
|
|
4722
|
+
return row?.name;
|
|
4723
|
+
}
|
|
4724
|
+
|
|
4725
|
+
// src/commands/backlog/web/loadVisibleItems.ts
|
|
4726
|
+
var completedStatuses = /* @__PURE__ */ new Set(["done", "wontdo"]);
|
|
4727
|
+
async function loadVisibleItems(req) {
|
|
4728
|
+
const params = new URL(req.url ?? "/", "http://localhost").searchParams;
|
|
4729
|
+
const q = params.get("q");
|
|
4730
|
+
const loaded = q ? await searchBacklogSummaries(q) : await loadBacklogSummaries();
|
|
4731
|
+
if (params.get("showCompleted") === "true") return loaded;
|
|
4732
|
+
return loaded.filter((item) => !completedStatuses.has(item.status));
|
|
4733
|
+
}
|
|
4696
4734
|
|
|
4697
4735
|
// src/commands/backlog/web/parseItemBody.ts
|
|
4698
4736
|
function readBody(req) {
|
|
@@ -4714,25 +4752,8 @@ async function parseStatusBody(req) {
|
|
|
4714
4752
|
async function parseRewindBody(req) {
|
|
4715
4753
|
return JSON.parse(await readBody(req));
|
|
4716
4754
|
}
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
import { and as and2, eq as eq12 } from "drizzle-orm";
|
|
4720
|
-
async function deleteComment(orm, itemId, commentId) {
|
|
4721
|
-
const [row] = await orm.select({ type: comments.type }).from(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4722
|
-
if (!row) return "not-found";
|
|
4723
|
-
if (row.type === "summary") return "is-summary";
|
|
4724
|
-
await orm.delete(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4725
|
-
return "deleted";
|
|
4726
|
-
}
|
|
4727
|
-
|
|
4728
|
-
// src/commands/backlog/web/loadVisibleItems.ts
|
|
4729
|
-
var completedStatuses = /* @__PURE__ */ new Set(["done", "wontdo"]);
|
|
4730
|
-
async function loadVisibleItems(req) {
|
|
4731
|
-
const params = new URL(req.url ?? "/", "http://localhost").searchParams;
|
|
4732
|
-
const q = params.get("q");
|
|
4733
|
-
const loaded = q ? await searchBacklogSummaries(q) : await loadBacklogSummaries();
|
|
4734
|
-
if (params.get("showCompleted") === "true") return loaded;
|
|
4735
|
-
return loaded.filter((item) => !completedStatuses.has(item.status));
|
|
4755
|
+
async function parseStarBody(req) {
|
|
4756
|
+
return JSON.parse(await readBody(req));
|
|
4736
4757
|
}
|
|
4737
4758
|
|
|
4738
4759
|
// src/commands/backlog/web/shared.ts
|
|
@@ -4741,25 +4762,43 @@ async function listItems(req, res) {
|
|
|
4741
4762
|
const items2 = await loadVisibleItems(req);
|
|
4742
4763
|
respondJson(res, 200, items2.slice().reverse());
|
|
4743
4764
|
}
|
|
4744
|
-
async function findItemOr404(res,
|
|
4765
|
+
async function findItemOr404(res, id2) {
|
|
4745
4766
|
const { orm } = await getReady();
|
|
4746
|
-
const item = await loadItem(orm,
|
|
4767
|
+
const item = await loadItem(orm, id2);
|
|
4747
4768
|
if (!item) {
|
|
4748
4769
|
respondJson(res, 404, { error: "Not found" });
|
|
4749
4770
|
return void 0;
|
|
4750
4771
|
}
|
|
4751
4772
|
return { orm, item };
|
|
4752
4773
|
}
|
|
4753
|
-
async function getItemById(res,
|
|
4754
|
-
const result = await findItemOr404(res,
|
|
4774
|
+
async function getItemById(res, id2) {
|
|
4775
|
+
const result = await findItemOr404(res, id2);
|
|
4755
4776
|
if (result) respondJson(res, 200, result.item);
|
|
4756
4777
|
}
|
|
4757
|
-
async function deleteItem2(res,
|
|
4758
|
-
const result = await findItemOr404(res,
|
|
4778
|
+
async function deleteItem2(res, id2) {
|
|
4779
|
+
const result = await findItemOr404(res, id2);
|
|
4759
4780
|
if (!result) return;
|
|
4760
|
-
await deleteItem(result.orm,
|
|
4781
|
+
await deleteItem(result.orm, id2);
|
|
4761
4782
|
respondJson(res, 200, result.item);
|
|
4762
4783
|
}
|
|
4784
|
+
async function patchItemStatus(req, res, id2) {
|
|
4785
|
+
const { status: status2 } = await parseStatusBody(req);
|
|
4786
|
+
const result = await findItemOr404(res, id2);
|
|
4787
|
+
if (!result) return;
|
|
4788
|
+
await updateStatus(result.orm, id2, status2);
|
|
4789
|
+
const updated = { ...result.item, status: status2 };
|
|
4790
|
+
respondJson(res, 200, updated);
|
|
4791
|
+
}
|
|
4792
|
+
async function patchItemStar(req, res, id2) {
|
|
4793
|
+
const { starred } = await parseStarBody(req);
|
|
4794
|
+
const result = await findItemOr404(res, id2);
|
|
4795
|
+
if (!result) return;
|
|
4796
|
+
await updateStarred(result.orm, id2, starred);
|
|
4797
|
+
const updated = { ...result.item, starred };
|
|
4798
|
+
respondJson(res, 200, updated);
|
|
4799
|
+
}
|
|
4800
|
+
|
|
4801
|
+
// src/commands/backlog/web/deleteItemComment.ts
|
|
4763
4802
|
async function deleteItemComment(res, itemId, commentId) {
|
|
4764
4803
|
const result = await findItemOr404(res, itemId);
|
|
4765
4804
|
if (!result) return;
|
|
@@ -4778,19 +4817,12 @@ async function deleteItemComment(res, itemId, commentId) {
|
|
|
4778
4817
|
}
|
|
4779
4818
|
respondJson(res, 200, await loadItem(result.orm, itemId));
|
|
4780
4819
|
}
|
|
4781
|
-
async function patchItemStatus(req, res, id) {
|
|
4782
|
-
const { status: status2 } = await parseStatusBody(req);
|
|
4783
|
-
const result = await findItemOr404(res, id);
|
|
4784
|
-
if (!result) return;
|
|
4785
|
-
await updateStatus(result.orm, id, status2);
|
|
4786
|
-
const updated = { ...result.item, status: status2 };
|
|
4787
|
-
respondJson(res, 200, updated);
|
|
4788
|
-
}
|
|
4789
4820
|
|
|
4790
4821
|
// src/commands/backlog/web/rewindItemPhase.ts
|
|
4791
|
-
|
|
4822
|
+
import { eq as eq14 } from "drizzle-orm";
|
|
4823
|
+
async function rewindItemPhase(req, res, id2) {
|
|
4792
4824
|
const { phase, reason } = await parseRewindBody(req);
|
|
4793
|
-
const result = await findItemOr404(res,
|
|
4825
|
+
const result = await findItemOr404(res, id2);
|
|
4794
4826
|
if (!result) return;
|
|
4795
4827
|
const { orm, item } = result;
|
|
4796
4828
|
const error = validateRewind(item, phase);
|
|
@@ -4801,12 +4833,12 @@ async function rewindItemPhase(req, res, id) {
|
|
|
4801
4833
|
const phaseName = item.plan?.[phase - 1].name;
|
|
4802
4834
|
await appendComment(
|
|
4803
4835
|
orm,
|
|
4804
|
-
|
|
4836
|
+
id2,
|
|
4805
4837
|
`Rewound to phase ${phase} (${phaseName}): ${reason}`,
|
|
4806
4838
|
{ phase }
|
|
4807
4839
|
);
|
|
4808
|
-
await orm.update(items).set({ currentPhase: phase, status: "in-progress" }).where(
|
|
4809
|
-
respondJson(res, 200, await loadItem(orm,
|
|
4840
|
+
await orm.update(items).set({ currentPhase: phase, status: "in-progress" }).where(eq14(items.id, id2));
|
|
4841
|
+
respondJson(res, 200, await loadItem(orm, id2));
|
|
4810
4842
|
}
|
|
4811
4843
|
function validateRewind(item, phase) {
|
|
4812
4844
|
if (!item.plan || item.plan.length === 0) {
|
|
@@ -4823,10 +4855,10 @@ function validateRewind(item, phase) {
|
|
|
4823
4855
|
}
|
|
4824
4856
|
|
|
4825
4857
|
// src/commands/backlog/web/updateItem.ts
|
|
4826
|
-
import { eq as
|
|
4827
|
-
async function updateItem(req, res,
|
|
4858
|
+
import { eq as eq15 } from "drizzle-orm";
|
|
4859
|
+
async function updateItem(req, res, id2) {
|
|
4828
4860
|
const body = await parseItemBody(req);
|
|
4829
|
-
const result = await findItemOr404(res,
|
|
4861
|
+
const result = await findItemOr404(res, id2);
|
|
4830
4862
|
if (!result) return;
|
|
4831
4863
|
const { orm } = result;
|
|
4832
4864
|
await orm.update(items).set({
|
|
@@ -4834,41 +4866,59 @@ async function updateItem(req, res, id) {
|
|
|
4834
4866
|
name: body.name,
|
|
4835
4867
|
description: body.description ?? null,
|
|
4836
4868
|
acceptanceCriteria: JSON.stringify(body.acceptanceCriteria ?? [])
|
|
4837
|
-
}).where(
|
|
4838
|
-
respondJson(res, 200, await loadItem(orm,
|
|
4869
|
+
}).where(eq15(items.id, id2));
|
|
4870
|
+
respondJson(res, 200, await loadItem(orm, id2));
|
|
4839
4871
|
}
|
|
4840
4872
|
|
|
4841
4873
|
// src/commands/backlog/web/handleItemRoute.ts
|
|
4842
|
-
var
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4874
|
+
var id = (match, group = 1) => Number.parseInt(match[group], 10);
|
|
4875
|
+
var routes = [
|
|
4876
|
+
{
|
|
4877
|
+
pattern: /^\/api\/items\/(\d+)\/rewind$/,
|
|
4878
|
+
method: "POST",
|
|
4879
|
+
run: (req, res, m) => rewindItemPhase(req, res, id(m))
|
|
4880
|
+
},
|
|
4881
|
+
{
|
|
4882
|
+
pattern: /^\/api\/items\/(\d+)\/star$/,
|
|
4883
|
+
method: "POST",
|
|
4884
|
+
run: (req, res, m) => patchItemStar(req, res, id(m))
|
|
4885
|
+
},
|
|
4886
|
+
{
|
|
4887
|
+
pattern: /^\/api\/items\/(\d+)\/comments\/(\d+)$/,
|
|
4888
|
+
method: "DELETE",
|
|
4889
|
+
run: (_req, res, m) => deleteItemComment(res, id(m), id(m, 2))
|
|
4890
|
+
},
|
|
4891
|
+
{
|
|
4892
|
+
pattern: /^\/api\/items\/(\d+)$/,
|
|
4893
|
+
method: "GET",
|
|
4894
|
+
run: (_req, res, m) => getItemById(res, id(m))
|
|
4895
|
+
},
|
|
4896
|
+
{
|
|
4897
|
+
pattern: /^\/api\/items\/(\d+)$/,
|
|
4898
|
+
method: "PUT",
|
|
4899
|
+
run: (req, res, m) => updateItem(req, res, id(m))
|
|
4900
|
+
},
|
|
4901
|
+
{
|
|
4902
|
+
pattern: /^\/api\/items\/(\d+)$/,
|
|
4903
|
+
method: "PATCH",
|
|
4904
|
+
run: (req, res, m) => patchItemStatus(req, res, id(m))
|
|
4905
|
+
},
|
|
4906
|
+
{
|
|
4907
|
+
pattern: /^\/api\/items\/(\d+)$/,
|
|
4908
|
+
method: "DELETE",
|
|
4909
|
+
run: (_req, res, m) => deleteItem2(res, id(m))
|
|
4854
4910
|
}
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4911
|
+
];
|
|
4912
|
+
async function handleItemRoute(req, res, pathname) {
|
|
4913
|
+
for (const route of routes) {
|
|
4914
|
+
const match = pathname.match(route.pattern);
|
|
4915
|
+
if (match && req.method === route.method) {
|
|
4916
|
+
applyCwdFromReq(req);
|
|
4917
|
+
await route.run(req, res, match);
|
|
4918
|
+
return true;
|
|
4919
|
+
}
|
|
4864
4920
|
}
|
|
4865
|
-
|
|
4866
|
-
if (!match) return false;
|
|
4867
|
-
const handler = itemRoutes[req.method ?? "GET"];
|
|
4868
|
-
if (!handler) return false;
|
|
4869
|
-
applyCwdFromReq(req);
|
|
4870
|
-
await handler(req, res, Number.parseInt(match[1], 10));
|
|
4871
|
-
return true;
|
|
4921
|
+
return false;
|
|
4872
4922
|
}
|
|
4873
4923
|
|
|
4874
4924
|
// src/commands/backlog/init/index.ts
|
|
@@ -5308,7 +5358,7 @@ function createCssHandler(packageEntry) {
|
|
|
5308
5358
|
};
|
|
5309
5359
|
}
|
|
5310
5360
|
var htmlHandler = createHtmlHandler(getHtml);
|
|
5311
|
-
var
|
|
5361
|
+
var routes2 = {
|
|
5312
5362
|
"GET /": htmlHandler,
|
|
5313
5363
|
"GET /bundle.js": createBundleHandler(
|
|
5314
5364
|
import.meta.url,
|
|
@@ -5325,7 +5375,7 @@ var routes = {
|
|
|
5325
5375
|
"GET /api/news/items": listNewsItems
|
|
5326
5376
|
};
|
|
5327
5377
|
var handleRequest = createFallbackHandler(
|
|
5328
|
-
|
|
5378
|
+
routes2,
|
|
5329
5379
|
htmlHandler,
|
|
5330
5380
|
handleItemRoute
|
|
5331
5381
|
);
|
|
@@ -5335,14 +5385,14 @@ import { createInterface as createInterface2 } from "readline";
|
|
|
5335
5385
|
|
|
5336
5386
|
// src/commands/sessions/daemon/toWindowsSessionId.ts
|
|
5337
5387
|
var PREFIX = "w-";
|
|
5338
|
-
function toWindowsSessionId(
|
|
5339
|
-
return `${PREFIX}${
|
|
5388
|
+
function toWindowsSessionId(id2) {
|
|
5389
|
+
return `${PREFIX}${id2}`;
|
|
5340
5390
|
}
|
|
5341
|
-
function isWindowsSessionId(
|
|
5342
|
-
return
|
|
5391
|
+
function isWindowsSessionId(id2) {
|
|
5392
|
+
return id2.startsWith(PREFIX);
|
|
5343
5393
|
}
|
|
5344
|
-
function stripWindowsSessionId(
|
|
5345
|
-
return
|
|
5394
|
+
function stripWindowsSessionId(id2) {
|
|
5395
|
+
return id2.startsWith(PREFIX) ? id2.slice(PREFIX.length) : id2;
|
|
5346
5396
|
}
|
|
5347
5397
|
|
|
5348
5398
|
// src/commands/sessions/web/ui/repoLabel.ts
|
|
@@ -5378,9 +5428,9 @@ function applySnapshot(known, sessions) {
|
|
|
5378
5428
|
if (previous === void 0) logEvent("started", session);
|
|
5379
5429
|
else if (isDone(session) && !isDone(previous)) logEvent("ended", session);
|
|
5380
5430
|
}
|
|
5381
|
-
for (const [
|
|
5382
|
-
if (present.has(
|
|
5383
|
-
known.delete(
|
|
5431
|
+
for (const [id2, session] of [...known]) {
|
|
5432
|
+
if (present.has(id2)) continue;
|
|
5433
|
+
known.delete(id2);
|
|
5384
5434
|
if (!isDone(session)) logEvent("ended", session);
|
|
5385
5435
|
}
|
|
5386
5436
|
}
|
|
@@ -5736,25 +5786,25 @@ async function web2(options2) {
|
|
|
5736
5786
|
|
|
5737
5787
|
// src/commands/backlog/comment/index.ts
|
|
5738
5788
|
import chalk48 from "chalk";
|
|
5739
|
-
async function comment(
|
|
5740
|
-
const found = await findOneItem(
|
|
5789
|
+
async function comment(id2, text3) {
|
|
5790
|
+
const found = await findOneItem(id2);
|
|
5741
5791
|
if (!found) process.exit(1);
|
|
5742
5792
|
await appendComment(found.orm, found.item.id, text3);
|
|
5743
|
-
console.log(chalk48.green(`Comment added to item #${
|
|
5793
|
+
console.log(chalk48.green(`Comment added to item #${id2}.`));
|
|
5744
5794
|
}
|
|
5745
5795
|
|
|
5746
5796
|
// src/commands/backlog/comments/index.ts
|
|
5747
5797
|
import chalk49 from "chalk";
|
|
5748
|
-
async function comments2(
|
|
5749
|
-
const found = await findOneItem(
|
|
5798
|
+
async function comments2(id2) {
|
|
5799
|
+
const found = await findOneItem(id2);
|
|
5750
5800
|
if (!found) process.exit(1);
|
|
5751
5801
|
const { item } = found;
|
|
5752
5802
|
const entries = item.comments ?? [];
|
|
5753
5803
|
if (entries.length === 0) {
|
|
5754
|
-
console.log(chalk49.dim(`No comments on item #${
|
|
5804
|
+
console.log(chalk49.dim(`No comments on item #${id2}.`));
|
|
5755
5805
|
return;
|
|
5756
5806
|
}
|
|
5757
|
-
console.log(chalk49.bold(`Comments for #${
|
|
5807
|
+
console.log(chalk49.bold(`Comments for #${id2}: ${item.name}
|
|
5758
5808
|
`));
|
|
5759
5809
|
for (const entry of entries) {
|
|
5760
5810
|
console.log(`${formatComment(entry)}
|
|
@@ -5764,8 +5814,8 @@ async function comments2(id) {
|
|
|
5764
5814
|
|
|
5765
5815
|
// src/commands/backlog/delete-comment/index.ts
|
|
5766
5816
|
import chalk50 from "chalk";
|
|
5767
|
-
async function deleteCommentCmd(
|
|
5768
|
-
const found = await findOneItem(
|
|
5817
|
+
async function deleteCommentCmd(id2, commentId) {
|
|
5818
|
+
const found = await findOneItem(id2);
|
|
5769
5819
|
if (!found) process.exit(1);
|
|
5770
5820
|
const outcome = await deleteComment(
|
|
5771
5821
|
found.orm,
|
|
@@ -5775,11 +5825,11 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
5775
5825
|
switch (outcome) {
|
|
5776
5826
|
case "deleted":
|
|
5777
5827
|
console.log(
|
|
5778
|
-
chalk50.green(`Comment #${commentId} deleted from item #${
|
|
5828
|
+
chalk50.green(`Comment #${commentId} deleted from item #${id2}.`)
|
|
5779
5829
|
);
|
|
5780
5830
|
break;
|
|
5781
5831
|
case "not-found":
|
|
5782
|
-
console.log(chalk50.red(`Comment #${commentId} not found on item #${
|
|
5832
|
+
console.log(chalk50.red(`Comment #${commentId} not found on item #${id2}.`));
|
|
5783
5833
|
process.exit(1);
|
|
5784
5834
|
break;
|
|
5785
5835
|
case "is-summary":
|
|
@@ -6151,40 +6201,41 @@ async function add(options2) {
|
|
|
6151
6201
|
const description = options2.desc?.replaceAll("\\n", "\n") ?? await promptDescription();
|
|
6152
6202
|
const acceptanceCriteria2 = options2.ac ?? await promptAcceptanceCriteria();
|
|
6153
6203
|
const orm = await getBacklogOrm();
|
|
6154
|
-
const
|
|
6204
|
+
const id2 = await insertItem(
|
|
6155
6205
|
orm,
|
|
6156
6206
|
{
|
|
6157
6207
|
type,
|
|
6158
6208
|
name,
|
|
6159
6209
|
description: description || void 0,
|
|
6160
6210
|
acceptanceCriteria: acceptanceCriteria2,
|
|
6161
|
-
status: "todo"
|
|
6211
|
+
status: "todo",
|
|
6212
|
+
starred: false
|
|
6162
6213
|
},
|
|
6163
6214
|
getOrigin()
|
|
6164
6215
|
);
|
|
6165
|
-
console.log(chalk54.green(`Added item #${
|
|
6216
|
+
console.log(chalk54.green(`Added item #${id2}: ${name}`));
|
|
6166
6217
|
}
|
|
6167
6218
|
|
|
6168
6219
|
// src/commands/backlog/addPhase.ts
|
|
6169
6220
|
import chalk56 from "chalk";
|
|
6170
6221
|
|
|
6171
6222
|
// src/commands/backlog/insertPhaseAt.ts
|
|
6172
|
-
import { count, eq as
|
|
6223
|
+
import { count, eq as eq17 } from "drizzle-orm";
|
|
6173
6224
|
|
|
6174
6225
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
6175
|
-
import { and as and3, desc, eq as
|
|
6226
|
+
import { and as and3, desc, eq as eq16, gte } from "drizzle-orm";
|
|
6176
6227
|
async function shiftPhasesUp(db, itemId, fromIdx) {
|
|
6177
|
-
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(
|
|
6228
|
+
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(eq16(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(desc(planPhases.idx));
|
|
6178
6229
|
for (const p of toShift) {
|
|
6179
|
-
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and3(
|
|
6180
|
-
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and3(
|
|
6230
|
+
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and3(eq16(planTasks.itemId, itemId), eq16(planTasks.phaseIdx, p.idx)));
|
|
6231
|
+
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and3(eq16(planPhases.itemId, itemId), eq16(planPhases.idx, p.idx)));
|
|
6181
6232
|
}
|
|
6182
6233
|
}
|
|
6183
6234
|
|
|
6184
6235
|
// src/commands/backlog/insertPhaseAt.ts
|
|
6185
6236
|
async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, currentPhase) {
|
|
6186
6237
|
await orm.transaction(async (tx) => {
|
|
6187
|
-
const [row] = await tx.select({ cnt: count() }).from(planPhases).where(
|
|
6238
|
+
const [row] = await tx.select({ cnt: count() }).from(planPhases).where(eq17(planPhases.itemId, itemId));
|
|
6188
6239
|
const phaseCount = row?.cnt ?? 0;
|
|
6189
6240
|
await shiftPhasesUp(tx, itemId, phaseIdx);
|
|
6190
6241
|
await tx.insert(planPhases).values({ itemId, idx: phaseIdx, name, manualChecks });
|
|
@@ -6193,16 +6244,16 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
|
|
|
6193
6244
|
}
|
|
6194
6245
|
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
6195
6246
|
const atReviewSlot = currentPhase - 1 >= phaseCount;
|
|
6196
|
-
await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(
|
|
6247
|
+
await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(eq17(items.id, itemId));
|
|
6197
6248
|
}
|
|
6198
6249
|
});
|
|
6199
6250
|
}
|
|
6200
6251
|
|
|
6201
6252
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
6202
6253
|
import chalk55 from "chalk";
|
|
6203
|
-
import { count as count2, eq as
|
|
6254
|
+
import { count as count2, eq as eq18 } from "drizzle-orm";
|
|
6204
6255
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
6205
|
-
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(
|
|
6256
|
+
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq18(planPhases.itemId, itemId));
|
|
6206
6257
|
const phaseCount = row?.cnt ?? 0;
|
|
6207
6258
|
if (position === void 0) return phaseCount;
|
|
6208
6259
|
const pos = Number.parseInt(position, 10);
|
|
@@ -6224,8 +6275,8 @@ function serializeManualChecks(manualCheck) {
|
|
|
6224
6275
|
}
|
|
6225
6276
|
|
|
6226
6277
|
// src/commands/backlog/addPhase.ts
|
|
6227
|
-
async function addPhase(
|
|
6228
|
-
const found = await findOneItem(
|
|
6278
|
+
async function addPhase(id2, name, options2) {
|
|
6279
|
+
const found = await findOneItem(id2);
|
|
6229
6280
|
if (!found) return;
|
|
6230
6281
|
const tasks = options2.task ?? [];
|
|
6231
6282
|
if (tasks.length === 0) {
|
|
@@ -6318,7 +6369,7 @@ async function list2(options2) {
|
|
|
6318
6369
|
for (const item of items2) {
|
|
6319
6370
|
const repoPrefix = options2.allRepos ? `${chalk57.dim(repoNameOf(item).padEnd(prefixWidth))} ` : "";
|
|
6320
6371
|
console.log(
|
|
6321
|
-
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk57.dim(`#${item.id}`)} ${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
6372
|
+
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk57.dim(`#${item.id}`)} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
6322
6373
|
);
|
|
6323
6374
|
if (options2.verbose) {
|
|
6324
6375
|
printVerboseDetails(item);
|
|
@@ -6363,9 +6414,9 @@ function hasCycle(adjacency, fromId, toId) {
|
|
|
6363
6414
|
}
|
|
6364
6415
|
|
|
6365
6416
|
// src/commands/backlog/loadDependencyGraph.ts
|
|
6366
|
-
import { eq as
|
|
6417
|
+
import { eq as eq19 } from "drizzle-orm";
|
|
6367
6418
|
async function loadDependencyGraph(orm) {
|
|
6368
|
-
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(
|
|
6419
|
+
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq19(links.type, "depends-on"));
|
|
6369
6420
|
const graph = /* @__PURE__ */ new Map();
|
|
6370
6421
|
for (const { itemId, targetId } of rows) {
|
|
6371
6422
|
const bucket = graph.get(itemId);
|
|
@@ -6428,7 +6479,7 @@ async function link(fromId, toId, opts) {
|
|
|
6428
6479
|
|
|
6429
6480
|
// src/commands/backlog/unlink.ts
|
|
6430
6481
|
import chalk60 from "chalk";
|
|
6431
|
-
import { and as and4, eq as
|
|
6482
|
+
import { and as and4, eq as eq20 } from "drizzle-orm";
|
|
6432
6483
|
async function unlink(fromId, toId) {
|
|
6433
6484
|
const fromNum = Number.parseInt(fromId, 10);
|
|
6434
6485
|
const toNum = Number.parseInt(toId, 10);
|
|
@@ -6446,7 +6497,7 @@ async function unlink(fromId, toId) {
|
|
|
6446
6497
|
console.log(chalk60.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
6447
6498
|
return;
|
|
6448
6499
|
}
|
|
6449
|
-
await orm.delete(links).where(and4(
|
|
6500
|
+
await orm.delete(links).where(and4(eq20(links.itemId, fromNum), eq20(links.targetId, toNum)));
|
|
6450
6501
|
console.log(chalk60.green(`Removed link from #${fromId} to #${toId}.`));
|
|
6451
6502
|
}
|
|
6452
6503
|
|
|
@@ -6462,7 +6513,7 @@ function registerLinkCommands(cmd) {
|
|
|
6462
6513
|
|
|
6463
6514
|
// src/commands/backlog/move-repo/index.ts
|
|
6464
6515
|
import chalk62 from "chalk";
|
|
6465
|
-
import { eq as
|
|
6516
|
+
import { eq as eq22 } from "drizzle-orm";
|
|
6466
6517
|
|
|
6467
6518
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
6468
6519
|
import chalk61 from "chalk";
|
|
@@ -6477,9 +6528,9 @@ async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
|
6477
6528
|
}
|
|
6478
6529
|
|
|
6479
6530
|
// src/commands/backlog/move-repo/countByOrigin.ts
|
|
6480
|
-
import { count as count3, eq as
|
|
6531
|
+
import { count as count3, eq as eq21 } from "drizzle-orm";
|
|
6481
6532
|
async function countByOrigin(orm, origin) {
|
|
6482
|
-
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(
|
|
6533
|
+
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(eq21(items.origin, origin));
|
|
6483
6534
|
return cnt;
|
|
6484
6535
|
}
|
|
6485
6536
|
|
|
@@ -6522,7 +6573,7 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
6522
6573
|
console.log(chalk62.yellow("Move cancelled; no changes made."));
|
|
6523
6574
|
return;
|
|
6524
6575
|
}
|
|
6525
|
-
await orm.update(items).set({ origin: newOrigin }).where(
|
|
6576
|
+
await orm.update(items).set({ origin: newOrigin }).where(eq22(items.origin, oldOrigin));
|
|
6526
6577
|
console.log(
|
|
6527
6578
|
chalk62.green(
|
|
6528
6579
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
@@ -6542,7 +6593,7 @@ function registerMoveRepoCommand(cmd) {
|
|
|
6542
6593
|
// src/commands/backlog/registerNextCommand.ts
|
|
6543
6594
|
function registerNextCommand(cmd) {
|
|
6544
6595
|
cmd.command("next").argument("[id]", "Backlog item ID to run first").description("Pick and run the next backlog item, or open /draft if none").option("-w, --write", "Run Claude with auto permission mode (default)").option("--no-write", "Run Claude without auto permission mode").option("--once", "Exit after the first completed item run").action(
|
|
6545
|
-
(
|
|
6596
|
+
(id2, opts) => next({ allowEdits: opts.write !== false, once: opts.once }, id2)
|
|
6546
6597
|
);
|
|
6547
6598
|
}
|
|
6548
6599
|
|
|
@@ -6560,8 +6611,8 @@ import enquirer7 from "enquirer";
|
|
|
6560
6611
|
import chalk64 from "chalk";
|
|
6561
6612
|
|
|
6562
6613
|
// src/commands/backlog/surfaceCreatedItem.ts
|
|
6563
|
-
async function surfaceCreatedItem(slashCommand,
|
|
6564
|
-
const numericId = Number.parseInt(
|
|
6614
|
+
async function surfaceCreatedItem(slashCommand, id2) {
|
|
6615
|
+
const numericId = Number.parseInt(id2, 10);
|
|
6565
6616
|
if (Number.isNaN(numericId)) return;
|
|
6566
6617
|
const { orm } = await getReady();
|
|
6567
6618
|
const item = await loadItem(orm, numericId);
|
|
@@ -6576,33 +6627,33 @@ async function surfaceCreatedItem(slashCommand, id) {
|
|
|
6576
6627
|
|
|
6577
6628
|
// src/commands/backlog/tryRunById.ts
|
|
6578
6629
|
import chalk63 from "chalk";
|
|
6579
|
-
async function tryRunById(
|
|
6580
|
-
const numericId = Number.parseInt(
|
|
6630
|
+
async function tryRunById(id2, options2) {
|
|
6631
|
+
const numericId = Number.parseInt(id2, 10);
|
|
6581
6632
|
const { orm } = await getReady();
|
|
6582
6633
|
const item = Number.isNaN(numericId) ? void 0 : await loadItem(orm, numericId);
|
|
6583
6634
|
if (!item) {
|
|
6584
|
-
console.log(chalk63.red(`Item #${
|
|
6635
|
+
console.log(chalk63.red(`Item #${id2} not found.`));
|
|
6585
6636
|
return false;
|
|
6586
6637
|
}
|
|
6587
6638
|
if (item.status === "done") {
|
|
6588
|
-
console.log(chalk63.red(`Item #${
|
|
6639
|
+
console.log(chalk63.red(`Item #${id2} is already done.`));
|
|
6589
6640
|
return false;
|
|
6590
6641
|
}
|
|
6591
6642
|
if (item.status === "wontdo") {
|
|
6592
|
-
console.log(chalk63.red(`Item #${
|
|
6643
|
+
console.log(chalk63.red(`Item #${id2} is marked won't do.`));
|
|
6593
6644
|
return false;
|
|
6594
6645
|
}
|
|
6595
6646
|
const hasDeps = (item.links ?? []).some((l) => l.type === "depends-on");
|
|
6596
6647
|
if (hasDeps && isBlocked(item, await loadItemSummaries(orm, getOrigin()))) {
|
|
6597
6648
|
console.log(
|
|
6598
|
-
chalk63.red(`Item #${
|
|
6649
|
+
chalk63.red(`Item #${id2} is blocked by unresolved dependencies.`)
|
|
6599
6650
|
);
|
|
6600
6651
|
return false;
|
|
6601
6652
|
}
|
|
6602
6653
|
console.log(chalk63.bold(`
|
|
6603
|
-
Running backlog item #${
|
|
6654
|
+
Running backlog item #${id2}...
|
|
6604
6655
|
`));
|
|
6605
|
-
await run2(
|
|
6656
|
+
await run2(id2, options2);
|
|
6606
6657
|
return true;
|
|
6607
6658
|
}
|
|
6608
6659
|
|
|
@@ -6668,8 +6719,8 @@ async function pickItemForRefine() {
|
|
|
6668
6719
|
);
|
|
6669
6720
|
return selected.match(/#(\d+)/)?.[1] ?? "";
|
|
6670
6721
|
}
|
|
6671
|
-
async function refine(
|
|
6672
|
-
const itemId =
|
|
6722
|
+
async function refine(id2, options2) {
|
|
6723
|
+
const itemId = id2 ?? await pickItemForRefine();
|
|
6673
6724
|
if (!itemId) return;
|
|
6674
6725
|
const numericId = Number.parseInt(itemId, 10);
|
|
6675
6726
|
const item = Number.isNaN(numericId) ? void 0 : await loadItem((await getReady()).orm, numericId);
|
|
@@ -6683,7 +6734,7 @@ async function refine(id, options2) {
|
|
|
6683
6734
|
// src/commands/backlog/registerRefineCommand.ts
|
|
6684
6735
|
function registerRefineCommand(cmd) {
|
|
6685
6736
|
cmd.command("refine").argument("[id]", "Backlog item ID").description("Alias for refine").option("--once", "Exit when the initial task completes").action(
|
|
6686
|
-
(
|
|
6737
|
+
(id2, opts) => refine(id2, { once: opts.once })
|
|
6687
6738
|
);
|
|
6688
6739
|
}
|
|
6689
6740
|
|
|
@@ -6702,13 +6753,13 @@ function validateRewind2(item, phaseNumber) {
|
|
|
6702
6753
|
}
|
|
6703
6754
|
return void 0;
|
|
6704
6755
|
}
|
|
6705
|
-
async function rewindPhase(
|
|
6756
|
+
async function rewindPhase(id2, phase, opts) {
|
|
6706
6757
|
const phaseNumber = Number.parseInt(phase, 10);
|
|
6707
6758
|
const phaseIndex = phaseNumber - 1;
|
|
6708
6759
|
const { orm } = await getReady();
|
|
6709
|
-
const item = await loadItem(orm, Number.parseInt(
|
|
6760
|
+
const item = await loadItem(orm, Number.parseInt(id2, 10));
|
|
6710
6761
|
if (!item) {
|
|
6711
|
-
console.log(chalk66.red(`Item #${
|
|
6762
|
+
console.log(chalk66.red(`Item #${id2} not found.`));
|
|
6712
6763
|
return;
|
|
6713
6764
|
}
|
|
6714
6765
|
const error = validateRewind2(item, phaseNumber);
|
|
@@ -6724,14 +6775,14 @@ async function rewindPhase(id, phase, opts) {
|
|
|
6724
6775
|
`Rewound to phase ${phaseNumber} (${phaseName}): ${opts.reason}`,
|
|
6725
6776
|
{ phase: phaseNumber }
|
|
6726
6777
|
);
|
|
6727
|
-
await setCurrentPhase(
|
|
6728
|
-
await setStatus(
|
|
6778
|
+
await setCurrentPhase(id2, phaseNumber);
|
|
6779
|
+
await setStatus(id2, "in-progress");
|
|
6729
6780
|
writeSignal("rewind", {
|
|
6730
|
-
itemId: Number.parseInt(
|
|
6781
|
+
itemId: Number.parseInt(id2, 10),
|
|
6731
6782
|
targetPhase: phaseIndex
|
|
6732
6783
|
});
|
|
6733
6784
|
console.log(
|
|
6734
|
-
chalk66.green(`Rewound item #${
|
|
6785
|
+
chalk66.green(`Rewound item #${id2} to phase ${phaseNumber} (${phaseName}).`)
|
|
6735
6786
|
);
|
|
6736
6787
|
}
|
|
6737
6788
|
|
|
@@ -6746,9 +6797,9 @@ function registerRunCommand(cmd) {
|
|
|
6746
6797
|
"--resume-session <id>",
|
|
6747
6798
|
"Resume an interrupted Claude session for the current phase (used by the sessions daemon on restart)"
|
|
6748
6799
|
).action(
|
|
6749
|
-
async (
|
|
6800
|
+
async (id2, opts) => {
|
|
6750
6801
|
if (!opts.resumeSession) pullIfConfigured();
|
|
6751
|
-
await run2(
|
|
6802
|
+
await run2(id2, {
|
|
6752
6803
|
allowEdits: opts.write !== false,
|
|
6753
6804
|
resumeSessionId: opts.resumeSession
|
|
6754
6805
|
});
|
|
@@ -6784,17 +6835,17 @@ function registerSearchCommand(cmd) {
|
|
|
6784
6835
|
|
|
6785
6836
|
// src/commands/backlog/delete/index.ts
|
|
6786
6837
|
import chalk68 from "chalk";
|
|
6787
|
-
async function del(
|
|
6788
|
-
const name = await removeItem(
|
|
6838
|
+
async function del(id2) {
|
|
6839
|
+
const name = await removeItem(id2);
|
|
6789
6840
|
if (name) {
|
|
6790
|
-
console.log(chalk68.green(`Deleted item #${
|
|
6841
|
+
console.log(chalk68.green(`Deleted item #${id2}: ${name}`));
|
|
6791
6842
|
}
|
|
6792
6843
|
}
|
|
6793
6844
|
|
|
6794
6845
|
// src/commands/backlog/done/index.ts
|
|
6795
6846
|
import chalk69 from "chalk";
|
|
6796
|
-
async function done(
|
|
6797
|
-
const found = await findOneItem(
|
|
6847
|
+
async function done(id2, summary) {
|
|
6848
|
+
const found = await findOneItem(id2);
|
|
6798
6849
|
if (!found) return;
|
|
6799
6850
|
const { orm, item } = found;
|
|
6800
6851
|
if (item.plan && item.plan.length > 0) {
|
|
@@ -6803,7 +6854,7 @@ async function done(id, summary) {
|
|
|
6803
6854
|
if (pending.length > 0) {
|
|
6804
6855
|
console.log(
|
|
6805
6856
|
chalk69.red(
|
|
6806
|
-
`Cannot complete item #${
|
|
6857
|
+
`Cannot complete item #${id2}: ${pending.length} pending phase(s):`
|
|
6807
6858
|
)
|
|
6808
6859
|
);
|
|
6809
6860
|
for (const phase of pending) {
|
|
@@ -6818,37 +6869,66 @@ async function done(id, summary) {
|
|
|
6818
6869
|
const phase = item.currentPhase ?? 1;
|
|
6819
6870
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
6820
6871
|
}
|
|
6821
|
-
console.log(chalk69.green(`Completed item #${
|
|
6872
|
+
console.log(chalk69.green(`Completed item #${id2}: ${item.name}`));
|
|
6822
6873
|
}
|
|
6823
6874
|
|
|
6824
|
-
// src/commands/backlog/
|
|
6875
|
+
// src/commands/backlog/star/index.ts
|
|
6876
|
+
import chalk71 from "chalk";
|
|
6877
|
+
|
|
6878
|
+
// src/commands/backlog/setStarred.ts
|
|
6825
6879
|
import chalk70 from "chalk";
|
|
6826
|
-
async function
|
|
6827
|
-
const
|
|
6880
|
+
async function setStarred(id2, starred) {
|
|
6881
|
+
const { orm } = await getReady();
|
|
6882
|
+
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
6883
|
+
if (name === void 0) console.log(chalk70.red(`Item #${id2} not found.`));
|
|
6884
|
+
return name;
|
|
6885
|
+
}
|
|
6886
|
+
|
|
6887
|
+
// src/commands/backlog/star/index.ts
|
|
6888
|
+
async function star(id2) {
|
|
6889
|
+
const name = await setStarred(id2, true);
|
|
6828
6890
|
if (name) {
|
|
6829
|
-
console.log(
|
|
6891
|
+
console.log(chalk71.green(`Starred item #${id2}: ${name}`));
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
|
|
6895
|
+
// src/commands/backlog/start/index.ts
|
|
6896
|
+
import chalk72 from "chalk";
|
|
6897
|
+
async function start(id2) {
|
|
6898
|
+
const name = await setStatus(id2, "in-progress");
|
|
6899
|
+
if (name) {
|
|
6900
|
+
console.log(chalk72.green(`Started item #${id2}: ${name}`));
|
|
6830
6901
|
}
|
|
6831
6902
|
}
|
|
6832
6903
|
|
|
6833
6904
|
// src/commands/backlog/stop/index.ts
|
|
6834
|
-
import
|
|
6835
|
-
import { and as and5, eq as
|
|
6905
|
+
import chalk73 from "chalk";
|
|
6906
|
+
import { and as and5, eq as eq23 } from "drizzle-orm";
|
|
6836
6907
|
async function stop() {
|
|
6837
6908
|
const { orm } = await getReady();
|
|
6838
|
-
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and5(
|
|
6909
|
+
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and5(eq23(items.status, "in-progress"), eq23(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
6839
6910
|
if (stopped.length === 0) {
|
|
6840
|
-
console.log(
|
|
6911
|
+
console.log(chalk73.yellow("No in-progress items to stop."));
|
|
6841
6912
|
return;
|
|
6842
6913
|
}
|
|
6843
6914
|
for (const item of stopped) {
|
|
6844
|
-
console.log(
|
|
6915
|
+
console.log(chalk73.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
6916
|
+
}
|
|
6917
|
+
}
|
|
6918
|
+
|
|
6919
|
+
// src/commands/backlog/unstar/index.ts
|
|
6920
|
+
import chalk74 from "chalk";
|
|
6921
|
+
async function unstar(id2) {
|
|
6922
|
+
const name = await setStarred(id2, false);
|
|
6923
|
+
if (name) {
|
|
6924
|
+
console.log(chalk74.green(`Unstarred item #${id2}: ${name}`));
|
|
6845
6925
|
}
|
|
6846
6926
|
}
|
|
6847
6927
|
|
|
6848
6928
|
// src/commands/backlog/wontdo/index.ts
|
|
6849
|
-
import
|
|
6850
|
-
async function wontdo(
|
|
6851
|
-
const found = await findOneItem(
|
|
6929
|
+
import chalk75 from "chalk";
|
|
6930
|
+
async function wontdo(id2, reason) {
|
|
6931
|
+
const found = await findOneItem(id2);
|
|
6852
6932
|
if (!found) return;
|
|
6853
6933
|
const { orm, item } = found;
|
|
6854
6934
|
await updateStatus(orm, item.id, "wontdo");
|
|
@@ -6856,7 +6936,7 @@ async function wontdo(id, reason) {
|
|
|
6856
6936
|
const phase = item.currentPhase ?? 1;
|
|
6857
6937
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
6858
6938
|
}
|
|
6859
|
-
console.log(
|
|
6939
|
+
console.log(chalk75.red(`Won't do item #${id2}: ${item.name}`));
|
|
6860
6940
|
}
|
|
6861
6941
|
|
|
6862
6942
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -6865,26 +6945,28 @@ function registerStatusCommands(cmd) {
|
|
|
6865
6945
|
cmd.command("stop").description("Revert all in-progress backlog items to todo").action(stop);
|
|
6866
6946
|
cmd.command("done <id> [summary]").description("Set a backlog item to done").action(done);
|
|
6867
6947
|
cmd.command("wontdo <id> [reason]").description("Set a backlog item to won't do").action(wontdo);
|
|
6948
|
+
cmd.command("star <id>").description("Star a backlog item to pin it in the web view").action(star);
|
|
6949
|
+
cmd.command("unstar <id>").description("Remove the star from a backlog item").action(unstar);
|
|
6868
6950
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
6869
6951
|
}
|
|
6870
6952
|
|
|
6871
6953
|
// src/commands/backlog/removePhase.ts
|
|
6872
|
-
import
|
|
6873
|
-
import { and as and8, eq as
|
|
6954
|
+
import chalk77 from "chalk";
|
|
6955
|
+
import { and as and8, eq as eq26 } from "drizzle-orm";
|
|
6874
6956
|
|
|
6875
6957
|
// src/commands/backlog/findPhase.ts
|
|
6876
|
-
import
|
|
6877
|
-
import { and as and6, count as count4, eq as
|
|
6878
|
-
async function findPhase(
|
|
6879
|
-
const found = await findOneItem(
|
|
6958
|
+
import chalk76 from "chalk";
|
|
6959
|
+
import { and as and6, count as count4, eq as eq24 } from "drizzle-orm";
|
|
6960
|
+
async function findPhase(id2, phase) {
|
|
6961
|
+
const found = await findOneItem(id2);
|
|
6880
6962
|
if (!found) return void 0;
|
|
6881
6963
|
const { orm, item } = found;
|
|
6882
6964
|
const itemId = item.id;
|
|
6883
6965
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
6884
|
-
const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and6(
|
|
6966
|
+
const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and6(eq24(planPhases.itemId, itemId), eq24(planPhases.idx, phaseIdx)));
|
|
6885
6967
|
if (!row || row.cnt === 0) {
|
|
6886
6968
|
console.log(
|
|
6887
|
-
|
|
6969
|
+
chalk76.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
6888
6970
|
);
|
|
6889
6971
|
process.exitCode = 1;
|
|
6890
6972
|
return void 0;
|
|
@@ -6893,14 +6975,14 @@ async function findPhase(id, phase) {
|
|
|
6893
6975
|
}
|
|
6894
6976
|
|
|
6895
6977
|
// src/commands/backlog/reindexPhases.ts
|
|
6896
|
-
import { and as and7, asc as asc6, count as count5, eq as
|
|
6978
|
+
import { and as and7, asc as asc6, count as count5, eq as eq25 } from "drizzle-orm";
|
|
6897
6979
|
async function reindexPhases(db, itemId) {
|
|
6898
|
-
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
6980
|
+
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq25(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
|
|
6899
6981
|
for (let i = 0; i < remaining.length; i++) {
|
|
6900
6982
|
const oldIdx = remaining[i].idx;
|
|
6901
6983
|
if (oldIdx === i) continue;
|
|
6902
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(and7(
|
|
6903
|
-
await db.update(planPhases).set({ idx: i }).where(and7(
|
|
6984
|
+
await db.update(planTasks).set({ phaseIdx: i }).where(and7(eq25(planTasks.itemId, itemId), eq25(planTasks.phaseIdx, oldIdx)));
|
|
6985
|
+
await db.update(planPhases).set({ idx: i }).where(and7(eq25(planPhases.itemId, itemId), eq25(planPhases.idx, oldIdx)));
|
|
6904
6986
|
}
|
|
6905
6987
|
}
|
|
6906
6988
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -6908,36 +6990,36 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
6908
6990
|
if (currentPhase === void 0) return;
|
|
6909
6991
|
const currentIdx = currentPhase - 1;
|
|
6910
6992
|
if (removedIdx < currentIdx) {
|
|
6911
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
6993
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq25(items.id, item.id));
|
|
6912
6994
|
return;
|
|
6913
6995
|
}
|
|
6914
6996
|
if (removedIdx !== currentIdx) return;
|
|
6915
|
-
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(
|
|
6997
|
+
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq25(planPhases.itemId, item.id));
|
|
6916
6998
|
const cnt = row?.cnt ?? 0;
|
|
6917
|
-
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(
|
|
6999
|
+
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq25(items.id, item.id));
|
|
6918
7000
|
}
|
|
6919
7001
|
|
|
6920
7002
|
// src/commands/backlog/removePhase.ts
|
|
6921
|
-
async function removePhase(
|
|
6922
|
-
const found = await findPhase(
|
|
7003
|
+
async function removePhase(id2, phase) {
|
|
7004
|
+
const found = await findPhase(id2, phase);
|
|
6923
7005
|
if (!found) return;
|
|
6924
7006
|
const { item, orm, itemId, phaseIdx } = found;
|
|
6925
7007
|
await orm.transaction(async (tx) => {
|
|
6926
7008
|
await tx.delete(planTasks).where(
|
|
6927
|
-
and8(
|
|
7009
|
+
and8(eq26(planTasks.itemId, itemId), eq26(planTasks.phaseIdx, phaseIdx))
|
|
6928
7010
|
);
|
|
6929
|
-
await tx.delete(planPhases).where(and8(
|
|
7011
|
+
await tx.delete(planPhases).where(and8(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
|
|
6930
7012
|
await reindexPhases(tx, itemId);
|
|
6931
7013
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
6932
7014
|
});
|
|
6933
7015
|
console.log(
|
|
6934
|
-
|
|
7016
|
+
chalk77.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
6935
7017
|
);
|
|
6936
7018
|
}
|
|
6937
7019
|
|
|
6938
7020
|
// src/commands/backlog/update/index.ts
|
|
6939
|
-
import
|
|
6940
|
-
import { eq as
|
|
7021
|
+
import chalk79 from "chalk";
|
|
7022
|
+
import { eq as eq27 } from "drizzle-orm";
|
|
6941
7023
|
|
|
6942
7024
|
// src/commands/backlog/update/parseListIndex.ts
|
|
6943
7025
|
function parseListIndex(raw, length, label2) {
|
|
@@ -7012,16 +7094,16 @@ function applyAcMutations(current, options2) {
|
|
|
7012
7094
|
}
|
|
7013
7095
|
|
|
7014
7096
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7015
|
-
import
|
|
7097
|
+
import chalk78 from "chalk";
|
|
7016
7098
|
function buildUpdateValues(options2) {
|
|
7017
7099
|
const { name, desc: desc2, type, ac } = options2;
|
|
7018
7100
|
if (!name && !desc2 && !type && !ac) {
|
|
7019
|
-
console.log(
|
|
7101
|
+
console.log(chalk78.red("Nothing to update. Provide at least one flag."));
|
|
7020
7102
|
process.exitCode = 1;
|
|
7021
7103
|
return void 0;
|
|
7022
7104
|
}
|
|
7023
7105
|
if (type && type !== "story" && type !== "bug") {
|
|
7024
|
-
console.log(
|
|
7106
|
+
console.log(chalk78.red('Invalid type. Must be "story" or "bug".'));
|
|
7025
7107
|
process.exitCode = 1;
|
|
7026
7108
|
return void 0;
|
|
7027
7109
|
}
|
|
@@ -7047,21 +7129,21 @@ function buildUpdateValues(options2) {
|
|
|
7047
7129
|
}
|
|
7048
7130
|
|
|
7049
7131
|
// src/commands/backlog/update/index.ts
|
|
7050
|
-
async function update(
|
|
7051
|
-
const found = await findOneItem(
|
|
7132
|
+
async function update(id2, options2) {
|
|
7133
|
+
const found = await findOneItem(id2);
|
|
7052
7134
|
if (!found) return;
|
|
7053
7135
|
let ac = options2.ac;
|
|
7054
7136
|
if (hasAcMutations(options2)) {
|
|
7055
7137
|
if (options2.ac) {
|
|
7056
7138
|
console.log(
|
|
7057
|
-
|
|
7139
|
+
chalk79.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
7058
7140
|
);
|
|
7059
7141
|
process.exitCode = 1;
|
|
7060
7142
|
return;
|
|
7061
7143
|
}
|
|
7062
7144
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
7063
7145
|
if (!mutation.ok) {
|
|
7064
|
-
console.log(
|
|
7146
|
+
console.log(chalk79.red(mutation.error));
|
|
7065
7147
|
process.exitCode = 1;
|
|
7066
7148
|
return;
|
|
7067
7149
|
}
|
|
@@ -7071,30 +7153,30 @@ async function update(id, options2) {
|
|
|
7071
7153
|
if (!built) return;
|
|
7072
7154
|
const { orm } = found;
|
|
7073
7155
|
const itemId = found.item.id;
|
|
7074
|
-
await orm.update(items).set(built.set).where(
|
|
7075
|
-
console.log(
|
|
7156
|
+
await orm.update(items).set(built.set).where(eq27(items.id, itemId));
|
|
7157
|
+
console.log(chalk79.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
7076
7158
|
}
|
|
7077
7159
|
|
|
7078
7160
|
// src/commands/backlog/updatePhase.ts
|
|
7079
|
-
import
|
|
7161
|
+
import chalk80 from "chalk";
|
|
7080
7162
|
|
|
7081
7163
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
7082
|
-
import { and as and9, eq as
|
|
7164
|
+
import { and as and9, eq as eq28 } from "drizzle-orm";
|
|
7083
7165
|
async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
|
|
7084
7166
|
await orm.transaction(async (tx) => {
|
|
7085
7167
|
if (fields.name) {
|
|
7086
7168
|
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
7087
|
-
and9(
|
|
7169
|
+
and9(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx))
|
|
7088
7170
|
);
|
|
7089
7171
|
}
|
|
7090
7172
|
if (fields.manualCheck) {
|
|
7091
7173
|
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
7092
|
-
and9(
|
|
7174
|
+
and9(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx))
|
|
7093
7175
|
);
|
|
7094
7176
|
}
|
|
7095
7177
|
if (fields.task) {
|
|
7096
7178
|
await tx.delete(planTasks).where(
|
|
7097
|
-
and9(
|
|
7179
|
+
and9(eq28(planTasks.itemId, itemId), eq28(planTasks.phaseIdx, phaseIdx))
|
|
7098
7180
|
);
|
|
7099
7181
|
if (fields.task.length) {
|
|
7100
7182
|
await tx.insert(planTasks).values(
|
|
@@ -7174,13 +7256,13 @@ function resolvePhaseFields(options2, current) {
|
|
|
7174
7256
|
}
|
|
7175
7257
|
|
|
7176
7258
|
// src/commands/backlog/updatePhase.ts
|
|
7177
|
-
async function updatePhase(
|
|
7178
|
-
const found = await findPhase(
|
|
7259
|
+
async function updatePhase(id2, phase, options2) {
|
|
7260
|
+
const found = await findPhase(id2, phase);
|
|
7179
7261
|
if (!found) return;
|
|
7180
7262
|
const { item, orm, itemId, phaseIdx } = found;
|
|
7181
7263
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
7182
7264
|
if (!resolved.ok) {
|
|
7183
|
-
console.log(
|
|
7265
|
+
console.log(chalk80.red(resolved.error));
|
|
7184
7266
|
process.exitCode = 1;
|
|
7185
7267
|
return;
|
|
7186
7268
|
}
|
|
@@ -7192,7 +7274,7 @@ async function updatePhase(id, phase, options2) {
|
|
|
7192
7274
|
manualCheck && "manual checks"
|
|
7193
7275
|
].filter(Boolean).join(", ");
|
|
7194
7276
|
console.log(
|
|
7195
|
-
|
|
7277
|
+
chalk80.green(
|
|
7196
7278
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
7197
7279
|
)
|
|
7198
7280
|
);
|
|
@@ -7925,11 +8007,11 @@ function assertCliExists(cli) {
|
|
|
7925
8007
|
}
|
|
7926
8008
|
|
|
7927
8009
|
// src/commands/permitCliReads/colorize.ts
|
|
7928
|
-
import
|
|
8010
|
+
import chalk81 from "chalk";
|
|
7929
8011
|
function colorize(plainOutput) {
|
|
7930
8012
|
return plainOutput.split("\n").map((line) => {
|
|
7931
|
-
if (line.startsWith(" R ")) return
|
|
7932
|
-
if (line.startsWith(" W ")) return
|
|
8013
|
+
if (line.startsWith(" R ")) return chalk81.green(line);
|
|
8014
|
+
if (line.startsWith(" W ")) return chalk81.red(line);
|
|
7933
8015
|
return line;
|
|
7934
8016
|
}).join("\n");
|
|
7935
8017
|
}
|
|
@@ -8227,7 +8309,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
8227
8309
|
}
|
|
8228
8310
|
|
|
8229
8311
|
// src/commands/deny/denyAdd.ts
|
|
8230
|
-
import
|
|
8312
|
+
import chalk82 from "chalk";
|
|
8231
8313
|
|
|
8232
8314
|
// src/commands/deny/loadDenyConfig.ts
|
|
8233
8315
|
function loadDenyConfig(global) {
|
|
@@ -8247,16 +8329,16 @@ function loadDenyConfig(global) {
|
|
|
8247
8329
|
function denyAdd(pattern2, message, options2) {
|
|
8248
8330
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
8249
8331
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
8250
|
-
console.log(
|
|
8332
|
+
console.log(chalk82.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
8251
8333
|
return;
|
|
8252
8334
|
}
|
|
8253
8335
|
deny.push({ pattern: pattern2, message });
|
|
8254
8336
|
saveDeny(deny);
|
|
8255
|
-
console.log(
|
|
8337
|
+
console.log(chalk82.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
8256
8338
|
}
|
|
8257
8339
|
|
|
8258
8340
|
// src/commands/deny/denyList.ts
|
|
8259
|
-
import
|
|
8341
|
+
import chalk83 from "chalk";
|
|
8260
8342
|
function denyList() {
|
|
8261
8343
|
const globalRaw = loadGlobalConfigRaw();
|
|
8262
8344
|
const projectRaw = loadProjectConfig();
|
|
@@ -8267,7 +8349,7 @@ function denyList() {
|
|
|
8267
8349
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
8268
8350
|
);
|
|
8269
8351
|
if (!merged || merged.length === 0) {
|
|
8270
|
-
console.log(
|
|
8352
|
+
console.log(chalk83.dim("No deny rules configured."));
|
|
8271
8353
|
return;
|
|
8272
8354
|
}
|
|
8273
8355
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -8275,23 +8357,23 @@ function denyList() {
|
|
|
8275
8357
|
for (const rule of merged) {
|
|
8276
8358
|
const inProject = projectPatterns.has(rule.pattern);
|
|
8277
8359
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
8278
|
-
const label2 = inProject && inGlobal ?
|
|
8279
|
-
console.log(`${
|
|
8360
|
+
const label2 = inProject && inGlobal ? chalk83.dim(" (project, overrides global)") : inGlobal ? chalk83.dim(" (global)") : "";
|
|
8361
|
+
console.log(`${chalk83.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
8280
8362
|
}
|
|
8281
8363
|
}
|
|
8282
8364
|
|
|
8283
8365
|
// src/commands/deny/denyRemove.ts
|
|
8284
|
-
import
|
|
8366
|
+
import chalk84 from "chalk";
|
|
8285
8367
|
function denyRemove(pattern2, options2) {
|
|
8286
8368
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
8287
8369
|
const index2 = deny.findIndex((r) => r.pattern === pattern2);
|
|
8288
8370
|
if (index2 === -1) {
|
|
8289
|
-
console.log(
|
|
8371
|
+
console.log(chalk84.yellow(`No deny rule found for: ${pattern2}`));
|
|
8290
8372
|
return;
|
|
8291
8373
|
}
|
|
8292
8374
|
deny.splice(index2, 1);
|
|
8293
8375
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
8294
|
-
console.log(
|
|
8376
|
+
console.log(chalk84.green(`Removed deny rule: ${pattern2}`));
|
|
8295
8377
|
}
|
|
8296
8378
|
|
|
8297
8379
|
// src/commands/registerDeny.ts
|
|
@@ -8320,15 +8402,15 @@ function registerCliHook(program2) {
|
|
|
8320
8402
|
}
|
|
8321
8403
|
|
|
8322
8404
|
// src/commands/complexity/analyze.ts
|
|
8323
|
-
import
|
|
8405
|
+
import chalk91 from "chalk";
|
|
8324
8406
|
|
|
8325
8407
|
// src/commands/complexity/cyclomatic.ts
|
|
8326
|
-
import
|
|
8408
|
+
import chalk86 from "chalk";
|
|
8327
8409
|
|
|
8328
8410
|
// src/commands/complexity/shared/index.ts
|
|
8329
8411
|
import fs13 from "fs";
|
|
8330
8412
|
import path19 from "path";
|
|
8331
|
-
import
|
|
8413
|
+
import chalk85 from "chalk";
|
|
8332
8414
|
import ts5 from "typescript";
|
|
8333
8415
|
|
|
8334
8416
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -8579,7 +8661,7 @@ function createSourceFromFile(filePath) {
|
|
|
8579
8661
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
8580
8662
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
8581
8663
|
if (files.length === 0) {
|
|
8582
|
-
console.log(
|
|
8664
|
+
console.log(chalk85.yellow("No files found matching pattern"));
|
|
8583
8665
|
return void 0;
|
|
8584
8666
|
}
|
|
8585
8667
|
return callback(files);
|
|
@@ -8612,11 +8694,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8612
8694
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
8613
8695
|
for (const { file, name, complexity } of results) {
|
|
8614
8696
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
8615
|
-
const color = exceedsThreshold ?
|
|
8616
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
8697
|
+
const color = exceedsThreshold ? chalk86.red : chalk86.white;
|
|
8698
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk86.cyan(complexity)}`);
|
|
8617
8699
|
}
|
|
8618
8700
|
console.log(
|
|
8619
|
-
|
|
8701
|
+
chalk86.dim(
|
|
8620
8702
|
`
|
|
8621
8703
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
8622
8704
|
)
|
|
@@ -8628,7 +8710,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
8628
8710
|
}
|
|
8629
8711
|
|
|
8630
8712
|
// src/commands/complexity/halstead.ts
|
|
8631
|
-
import
|
|
8713
|
+
import chalk87 from "chalk";
|
|
8632
8714
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
8633
8715
|
withSourceFiles(pattern2, (files) => {
|
|
8634
8716
|
const results = [];
|
|
@@ -8643,13 +8725,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8643
8725
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
8644
8726
|
for (const { file, name, metrics } of results) {
|
|
8645
8727
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
8646
|
-
const color = exceedsThreshold ?
|
|
8728
|
+
const color = exceedsThreshold ? chalk87.red : chalk87.white;
|
|
8647
8729
|
console.log(
|
|
8648
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
8730
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk87.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk87.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk87.magenta(metrics.effort.toFixed(1))}`
|
|
8649
8731
|
);
|
|
8650
8732
|
}
|
|
8651
8733
|
console.log(
|
|
8652
|
-
|
|
8734
|
+
chalk87.dim(
|
|
8653
8735
|
`
|
|
8654
8736
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
8655
8737
|
)
|
|
@@ -8673,28 +8755,28 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
|
|
|
8673
8755
|
}
|
|
8674
8756
|
|
|
8675
8757
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
8676
|
-
import
|
|
8758
|
+
import chalk88 from "chalk";
|
|
8677
8759
|
function displayMaintainabilityResults(results, threshold) {
|
|
8678
8760
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
8679
8761
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
8680
|
-
console.log(
|
|
8762
|
+
console.log(chalk88.green("All files pass maintainability threshold"));
|
|
8681
8763
|
} else {
|
|
8682
8764
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
8683
|
-
const color = threshold !== void 0 ?
|
|
8765
|
+
const color = threshold !== void 0 ? chalk88.red : chalk88.white;
|
|
8684
8766
|
console.log(
|
|
8685
|
-
`${color(file)} \u2192 avg: ${
|
|
8767
|
+
`${color(file)} \u2192 avg: ${chalk88.cyan(avgMaintainability.toFixed(1))}, min: ${chalk88.yellow(minMaintainability.toFixed(1))}`
|
|
8686
8768
|
);
|
|
8687
8769
|
}
|
|
8688
8770
|
}
|
|
8689
|
-
console.log(
|
|
8771
|
+
console.log(chalk88.dim(`
|
|
8690
8772
|
Analyzed ${results.length} files`));
|
|
8691
8773
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
8692
8774
|
console.error(
|
|
8693
|
-
|
|
8775
|
+
chalk88.red(
|
|
8694
8776
|
`
|
|
8695
8777
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
8696
8778
|
|
|
8697
|
-
\u26A0\uFE0F ${
|
|
8779
|
+
\u26A0\uFE0F ${chalk88.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
|
|
8698
8780
|
)
|
|
8699
8781
|
);
|
|
8700
8782
|
process.exit(1);
|
|
@@ -8702,10 +8784,10 @@ Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability i
|
|
|
8702
8784
|
}
|
|
8703
8785
|
|
|
8704
8786
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
8705
|
-
import
|
|
8787
|
+
import chalk89 from "chalk";
|
|
8706
8788
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
8707
8789
|
function printMaintainabilityFormula() {
|
|
8708
|
-
console.log(
|
|
8790
|
+
console.log(chalk89.dim(MI_FORMULA));
|
|
8709
8791
|
}
|
|
8710
8792
|
|
|
8711
8793
|
// src/commands/complexity/maintainability/index.ts
|
|
@@ -8756,7 +8838,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8756
8838
|
|
|
8757
8839
|
// src/commands/complexity/sloc.ts
|
|
8758
8840
|
import fs15 from "fs";
|
|
8759
|
-
import
|
|
8841
|
+
import chalk90 from "chalk";
|
|
8760
8842
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
8761
8843
|
withSourceFiles(pattern2, (files) => {
|
|
8762
8844
|
const results = [];
|
|
@@ -8772,12 +8854,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8772
8854
|
results.sort((a, b) => b.lines - a.lines);
|
|
8773
8855
|
for (const { file, lines } of results) {
|
|
8774
8856
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
8775
|
-
const color = exceedsThreshold ?
|
|
8776
|
-
console.log(`${color(file)} \u2192 ${
|
|
8857
|
+
const color = exceedsThreshold ? chalk90.red : chalk90.white;
|
|
8858
|
+
console.log(`${color(file)} \u2192 ${chalk90.cyan(lines)} lines`);
|
|
8777
8859
|
}
|
|
8778
8860
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
8779
8861
|
console.log(
|
|
8780
|
-
|
|
8862
|
+
chalk90.dim(`
|
|
8781
8863
|
Total: ${total} lines across ${files.length} files`)
|
|
8782
8864
|
);
|
|
8783
8865
|
if (hasViolation) {
|
|
@@ -8791,22 +8873,28 @@ async function analyze(pattern2) {
|
|
|
8791
8873
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
8792
8874
|
const files = findSourceFiles2(searchPattern);
|
|
8793
8875
|
if (files.length === 0) {
|
|
8794
|
-
console.log(
|
|
8876
|
+
console.log(chalk91.yellow("No files found matching pattern"));
|
|
8795
8877
|
return;
|
|
8796
8878
|
}
|
|
8797
8879
|
if (files.length === 1) {
|
|
8798
8880
|
const file = files[0];
|
|
8799
|
-
console.log(
|
|
8881
|
+
console.log(chalk91.bold.underline("SLOC"));
|
|
8800
8882
|
await sloc(file);
|
|
8801
8883
|
console.log();
|
|
8802
|
-
console.log(
|
|
8884
|
+
console.log(chalk91.bold.underline("Cyclomatic Complexity"));
|
|
8803
8885
|
await cyclomatic(file);
|
|
8804
8886
|
console.log();
|
|
8805
|
-
console.log(
|
|
8887
|
+
console.log(chalk91.bold.underline("Halstead Metrics"));
|
|
8806
8888
|
await halstead(file);
|
|
8807
8889
|
console.log();
|
|
8808
|
-
console.log(
|
|
8890
|
+
console.log(chalk91.bold.underline("Maintainability Index"));
|
|
8809
8891
|
await maintainability(file);
|
|
8892
|
+
console.log();
|
|
8893
|
+
console.log(
|
|
8894
|
+
chalk91.dim(
|
|
8895
|
+
"To improve the maintainability index, extract functions and logic out of this file into separate, smaller modules. Collapsing whitespace or removing comments is not the goal."
|
|
8896
|
+
)
|
|
8897
|
+
);
|
|
8810
8898
|
return;
|
|
8811
8899
|
}
|
|
8812
8900
|
await maintainability(searchPattern);
|
|
@@ -8837,7 +8925,7 @@ function registerComplexity(program2) {
|
|
|
8837
8925
|
}
|
|
8838
8926
|
|
|
8839
8927
|
// src/commands/config/index.ts
|
|
8840
|
-
import
|
|
8928
|
+
import chalk92 from "chalk";
|
|
8841
8929
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
8842
8930
|
|
|
8843
8931
|
// src/commands/config/setNestedValue.ts
|
|
@@ -8900,7 +8988,7 @@ function formatIssuePath(issue, key) {
|
|
|
8900
8988
|
function printValidationErrors(issues, key) {
|
|
8901
8989
|
for (const issue of issues) {
|
|
8902
8990
|
console.error(
|
|
8903
|
-
|
|
8991
|
+
chalk92.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
8904
8992
|
);
|
|
8905
8993
|
}
|
|
8906
8994
|
}
|
|
@@ -8917,7 +9005,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
8917
9005
|
function assertNotGlobalOnly(key, global) {
|
|
8918
9006
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
8919
9007
|
console.error(
|
|
8920
|
-
|
|
9008
|
+
chalk92.red(
|
|
8921
9009
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
8922
9010
|
)
|
|
8923
9011
|
);
|
|
@@ -8940,7 +9028,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
8940
9028
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
8941
9029
|
const target = options2.global ? "global" : "project";
|
|
8942
9030
|
console.log(
|
|
8943
|
-
|
|
9031
|
+
chalk92.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
8944
9032
|
);
|
|
8945
9033
|
}
|
|
8946
9034
|
function configList() {
|
|
@@ -8949,7 +9037,7 @@ function configList() {
|
|
|
8949
9037
|
}
|
|
8950
9038
|
|
|
8951
9039
|
// src/commands/config/configGet.ts
|
|
8952
|
-
import
|
|
9040
|
+
import chalk93 from "chalk";
|
|
8953
9041
|
|
|
8954
9042
|
// src/commands/config/getNestedValue.ts
|
|
8955
9043
|
function isTraversable(value) {
|
|
@@ -8981,7 +9069,7 @@ function requireNestedValue(config, key) {
|
|
|
8981
9069
|
return value;
|
|
8982
9070
|
}
|
|
8983
9071
|
function exitKeyNotSet(key) {
|
|
8984
|
-
console.error(
|
|
9072
|
+
console.error(chalk93.red(`Key "${key}" is not set`));
|
|
8985
9073
|
process.exit(1);
|
|
8986
9074
|
}
|
|
8987
9075
|
|
|
@@ -8995,7 +9083,7 @@ function registerConfig(program2) {
|
|
|
8995
9083
|
|
|
8996
9084
|
// src/commands/deploy/redirect.ts
|
|
8997
9085
|
import { existsSync as existsSync25, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
8998
|
-
import
|
|
9086
|
+
import chalk94 from "chalk";
|
|
8999
9087
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
9000
9088
|
if (!window.location.pathname.endsWith('/')) {
|
|
9001
9089
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -9004,22 +9092,22 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
9004
9092
|
function redirect() {
|
|
9005
9093
|
const indexPath = "index.html";
|
|
9006
9094
|
if (!existsSync25(indexPath)) {
|
|
9007
|
-
console.log(
|
|
9095
|
+
console.log(chalk94.yellow("No index.html found"));
|
|
9008
9096
|
return;
|
|
9009
9097
|
}
|
|
9010
9098
|
const content = readFileSync19(indexPath, "utf-8");
|
|
9011
9099
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
9012
|
-
console.log(
|
|
9100
|
+
console.log(chalk94.dim("Trailing slash script already present"));
|
|
9013
9101
|
return;
|
|
9014
9102
|
}
|
|
9015
9103
|
const headCloseIndex = content.indexOf("</head>");
|
|
9016
9104
|
if (headCloseIndex === -1) {
|
|
9017
|
-
console.log(
|
|
9105
|
+
console.log(chalk94.red("Could not find </head> tag in index.html"));
|
|
9018
9106
|
return;
|
|
9019
9107
|
}
|
|
9020
9108
|
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
|
|
9021
9109
|
writeFileSync18(indexPath, newContent);
|
|
9022
|
-
console.log(
|
|
9110
|
+
console.log(chalk94.green("Added trailing slash redirect to index.html"));
|
|
9023
9111
|
}
|
|
9024
9112
|
|
|
9025
9113
|
// src/commands/registerDeploy.ts
|
|
@@ -9046,7 +9134,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
9046
9134
|
|
|
9047
9135
|
// src/commands/devlog/shared.ts
|
|
9048
9136
|
import { execSync as execSync22 } from "child_process";
|
|
9049
|
-
import
|
|
9137
|
+
import chalk95 from "chalk";
|
|
9050
9138
|
|
|
9051
9139
|
// src/shared/getRepoName.ts
|
|
9052
9140
|
import { existsSync as existsSync26, readFileSync as readFileSync20 } from "fs";
|
|
@@ -9155,13 +9243,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
9155
9243
|
}
|
|
9156
9244
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
9157
9245
|
for (const commit2 of commits2) {
|
|
9158
|
-
console.log(` ${
|
|
9246
|
+
console.log(` ${chalk95.yellow(commit2.hash)} ${commit2.message}`);
|
|
9159
9247
|
if (verbose) {
|
|
9160
9248
|
const visibleFiles = commit2.files.filter(
|
|
9161
9249
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
9162
9250
|
);
|
|
9163
9251
|
for (const file of visibleFiles) {
|
|
9164
|
-
console.log(` ${
|
|
9252
|
+
console.log(` ${chalk95.dim(file)}`);
|
|
9165
9253
|
}
|
|
9166
9254
|
}
|
|
9167
9255
|
}
|
|
@@ -9186,15 +9274,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
9186
9274
|
}
|
|
9187
9275
|
|
|
9188
9276
|
// src/commands/devlog/list/printDateHeader.ts
|
|
9189
|
-
import
|
|
9277
|
+
import chalk96 from "chalk";
|
|
9190
9278
|
function printDateHeader(date, isSkipped, entries) {
|
|
9191
9279
|
if (isSkipped) {
|
|
9192
|
-
console.log(`${
|
|
9280
|
+
console.log(`${chalk96.bold.blue(date)} ${chalk96.dim("skipped")}`);
|
|
9193
9281
|
} else if (entries && entries.length > 0) {
|
|
9194
|
-
const entryInfo = entries.map((e) => `${
|
|
9195
|
-
console.log(`${
|
|
9282
|
+
const entryInfo = entries.map((e) => `${chalk96.green(e.version)} ${e.title}`).join(" | ");
|
|
9283
|
+
console.log(`${chalk96.bold.blue(date)} ${entryInfo}`);
|
|
9196
9284
|
} else {
|
|
9197
|
-
console.log(`${
|
|
9285
|
+
console.log(`${chalk96.bold.blue(date)} ${chalk96.red("\u26A0 devlog missing")}`);
|
|
9198
9286
|
}
|
|
9199
9287
|
}
|
|
9200
9288
|
|
|
@@ -9298,24 +9386,24 @@ function bumpVersion(version2, type) {
|
|
|
9298
9386
|
|
|
9299
9387
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
9300
9388
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
9301
|
-
import
|
|
9389
|
+
import chalk98 from "chalk";
|
|
9302
9390
|
|
|
9303
9391
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
9304
|
-
import
|
|
9392
|
+
import chalk97 from "chalk";
|
|
9305
9393
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
9306
9394
|
if (conventional && firstHash) {
|
|
9307
9395
|
const version2 = getVersionAtCommit(firstHash);
|
|
9308
9396
|
if (version2) {
|
|
9309
|
-
console.log(`${
|
|
9397
|
+
console.log(`${chalk97.bold("version:")} ${stripToMinor(version2)}`);
|
|
9310
9398
|
} else {
|
|
9311
|
-
console.log(`${
|
|
9399
|
+
console.log(`${chalk97.bold("version:")} ${chalk97.red("unknown")}`);
|
|
9312
9400
|
}
|
|
9313
9401
|
} else if (patchVersion && minorVersion) {
|
|
9314
9402
|
console.log(
|
|
9315
|
-
`${
|
|
9403
|
+
`${chalk97.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
9316
9404
|
);
|
|
9317
9405
|
} else {
|
|
9318
|
-
console.log(`${
|
|
9406
|
+
console.log(`${chalk97.bold("version:")} v0.1 (initial)`);
|
|
9319
9407
|
}
|
|
9320
9408
|
}
|
|
9321
9409
|
|
|
@@ -9363,16 +9451,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
9363
9451
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
9364
9452
|
}
|
|
9365
9453
|
function logName(repoName) {
|
|
9366
|
-
console.log(`${
|
|
9454
|
+
console.log(`${chalk98.bold("name:")} ${repoName}`);
|
|
9367
9455
|
}
|
|
9368
9456
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
9369
9457
|
logName(ctx.repoName);
|
|
9370
9458
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
9371
|
-
console.log(
|
|
9459
|
+
console.log(chalk98.bold.blue(targetDate));
|
|
9372
9460
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
9373
9461
|
}
|
|
9374
9462
|
function logNoCommits(lastInfo) {
|
|
9375
|
-
console.log(
|
|
9463
|
+
console.log(chalk98.dim(noCommitsMessage(!!lastInfo)));
|
|
9376
9464
|
}
|
|
9377
9465
|
|
|
9378
9466
|
// src/commands/devlog/next/index.ts
|
|
@@ -9413,11 +9501,11 @@ function next2(options2) {
|
|
|
9413
9501
|
import { execSync as execSync24 } from "child_process";
|
|
9414
9502
|
|
|
9415
9503
|
// src/commands/devlog/repos/printReposTable.ts
|
|
9416
|
-
import
|
|
9504
|
+
import chalk99 from "chalk";
|
|
9417
9505
|
function colorStatus(status2) {
|
|
9418
|
-
if (status2 === "missing") return
|
|
9419
|
-
if (status2 === "outdated") return
|
|
9420
|
-
return
|
|
9506
|
+
if (status2 === "missing") return chalk99.red(status2);
|
|
9507
|
+
if (status2 === "outdated") return chalk99.yellow(status2);
|
|
9508
|
+
return chalk99.green(status2);
|
|
9421
9509
|
}
|
|
9422
9510
|
function formatRow(row, nameWidth) {
|
|
9423
9511
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -9431,8 +9519,8 @@ function printReposTable(rows) {
|
|
|
9431
9519
|
"Last Devlog".padEnd(11),
|
|
9432
9520
|
"Status"
|
|
9433
9521
|
].join(" ");
|
|
9434
|
-
console.log(
|
|
9435
|
-
console.log(
|
|
9522
|
+
console.log(chalk99.dim(header));
|
|
9523
|
+
console.log(chalk99.dim("-".repeat(header.length)));
|
|
9436
9524
|
for (const row of rows) {
|
|
9437
9525
|
console.log(formatRow(row, nameWidth));
|
|
9438
9526
|
}
|
|
@@ -9490,14 +9578,14 @@ function repos(options2) {
|
|
|
9490
9578
|
// src/commands/devlog/skip.ts
|
|
9491
9579
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
9492
9580
|
import { join as join26 } from "path";
|
|
9493
|
-
import
|
|
9581
|
+
import chalk100 from "chalk";
|
|
9494
9582
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
9495
9583
|
function getBlogConfigPath() {
|
|
9496
9584
|
return join26(BLOG_REPO_ROOT, "assist.yml");
|
|
9497
9585
|
}
|
|
9498
9586
|
function skip(date) {
|
|
9499
9587
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
9500
|
-
console.log(
|
|
9588
|
+
console.log(chalk100.red("Invalid date format. Use YYYY-MM-DD"));
|
|
9501
9589
|
process.exit(1);
|
|
9502
9590
|
}
|
|
9503
9591
|
const repoName = getRepoName();
|
|
@@ -9508,7 +9596,7 @@ function skip(date) {
|
|
|
9508
9596
|
const skipDays = skip2[repoName] ?? [];
|
|
9509
9597
|
if (skipDays.includes(date)) {
|
|
9510
9598
|
console.log(
|
|
9511
|
-
|
|
9599
|
+
chalk100.yellow(`${date} is already in skip list for ${repoName}`)
|
|
9512
9600
|
);
|
|
9513
9601
|
return;
|
|
9514
9602
|
}
|
|
@@ -9518,20 +9606,20 @@ function skip(date) {
|
|
|
9518
9606
|
devlog.skip = skip2;
|
|
9519
9607
|
config.devlog = devlog;
|
|
9520
9608
|
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
9521
|
-
console.log(
|
|
9609
|
+
console.log(chalk100.green(`Added ${date} to skip list for ${repoName}`));
|
|
9522
9610
|
}
|
|
9523
9611
|
|
|
9524
9612
|
// src/commands/devlog/version.ts
|
|
9525
|
-
import
|
|
9613
|
+
import chalk101 from "chalk";
|
|
9526
9614
|
function version() {
|
|
9527
9615
|
const config = loadConfig();
|
|
9528
9616
|
const name = getRepoName();
|
|
9529
9617
|
const lastInfo = getLastVersionInfo(name, config);
|
|
9530
9618
|
const lastVersion = lastInfo?.version ?? null;
|
|
9531
9619
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
9532
|
-
console.log(`${
|
|
9533
|
-
console.log(`${
|
|
9534
|
-
console.log(`${
|
|
9620
|
+
console.log(`${chalk101.bold("name:")} ${name}`);
|
|
9621
|
+
console.log(`${chalk101.bold("last:")} ${lastVersion ?? chalk101.dim("none")}`);
|
|
9622
|
+
console.log(`${chalk101.bold("next:")} ${nextVersion ?? chalk101.dim("none")}`);
|
|
9535
9623
|
}
|
|
9536
9624
|
|
|
9537
9625
|
// src/commands/registerDevlog.ts
|
|
@@ -9555,7 +9643,7 @@ function registerDevlog(program2) {
|
|
|
9555
9643
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
9556
9644
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync2 } from "fs";
|
|
9557
9645
|
import { join as join27 } from "path";
|
|
9558
|
-
import
|
|
9646
|
+
import chalk102 from "chalk";
|
|
9559
9647
|
|
|
9560
9648
|
// src/shared/findRepoRoot.ts
|
|
9561
9649
|
import { existsSync as existsSync27 } from "fs";
|
|
@@ -9618,14 +9706,14 @@ function checkBuildLocks(startDir) {
|
|
|
9618
9706
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
9619
9707
|
if (locked) {
|
|
9620
9708
|
console.error(
|
|
9621
|
-
|
|
9709
|
+
chalk102.red("Build output locked (is VS debugging?): ") + locked
|
|
9622
9710
|
);
|
|
9623
9711
|
process.exit(1);
|
|
9624
9712
|
}
|
|
9625
9713
|
}
|
|
9626
9714
|
async function checkBuildLocksCommand() {
|
|
9627
9715
|
checkBuildLocks();
|
|
9628
|
-
console.log(
|
|
9716
|
+
console.log(chalk102.green("No build locks detected"));
|
|
9629
9717
|
}
|
|
9630
9718
|
|
|
9631
9719
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -9724,30 +9812,30 @@ function escapeRegex(s) {
|
|
|
9724
9812
|
}
|
|
9725
9813
|
|
|
9726
9814
|
// src/commands/dotnet/printTree.ts
|
|
9727
|
-
import
|
|
9815
|
+
import chalk103 from "chalk";
|
|
9728
9816
|
function printNodes(nodes, prefix2) {
|
|
9729
9817
|
for (let i = 0; i < nodes.length; i++) {
|
|
9730
9818
|
const isLast = i === nodes.length - 1;
|
|
9731
9819
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
9732
9820
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
9733
9821
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
9734
|
-
const label2 = isMissing ?
|
|
9822
|
+
const label2 = isMissing ? chalk103.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
9735
9823
|
console.log(`${prefix2}${connector}${label2}`);
|
|
9736
9824
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
9737
9825
|
}
|
|
9738
9826
|
}
|
|
9739
9827
|
function printTree(tree, totalCount, solutions) {
|
|
9740
|
-
console.log(
|
|
9741
|
-
console.log(
|
|
9828
|
+
console.log(chalk103.bold("\nProject Dependency Tree"));
|
|
9829
|
+
console.log(chalk103.cyan(tree.relativePath));
|
|
9742
9830
|
printNodes(tree.children, "");
|
|
9743
|
-
console.log(
|
|
9831
|
+
console.log(chalk103.dim(`
|
|
9744
9832
|
${totalCount} projects total (including root)`));
|
|
9745
|
-
console.log(
|
|
9833
|
+
console.log(chalk103.bold("\nSolution Membership"));
|
|
9746
9834
|
if (solutions.length === 0) {
|
|
9747
|
-
console.log(
|
|
9835
|
+
console.log(chalk103.yellow(" Not found in any .sln"));
|
|
9748
9836
|
} else {
|
|
9749
9837
|
for (const sln of solutions) {
|
|
9750
|
-
console.log(` ${
|
|
9838
|
+
console.log(` ${chalk103.green(sln)}`);
|
|
9751
9839
|
}
|
|
9752
9840
|
}
|
|
9753
9841
|
console.log();
|
|
@@ -9776,16 +9864,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
9776
9864
|
// src/commands/dotnet/resolveCsproj.ts
|
|
9777
9865
|
import { existsSync as existsSync28 } from "fs";
|
|
9778
9866
|
import path23 from "path";
|
|
9779
|
-
import
|
|
9867
|
+
import chalk104 from "chalk";
|
|
9780
9868
|
function resolveCsproj(csprojPath) {
|
|
9781
9869
|
const resolved = path23.resolve(csprojPath);
|
|
9782
9870
|
if (!existsSync28(resolved)) {
|
|
9783
|
-
console.error(
|
|
9871
|
+
console.error(chalk104.red(`File not found: ${resolved}`));
|
|
9784
9872
|
process.exit(1);
|
|
9785
9873
|
}
|
|
9786
9874
|
const repoRoot = findRepoRoot(path23.dirname(resolved));
|
|
9787
9875
|
if (!repoRoot) {
|
|
9788
|
-
console.error(
|
|
9876
|
+
console.error(chalk104.red("Could not find git repository root"));
|
|
9789
9877
|
process.exit(1);
|
|
9790
9878
|
}
|
|
9791
9879
|
return { resolved, repoRoot };
|
|
@@ -9835,12 +9923,12 @@ function getChangedCsFiles(scope) {
|
|
|
9835
9923
|
}
|
|
9836
9924
|
|
|
9837
9925
|
// src/commands/dotnet/inSln.ts
|
|
9838
|
-
import
|
|
9926
|
+
import chalk105 from "chalk";
|
|
9839
9927
|
async function inSln(csprojPath) {
|
|
9840
9928
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
9841
9929
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
9842
9930
|
if (solutions.length === 0) {
|
|
9843
|
-
console.log(
|
|
9931
|
+
console.log(chalk105.yellow("Not found in any .sln file"));
|
|
9844
9932
|
process.exit(1);
|
|
9845
9933
|
}
|
|
9846
9934
|
for (const sln of solutions) {
|
|
@@ -9849,7 +9937,7 @@ async function inSln(csprojPath) {
|
|
|
9849
9937
|
}
|
|
9850
9938
|
|
|
9851
9939
|
// src/commands/dotnet/inspect.ts
|
|
9852
|
-
import
|
|
9940
|
+
import chalk111 from "chalk";
|
|
9853
9941
|
|
|
9854
9942
|
// src/shared/formatElapsed.ts
|
|
9855
9943
|
function formatElapsed(ms) {
|
|
@@ -9861,12 +9949,12 @@ function formatElapsed(ms) {
|
|
|
9861
9949
|
}
|
|
9862
9950
|
|
|
9863
9951
|
// src/commands/dotnet/displayIssues.ts
|
|
9864
|
-
import
|
|
9952
|
+
import chalk106 from "chalk";
|
|
9865
9953
|
var SEVERITY_COLOR = {
|
|
9866
|
-
ERROR:
|
|
9867
|
-
WARNING:
|
|
9868
|
-
SUGGESTION:
|
|
9869
|
-
HINT:
|
|
9954
|
+
ERROR: chalk106.red,
|
|
9955
|
+
WARNING: chalk106.yellow,
|
|
9956
|
+
SUGGESTION: chalk106.cyan,
|
|
9957
|
+
HINT: chalk106.dim
|
|
9870
9958
|
};
|
|
9871
9959
|
function groupByFile(issues) {
|
|
9872
9960
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -9882,15 +9970,15 @@ function groupByFile(issues) {
|
|
|
9882
9970
|
}
|
|
9883
9971
|
function displayIssues(issues) {
|
|
9884
9972
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
9885
|
-
console.log(
|
|
9973
|
+
console.log(chalk106.bold(file));
|
|
9886
9974
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
9887
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
9975
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk106.white;
|
|
9888
9976
|
console.log(
|
|
9889
|
-
` ${
|
|
9977
|
+
` ${chalk106.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
9890
9978
|
);
|
|
9891
9979
|
}
|
|
9892
9980
|
}
|
|
9893
|
-
console.log(
|
|
9981
|
+
console.log(chalk106.dim(`
|
|
9894
9982
|
${issues.length} issue(s) found`));
|
|
9895
9983
|
}
|
|
9896
9984
|
|
|
@@ -9949,12 +10037,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
9949
10037
|
// src/commands/dotnet/resolveSolution.ts
|
|
9950
10038
|
import { existsSync as existsSync29 } from "fs";
|
|
9951
10039
|
import path24 from "path";
|
|
9952
|
-
import
|
|
10040
|
+
import chalk108 from "chalk";
|
|
9953
10041
|
|
|
9954
10042
|
// src/commands/dotnet/findSolution.ts
|
|
9955
10043
|
import { readdirSync as readdirSync4 } from "fs";
|
|
9956
10044
|
import { dirname as dirname18, join as join28 } from "path";
|
|
9957
|
-
import
|
|
10045
|
+
import chalk107 from "chalk";
|
|
9958
10046
|
function findSlnInDir(dir) {
|
|
9959
10047
|
try {
|
|
9960
10048
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join28(dir, f));
|
|
@@ -9970,17 +10058,17 @@ function findSolution() {
|
|
|
9970
10058
|
const slnFiles = findSlnInDir(current);
|
|
9971
10059
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
9972
10060
|
if (slnFiles.length > 1) {
|
|
9973
|
-
console.error(
|
|
10061
|
+
console.error(chalk107.red(`Multiple .sln files found in ${current}:`));
|
|
9974
10062
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
9975
10063
|
console.error(
|
|
9976
|
-
|
|
10064
|
+
chalk107.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
9977
10065
|
);
|
|
9978
10066
|
process.exit(1);
|
|
9979
10067
|
}
|
|
9980
10068
|
if (current === ceiling) break;
|
|
9981
10069
|
current = dirname18(current);
|
|
9982
10070
|
}
|
|
9983
|
-
console.error(
|
|
10071
|
+
console.error(chalk107.red("No .sln file found between cwd and repo root"));
|
|
9984
10072
|
process.exit(1);
|
|
9985
10073
|
}
|
|
9986
10074
|
|
|
@@ -9989,7 +10077,7 @@ function resolveSolution(sln) {
|
|
|
9989
10077
|
if (sln) {
|
|
9990
10078
|
const resolved = path24.resolve(sln);
|
|
9991
10079
|
if (!existsSync29(resolved)) {
|
|
9992
|
-
console.error(
|
|
10080
|
+
console.error(chalk108.red(`Solution file not found: ${resolved}`));
|
|
9993
10081
|
process.exit(1);
|
|
9994
10082
|
}
|
|
9995
10083
|
return resolved;
|
|
@@ -10031,14 +10119,14 @@ import { execSync as execSync26 } from "child_process";
|
|
|
10031
10119
|
import { existsSync as existsSync30, readFileSync as readFileSync24, unlinkSync as unlinkSync7 } from "fs";
|
|
10032
10120
|
import { tmpdir as tmpdir3 } from "os";
|
|
10033
10121
|
import path25 from "path";
|
|
10034
|
-
import
|
|
10122
|
+
import chalk109 from "chalk";
|
|
10035
10123
|
function assertJbInstalled() {
|
|
10036
10124
|
try {
|
|
10037
10125
|
execSync26("jb inspectcode --version", { stdio: "pipe" });
|
|
10038
10126
|
} catch {
|
|
10039
|
-
console.error(
|
|
10127
|
+
console.error(chalk109.red("jb is not installed. Install with:"));
|
|
10040
10128
|
console.error(
|
|
10041
|
-
|
|
10129
|
+
chalk109.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
10042
10130
|
);
|
|
10043
10131
|
process.exit(1);
|
|
10044
10132
|
}
|
|
@@ -10056,11 +10144,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
10056
10144
|
if (err && typeof err === "object" && "stderr" in err) {
|
|
10057
10145
|
process.stderr.write(err.stderr);
|
|
10058
10146
|
}
|
|
10059
|
-
console.error(
|
|
10147
|
+
console.error(chalk109.red("jb inspectcode failed"));
|
|
10060
10148
|
process.exit(1);
|
|
10061
10149
|
}
|
|
10062
10150
|
if (!existsSync30(reportPath)) {
|
|
10063
|
-
console.error(
|
|
10151
|
+
console.error(chalk109.red("Report file not generated"));
|
|
10064
10152
|
process.exit(1);
|
|
10065
10153
|
}
|
|
10066
10154
|
const xml = readFileSync24(reportPath, "utf-8");
|
|
@@ -10070,7 +10158,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
10070
10158
|
|
|
10071
10159
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
10072
10160
|
import { execSync as execSync27 } from "child_process";
|
|
10073
|
-
import
|
|
10161
|
+
import chalk110 from "chalk";
|
|
10074
10162
|
function resolveMsbuildPath() {
|
|
10075
10163
|
const { run: run4 } = loadConfig();
|
|
10076
10164
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -10082,9 +10170,9 @@ function assertMsbuildInstalled() {
|
|
|
10082
10170
|
try {
|
|
10083
10171
|
execSync27(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
10084
10172
|
} catch {
|
|
10085
|
-
console.error(
|
|
10173
|
+
console.error(chalk110.red(`msbuild not found at: ${msbuild}`));
|
|
10086
10174
|
console.error(
|
|
10087
|
-
|
|
10175
|
+
chalk110.yellow(
|
|
10088
10176
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
10089
10177
|
)
|
|
10090
10178
|
);
|
|
@@ -10131,17 +10219,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
10131
10219
|
// src/commands/dotnet/inspect.ts
|
|
10132
10220
|
function logScope(changedFiles) {
|
|
10133
10221
|
if (changedFiles === null) {
|
|
10134
|
-
console.log(
|
|
10222
|
+
console.log(chalk111.dim("Inspecting full solution..."));
|
|
10135
10223
|
} else {
|
|
10136
10224
|
console.log(
|
|
10137
|
-
|
|
10225
|
+
chalk111.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
10138
10226
|
);
|
|
10139
10227
|
}
|
|
10140
10228
|
}
|
|
10141
10229
|
function reportResults(issues, elapsed) {
|
|
10142
10230
|
if (issues.length > 0) displayIssues(issues);
|
|
10143
|
-
else console.log(
|
|
10144
|
-
console.log(
|
|
10231
|
+
else console.log(chalk111.green("No issues found"));
|
|
10232
|
+
console.log(chalk111.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
10145
10233
|
if (issues.length > 0) process.exit(1);
|
|
10146
10234
|
}
|
|
10147
10235
|
async function inspect(sln, options2) {
|
|
@@ -10152,7 +10240,7 @@ async function inspect(sln, options2) {
|
|
|
10152
10240
|
const scope = parseScope(options2.scope);
|
|
10153
10241
|
const changedFiles = getChangedCsFiles(scope);
|
|
10154
10242
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
10155
|
-
console.log(
|
|
10243
|
+
console.log(chalk111.green("No changed .cs files found"));
|
|
10156
10244
|
return;
|
|
10157
10245
|
}
|
|
10158
10246
|
logScope(changedFiles);
|
|
@@ -10281,25 +10369,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
10281
10369
|
}
|
|
10282
10370
|
|
|
10283
10371
|
// src/commands/github/printCountTable.ts
|
|
10284
|
-
import
|
|
10372
|
+
import chalk112 from "chalk";
|
|
10285
10373
|
function printCountTable(labelHeader, rows) {
|
|
10286
10374
|
const labelWidth = Math.max(
|
|
10287
10375
|
labelHeader.length,
|
|
10288
10376
|
...rows.map((row) => row.label.length)
|
|
10289
10377
|
);
|
|
10290
10378
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
10291
|
-
console.log(
|
|
10292
|
-
console.log(
|
|
10379
|
+
console.log(chalk112.dim(header));
|
|
10380
|
+
console.log(chalk112.dim("-".repeat(header.length)));
|
|
10293
10381
|
for (const row of rows) {
|
|
10294
10382
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
10295
10383
|
}
|
|
10296
10384
|
}
|
|
10297
10385
|
|
|
10298
10386
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
10299
|
-
import
|
|
10387
|
+
import chalk113 from "chalk";
|
|
10300
10388
|
function printRepoAuthorBreakdown(repos2) {
|
|
10301
10389
|
for (const repo of repos2) {
|
|
10302
|
-
console.log(
|
|
10390
|
+
console.log(chalk113.bold(repo.name));
|
|
10303
10391
|
const authorWidth = Math.max(
|
|
10304
10392
|
0,
|
|
10305
10393
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -10624,7 +10712,7 @@ function registerHandover(program2) {
|
|
|
10624
10712
|
}
|
|
10625
10713
|
|
|
10626
10714
|
// src/commands/jira/acceptanceCriteria.ts
|
|
10627
|
-
import
|
|
10715
|
+
import chalk115 from "chalk";
|
|
10628
10716
|
|
|
10629
10717
|
// src/commands/jira/adfToText.ts
|
|
10630
10718
|
function renderInline(node) {
|
|
@@ -10685,7 +10773,7 @@ function adfToText(doc) {
|
|
|
10685
10773
|
|
|
10686
10774
|
// src/commands/jira/fetchIssue.ts
|
|
10687
10775
|
import { execSync as execSync28 } from "child_process";
|
|
10688
|
-
import
|
|
10776
|
+
import chalk114 from "chalk";
|
|
10689
10777
|
function fetchIssue(issueKey, fields) {
|
|
10690
10778
|
let result;
|
|
10691
10779
|
try {
|
|
@@ -10698,15 +10786,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
10698
10786
|
const stderr = error.stderr;
|
|
10699
10787
|
if (stderr.includes("unauthorized")) {
|
|
10700
10788
|
console.error(
|
|
10701
|
-
|
|
10789
|
+
chalk114.red("Jira authentication expired."),
|
|
10702
10790
|
"Run",
|
|
10703
|
-
|
|
10791
|
+
chalk114.cyan("assist jira auth"),
|
|
10704
10792
|
"to re-authenticate."
|
|
10705
10793
|
);
|
|
10706
10794
|
process.exit(1);
|
|
10707
10795
|
}
|
|
10708
10796
|
}
|
|
10709
|
-
console.error(
|
|
10797
|
+
console.error(chalk114.red(`Failed to fetch ${issueKey}.`));
|
|
10710
10798
|
process.exit(1);
|
|
10711
10799
|
}
|
|
10712
10800
|
return JSON.parse(result);
|
|
@@ -10720,7 +10808,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
10720
10808
|
const parsed = fetchIssue(issueKey, field);
|
|
10721
10809
|
const acValue = parsed?.fields?.[field];
|
|
10722
10810
|
if (!acValue) {
|
|
10723
|
-
console.log(
|
|
10811
|
+
console.log(chalk115.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
10724
10812
|
return;
|
|
10725
10813
|
}
|
|
10726
10814
|
if (typeof acValue === "string") {
|
|
@@ -10815,14 +10903,14 @@ async function jiraAuth() {
|
|
|
10815
10903
|
}
|
|
10816
10904
|
|
|
10817
10905
|
// src/commands/jira/viewIssue.ts
|
|
10818
|
-
import
|
|
10906
|
+
import chalk116 from "chalk";
|
|
10819
10907
|
function viewIssue(issueKey) {
|
|
10820
10908
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
10821
10909
|
const fields = parsed?.fields;
|
|
10822
10910
|
const summary = fields?.summary;
|
|
10823
10911
|
const description = fields?.description;
|
|
10824
10912
|
if (summary) {
|
|
10825
|
-
console.log(
|
|
10913
|
+
console.log(chalk116.bold(summary));
|
|
10826
10914
|
}
|
|
10827
10915
|
if (description) {
|
|
10828
10916
|
if (summary) console.log();
|
|
@@ -10836,7 +10924,7 @@ function viewIssue(issueKey) {
|
|
|
10836
10924
|
}
|
|
10837
10925
|
if (!summary && !description) {
|
|
10838
10926
|
console.log(
|
|
10839
|
-
|
|
10927
|
+
chalk116.yellow(`No summary or description found on ${issueKey}.`)
|
|
10840
10928
|
);
|
|
10841
10929
|
}
|
|
10842
10930
|
}
|
|
@@ -10851,13 +10939,13 @@ function registerJira(program2) {
|
|
|
10851
10939
|
|
|
10852
10940
|
// src/commands/reviewComments.ts
|
|
10853
10941
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
10854
|
-
import
|
|
10942
|
+
import chalk117 from "chalk";
|
|
10855
10943
|
async function reviewComments(number) {
|
|
10856
10944
|
if (number) {
|
|
10857
10945
|
try {
|
|
10858
10946
|
execFileSync6("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
10859
10947
|
} catch {
|
|
10860
|
-
console.error(
|
|
10948
|
+
console.error(chalk117.red(`gh pr checkout ${number} failed; aborting.`));
|
|
10861
10949
|
process.exit(1);
|
|
10862
10950
|
}
|
|
10863
10951
|
}
|
|
@@ -10870,7 +10958,7 @@ async function reviewComments(number) {
|
|
|
10870
10958
|
// src/commands/registerLaunch.ts
|
|
10871
10959
|
function registerLaunch(program2) {
|
|
10872
10960
|
program2.command("next").argument("[id]", "Backlog item ID to run first").description("Alias for backlog next").option("--once", "Exit after the first completed item run").action(
|
|
10873
|
-
(
|
|
10961
|
+
(id2, opts) => next({ allowEdits: true, once: opts.once }, id2)
|
|
10874
10962
|
);
|
|
10875
10963
|
program2.command("draft").alias("feat").argument("[description]", "Text to forward to the /draft slash command").description(
|
|
10876
10964
|
"Launch Claude in /draft mode, chain into next on /next signal"
|
|
@@ -10882,7 +10970,7 @@ function registerLaunch(program2) {
|
|
|
10882
10970
|
);
|
|
10883
10971
|
program2.command("review-comments").argument("[number]", "PR number to check out first").description("Launch Claude in /review-comments mode (single session)").action((number) => reviewComments(number));
|
|
10884
10972
|
program2.command("refine").argument("[id]", "Backlog item ID").description("Launch Claude in /refine mode to refine a backlog item").option("--once", "Exit when the initial task completes").action(
|
|
10885
|
-
(
|
|
10973
|
+
(id2, opts) => refine(id2, { once: opts.once })
|
|
10886
10974
|
);
|
|
10887
10975
|
}
|
|
10888
10976
|
|
|
@@ -10900,15 +10988,15 @@ function registerList(program2) {
|
|
|
10900
10988
|
// src/commands/mermaid/index.ts
|
|
10901
10989
|
import { mkdirSync as mkdirSync12, readdirSync as readdirSync5 } from "fs";
|
|
10902
10990
|
import { resolve as resolve10 } from "path";
|
|
10903
|
-
import
|
|
10991
|
+
import chalk120 from "chalk";
|
|
10904
10992
|
|
|
10905
10993
|
// src/commands/mermaid/exportFile.ts
|
|
10906
10994
|
import { readFileSync as readFileSync28, writeFileSync as writeFileSync22 } from "fs";
|
|
10907
10995
|
import { basename as basename5, extname, resolve as resolve9 } from "path";
|
|
10908
|
-
import
|
|
10996
|
+
import chalk119 from "chalk";
|
|
10909
10997
|
|
|
10910
10998
|
// src/commands/mermaid/renderBlock.ts
|
|
10911
|
-
import
|
|
10999
|
+
import chalk118 from "chalk";
|
|
10912
11000
|
async function renderBlock(krokiUrl, source) {
|
|
10913
11001
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
10914
11002
|
method: "POST",
|
|
@@ -10917,7 +11005,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
10917
11005
|
});
|
|
10918
11006
|
if (!response.ok) {
|
|
10919
11007
|
console.error(
|
|
10920
|
-
|
|
11008
|
+
chalk118.red(
|
|
10921
11009
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
10922
11010
|
)
|
|
10923
11011
|
);
|
|
@@ -10935,19 +11023,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
10935
11023
|
if (onlyIndex !== void 0) {
|
|
10936
11024
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
10937
11025
|
console.error(
|
|
10938
|
-
|
|
11026
|
+
chalk119.red(
|
|
10939
11027
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
10940
11028
|
)
|
|
10941
11029
|
);
|
|
10942
11030
|
process.exit(1);
|
|
10943
11031
|
}
|
|
10944
11032
|
console.log(
|
|
10945
|
-
|
|
11033
|
+
chalk119.gray(
|
|
10946
11034
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
10947
11035
|
)
|
|
10948
11036
|
);
|
|
10949
11037
|
} else {
|
|
10950
|
-
console.log(
|
|
11038
|
+
console.log(chalk119.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
10951
11039
|
}
|
|
10952
11040
|
for (const [i, source] of blocks.entries()) {
|
|
10953
11041
|
const idx = i + 1;
|
|
@@ -10955,7 +11043,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
10955
11043
|
const outPath = resolve9(outDir, `${stem}-${idx}.svg`);
|
|
10956
11044
|
const svg = await renderBlock(krokiUrl, source);
|
|
10957
11045
|
writeFileSync22(outPath, svg, "utf8");
|
|
10958
|
-
console.log(
|
|
11046
|
+
console.log(chalk119.green(` \u2192 ${outPath}`));
|
|
10959
11047
|
}
|
|
10960
11048
|
}
|
|
10961
11049
|
function extractMermaidBlocks(markdown) {
|
|
@@ -10971,18 +11059,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
10971
11059
|
if (options2.index !== void 0) {
|
|
10972
11060
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
10973
11061
|
console.error(
|
|
10974
|
-
|
|
11062
|
+
chalk120.red(`--index must be a positive integer (got ${options2.index})`)
|
|
10975
11063
|
);
|
|
10976
11064
|
process.exit(1);
|
|
10977
11065
|
}
|
|
10978
11066
|
if (!file) {
|
|
10979
|
-
console.error(
|
|
11067
|
+
console.error(chalk120.red("--index requires a file argument"));
|
|
10980
11068
|
process.exit(1);
|
|
10981
11069
|
}
|
|
10982
11070
|
}
|
|
10983
11071
|
const files = file ? [file] : readdirSync5(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
10984
11072
|
if (files.length === 0) {
|
|
10985
|
-
console.log(
|
|
11073
|
+
console.log(chalk120.gray("No markdown files found in current directory."));
|
|
10986
11074
|
return;
|
|
10987
11075
|
}
|
|
10988
11076
|
for (const f of files) {
|
|
@@ -11005,7 +11093,7 @@ function registerMermaid(program2) {
|
|
|
11005
11093
|
}
|
|
11006
11094
|
|
|
11007
11095
|
// src/commands/news/add/index.ts
|
|
11008
|
-
import
|
|
11096
|
+
import chalk121 from "chalk";
|
|
11009
11097
|
import enquirer8 from "enquirer";
|
|
11010
11098
|
async function add2(url) {
|
|
11011
11099
|
if (!url) {
|
|
@@ -11027,10 +11115,10 @@ async function add2(url) {
|
|
|
11027
11115
|
const { orm } = await getReady();
|
|
11028
11116
|
const added = await addFeed(orm, url);
|
|
11029
11117
|
if (!added) {
|
|
11030
|
-
console.log(
|
|
11118
|
+
console.log(chalk121.yellow("Feed already exists"));
|
|
11031
11119
|
return;
|
|
11032
11120
|
}
|
|
11033
|
-
console.log(
|
|
11121
|
+
console.log(chalk121.green(`Added feed: ${url}`));
|
|
11034
11122
|
}
|
|
11035
11123
|
|
|
11036
11124
|
// src/commands/registerNews.ts
|
|
@@ -11040,7 +11128,7 @@ function registerNews(program2) {
|
|
|
11040
11128
|
}
|
|
11041
11129
|
|
|
11042
11130
|
// src/commands/prompts/printPromptsTable.ts
|
|
11043
|
-
import
|
|
11131
|
+
import chalk122 from "chalk";
|
|
11044
11132
|
function truncate(str, max) {
|
|
11045
11133
|
if (str.length <= max) return str;
|
|
11046
11134
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -11058,14 +11146,14 @@ function printPromptsTable(rows) {
|
|
|
11058
11146
|
"Command".padEnd(commandWidth),
|
|
11059
11147
|
"Repos"
|
|
11060
11148
|
].join(" ");
|
|
11061
|
-
console.log(
|
|
11062
|
-
console.log(
|
|
11149
|
+
console.log(chalk122.dim(header));
|
|
11150
|
+
console.log(chalk122.dim("-".repeat(header.length)));
|
|
11063
11151
|
for (const row of rows) {
|
|
11064
11152
|
const count6 = String(row.count).padStart(countWidth);
|
|
11065
11153
|
const tool = row.tool.padEnd(toolWidth);
|
|
11066
11154
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
11067
11155
|
console.log(
|
|
11068
|
-
`${
|
|
11156
|
+
`${chalk122.yellow(count6)} ${tool} ${command} ${chalk122.dim(row.repos)}`
|
|
11069
11157
|
);
|
|
11070
11158
|
}
|
|
11071
11159
|
}
|
|
@@ -11197,8 +11285,8 @@ function assertThreadCreated(stdout) {
|
|
|
11197
11285
|
} catch {
|
|
11198
11286
|
throw new Error(`GitHub returned an unparseable response: ${stdout}`);
|
|
11199
11287
|
}
|
|
11200
|
-
const
|
|
11201
|
-
if (typeof
|
|
11288
|
+
const id2 = parsed.data?.addPullRequestReviewThread?.thread?.id;
|
|
11289
|
+
if (typeof id2 !== "string" || id2.length === 0) {
|
|
11202
11290
|
throw new Error(
|
|
11203
11291
|
"GitHub did not create a review thread (no thread id returned); the line is likely outside the PR diff."
|
|
11204
11292
|
);
|
|
@@ -11611,20 +11699,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
11611
11699
|
}
|
|
11612
11700
|
|
|
11613
11701
|
// src/commands/prs/listComments/printComments.ts
|
|
11614
|
-
import
|
|
11702
|
+
import chalk123 from "chalk";
|
|
11615
11703
|
function formatForHuman(comment3) {
|
|
11616
11704
|
if (comment3.type === "review") {
|
|
11617
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
11705
|
+
const stateColor = comment3.state === "APPROVED" ? chalk123.green : comment3.state === "CHANGES_REQUESTED" ? chalk123.red : chalk123.yellow;
|
|
11618
11706
|
return [
|
|
11619
|
-
`${
|
|
11707
|
+
`${chalk123.cyan("Review")} by ${chalk123.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
11620
11708
|
comment3.body,
|
|
11621
11709
|
""
|
|
11622
11710
|
].join("\n");
|
|
11623
11711
|
}
|
|
11624
11712
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
11625
11713
|
return [
|
|
11626
|
-
`${
|
|
11627
|
-
|
|
11714
|
+
`${chalk123.cyan("Line comment")} by ${chalk123.bold(comment3.user)} on ${chalk123.dim(`${comment3.path}${location}`)}`,
|
|
11715
|
+
chalk123.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
11628
11716
|
comment3.body,
|
|
11629
11717
|
""
|
|
11630
11718
|
].join("\n");
|
|
@@ -11714,13 +11802,13 @@ import { execSync as execSync36 } from "child_process";
|
|
|
11714
11802
|
import enquirer9 from "enquirer";
|
|
11715
11803
|
|
|
11716
11804
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
11717
|
-
import
|
|
11805
|
+
import chalk124 from "chalk";
|
|
11718
11806
|
var STATUS_MAP = {
|
|
11719
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
11720
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
11807
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk124.magenta("merged"), date: pr.mergedAt } : null,
|
|
11808
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk124.red("closed"), date: pr.closedAt } : null
|
|
11721
11809
|
};
|
|
11722
11810
|
function defaultStatus(pr) {
|
|
11723
|
-
return { label:
|
|
11811
|
+
return { label: chalk124.green("opened"), date: pr.createdAt };
|
|
11724
11812
|
}
|
|
11725
11813
|
function getStatus2(pr) {
|
|
11726
11814
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -11729,11 +11817,11 @@ function formatDate(dateStr) {
|
|
|
11729
11817
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
11730
11818
|
}
|
|
11731
11819
|
function formatPrHeader(pr, status2) {
|
|
11732
|
-
return `${
|
|
11820
|
+
return `${chalk124.cyan(`#${pr.number}`)} ${pr.title} ${chalk124.dim(`(${pr.author.login},`)} ${status2.label} ${chalk124.dim(`${formatDate(status2.date)})`)}`;
|
|
11733
11821
|
}
|
|
11734
11822
|
function logPrDetails(pr) {
|
|
11735
11823
|
console.log(
|
|
11736
|
-
|
|
11824
|
+
chalk124.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
11737
11825
|
);
|
|
11738
11826
|
console.log();
|
|
11739
11827
|
}
|
|
@@ -12012,10 +12100,10 @@ function registerPrs(program2) {
|
|
|
12012
12100
|
}
|
|
12013
12101
|
|
|
12014
12102
|
// src/commands/ravendb/ravendbAuth.ts
|
|
12015
|
-
import
|
|
12103
|
+
import chalk130 from "chalk";
|
|
12016
12104
|
|
|
12017
12105
|
// src/shared/createConnectionAuth.ts
|
|
12018
|
-
import
|
|
12106
|
+
import chalk125 from "chalk";
|
|
12019
12107
|
function listConnections(connections, format2) {
|
|
12020
12108
|
if (connections.length === 0) {
|
|
12021
12109
|
console.log("No connections configured.");
|
|
@@ -12028,7 +12116,7 @@ function listConnections(connections, format2) {
|
|
|
12028
12116
|
function removeConnection(connections, name, save) {
|
|
12029
12117
|
const filtered = connections.filter((c) => c.name !== name);
|
|
12030
12118
|
if (filtered.length === connections.length) {
|
|
12031
|
-
console.error(
|
|
12119
|
+
console.error(chalk125.red(`Connection "${name}" not found.`));
|
|
12032
12120
|
process.exit(1);
|
|
12033
12121
|
}
|
|
12034
12122
|
save(filtered);
|
|
@@ -12074,15 +12162,15 @@ function saveConnections(connections) {
|
|
|
12074
12162
|
}
|
|
12075
12163
|
|
|
12076
12164
|
// src/commands/ravendb/promptConnection.ts
|
|
12077
|
-
import
|
|
12165
|
+
import chalk128 from "chalk";
|
|
12078
12166
|
|
|
12079
12167
|
// src/commands/ravendb/selectOpSecret.ts
|
|
12080
|
-
import
|
|
12168
|
+
import chalk127 from "chalk";
|
|
12081
12169
|
import Enquirer2 from "enquirer";
|
|
12082
12170
|
|
|
12083
12171
|
// src/commands/ravendb/searchItems.ts
|
|
12084
12172
|
import { execSync as execSync39 } from "child_process";
|
|
12085
|
-
import
|
|
12173
|
+
import chalk126 from "chalk";
|
|
12086
12174
|
function opExec(args) {
|
|
12087
12175
|
return execSync39(`op ${args}`, {
|
|
12088
12176
|
encoding: "utf-8",
|
|
@@ -12095,7 +12183,7 @@ function searchItems(search2) {
|
|
|
12095
12183
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
12096
12184
|
} catch {
|
|
12097
12185
|
console.error(
|
|
12098
|
-
|
|
12186
|
+
chalk126.red(
|
|
12099
12187
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
12100
12188
|
)
|
|
12101
12189
|
);
|
|
@@ -12109,7 +12197,7 @@ function getItemFields(itemId) {
|
|
|
12109
12197
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
12110
12198
|
return item.fields.filter((f) => f.reference && f.label);
|
|
12111
12199
|
} catch {
|
|
12112
|
-
console.error(
|
|
12200
|
+
console.error(chalk126.red("Failed to get item details from 1Password."));
|
|
12113
12201
|
process.exit(1);
|
|
12114
12202
|
}
|
|
12115
12203
|
}
|
|
@@ -12128,7 +12216,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12128
12216
|
}).run();
|
|
12129
12217
|
const items2 = searchItems(search2);
|
|
12130
12218
|
if (items2.length === 0) {
|
|
12131
|
-
console.error(
|
|
12219
|
+
console.error(chalk127.red(`No items found matching "${search2}".`));
|
|
12132
12220
|
process.exit(1);
|
|
12133
12221
|
}
|
|
12134
12222
|
const itemId = await selectOne(
|
|
@@ -12137,7 +12225,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12137
12225
|
);
|
|
12138
12226
|
const fields = getItemFields(itemId);
|
|
12139
12227
|
if (fields.length === 0) {
|
|
12140
|
-
console.error(
|
|
12228
|
+
console.error(chalk127.red("No fields with references found on this item."));
|
|
12141
12229
|
process.exit(1);
|
|
12142
12230
|
}
|
|
12143
12231
|
const ref = await selectOne(
|
|
@@ -12151,7 +12239,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12151
12239
|
async function promptConnection(existingNames) {
|
|
12152
12240
|
const name = await promptInput("name", "Connection name:");
|
|
12153
12241
|
if (existingNames.includes(name)) {
|
|
12154
|
-
console.error(
|
|
12242
|
+
console.error(chalk128.red(`Connection "${name}" already exists.`));
|
|
12155
12243
|
process.exit(1);
|
|
12156
12244
|
}
|
|
12157
12245
|
const url = await promptInput(
|
|
@@ -12160,22 +12248,22 @@ async function promptConnection(existingNames) {
|
|
|
12160
12248
|
);
|
|
12161
12249
|
const database = await promptInput("database", "Database name:");
|
|
12162
12250
|
if (!name || !url || !database) {
|
|
12163
|
-
console.error(
|
|
12251
|
+
console.error(chalk128.red("All fields are required."));
|
|
12164
12252
|
process.exit(1);
|
|
12165
12253
|
}
|
|
12166
12254
|
const apiKeyRef = await selectOpSecret();
|
|
12167
|
-
console.log(
|
|
12255
|
+
console.log(chalk128.dim(`Using: ${apiKeyRef}`));
|
|
12168
12256
|
return { name, url, database, apiKeyRef };
|
|
12169
12257
|
}
|
|
12170
12258
|
|
|
12171
12259
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
12172
|
-
import
|
|
12260
|
+
import chalk129 from "chalk";
|
|
12173
12261
|
function ravendbSetConnection(name) {
|
|
12174
12262
|
const raw = loadGlobalConfigRaw();
|
|
12175
12263
|
const ravendb = raw.ravendb ?? {};
|
|
12176
12264
|
const connections = ravendb.connections ?? [];
|
|
12177
12265
|
if (!connections.some((c) => c.name === name)) {
|
|
12178
|
-
console.error(
|
|
12266
|
+
console.error(chalk129.red(`Connection "${name}" not found.`));
|
|
12179
12267
|
console.error(
|
|
12180
12268
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12181
12269
|
);
|
|
@@ -12191,16 +12279,16 @@ function ravendbSetConnection(name) {
|
|
|
12191
12279
|
var ravendbAuth = createConnectionAuth({
|
|
12192
12280
|
load: loadConnections,
|
|
12193
12281
|
save: saveConnections,
|
|
12194
|
-
format: (c) => `${
|
|
12282
|
+
format: (c) => `${chalk130.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
12195
12283
|
promptNew: promptConnection,
|
|
12196
12284
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
12197
12285
|
});
|
|
12198
12286
|
|
|
12199
12287
|
// src/commands/ravendb/ravendbCollections.ts
|
|
12200
|
-
import
|
|
12288
|
+
import chalk134 from "chalk";
|
|
12201
12289
|
|
|
12202
12290
|
// src/commands/ravendb/ravenFetch.ts
|
|
12203
|
-
import
|
|
12291
|
+
import chalk132 from "chalk";
|
|
12204
12292
|
|
|
12205
12293
|
// src/commands/ravendb/getAccessToken.ts
|
|
12206
12294
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -12237,10 +12325,10 @@ ${errorText}`
|
|
|
12237
12325
|
|
|
12238
12326
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
12239
12327
|
import { execSync as execSync40 } from "child_process";
|
|
12240
|
-
import
|
|
12328
|
+
import chalk131 from "chalk";
|
|
12241
12329
|
function resolveOpSecret(reference) {
|
|
12242
12330
|
if (!reference.startsWith("op://")) {
|
|
12243
|
-
console.error(
|
|
12331
|
+
console.error(chalk131.red(`Invalid secret reference: must start with op://`));
|
|
12244
12332
|
process.exit(1);
|
|
12245
12333
|
}
|
|
12246
12334
|
try {
|
|
@@ -12250,7 +12338,7 @@ function resolveOpSecret(reference) {
|
|
|
12250
12338
|
}).trim();
|
|
12251
12339
|
} catch {
|
|
12252
12340
|
console.error(
|
|
12253
|
-
|
|
12341
|
+
chalk131.red(
|
|
12254
12342
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
12255
12343
|
)
|
|
12256
12344
|
);
|
|
@@ -12277,7 +12365,7 @@ async function ravenFetch(connection, path56) {
|
|
|
12277
12365
|
if (!response.ok) {
|
|
12278
12366
|
const body = await response.text();
|
|
12279
12367
|
console.error(
|
|
12280
|
-
|
|
12368
|
+
chalk132.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
12281
12369
|
);
|
|
12282
12370
|
console.error(body.substring(0, 500));
|
|
12283
12371
|
process.exit(1);
|
|
@@ -12286,7 +12374,7 @@ async function ravenFetch(connection, path56) {
|
|
|
12286
12374
|
}
|
|
12287
12375
|
|
|
12288
12376
|
// src/commands/ravendb/resolveConnection.ts
|
|
12289
|
-
import
|
|
12377
|
+
import chalk133 from "chalk";
|
|
12290
12378
|
function loadRavendb() {
|
|
12291
12379
|
const raw = loadGlobalConfigRaw();
|
|
12292
12380
|
const ravendb = raw.ravendb;
|
|
@@ -12300,7 +12388,7 @@ function resolveConnection(name) {
|
|
|
12300
12388
|
const connectionName = name ?? defaultConnection;
|
|
12301
12389
|
if (!connectionName) {
|
|
12302
12390
|
console.error(
|
|
12303
|
-
|
|
12391
|
+
chalk133.red(
|
|
12304
12392
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
12305
12393
|
)
|
|
12306
12394
|
);
|
|
@@ -12308,7 +12396,7 @@ function resolveConnection(name) {
|
|
|
12308
12396
|
}
|
|
12309
12397
|
const connection = connections.find((c) => c.name === connectionName);
|
|
12310
12398
|
if (!connection) {
|
|
12311
|
-
console.error(
|
|
12399
|
+
console.error(chalk133.red(`Connection "${connectionName}" not found.`));
|
|
12312
12400
|
console.error(
|
|
12313
12401
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12314
12402
|
);
|
|
@@ -12339,15 +12427,15 @@ async function ravendbCollections(connectionName) {
|
|
|
12339
12427
|
return;
|
|
12340
12428
|
}
|
|
12341
12429
|
for (const c of collections) {
|
|
12342
|
-
console.log(`${
|
|
12430
|
+
console.log(`${chalk134.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
12343
12431
|
}
|
|
12344
12432
|
}
|
|
12345
12433
|
|
|
12346
12434
|
// src/commands/ravendb/ravendbQuery.ts
|
|
12347
|
-
import
|
|
12435
|
+
import chalk136 from "chalk";
|
|
12348
12436
|
|
|
12349
12437
|
// src/commands/ravendb/fetchAllPages.ts
|
|
12350
|
-
import
|
|
12438
|
+
import chalk135 from "chalk";
|
|
12351
12439
|
|
|
12352
12440
|
// src/commands/ravendb/buildQueryPath.ts
|
|
12353
12441
|
function buildQueryPath(opts) {
|
|
@@ -12385,7 +12473,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12385
12473
|
allResults.push(...results);
|
|
12386
12474
|
start3 += results.length;
|
|
12387
12475
|
process.stderr.write(
|
|
12388
|
-
`\r${
|
|
12476
|
+
`\r${chalk135.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
12389
12477
|
);
|
|
12390
12478
|
if (start3 >= totalResults) break;
|
|
12391
12479
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -12400,7 +12488,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12400
12488
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
12401
12489
|
const resolved = resolveArgs(connectionName, collection);
|
|
12402
12490
|
if (!resolved.collection && !options2.query) {
|
|
12403
|
-
console.error(
|
|
12491
|
+
console.error(chalk136.red("Provide a collection name or --query filter."));
|
|
12404
12492
|
process.exit(1);
|
|
12405
12493
|
}
|
|
12406
12494
|
const { collection: col } = resolved;
|
|
@@ -12438,7 +12526,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
12438
12526
|
import * as path26 from "path";
|
|
12439
12527
|
|
|
12440
12528
|
// src/commands/refactor/logViolations.ts
|
|
12441
|
-
import
|
|
12529
|
+
import chalk137 from "chalk";
|
|
12442
12530
|
var DEFAULT_MAX_LINES = 100;
|
|
12443
12531
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
12444
12532
|
if (violations.length === 0) {
|
|
@@ -12447,43 +12535,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
12447
12535
|
}
|
|
12448
12536
|
return;
|
|
12449
12537
|
}
|
|
12450
|
-
console.error(
|
|
12538
|
+
console.error(chalk137.red(`
|
|
12451
12539
|
Refactor check failed:
|
|
12452
12540
|
`));
|
|
12453
|
-
console.error(
|
|
12541
|
+
console.error(chalk137.red(` The following files exceed ${maxLines} lines:
|
|
12454
12542
|
`));
|
|
12455
12543
|
for (const violation of violations) {
|
|
12456
|
-
console.error(
|
|
12544
|
+
console.error(chalk137.red(` ${violation.file} (${violation.lines} lines)`));
|
|
12457
12545
|
}
|
|
12458
12546
|
console.error(
|
|
12459
|
-
|
|
12547
|
+
chalk137.yellow(
|
|
12460
12548
|
`
|
|
12461
12549
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
12462
12550
|
way to refactor it, ignore it with:
|
|
12463
12551
|
`
|
|
12464
12552
|
)
|
|
12465
12553
|
);
|
|
12466
|
-
console.error(
|
|
12554
|
+
console.error(chalk137.gray(` assist refactor ignore <file>
|
|
12467
12555
|
`));
|
|
12468
12556
|
if (process.env.CLAUDECODE) {
|
|
12469
|
-
console.error(
|
|
12557
|
+
console.error(chalk137.cyan(`
|
|
12470
12558
|
## Extracting Code to New Files
|
|
12471
12559
|
`));
|
|
12472
12560
|
console.error(
|
|
12473
|
-
|
|
12561
|
+
chalk137.cyan(
|
|
12474
12562
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
12475
12563
|
`
|
|
12476
12564
|
)
|
|
12477
12565
|
);
|
|
12478
12566
|
console.error(
|
|
12479
|
-
|
|
12567
|
+
chalk137.cyan(
|
|
12480
12568
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
12481
12569
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
12482
12570
|
`
|
|
12483
12571
|
)
|
|
12484
12572
|
);
|
|
12485
12573
|
console.error(
|
|
12486
|
-
|
|
12574
|
+
chalk137.cyan(
|
|
12487
12575
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
12488
12576
|
domains, move it to a common/shared folder.
|
|
12489
12577
|
`
|
|
@@ -12639,7 +12727,7 @@ async function check(pattern2, options2) {
|
|
|
12639
12727
|
|
|
12640
12728
|
// src/commands/refactor/extract/index.ts
|
|
12641
12729
|
import path33 from "path";
|
|
12642
|
-
import
|
|
12730
|
+
import chalk140 from "chalk";
|
|
12643
12731
|
|
|
12644
12732
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
12645
12733
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -12676,9 +12764,9 @@ function addImportPreservingSuppressions(sourceFile, structure) {
|
|
|
12676
12764
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
12677
12765
|
function collectReferencedNames(sourceFile) {
|
|
12678
12766
|
const names = /* @__PURE__ */ new Set();
|
|
12679
|
-
for (const
|
|
12680
|
-
if (
|
|
12681
|
-
names.add(
|
|
12767
|
+
for (const id2 of sourceFile.getDescendantsOfKind(SyntaxKind3.Identifier)) {
|
|
12768
|
+
if (id2.getFirstAncestorByKind(SyntaxKind3.ImportDeclaration)) continue;
|
|
12769
|
+
names.add(id2.getText());
|
|
12682
12770
|
}
|
|
12683
12771
|
return names;
|
|
12684
12772
|
}
|
|
@@ -12729,7 +12817,7 @@ function updateImporters(functionName, sourceFile, importers) {
|
|
|
12729
12817
|
|
|
12730
12818
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
12731
12819
|
function isNameReferencedInSource(sourceFile, name) {
|
|
12732
|
-
return sourceFile.getDescendantsOfKind(SyntaxKind4.Identifier).some((
|
|
12820
|
+
return sourceFile.getDescendantsOfKind(SyntaxKind4.Identifier).some((id2) => id2.getText() === name);
|
|
12733
12821
|
}
|
|
12734
12822
|
async function applyExtraction(functionName, sourceFile, destPath, plan2, project) {
|
|
12735
12823
|
project.createSourceFile(destPath, plan2.destContent, { overwrite: false });
|
|
@@ -12813,8 +12901,8 @@ function collectPrivateFunctions(target, fnMap) {
|
|
|
12813
12901
|
import { SyntaxKind as SyntaxKind6 } from "ts-morph";
|
|
12814
12902
|
function getReferencedIdentifiers(fn) {
|
|
12815
12903
|
const names = /* @__PURE__ */ new Set();
|
|
12816
|
-
for (const
|
|
12817
|
-
names.add(
|
|
12904
|
+
for (const id2 of fn.getDescendantsOfKind(SyntaxKind6.Identifier)) {
|
|
12905
|
+
names.add(id2.getText());
|
|
12818
12906
|
}
|
|
12819
12907
|
return names;
|
|
12820
12908
|
}
|
|
@@ -12982,8 +13070,8 @@ function matchImport(importDecl, neededNames) {
|
|
|
12982
13070
|
function getReferencedNames(nodes) {
|
|
12983
13071
|
const names = /* @__PURE__ */ new Set();
|
|
12984
13072
|
for (const node of nodes) {
|
|
12985
|
-
for (const
|
|
12986
|
-
names.add(
|
|
13073
|
+
for (const id2 of node.getDescendantsOfKind(SyntaxKind12.Identifier)) {
|
|
13074
|
+
names.add(id2.getText());
|
|
12987
13075
|
}
|
|
12988
13076
|
}
|
|
12989
13077
|
return names;
|
|
@@ -13173,9 +13261,9 @@ function isInsideExtractedFunction(node, extracted) {
|
|
|
13173
13261
|
}
|
|
13174
13262
|
function sourceReferencesName(sourceFile, functionName, extractedNames) {
|
|
13175
13263
|
const extracted = new Set(extractedNames);
|
|
13176
|
-
for (const
|
|
13177
|
-
if (
|
|
13178
|
-
const parent =
|
|
13264
|
+
for (const id2 of sourceFile.getDescendantsOfKind(SyntaxKind13.Identifier)) {
|
|
13265
|
+
if (id2.getText() !== functionName) continue;
|
|
13266
|
+
const parent = id2.getParent();
|
|
13179
13267
|
if (!parent || DECLARATION_KINDS.has(parent.getKind())) continue;
|
|
13180
13268
|
if (!isInsideExtractedFunction(parent, extracted)) return true;
|
|
13181
13269
|
}
|
|
@@ -13214,23 +13302,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
13214
13302
|
|
|
13215
13303
|
// src/commands/refactor/extract/displayPlan.ts
|
|
13216
13304
|
import path30 from "path";
|
|
13217
|
-
import
|
|
13305
|
+
import chalk138 from "chalk";
|
|
13218
13306
|
function section(title) {
|
|
13219
13307
|
return `
|
|
13220
|
-
${
|
|
13308
|
+
${chalk138.cyan(title)}`;
|
|
13221
13309
|
}
|
|
13222
13310
|
function displayImporters(plan2, cwd) {
|
|
13223
13311
|
if (plan2.importersToUpdate.length === 0) return;
|
|
13224
13312
|
console.log(section("Update importers:"));
|
|
13225
13313
|
for (const imp of plan2.importersToUpdate) {
|
|
13226
13314
|
const rel = path30.relative(cwd, imp.file.getFilePath());
|
|
13227
|
-
console.log(` ${
|
|
13315
|
+
console.log(` ${chalk138.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
13228
13316
|
}
|
|
13229
13317
|
}
|
|
13230
13318
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
13231
|
-
console.log(
|
|
13319
|
+
console.log(chalk138.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
13232
13320
|
`));
|
|
13233
|
-
console.log(` ${
|
|
13321
|
+
console.log(` ${chalk138.cyan("Functions to move:")}`);
|
|
13234
13322
|
for (const name of plan2.extractedNames) {
|
|
13235
13323
|
console.log(` ${name}`);
|
|
13236
13324
|
}
|
|
@@ -13264,7 +13352,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
13264
13352
|
|
|
13265
13353
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
13266
13354
|
import path32 from "path";
|
|
13267
|
-
import
|
|
13355
|
+
import chalk139 from "chalk";
|
|
13268
13356
|
import { Project as Project4 } from "ts-morph";
|
|
13269
13357
|
|
|
13270
13358
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -13324,7 +13412,7 @@ function loadProjectFile(file) {
|
|
|
13324
13412
|
});
|
|
13325
13413
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
13326
13414
|
if (!sourceFile) {
|
|
13327
|
-
console.log(
|
|
13415
|
+
console.log(chalk139.red(`File not found in project: ${file}`));
|
|
13328
13416
|
process.exit(1);
|
|
13329
13417
|
}
|
|
13330
13418
|
return { project, sourceFile };
|
|
@@ -13347,19 +13435,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
13347
13435
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
13348
13436
|
if (options2.apply) {
|
|
13349
13437
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
13350
|
-
console.log(
|
|
13438
|
+
console.log(chalk140.green("\nExtraction complete"));
|
|
13351
13439
|
} else {
|
|
13352
|
-
console.log(
|
|
13440
|
+
console.log(chalk140.dim("\nDry run. Use --apply to execute."));
|
|
13353
13441
|
}
|
|
13354
13442
|
}
|
|
13355
13443
|
|
|
13356
13444
|
// src/commands/refactor/ignore.ts
|
|
13357
13445
|
import fs20 from "fs";
|
|
13358
|
-
import
|
|
13446
|
+
import chalk141 from "chalk";
|
|
13359
13447
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
13360
13448
|
function ignore(file) {
|
|
13361
13449
|
if (!fs20.existsSync(file)) {
|
|
13362
|
-
console.error(
|
|
13450
|
+
console.error(chalk141.red(`Error: File does not exist: ${file}`));
|
|
13363
13451
|
process.exit(1);
|
|
13364
13452
|
}
|
|
13365
13453
|
const content = fs20.readFileSync(file, "utf-8");
|
|
@@ -13375,7 +13463,7 @@ function ignore(file) {
|
|
|
13375
13463
|
fs20.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
13376
13464
|
}
|
|
13377
13465
|
console.log(
|
|
13378
|
-
|
|
13466
|
+
chalk141.green(
|
|
13379
13467
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
13380
13468
|
)
|
|
13381
13469
|
);
|
|
@@ -13384,12 +13472,12 @@ function ignore(file) {
|
|
|
13384
13472
|
// src/commands/refactor/rename/index.ts
|
|
13385
13473
|
import fs23 from "fs";
|
|
13386
13474
|
import path38 from "path";
|
|
13387
|
-
import
|
|
13475
|
+
import chalk144 from "chalk";
|
|
13388
13476
|
|
|
13389
13477
|
// src/commands/refactor/rename/applyRename.ts
|
|
13390
13478
|
import fs22 from "fs";
|
|
13391
13479
|
import path35 from "path";
|
|
13392
|
-
import
|
|
13480
|
+
import chalk142 from "chalk";
|
|
13393
13481
|
|
|
13394
13482
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13395
13483
|
import path34 from "path";
|
|
@@ -13494,13 +13582,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
13494
13582
|
const updatedContents = applyRewrites(rewrites);
|
|
13495
13583
|
for (const [file, content] of updatedContents) {
|
|
13496
13584
|
fs22.writeFileSync(file, content, "utf-8");
|
|
13497
|
-
console.log(
|
|
13585
|
+
console.log(chalk142.cyan(` Updated imports in ${path35.relative(cwd, file)}`));
|
|
13498
13586
|
}
|
|
13499
13587
|
const destDir = path35.dirname(destPath);
|
|
13500
13588
|
if (!fs22.existsSync(destDir)) fs22.mkdirSync(destDir, { recursive: true });
|
|
13501
13589
|
fs22.renameSync(sourcePath, destPath);
|
|
13502
13590
|
console.log(
|
|
13503
|
-
|
|
13591
|
+
chalk142.white(
|
|
13504
13592
|
` Moved ${path35.relative(cwd, sourcePath)} \u2192 ${path35.relative(cwd, destPath)}`
|
|
13505
13593
|
)
|
|
13506
13594
|
);
|
|
@@ -13587,16 +13675,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
13587
13675
|
|
|
13588
13676
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
13589
13677
|
import path37 from "path";
|
|
13590
|
-
import
|
|
13678
|
+
import chalk143 from "chalk";
|
|
13591
13679
|
function printRenamePreview(rewrites, cwd) {
|
|
13592
13680
|
for (const rewrite of rewrites) {
|
|
13593
13681
|
console.log(
|
|
13594
|
-
|
|
13682
|
+
chalk143.dim(
|
|
13595
13683
|
` ${path37.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
13596
13684
|
)
|
|
13597
13685
|
);
|
|
13598
13686
|
}
|
|
13599
|
-
console.log(
|
|
13687
|
+
console.log(chalk143.dim("Dry run. Use --apply to execute."));
|
|
13600
13688
|
}
|
|
13601
13689
|
|
|
13602
13690
|
// src/commands/refactor/rename/index.ts
|
|
@@ -13607,20 +13695,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
13607
13695
|
const relSource = path38.relative(cwd, sourcePath);
|
|
13608
13696
|
const relDest = path38.relative(cwd, destPath);
|
|
13609
13697
|
if (!fs23.existsSync(sourcePath)) {
|
|
13610
|
-
console.log(
|
|
13698
|
+
console.log(chalk144.red(`File not found: ${source}`));
|
|
13611
13699
|
process.exit(1);
|
|
13612
13700
|
}
|
|
13613
13701
|
if (destPath !== sourcePath && fs23.existsSync(destPath)) {
|
|
13614
|
-
console.log(
|
|
13702
|
+
console.log(chalk144.red(`Destination already exists: ${destination}`));
|
|
13615
13703
|
process.exit(1);
|
|
13616
13704
|
}
|
|
13617
|
-
console.log(
|
|
13618
|
-
console.log(
|
|
13619
|
-
console.log(
|
|
13705
|
+
console.log(chalk144.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
13706
|
+
console.log(chalk144.dim("Loading project..."));
|
|
13707
|
+
console.log(chalk144.dim("Scanning imports across the project..."));
|
|
13620
13708
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
13621
13709
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
13622
13710
|
console.log(
|
|
13623
|
-
|
|
13711
|
+
chalk144.dim(
|
|
13624
13712
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
13625
13713
|
)
|
|
13626
13714
|
);
|
|
@@ -13629,11 +13717,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
13629
13717
|
return;
|
|
13630
13718
|
}
|
|
13631
13719
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
13632
|
-
console.log(
|
|
13720
|
+
console.log(chalk144.green("Done"));
|
|
13633
13721
|
}
|
|
13634
13722
|
|
|
13635
13723
|
// src/commands/refactor/renameSymbol/index.ts
|
|
13636
|
-
import
|
|
13724
|
+
import chalk145 from "chalk";
|
|
13637
13725
|
|
|
13638
13726
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
13639
13727
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -13653,8 +13741,8 @@ function isDeclaration(identifier) {
|
|
|
13653
13741
|
return parent !== void 0 && declarationKinds.includes(parent.getKind());
|
|
13654
13742
|
}
|
|
13655
13743
|
function findSymbol(sourceFile, symbolName) {
|
|
13656
|
-
for (const
|
|
13657
|
-
if (
|
|
13744
|
+
for (const id2 of sourceFile.getDescendantsOfKind(SyntaxKind14.Identifier)) {
|
|
13745
|
+
if (id2.getText() === symbolName && isDeclaration(id2)) return id2;
|
|
13658
13746
|
}
|
|
13659
13747
|
return void 0;
|
|
13660
13748
|
}
|
|
@@ -13679,33 +13767,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
13679
13767
|
const { project, sourceFile } = loadProjectFile(file);
|
|
13680
13768
|
const symbol = findSymbol(sourceFile, oldName);
|
|
13681
13769
|
if (!symbol) {
|
|
13682
|
-
console.log(
|
|
13770
|
+
console.log(chalk145.red(`Symbol "${oldName}" not found in ${file}`));
|
|
13683
13771
|
process.exit(1);
|
|
13684
13772
|
}
|
|
13685
13773
|
const grouped = groupReferences(symbol, cwd);
|
|
13686
13774
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
13687
13775
|
console.log(
|
|
13688
|
-
|
|
13776
|
+
chalk145.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
13689
13777
|
`)
|
|
13690
13778
|
);
|
|
13691
13779
|
for (const [refFile, lines] of grouped) {
|
|
13692
13780
|
console.log(
|
|
13693
|
-
` ${
|
|
13781
|
+
` ${chalk145.dim(refFile)}: lines ${chalk145.cyan(lines.join(", "))}`
|
|
13694
13782
|
);
|
|
13695
13783
|
}
|
|
13696
13784
|
if (options2.apply) {
|
|
13697
13785
|
symbol.rename(newName);
|
|
13698
13786
|
await project.save();
|
|
13699
|
-
console.log(
|
|
13787
|
+
console.log(chalk145.green(`
|
|
13700
13788
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
13701
13789
|
} else {
|
|
13702
|
-
console.log(
|
|
13790
|
+
console.log(chalk145.dim("\nDry run. Use --apply to execute."));
|
|
13703
13791
|
}
|
|
13704
13792
|
}
|
|
13705
13793
|
|
|
13706
13794
|
// src/commands/refactor/restructure/index.ts
|
|
13707
13795
|
import path46 from "path";
|
|
13708
|
-
import
|
|
13796
|
+
import chalk148 from "chalk";
|
|
13709
13797
|
|
|
13710
13798
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
13711
13799
|
import path40 from "path";
|
|
@@ -13784,50 +13872,50 @@ function clusterFiles(graph) {
|
|
|
13784
13872
|
|
|
13785
13873
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
13786
13874
|
import path42 from "path";
|
|
13787
|
-
import
|
|
13875
|
+
import chalk146 from "chalk";
|
|
13788
13876
|
function relPath(filePath) {
|
|
13789
13877
|
return path42.relative(process.cwd(), filePath);
|
|
13790
13878
|
}
|
|
13791
13879
|
function displayMoves(plan2) {
|
|
13792
13880
|
if (plan2.moves.length === 0) return;
|
|
13793
|
-
console.log(
|
|
13881
|
+
console.log(chalk146.bold("\nFile moves:"));
|
|
13794
13882
|
for (const move of plan2.moves) {
|
|
13795
13883
|
console.log(
|
|
13796
|
-
` ${
|
|
13884
|
+
` ${chalk146.red(relPath(move.from))} \u2192 ${chalk146.green(relPath(move.to))}`
|
|
13797
13885
|
);
|
|
13798
|
-
console.log(
|
|
13886
|
+
console.log(chalk146.dim(` ${move.reason}`));
|
|
13799
13887
|
}
|
|
13800
13888
|
}
|
|
13801
13889
|
function displayRewrites(rewrites) {
|
|
13802
13890
|
if (rewrites.length === 0) return;
|
|
13803
13891
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
13804
|
-
console.log(
|
|
13892
|
+
console.log(chalk146.bold(`
|
|
13805
13893
|
Import rewrites (${affectedFiles.size} files):`));
|
|
13806
13894
|
for (const file of affectedFiles) {
|
|
13807
|
-
console.log(` ${
|
|
13895
|
+
console.log(` ${chalk146.cyan(relPath(file))}:`);
|
|
13808
13896
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
13809
13897
|
(r) => r.file === file
|
|
13810
13898
|
)) {
|
|
13811
13899
|
console.log(
|
|
13812
|
-
` ${
|
|
13900
|
+
` ${chalk146.red(`"${oldSpecifier}"`)} \u2192 ${chalk146.green(`"${newSpecifier}"`)}`
|
|
13813
13901
|
);
|
|
13814
13902
|
}
|
|
13815
13903
|
}
|
|
13816
13904
|
}
|
|
13817
13905
|
function displayPlan2(plan2) {
|
|
13818
13906
|
if (plan2.warnings.length > 0) {
|
|
13819
|
-
console.log(
|
|
13820
|
-
for (const w of plan2.warnings) console.log(
|
|
13907
|
+
console.log(chalk146.yellow("\nWarnings:"));
|
|
13908
|
+
for (const w of plan2.warnings) console.log(chalk146.yellow(` ${w}`));
|
|
13821
13909
|
}
|
|
13822
13910
|
if (plan2.newDirectories.length > 0) {
|
|
13823
|
-
console.log(
|
|
13911
|
+
console.log(chalk146.bold("\nNew directories:"));
|
|
13824
13912
|
for (const dir of plan2.newDirectories)
|
|
13825
|
-
console.log(
|
|
13913
|
+
console.log(chalk146.green(` ${dir}/`));
|
|
13826
13914
|
}
|
|
13827
13915
|
displayMoves(plan2);
|
|
13828
13916
|
displayRewrites(plan2.rewrites);
|
|
13829
13917
|
console.log(
|
|
13830
|
-
|
|
13918
|
+
chalk146.dim(
|
|
13831
13919
|
`
|
|
13832
13920
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
13833
13921
|
)
|
|
@@ -13837,18 +13925,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
13837
13925
|
// src/commands/refactor/restructure/executePlan.ts
|
|
13838
13926
|
import fs24 from "fs";
|
|
13839
13927
|
import path43 from "path";
|
|
13840
|
-
import
|
|
13928
|
+
import chalk147 from "chalk";
|
|
13841
13929
|
function executePlan(plan2) {
|
|
13842
13930
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
13843
13931
|
for (const [file, content] of updatedContents) {
|
|
13844
13932
|
fs24.writeFileSync(file, content, "utf-8");
|
|
13845
13933
|
console.log(
|
|
13846
|
-
|
|
13934
|
+
chalk147.cyan(` Rewrote imports in ${path43.relative(process.cwd(), file)}`)
|
|
13847
13935
|
);
|
|
13848
13936
|
}
|
|
13849
13937
|
for (const dir of plan2.newDirectories) {
|
|
13850
13938
|
fs24.mkdirSync(dir, { recursive: true });
|
|
13851
|
-
console.log(
|
|
13939
|
+
console.log(chalk147.green(` Created ${path43.relative(process.cwd(), dir)}/`));
|
|
13852
13940
|
}
|
|
13853
13941
|
for (const move of plan2.moves) {
|
|
13854
13942
|
const targetDir = path43.dirname(move.to);
|
|
@@ -13857,7 +13945,7 @@ function executePlan(plan2) {
|
|
|
13857
13945
|
}
|
|
13858
13946
|
fs24.renameSync(move.from, move.to);
|
|
13859
13947
|
console.log(
|
|
13860
|
-
|
|
13948
|
+
chalk147.white(
|
|
13861
13949
|
` Moved ${path43.relative(process.cwd(), move.from)} \u2192 ${path43.relative(process.cwd(), move.to)}`
|
|
13862
13950
|
)
|
|
13863
13951
|
);
|
|
@@ -13872,7 +13960,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
13872
13960
|
if (entries.length === 0) {
|
|
13873
13961
|
fs24.rmdirSync(dir);
|
|
13874
13962
|
console.log(
|
|
13875
|
-
|
|
13963
|
+
chalk147.dim(
|
|
13876
13964
|
` Removed empty directory ${path43.relative(process.cwd(), dir)}`
|
|
13877
13965
|
)
|
|
13878
13966
|
);
|
|
@@ -14005,22 +14093,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
14005
14093
|
const targetPattern = pattern2 ?? "src";
|
|
14006
14094
|
const files = findSourceFiles2(targetPattern);
|
|
14007
14095
|
if (files.length === 0) {
|
|
14008
|
-
console.log(
|
|
14096
|
+
console.log(chalk148.yellow("No files found matching pattern"));
|
|
14009
14097
|
return;
|
|
14010
14098
|
}
|
|
14011
14099
|
const tsConfigPath = path46.resolve("tsconfig.json");
|
|
14012
14100
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
14013
14101
|
if (plan2.moves.length === 0) {
|
|
14014
|
-
console.log(
|
|
14102
|
+
console.log(chalk148.green("No restructuring needed"));
|
|
14015
14103
|
return;
|
|
14016
14104
|
}
|
|
14017
14105
|
displayPlan2(plan2);
|
|
14018
14106
|
if (options2.apply) {
|
|
14019
|
-
console.log(
|
|
14107
|
+
console.log(chalk148.bold("\nApplying changes..."));
|
|
14020
14108
|
executePlan(plan2);
|
|
14021
|
-
console.log(
|
|
14109
|
+
console.log(chalk148.green("\nRestructuring complete"));
|
|
14022
14110
|
} else {
|
|
14023
|
-
console.log(
|
|
14111
|
+
console.log(chalk148.dim("\nDry run. Use --apply to execute."));
|
|
14024
14112
|
}
|
|
14025
14113
|
}
|
|
14026
14114
|
|
|
@@ -14589,18 +14677,18 @@ function partitionFindingsByDiff(findings, index2) {
|
|
|
14589
14677
|
}
|
|
14590
14678
|
|
|
14591
14679
|
// src/commands/review/warnOutOfDiff.ts
|
|
14592
|
-
import
|
|
14680
|
+
import chalk149 from "chalk";
|
|
14593
14681
|
function warnOutOfDiff(outOfDiff) {
|
|
14594
14682
|
if (outOfDiff.length === 0) return;
|
|
14595
14683
|
console.warn(
|
|
14596
|
-
|
|
14684
|
+
chalk149.yellow(
|
|
14597
14685
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
14598
14686
|
)
|
|
14599
14687
|
);
|
|
14600
14688
|
for (const finding of outOfDiff) {
|
|
14601
14689
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
14602
14690
|
console.warn(
|
|
14603
|
-
` ${
|
|
14691
|
+
` ${chalk149.yellow("\xB7")} ${finding.title} ${chalk149.dim(
|
|
14604
14692
|
`(${finding.file}:${range})`
|
|
14605
14693
|
)}`
|
|
14606
14694
|
);
|
|
@@ -14619,18 +14707,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
14619
14707
|
}
|
|
14620
14708
|
|
|
14621
14709
|
// src/commands/review/warnUnlocated.ts
|
|
14622
|
-
import
|
|
14710
|
+
import chalk150 from "chalk";
|
|
14623
14711
|
function warnUnlocated(unlocated) {
|
|
14624
14712
|
if (unlocated.length === 0) return;
|
|
14625
14713
|
console.warn(
|
|
14626
|
-
|
|
14714
|
+
chalk150.yellow(
|
|
14627
14715
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
14628
14716
|
)
|
|
14629
14717
|
);
|
|
14630
14718
|
for (const finding of unlocated) {
|
|
14631
|
-
const where = finding.location ||
|
|
14719
|
+
const where = finding.location || chalk150.dim("missing");
|
|
14632
14720
|
console.warn(
|
|
14633
|
-
` ${
|
|
14721
|
+
` ${chalk150.yellow("\xB7")} ${finding.title} ${chalk150.dim(`(${where})`)}`
|
|
14634
14722
|
);
|
|
14635
14723
|
}
|
|
14636
14724
|
}
|
|
@@ -15801,7 +15889,7 @@ function registerReview(program2) {
|
|
|
15801
15889
|
}
|
|
15802
15890
|
|
|
15803
15891
|
// src/commands/seq/seqAuth.ts
|
|
15804
|
-
import
|
|
15892
|
+
import chalk152 from "chalk";
|
|
15805
15893
|
|
|
15806
15894
|
// src/commands/seq/loadConnections.ts
|
|
15807
15895
|
function loadConnections2() {
|
|
@@ -15830,10 +15918,10 @@ function setDefaultConnection(name) {
|
|
|
15830
15918
|
}
|
|
15831
15919
|
|
|
15832
15920
|
// src/shared/assertUniqueName.ts
|
|
15833
|
-
import
|
|
15921
|
+
import chalk151 from "chalk";
|
|
15834
15922
|
function assertUniqueName(existingNames, name) {
|
|
15835
15923
|
if (existingNames.includes(name)) {
|
|
15836
|
-
console.error(
|
|
15924
|
+
console.error(chalk151.red(`Connection "${name}" already exists.`));
|
|
15837
15925
|
process.exit(1);
|
|
15838
15926
|
}
|
|
15839
15927
|
}
|
|
@@ -15851,16 +15939,16 @@ async function promptConnection2(existingNames) {
|
|
|
15851
15939
|
var seqAuth = createConnectionAuth({
|
|
15852
15940
|
load: loadConnections2,
|
|
15853
15941
|
save: saveConnections2,
|
|
15854
|
-
format: (c) => `${
|
|
15942
|
+
format: (c) => `${chalk152.bold(c.name)} ${c.url}`,
|
|
15855
15943
|
promptNew: promptConnection2,
|
|
15856
15944
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
15857
15945
|
});
|
|
15858
15946
|
|
|
15859
15947
|
// src/commands/seq/seqQuery.ts
|
|
15860
|
-
import
|
|
15948
|
+
import chalk156 from "chalk";
|
|
15861
15949
|
|
|
15862
15950
|
// src/commands/seq/fetchSeq.ts
|
|
15863
|
-
import
|
|
15951
|
+
import chalk153 from "chalk";
|
|
15864
15952
|
async function fetchSeq(conn, path56, params) {
|
|
15865
15953
|
const url = `${conn.url}${path56}?${params}`;
|
|
15866
15954
|
const response = await fetch(url, {
|
|
@@ -15871,7 +15959,7 @@ async function fetchSeq(conn, path56, params) {
|
|
|
15871
15959
|
});
|
|
15872
15960
|
if (!response.ok) {
|
|
15873
15961
|
const body = await response.text();
|
|
15874
|
-
console.error(
|
|
15962
|
+
console.error(chalk153.red(`Seq returned ${response.status}: ${body}`));
|
|
15875
15963
|
process.exit(1);
|
|
15876
15964
|
}
|
|
15877
15965
|
return response;
|
|
@@ -15930,23 +16018,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
15930
16018
|
}
|
|
15931
16019
|
|
|
15932
16020
|
// src/commands/seq/formatEvent.ts
|
|
15933
|
-
import
|
|
16021
|
+
import chalk154 from "chalk";
|
|
15934
16022
|
function levelColor(level) {
|
|
15935
16023
|
switch (level) {
|
|
15936
16024
|
case "Fatal":
|
|
15937
|
-
return
|
|
16025
|
+
return chalk154.bgRed.white;
|
|
15938
16026
|
case "Error":
|
|
15939
|
-
return
|
|
16027
|
+
return chalk154.red;
|
|
15940
16028
|
case "Warning":
|
|
15941
|
-
return
|
|
16029
|
+
return chalk154.yellow;
|
|
15942
16030
|
case "Information":
|
|
15943
|
-
return
|
|
16031
|
+
return chalk154.cyan;
|
|
15944
16032
|
case "Debug":
|
|
15945
|
-
return
|
|
16033
|
+
return chalk154.gray;
|
|
15946
16034
|
case "Verbose":
|
|
15947
|
-
return
|
|
16035
|
+
return chalk154.dim;
|
|
15948
16036
|
default:
|
|
15949
|
-
return
|
|
16037
|
+
return chalk154.white;
|
|
15950
16038
|
}
|
|
15951
16039
|
}
|
|
15952
16040
|
function levelAbbrev(level) {
|
|
@@ -15987,12 +16075,12 @@ function formatTimestamp(iso) {
|
|
|
15987
16075
|
function formatEvent(event) {
|
|
15988
16076
|
const color = levelColor(event.Level);
|
|
15989
16077
|
const abbrev = levelAbbrev(event.Level);
|
|
15990
|
-
const ts8 =
|
|
16078
|
+
const ts8 = chalk154.dim(formatTimestamp(event.Timestamp));
|
|
15991
16079
|
const msg = renderMessage(event);
|
|
15992
16080
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
15993
16081
|
if (event.Exception) {
|
|
15994
16082
|
for (const line of event.Exception.split("\n")) {
|
|
15995
|
-
lines.push(
|
|
16083
|
+
lines.push(chalk154.red(` ${line}`));
|
|
15996
16084
|
}
|
|
15997
16085
|
}
|
|
15998
16086
|
return lines.join("\n");
|
|
@@ -16025,11 +16113,11 @@ function rejectTimestampFilter(filter) {
|
|
|
16025
16113
|
}
|
|
16026
16114
|
|
|
16027
16115
|
// src/shared/resolveNamedConnection.ts
|
|
16028
|
-
import
|
|
16116
|
+
import chalk155 from "chalk";
|
|
16029
16117
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
16030
16118
|
if (connections.length === 0) {
|
|
16031
16119
|
console.error(
|
|
16032
|
-
|
|
16120
|
+
chalk155.red(
|
|
16033
16121
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
16034
16122
|
)
|
|
16035
16123
|
);
|
|
@@ -16038,7 +16126,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
16038
16126
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
16039
16127
|
const connection = connections.find((c) => c.name === target);
|
|
16040
16128
|
if (!connection) {
|
|
16041
|
-
console.error(
|
|
16129
|
+
console.error(chalk155.red(`${kind} connection "${target}" not found.`));
|
|
16042
16130
|
process.exit(1);
|
|
16043
16131
|
}
|
|
16044
16132
|
return connection;
|
|
@@ -16067,7 +16155,7 @@ async function seqQuery(filter, options2) {
|
|
|
16067
16155
|
new URLSearchParams({ filter, count: String(count6) })
|
|
16068
16156
|
);
|
|
16069
16157
|
if (events.length === 0) {
|
|
16070
|
-
console.log(
|
|
16158
|
+
console.log(chalk156.yellow("No events found."));
|
|
16071
16159
|
return;
|
|
16072
16160
|
}
|
|
16073
16161
|
if (options2.json) {
|
|
@@ -16078,11 +16166,11 @@ async function seqQuery(filter, options2) {
|
|
|
16078
16166
|
for (const event of chronological) {
|
|
16079
16167
|
console.log(formatEvent(event));
|
|
16080
16168
|
}
|
|
16081
|
-
console.log(
|
|
16169
|
+
console.log(chalk156.dim(`
|
|
16082
16170
|
${events.length} events`));
|
|
16083
16171
|
if (events.length >= count6) {
|
|
16084
16172
|
console.log(
|
|
16085
|
-
|
|
16173
|
+
chalk156.yellow(
|
|
16086
16174
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
16087
16175
|
)
|
|
16088
16176
|
);
|
|
@@ -16090,10 +16178,10 @@ ${events.length} events`));
|
|
|
16090
16178
|
}
|
|
16091
16179
|
|
|
16092
16180
|
// src/shared/setNamedDefaultConnection.ts
|
|
16093
|
-
import
|
|
16181
|
+
import chalk157 from "chalk";
|
|
16094
16182
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
16095
16183
|
if (!connections.find((c) => c.name === name)) {
|
|
16096
|
-
console.error(
|
|
16184
|
+
console.error(chalk157.red(`Connection "${name}" not found.`));
|
|
16097
16185
|
process.exit(1);
|
|
16098
16186
|
}
|
|
16099
16187
|
setDefault(name);
|
|
@@ -16130,18 +16218,18 @@ function registerSeq(program2) {
|
|
|
16130
16218
|
// src/commands/registerSignal.ts
|
|
16131
16219
|
function registerSignal(program2) {
|
|
16132
16220
|
const signalCommand = program2.command("signal").description("Write an assist signal file");
|
|
16133
|
-
signalCommand.command("next").argument("[id]", "Backlog item ID to run directly").description("Write a next signal to chain into assist next").action((
|
|
16134
|
-
writeSignal("next",
|
|
16221
|
+
signalCommand.command("next").argument("[id]", "Backlog item ID to run directly").description("Write a next signal to chain into assist next").action((id2) => {
|
|
16222
|
+
writeSignal("next", id2 ? { id: id2 } : void 0);
|
|
16135
16223
|
console.log("Signal written.");
|
|
16136
16224
|
});
|
|
16137
|
-
signalCommand.command("done").argument("[id]", "Backlog item ID created by the session").description("Write a done signal to end a --once launch session").action((
|
|
16138
|
-
writeSignal("done",
|
|
16225
|
+
signalCommand.command("done").argument("[id]", "Backlog item ID created by the session").description("Write a done signal to end a --once launch session").action((id2) => {
|
|
16226
|
+
writeSignal("done", id2 ? { id: id2 } : void 0);
|
|
16139
16227
|
console.log("Signal written.");
|
|
16140
16228
|
});
|
|
16141
16229
|
}
|
|
16142
16230
|
|
|
16143
16231
|
// src/commands/sql/sqlAuth.ts
|
|
16144
|
-
import
|
|
16232
|
+
import chalk159 from "chalk";
|
|
16145
16233
|
|
|
16146
16234
|
// src/commands/sql/loadConnections.ts
|
|
16147
16235
|
function loadConnections3() {
|
|
@@ -16170,7 +16258,7 @@ function setDefaultConnection2(name) {
|
|
|
16170
16258
|
}
|
|
16171
16259
|
|
|
16172
16260
|
// src/commands/sql/promptConnection.ts
|
|
16173
|
-
import
|
|
16261
|
+
import chalk158 from "chalk";
|
|
16174
16262
|
async function promptConnection3(existingNames) {
|
|
16175
16263
|
const name = await promptInput("name", "Connection name:", "default");
|
|
16176
16264
|
assertUniqueName(existingNames, name);
|
|
@@ -16178,7 +16266,7 @@ async function promptConnection3(existingNames) {
|
|
|
16178
16266
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
16179
16267
|
const port = Number.parseInt(portStr, 10);
|
|
16180
16268
|
if (!Number.isFinite(port)) {
|
|
16181
|
-
console.error(
|
|
16269
|
+
console.error(chalk158.red(`Invalid port "${portStr}".`));
|
|
16182
16270
|
process.exit(1);
|
|
16183
16271
|
}
|
|
16184
16272
|
const user = await promptInput("user", "User:");
|
|
@@ -16191,13 +16279,13 @@ async function promptConnection3(existingNames) {
|
|
|
16191
16279
|
var sqlAuth = createConnectionAuth({
|
|
16192
16280
|
load: loadConnections3,
|
|
16193
16281
|
save: saveConnections3,
|
|
16194
|
-
format: (c) => `${
|
|
16282
|
+
format: (c) => `${chalk159.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
16195
16283
|
promptNew: promptConnection3,
|
|
16196
16284
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
16197
16285
|
});
|
|
16198
16286
|
|
|
16199
16287
|
// src/commands/sql/printTable.ts
|
|
16200
|
-
import
|
|
16288
|
+
import chalk160 from "chalk";
|
|
16201
16289
|
function formatCell(value) {
|
|
16202
16290
|
if (value === null || value === void 0) return "";
|
|
16203
16291
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -16206,7 +16294,7 @@ function formatCell(value) {
|
|
|
16206
16294
|
}
|
|
16207
16295
|
function printTable(rows) {
|
|
16208
16296
|
if (rows.length === 0) {
|
|
16209
|
-
console.log(
|
|
16297
|
+
console.log(chalk160.yellow("(no rows)"));
|
|
16210
16298
|
return;
|
|
16211
16299
|
}
|
|
16212
16300
|
const columns = Object.keys(rows[0]);
|
|
@@ -16214,13 +16302,13 @@ function printTable(rows) {
|
|
|
16214
16302
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
16215
16303
|
);
|
|
16216
16304
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
16217
|
-
console.log(
|
|
16218
|
-
console.log(
|
|
16305
|
+
console.log(chalk160.dim(header));
|
|
16306
|
+
console.log(chalk160.dim("-".repeat(header.length)));
|
|
16219
16307
|
for (const row of rows) {
|
|
16220
16308
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
16221
16309
|
console.log(line);
|
|
16222
16310
|
}
|
|
16223
|
-
console.log(
|
|
16311
|
+
console.log(chalk160.dim(`
|
|
16224
16312
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
16225
16313
|
}
|
|
16226
16314
|
|
|
@@ -16280,7 +16368,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
16280
16368
|
}
|
|
16281
16369
|
|
|
16282
16370
|
// src/commands/sql/sqlMutate.ts
|
|
16283
|
-
import
|
|
16371
|
+
import chalk161 from "chalk";
|
|
16284
16372
|
|
|
16285
16373
|
// src/commands/sql/isMutation.ts
|
|
16286
16374
|
var MUTATION_KEYWORDS = [
|
|
@@ -16314,7 +16402,7 @@ function isMutation(sql4) {
|
|
|
16314
16402
|
async function sqlMutate(query, connectionName) {
|
|
16315
16403
|
if (!isMutation(query)) {
|
|
16316
16404
|
console.error(
|
|
16317
|
-
|
|
16405
|
+
chalk161.red(
|
|
16318
16406
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
16319
16407
|
)
|
|
16320
16408
|
);
|
|
@@ -16324,18 +16412,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
16324
16412
|
const pool = await sqlConnect(conn);
|
|
16325
16413
|
try {
|
|
16326
16414
|
const result = await pool.request().query(query);
|
|
16327
|
-
console.log(
|
|
16415
|
+
console.log(chalk161.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
16328
16416
|
} finally {
|
|
16329
16417
|
await pool.close();
|
|
16330
16418
|
}
|
|
16331
16419
|
}
|
|
16332
16420
|
|
|
16333
16421
|
// src/commands/sql/sqlQuery.ts
|
|
16334
|
-
import
|
|
16422
|
+
import chalk162 from "chalk";
|
|
16335
16423
|
async function sqlQuery(query, connectionName) {
|
|
16336
16424
|
if (isMutation(query)) {
|
|
16337
16425
|
console.error(
|
|
16338
|
-
|
|
16426
|
+
chalk162.red(
|
|
16339
16427
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
16340
16428
|
)
|
|
16341
16429
|
);
|
|
@@ -16350,7 +16438,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
16350
16438
|
printTable(rows);
|
|
16351
16439
|
} else {
|
|
16352
16440
|
console.log(
|
|
16353
|
-
|
|
16441
|
+
chalk162.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
16354
16442
|
);
|
|
16355
16443
|
}
|
|
16356
16444
|
} finally {
|
|
@@ -16930,14 +17018,14 @@ import {
|
|
|
16930
17018
|
import { dirname as dirname22, join as join42 } from "path";
|
|
16931
17019
|
|
|
16932
17020
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
16933
|
-
import
|
|
17021
|
+
import chalk163 from "chalk";
|
|
16934
17022
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
16935
17023
|
function validateStagedContent(filename, content) {
|
|
16936
17024
|
const firstLine = content.split("\n")[0];
|
|
16937
17025
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
16938
17026
|
if (!match) {
|
|
16939
17027
|
console.error(
|
|
16940
|
-
|
|
17028
|
+
chalk163.red(
|
|
16941
17029
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
16942
17030
|
)
|
|
16943
17031
|
);
|
|
@@ -16946,7 +17034,7 @@ function validateStagedContent(filename, content) {
|
|
|
16946
17034
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
16947
17035
|
if (!contentAfterLink) {
|
|
16948
17036
|
console.error(
|
|
16949
|
-
|
|
17037
|
+
chalk163.red(
|
|
16950
17038
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
16951
17039
|
)
|
|
16952
17040
|
);
|
|
@@ -17343,7 +17431,7 @@ function registerVoice(program2) {
|
|
|
17343
17431
|
|
|
17344
17432
|
// src/commands/roam/auth.ts
|
|
17345
17433
|
import { randomBytes } from "crypto";
|
|
17346
|
-
import
|
|
17434
|
+
import chalk164 from "chalk";
|
|
17347
17435
|
|
|
17348
17436
|
// src/commands/roam/waitForCallback.ts
|
|
17349
17437
|
import { createServer as createServer2 } from "http";
|
|
@@ -17474,13 +17562,13 @@ async function auth() {
|
|
|
17474
17562
|
saveGlobalConfig(config);
|
|
17475
17563
|
const state = randomBytes(16).toString("hex");
|
|
17476
17564
|
console.log(
|
|
17477
|
-
|
|
17565
|
+
chalk164.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
17478
17566
|
);
|
|
17479
|
-
console.log(
|
|
17480
|
-
console.log(
|
|
17481
|
-
console.log(
|
|
17567
|
+
console.log(chalk164.white("http://localhost:14523/callback\n"));
|
|
17568
|
+
console.log(chalk164.blue("Opening browser for authorization..."));
|
|
17569
|
+
console.log(chalk164.dim("Waiting for authorization callback..."));
|
|
17482
17570
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
17483
|
-
console.log(
|
|
17571
|
+
console.log(chalk164.dim("Exchanging code for tokens..."));
|
|
17484
17572
|
const tokens = await exchangeToken({
|
|
17485
17573
|
code,
|
|
17486
17574
|
clientId,
|
|
@@ -17496,7 +17584,7 @@ async function auth() {
|
|
|
17496
17584
|
};
|
|
17497
17585
|
saveGlobalConfig(config);
|
|
17498
17586
|
console.log(
|
|
17499
|
-
|
|
17587
|
+
chalk164.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
17500
17588
|
);
|
|
17501
17589
|
}
|
|
17502
17590
|
|
|
@@ -17735,13 +17823,13 @@ function execRunConfig(config, args) {
|
|
|
17735
17823
|
config.quiet
|
|
17736
17824
|
);
|
|
17737
17825
|
}
|
|
17738
|
-
function parseBacklogRunOptions(
|
|
17826
|
+
function parseBacklogRunOptions(id2, args) {
|
|
17739
17827
|
let allowEdits = true;
|
|
17740
17828
|
for (const arg of args) {
|
|
17741
17829
|
if (arg === "--write" || arg === "-w") allowEdits = true;
|
|
17742
17830
|
else if (arg === "--no-write") allowEdits = false;
|
|
17743
17831
|
else {
|
|
17744
|
-
console.error(`error: unexpected argument '${arg}' for 'run ${
|
|
17832
|
+
console.error(`error: unexpected argument '${arg}' for 'run ${id2}'`);
|
|
17745
17833
|
process.exit(1);
|
|
17746
17834
|
}
|
|
17747
17835
|
}
|
|
@@ -17948,7 +18036,7 @@ import { execSync as execSync48 } from "child_process";
|
|
|
17948
18036
|
import { existsSync as existsSync50, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
|
|
17949
18037
|
import { tmpdir as tmpdir7 } from "os";
|
|
17950
18038
|
import { join as join53, resolve as resolve13 } from "path";
|
|
17951
|
-
import
|
|
18039
|
+
import chalk165 from "chalk";
|
|
17952
18040
|
|
|
17953
18041
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
17954
18042
|
var captureWindowPs1 = `
|
|
@@ -18099,13 +18187,13 @@ function screenshot(processName) {
|
|
|
18099
18187
|
const config = loadConfig();
|
|
18100
18188
|
const outputDir = resolve13(config.screenshot.outputDir);
|
|
18101
18189
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
18102
|
-
console.log(
|
|
18190
|
+
console.log(chalk165.gray(`Capturing window for process "${processName}" ...`));
|
|
18103
18191
|
try {
|
|
18104
18192
|
runPowerShellScript(processName, outputPath);
|
|
18105
|
-
console.log(
|
|
18193
|
+
console.log(chalk165.green(`Screenshot saved: ${outputPath}`));
|
|
18106
18194
|
} catch (error) {
|
|
18107
18195
|
const msg = error instanceof Error ? error.message : String(error);
|
|
18108
|
-
console.error(
|
|
18196
|
+
console.error(chalk165.red(`Failed to capture screenshot: ${msg}`));
|
|
18109
18197
|
process.exit(1);
|
|
18110
18198
|
}
|
|
18111
18199
|
}
|
|
@@ -18292,7 +18380,7 @@ function toPersistedSession(session) {
|
|
|
18292
18380
|
|
|
18293
18381
|
// src/commands/sessions/daemon/toSessionInfo.ts
|
|
18294
18382
|
function toSessionInfo({
|
|
18295
|
-
id,
|
|
18383
|
+
id: id2,
|
|
18296
18384
|
name,
|
|
18297
18385
|
commandType,
|
|
18298
18386
|
status: status2,
|
|
@@ -18307,7 +18395,7 @@ function toSessionInfo({
|
|
|
18307
18395
|
autoAdvance
|
|
18308
18396
|
}) {
|
|
18309
18397
|
return {
|
|
18310
|
-
id,
|
|
18398
|
+
id: id2,
|
|
18311
18399
|
name,
|
|
18312
18400
|
commandType,
|
|
18313
18401
|
status: status2,
|
|
@@ -18394,14 +18482,14 @@ function shellEscape(s) {
|
|
|
18394
18482
|
}
|
|
18395
18483
|
|
|
18396
18484
|
// src/commands/sessions/daemon/createAssistSession.ts
|
|
18397
|
-
function createAssistSession(
|
|
18485
|
+
function createAssistSession(id2, assistArgs, cwd) {
|
|
18398
18486
|
return {
|
|
18399
|
-
id,
|
|
18487
|
+
id: id2,
|
|
18400
18488
|
name: `assist ${assistArgs.join(" ")}`,
|
|
18401
18489
|
commandType: "assist",
|
|
18402
18490
|
status: "running",
|
|
18403
18491
|
startedAt: Date.now(),
|
|
18404
|
-
pty: spawnPty(["assist", ...assistArgs], cwd,
|
|
18492
|
+
pty: spawnPty(["assist", ...assistArgs], cwd, id2),
|
|
18405
18493
|
scrollback: "",
|
|
18406
18494
|
idleTimer: null,
|
|
18407
18495
|
lastResizeAt: 0,
|
|
@@ -18426,10 +18514,10 @@ function spawnRun(opts) {
|
|
|
18426
18514
|
}
|
|
18427
18515
|
|
|
18428
18516
|
// src/commands/sessions/daemon/createSession.ts
|
|
18429
|
-
function createSession(
|
|
18517
|
+
function createSession(id2, prompt, cwd) {
|
|
18430
18518
|
return {
|
|
18431
|
-
id,
|
|
18432
|
-
name: prompt?.slice(0, 40) || `Session ${
|
|
18519
|
+
id: id2,
|
|
18520
|
+
name: prompt?.slice(0, 40) || `Session ${id2}`,
|
|
18433
18521
|
commandType: "claude",
|
|
18434
18522
|
status: "running",
|
|
18435
18523
|
startedAt: Date.now(),
|
|
@@ -18440,9 +18528,9 @@ function createSession(id, prompt, cwd) {
|
|
|
18440
18528
|
cwd
|
|
18441
18529
|
};
|
|
18442
18530
|
}
|
|
18443
|
-
function createRunSession(
|
|
18531
|
+
function createRunSession(id2, runName, runArgs, cwd) {
|
|
18444
18532
|
return {
|
|
18445
|
-
id,
|
|
18533
|
+
id: id2,
|
|
18446
18534
|
name: `run: ${runName}`,
|
|
18447
18535
|
commandType: "run",
|
|
18448
18536
|
status: "running",
|
|
@@ -18513,9 +18601,9 @@ function backlogRunArgs(persisted) {
|
|
|
18513
18601
|
}
|
|
18514
18602
|
|
|
18515
18603
|
// src/commands/sessions/daemon/restoreBase.ts
|
|
18516
|
-
function restoreBase(
|
|
18604
|
+
function restoreBase(id2, persisted) {
|
|
18517
18605
|
return {
|
|
18518
|
-
id,
|
|
18606
|
+
id: id2,
|
|
18519
18607
|
name: persisted.name,
|
|
18520
18608
|
commandType: persisted.commandType,
|
|
18521
18609
|
scrollback: "",
|
|
@@ -18540,10 +18628,10 @@ function runningSession(base, persisted, pty2) {
|
|
|
18540
18628
|
}
|
|
18541
18629
|
|
|
18542
18630
|
// src/commands/sessions/daemon/restoreSession.ts
|
|
18543
|
-
function restoreSession(
|
|
18544
|
-
const base = restoreBase(
|
|
18631
|
+
function restoreSession(id2, persisted) {
|
|
18632
|
+
const base = restoreBase(id2, persisted);
|
|
18545
18633
|
if (isBacklogRun(persisted)) {
|
|
18546
|
-
const pty2 = spawnPty(backlogRunArgs(persisted), persisted.cwd,
|
|
18634
|
+
const pty2 = spawnPty(backlogRunArgs(persisted), persisted.cwd, id2);
|
|
18547
18635
|
return runningSession(base, persisted, pty2);
|
|
18548
18636
|
}
|
|
18549
18637
|
if (persisted.commandType !== "run" && persisted.claudeSessionId) {
|
|
@@ -18568,9 +18656,9 @@ function isBacklogRun(persisted) {
|
|
|
18568
18656
|
}
|
|
18569
18657
|
|
|
18570
18658
|
// src/commands/sessions/daemon/resumeSession.ts
|
|
18571
|
-
function resumeSession(
|
|
18659
|
+
function resumeSession(id2, sessionId, cwd, name) {
|
|
18572
18660
|
return {
|
|
18573
|
-
id,
|
|
18661
|
+
id: id2,
|
|
18574
18662
|
name: name ? `${name.slice(0, 36)} (R)` : `Resume ${sessionId.slice(0, 8)}`,
|
|
18575
18663
|
commandType: "claude",
|
|
18576
18664
|
status: "running",
|
|
@@ -18939,8 +19027,8 @@ function handleSessions(state, msg) {
|
|
|
18939
19027
|
id: toWindowsSessionId(s.id)
|
|
18940
19028
|
}));
|
|
18941
19029
|
const live = new Set(state.windowsSessions.map((s) => s.id));
|
|
18942
|
-
for (const
|
|
18943
|
-
if (!live.has(
|
|
19030
|
+
for (const id2 of state.scrollback.keys())
|
|
19031
|
+
if (!live.has(id2)) state.scrollback.delete(id2);
|
|
18944
19032
|
state.onSessionsChanged();
|
|
18945
19033
|
}
|
|
18946
19034
|
function handleOutput(state, msg) {
|
|
@@ -19402,25 +19490,25 @@ function isBacklogRun2(session) {
|
|
|
19402
19490
|
}
|
|
19403
19491
|
|
|
19404
19492
|
// src/commands/sessions/daemon/writeToSession.ts
|
|
19405
|
-
function writeToSession(sessions,
|
|
19406
|
-
const s = sessions.get(
|
|
19493
|
+
function writeToSession(sessions, id2, data) {
|
|
19494
|
+
const s = sessions.get(id2);
|
|
19407
19495
|
if (s && s.status !== "done") s.pty?.write(data);
|
|
19408
19496
|
}
|
|
19409
|
-
function resizeSession(sessions,
|
|
19410
|
-
const s = sessions.get(
|
|
19497
|
+
function resizeSession(sessions, id2, cols, rows) {
|
|
19498
|
+
const s = sessions.get(id2);
|
|
19411
19499
|
if (s && s.status !== "done") {
|
|
19412
19500
|
s.lastResizeAt = Date.now();
|
|
19413
19501
|
s.pty?.resize(cols, rows);
|
|
19414
19502
|
}
|
|
19415
19503
|
}
|
|
19416
|
-
function setAutoRun(sessions,
|
|
19417
|
-
const s = sessions.get(
|
|
19504
|
+
function setAutoRun(sessions, id2, enabled) {
|
|
19505
|
+
const s = sessions.get(id2);
|
|
19418
19506
|
if (!s) return false;
|
|
19419
19507
|
s.autoRun = enabled;
|
|
19420
19508
|
return true;
|
|
19421
19509
|
}
|
|
19422
|
-
function setAutoAdvance(sessions,
|
|
19423
|
-
const s = sessions.get(
|
|
19510
|
+
function setAutoAdvance(sessions, id2, enabled) {
|
|
19511
|
+
const s = sessions.get(id2);
|
|
19424
19512
|
if (!s) return false;
|
|
19425
19513
|
s.autoAdvance = enabled;
|
|
19426
19514
|
const itemId = s.activity?.itemId;
|
|
@@ -19430,15 +19518,15 @@ function setAutoAdvance(sessions, id, enabled) {
|
|
|
19430
19518
|
}
|
|
19431
19519
|
return true;
|
|
19432
19520
|
}
|
|
19433
|
-
function dismissSession(sessions,
|
|
19434
|
-
const s = sessions.get(
|
|
19521
|
+
function dismissSession(sessions, id2) {
|
|
19522
|
+
const s = sessions.get(id2);
|
|
19435
19523
|
if (!s) return false;
|
|
19436
19524
|
if (s.status !== "done") s.pty?.kill();
|
|
19437
19525
|
clearIdle(s);
|
|
19438
19526
|
s.activityWatcher?.close();
|
|
19439
19527
|
removeActivity(s.id);
|
|
19440
19528
|
if (s.activity?.itemId != null) releaseLock(s.activity.itemId);
|
|
19441
|
-
sessions.delete(
|
|
19529
|
+
sessions.delete(id2);
|
|
19442
19530
|
return true;
|
|
19443
19531
|
}
|
|
19444
19532
|
|
|
@@ -19471,7 +19559,7 @@ var SessionManager = class {
|
|
|
19471
19559
|
}
|
|
19472
19560
|
restore() {
|
|
19473
19561
|
return loadPersistedSessions().map((persisted) => {
|
|
19474
|
-
this.spawnWith((
|
|
19562
|
+
this.spawnWith((id2) => restoreSession(id2, persisted));
|
|
19475
19563
|
return persisted.name;
|
|
19476
19564
|
});
|
|
19477
19565
|
}
|
|
@@ -19485,19 +19573,19 @@ var SessionManager = class {
|
|
|
19485
19573
|
return this.add(create(String(this.nextId++)));
|
|
19486
19574
|
}
|
|
19487
19575
|
spawn(prompt, cwd) {
|
|
19488
|
-
return this.spawnWith((
|
|
19576
|
+
return this.spawnWith((id2) => createSession(id2, prompt, cwd));
|
|
19489
19577
|
}
|
|
19490
19578
|
spawnRun(runName, runArgs, cwd) {
|
|
19491
|
-
return this.spawnWith((
|
|
19579
|
+
return this.spawnWith((id2) => createRunSession(id2, runName, runArgs, cwd));
|
|
19492
19580
|
}
|
|
19493
19581
|
spawnAssist(assistArgs, cwd) {
|
|
19494
|
-
return this.spawnWith((
|
|
19582
|
+
return this.spawnWith((id2) => createAssistSession(id2, assistArgs, cwd));
|
|
19495
19583
|
}
|
|
19496
19584
|
resume(sessionId, cwd, name) {
|
|
19497
|
-
return this.spawnWith((
|
|
19585
|
+
return this.spawnWith((id2) => resumeSession(id2, sessionId, cwd, name));
|
|
19498
19586
|
}
|
|
19499
19587
|
onStatusChange = makeStatusChangeHandler(
|
|
19500
|
-
(
|
|
19588
|
+
(id2) => this.dismissSession(id2),
|
|
19501
19589
|
() => this.notify(),
|
|
19502
19590
|
(session, itemId) => reuseSessionForRun(session, itemId, this.clients, this.onStatusChange)
|
|
19503
19591
|
);
|
|
@@ -19506,24 +19594,24 @@ var SessionManager = class {
|
|
|
19506
19594
|
wirePtyEvents(session, this.clients, this.onStatusChange);
|
|
19507
19595
|
this.notify();
|
|
19508
19596
|
}
|
|
19509
|
-
writeToSession(
|
|
19510
|
-
writeToSession(this.sessions,
|
|
19597
|
+
writeToSession(id2, data) {
|
|
19598
|
+
writeToSession(this.sessions, id2, data);
|
|
19511
19599
|
}
|
|
19512
|
-
resizeSession(
|
|
19513
|
-
resizeSession(this.sessions,
|
|
19600
|
+
resizeSession(id2, cols, rows) {
|
|
19601
|
+
resizeSession(this.sessions, id2, cols, rows);
|
|
19514
19602
|
}
|
|
19515
|
-
retrySession(
|
|
19516
|
-
const s = this.sessions.get(
|
|
19603
|
+
retrySession(id2) {
|
|
19604
|
+
const s = this.sessions.get(id2);
|
|
19517
19605
|
if (s && retrySession(s, this.clients, this.onStatusChange)) this.notify();
|
|
19518
19606
|
}
|
|
19519
|
-
dismissSession = (
|
|
19520
|
-
if (dismissSession(this.sessions,
|
|
19607
|
+
dismissSession = (id2) => {
|
|
19608
|
+
if (dismissSession(this.sessions, id2)) this.notify();
|
|
19521
19609
|
};
|
|
19522
|
-
setAutoRun(
|
|
19523
|
-
if (setAutoRun(this.sessions,
|
|
19610
|
+
setAutoRun(id2, enabled) {
|
|
19611
|
+
if (setAutoRun(this.sessions, id2, enabled)) this.notify();
|
|
19524
19612
|
}
|
|
19525
|
-
setAutoAdvance(
|
|
19526
|
-
if (setAutoAdvance(this.sessions,
|
|
19613
|
+
setAutoAdvance(id2, enabled) {
|
|
19614
|
+
if (setAutoAdvance(this.sessions, id2, enabled)) this.notify();
|
|
19527
19615
|
}
|
|
19528
19616
|
listSessions = () => {
|
|
19529
19617
|
const local = [...this.sessions.values()].map(toSessionInfo);
|
|
@@ -19881,7 +19969,7 @@ function registerDaemon(program2) {
|
|
|
19881
19969
|
|
|
19882
19970
|
// src/commands/sessions/summarise/index.ts
|
|
19883
19971
|
import * as fs33 from "fs";
|
|
19884
|
-
import
|
|
19972
|
+
import chalk166 from "chalk";
|
|
19885
19973
|
|
|
19886
19974
|
// src/commands/sessions/summarise/shared.ts
|
|
19887
19975
|
import * as fs31 from "fs";
|
|
@@ -19939,8 +20027,8 @@ function truncate3(text3, maxChars = 500) {
|
|
|
19939
20027
|
function scanSessionBacklogRefs(filePath) {
|
|
19940
20028
|
const ids = /* @__PURE__ */ new Set();
|
|
19941
20029
|
for (const text3 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
19942
|
-
for (const
|
|
19943
|
-
ids.add(
|
|
20030
|
+
for (const id2 of extractBacklogIds(text3)) {
|
|
20031
|
+
ids.add(id2);
|
|
19944
20032
|
}
|
|
19945
20033
|
}
|
|
19946
20034
|
return [...ids].sort((a, b) => a - b);
|
|
@@ -19992,7 +20080,7 @@ function buildPrompt2(firstMessage, backlogIds) {
|
|
|
19992
20080
|
"Return ONLY the summary, no quotes or explanation."
|
|
19993
20081
|
];
|
|
19994
20082
|
if (backlogIds.length > 0) {
|
|
19995
|
-
const refs = backlogIds.map((
|
|
20083
|
+
const refs = backlogIds.map((id2) => `#${id2}`).join(", ");
|
|
19996
20084
|
parts.push(
|
|
19997
20085
|
`The session references backlog item(s) ${refs}. Start the summary with "Backlog ${refs} \u2014" if relevant.`
|
|
19998
20086
|
);
|
|
@@ -20008,22 +20096,22 @@ ${firstMessage}`);
|
|
|
20008
20096
|
async function summarise4(options2) {
|
|
20009
20097
|
const files = await discoverSessionFiles();
|
|
20010
20098
|
if (files.length === 0) {
|
|
20011
|
-
console.log(
|
|
20099
|
+
console.log(chalk166.yellow("No sessions found."));
|
|
20012
20100
|
return;
|
|
20013
20101
|
}
|
|
20014
20102
|
const toProcess = selectCandidates(files, options2);
|
|
20015
20103
|
if (toProcess.length === 0) {
|
|
20016
|
-
console.log(
|
|
20104
|
+
console.log(chalk166.green("All sessions already summarised."));
|
|
20017
20105
|
return;
|
|
20018
20106
|
}
|
|
20019
20107
|
console.log(
|
|
20020
|
-
|
|
20108
|
+
chalk166.cyan(
|
|
20021
20109
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
20022
20110
|
)
|
|
20023
20111
|
);
|
|
20024
20112
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
20025
20113
|
console.log(
|
|
20026
|
-
|
|
20114
|
+
chalk166.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk166.yellow(`, ${failed2} skipped`) : "")
|
|
20027
20115
|
);
|
|
20028
20116
|
}
|
|
20029
20117
|
function selectCandidates(files, options2) {
|
|
@@ -20043,16 +20131,16 @@ function processSessions(files) {
|
|
|
20043
20131
|
let failed2 = 0;
|
|
20044
20132
|
for (let i = 0; i < files.length; i++) {
|
|
20045
20133
|
const file = files[i];
|
|
20046
|
-
process.stdout.write(
|
|
20134
|
+
process.stdout.write(chalk166.dim(` [${i + 1}/${files.length}] `));
|
|
20047
20135
|
const summary = summariseSession(file);
|
|
20048
20136
|
if (summary) {
|
|
20049
20137
|
writeSummary(file, summary);
|
|
20050
20138
|
succeeded++;
|
|
20051
|
-
process.stdout.write(`${
|
|
20139
|
+
process.stdout.write(`${chalk166.green("\u2713")} ${summary}
|
|
20052
20140
|
`);
|
|
20053
20141
|
} else {
|
|
20054
20142
|
failed2++;
|
|
20055
|
-
process.stdout.write(` ${
|
|
20143
|
+
process.stdout.write(` ${chalk166.yellow("skip")}
|
|
20056
20144
|
`);
|
|
20057
20145
|
}
|
|
20058
20146
|
}
|
|
@@ -20067,10 +20155,10 @@ function registerSessions(program2) {
|
|
|
20067
20155
|
}
|
|
20068
20156
|
|
|
20069
20157
|
// src/commands/statusLine.ts
|
|
20070
|
-
import
|
|
20158
|
+
import chalk168 from "chalk";
|
|
20071
20159
|
|
|
20072
20160
|
// src/commands/buildLimitsSegment.ts
|
|
20073
|
-
import
|
|
20161
|
+
import chalk167 from "chalk";
|
|
20074
20162
|
|
|
20075
20163
|
// src/shared/rateLimitLevel.ts
|
|
20076
20164
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -20101,9 +20189,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
20101
20189
|
|
|
20102
20190
|
// src/commands/buildLimitsSegment.ts
|
|
20103
20191
|
var LEVEL_COLOR = {
|
|
20104
|
-
ok:
|
|
20105
|
-
warn:
|
|
20106
|
-
over:
|
|
20192
|
+
ok: chalk167.green,
|
|
20193
|
+
warn: chalk167.yellow,
|
|
20194
|
+
over: chalk167.red
|
|
20107
20195
|
};
|
|
20108
20196
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
20109
20197
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -20151,14 +20239,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
20151
20239
|
}
|
|
20152
20240
|
|
|
20153
20241
|
// src/commands/statusLine.ts
|
|
20154
|
-
|
|
20242
|
+
chalk168.level = 3;
|
|
20155
20243
|
function formatNumber(num) {
|
|
20156
20244
|
return num.toLocaleString("en-US");
|
|
20157
20245
|
}
|
|
20158
20246
|
function colorizePercent(pct) {
|
|
20159
20247
|
const label2 = `${Math.round(pct)}%`;
|
|
20160
|
-
if (pct > 80) return
|
|
20161
|
-
if (pct > 40) return
|
|
20248
|
+
if (pct > 80) return chalk168.red(label2);
|
|
20249
|
+
if (pct > 40) return chalk168.yellow(label2);
|
|
20162
20250
|
return label2;
|
|
20163
20251
|
}
|
|
20164
20252
|
async function statusLine() {
|
|
@@ -20182,7 +20270,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
20182
20270
|
// src/commands/sync/syncClaudeMd.ts
|
|
20183
20271
|
import * as fs34 from "fs";
|
|
20184
20272
|
import * as path52 from "path";
|
|
20185
|
-
import
|
|
20273
|
+
import chalk169 from "chalk";
|
|
20186
20274
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
20187
20275
|
const source = path52.join(claudeDir, "CLAUDE.md");
|
|
20188
20276
|
const target = path52.join(targetBase, "CLAUDE.md");
|
|
@@ -20191,12 +20279,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
20191
20279
|
const targetContent = fs34.readFileSync(target, "utf-8");
|
|
20192
20280
|
if (sourceContent !== targetContent) {
|
|
20193
20281
|
console.log(
|
|
20194
|
-
|
|
20282
|
+
chalk169.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
20195
20283
|
);
|
|
20196
20284
|
console.log();
|
|
20197
20285
|
printDiff(targetContent, sourceContent);
|
|
20198
20286
|
const confirm = options2?.yes || await promptConfirm(
|
|
20199
|
-
|
|
20287
|
+
chalk169.red("Overwrite existing CLAUDE.md?"),
|
|
20200
20288
|
false
|
|
20201
20289
|
);
|
|
20202
20290
|
if (!confirm) {
|
|
@@ -20212,7 +20300,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
20212
20300
|
// src/commands/sync/syncSettings.ts
|
|
20213
20301
|
import * as fs35 from "fs";
|
|
20214
20302
|
import * as path53 from "path";
|
|
20215
|
-
import
|
|
20303
|
+
import chalk170 from "chalk";
|
|
20216
20304
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
20217
20305
|
const source = path53.join(claudeDir, "settings.json");
|
|
20218
20306
|
const target = path53.join(targetBase, "settings.json");
|
|
@@ -20228,14 +20316,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20228
20316
|
if (mergedContent !== normalizedTarget) {
|
|
20229
20317
|
if (!options2?.yes) {
|
|
20230
20318
|
console.log(
|
|
20231
|
-
|
|
20319
|
+
chalk170.yellow(
|
|
20232
20320
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
20233
20321
|
)
|
|
20234
20322
|
);
|
|
20235
20323
|
console.log();
|
|
20236
20324
|
printDiff(targetContent, mergedContent);
|
|
20237
20325
|
const confirm = await promptConfirm(
|
|
20238
|
-
|
|
20326
|
+
chalk170.red("Overwrite existing settings.json?"),
|
|
20239
20327
|
false
|
|
20240
20328
|
);
|
|
20241
20329
|
if (!confirm) {
|