@staff0rd/assist 0.327.0 → 0.328.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 +6 -4
- package/claude/commands/associate-jira.md +34 -0
- package/dist/index.js +723 -617
- 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.328.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -2925,7 +2925,8 @@ var items = pgTable4(
|
|
|
2925
2925
|
acceptanceCriteria: text4("acceptance_criteria").notNull().default("[]"),
|
|
2926
2926
|
status: text4().notNull().default("todo"),
|
|
2927
2927
|
currentPhase: integer4("current_phase"),
|
|
2928
|
-
starred: boolean2().notNull().default(false)
|
|
2928
|
+
starred: boolean2().notNull().default(false),
|
|
2929
|
+
jiraKey: text4("jira_key")
|
|
2929
2930
|
},
|
|
2930
2931
|
(t) => [index2("items_origin_idx").on(t.origin)]
|
|
2931
2932
|
);
|
|
@@ -3143,11 +3144,13 @@ var SCHEMA = `
|
|
|
3143
3144
|
acceptance_criteria TEXT NOT NULL DEFAULT '[]',
|
|
3144
3145
|
status TEXT NOT NULL DEFAULT 'todo',
|
|
3145
3146
|
current_phase INTEGER,
|
|
3146
|
-
starred BOOLEAN NOT NULL DEFAULT false
|
|
3147
|
+
starred BOOLEAN NOT NULL DEFAULT false,
|
|
3148
|
+
jira_key TEXT
|
|
3147
3149
|
);
|
|
3148
3150
|
|
|
3149
3151
|
-- Backfill the column on databases created before it was introduced.
|
|
3150
3152
|
ALTER TABLE items ADD COLUMN IF NOT EXISTS starred BOOLEAN NOT NULL DEFAULT false;
|
|
3153
|
+
ALTER TABLE items ADD COLUMN IF NOT EXISTS jira_key TEXT;
|
|
3151
3154
|
|
|
3152
3155
|
CREATE INDEX IF NOT EXISTS items_origin_idx ON items (origin);
|
|
3153
3156
|
|
|
@@ -4014,7 +4017,8 @@ function itemColumns(item, origin) {
|
|
|
4014
4017
|
acceptanceCriteria: JSON.stringify(item.acceptanceCriteria),
|
|
4015
4018
|
status: item.status,
|
|
4016
4019
|
currentPhase: item.currentPhase ?? null,
|
|
4017
|
-
starred: item.starred
|
|
4020
|
+
starred: item.starred,
|
|
4021
|
+
jiraKey: item.jiraKey ?? null
|
|
4018
4022
|
};
|
|
4019
4023
|
}
|
|
4020
4024
|
|
|
@@ -4181,6 +4185,7 @@ function buildPlan(phaseRows, taskRows) {
|
|
|
4181
4185
|
function assignOptionalColumns(item, row) {
|
|
4182
4186
|
if (row.description != null) item.description = row.description;
|
|
4183
4187
|
if (row.currentPhase != null) item.currentPhase = row.currentPhase;
|
|
4188
|
+
if (row.jiraKey != null) item.jiraKey = row.jiraKey;
|
|
4184
4189
|
}
|
|
4185
4190
|
function baseItem(row) {
|
|
4186
4191
|
const item = {
|
|
@@ -4267,7 +4272,8 @@ var backlogItemSchema = z3.strictObject({
|
|
|
4267
4272
|
status: backlogStatusSchema,
|
|
4268
4273
|
comments: z3.array(backlogCommentSchema).optional(),
|
|
4269
4274
|
links: z3.array(backlogLinkSchema).optional(),
|
|
4270
|
-
origin: z3.string().optional()
|
|
4275
|
+
origin: z3.string().optional(),
|
|
4276
|
+
jiraKey: z3.string().optional()
|
|
4271
4277
|
});
|
|
4272
4278
|
var backlogFileSchema = z3.array(backlogItemSchema);
|
|
4273
4279
|
|
|
@@ -5287,6 +5293,9 @@ function printHeader(item) {
|
|
|
5287
5293
|
console.log(
|
|
5288
5294
|
`${chalk49.dim("Type:")} ${item.type} ${chalk49.dim("Status:")} ${item.status}`
|
|
5289
5295
|
);
|
|
5296
|
+
if (item.jiraKey) {
|
|
5297
|
+
console.log(`${chalk49.dim("Jira:")} ${item.jiraKey}`);
|
|
5298
|
+
}
|
|
5290
5299
|
console.log();
|
|
5291
5300
|
}
|
|
5292
5301
|
function printAcceptanceCriteria(criteria) {
|
|
@@ -6729,27 +6738,102 @@ async function web2(options2) {
|
|
|
6729
6738
|
});
|
|
6730
6739
|
}
|
|
6731
6740
|
|
|
6732
|
-
// src/commands/backlog/
|
|
6741
|
+
// src/commands/backlog/associate-jira/index.ts
|
|
6742
|
+
import chalk57 from "chalk";
|
|
6743
|
+
import { eq as eq17 } from "drizzle-orm";
|
|
6744
|
+
|
|
6745
|
+
// src/commands/jira/fetchIssue.ts
|
|
6746
|
+
import { execSync as execSync22 } from "child_process";
|
|
6733
6747
|
import chalk56 from "chalk";
|
|
6748
|
+
function fetchIssue(issueKey, fields) {
|
|
6749
|
+
let result;
|
|
6750
|
+
try {
|
|
6751
|
+
result = execSync22(
|
|
6752
|
+
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
6753
|
+
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
6754
|
+
);
|
|
6755
|
+
} catch (error) {
|
|
6756
|
+
if (error instanceof Error && "stderr" in error) {
|
|
6757
|
+
const stderr = error.stderr;
|
|
6758
|
+
if (stderr.includes("unauthorized")) {
|
|
6759
|
+
console.error(
|
|
6760
|
+
chalk56.red("Jira authentication expired."),
|
|
6761
|
+
"Run",
|
|
6762
|
+
chalk56.cyan("assist jira auth"),
|
|
6763
|
+
"to re-authenticate."
|
|
6764
|
+
);
|
|
6765
|
+
process.exit(1);
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
console.error(chalk56.red(`Failed to fetch ${issueKey}.`));
|
|
6769
|
+
process.exit(1);
|
|
6770
|
+
}
|
|
6771
|
+
return JSON.parse(result);
|
|
6772
|
+
}
|
|
6773
|
+
|
|
6774
|
+
// src/commands/backlog/associate-jira/index.ts
|
|
6775
|
+
var JIRA_KEY_PATTERN = /^[A-Z]+-\d+$/;
|
|
6776
|
+
async function associateJira(id2, key, options2) {
|
|
6777
|
+
const found = await findOneItem(id2);
|
|
6778
|
+
if (!found) {
|
|
6779
|
+
process.exitCode = 1;
|
|
6780
|
+
return;
|
|
6781
|
+
}
|
|
6782
|
+
const { orm } = found;
|
|
6783
|
+
const itemId = found.item.id;
|
|
6784
|
+
if (options2.clear) {
|
|
6785
|
+
await orm.update(items).set({ jiraKey: null }).where(eq17(items.id, itemId));
|
|
6786
|
+
console.log(chalk57.green(`Cleared Jira association on item #${itemId}.`));
|
|
6787
|
+
return;
|
|
6788
|
+
}
|
|
6789
|
+
if (!key) {
|
|
6790
|
+
console.log(chalk57.red("Provide a Jira key, or use --clear to remove one."));
|
|
6791
|
+
process.exitCode = 1;
|
|
6792
|
+
return;
|
|
6793
|
+
}
|
|
6794
|
+
if (!JIRA_KEY_PATTERN.test(key)) {
|
|
6795
|
+
console.log(
|
|
6796
|
+
chalk57.red(`Malformed Jira key "${key}". Expected a key like PROJ-123.`)
|
|
6797
|
+
);
|
|
6798
|
+
process.exitCode = 1;
|
|
6799
|
+
return;
|
|
6800
|
+
}
|
|
6801
|
+
const parsed = fetchIssue(key, "summary");
|
|
6802
|
+
const fields = parsed?.fields;
|
|
6803
|
+
const summary = fields?.summary;
|
|
6804
|
+
await orm.update(items).set({ jiraKey: key }).where(eq17(items.id, itemId));
|
|
6805
|
+
console.log(
|
|
6806
|
+
chalk57.green(`Associated ${key} with item #${itemId}.`),
|
|
6807
|
+
summary ? chalk57.dim(`(${summary})`) : ""
|
|
6808
|
+
);
|
|
6809
|
+
}
|
|
6810
|
+
|
|
6811
|
+
// src/commands/backlog/registerAssociateJiraCommand.ts
|
|
6812
|
+
function registerAssociateJiraCommand(cmd) {
|
|
6813
|
+
cmd.command("associate-jira <id> [key]").description("Associate a Jira ticket with a backlog item").option("--clear", "Remove the Jira association from the item").action(associateJira);
|
|
6814
|
+
}
|
|
6815
|
+
|
|
6816
|
+
// src/commands/backlog/comment/index.ts
|
|
6817
|
+
import chalk58 from "chalk";
|
|
6734
6818
|
async function comment(id2, text6) {
|
|
6735
6819
|
const found = await findOneItem(id2);
|
|
6736
6820
|
if (!found) process.exit(1);
|
|
6737
6821
|
await appendComment(found.orm, found.item.id, text6);
|
|
6738
|
-
console.log(
|
|
6822
|
+
console.log(chalk58.green(`Comment added to item #${id2}.`));
|
|
6739
6823
|
}
|
|
6740
6824
|
|
|
6741
6825
|
// src/commands/backlog/comments/index.ts
|
|
6742
|
-
import
|
|
6826
|
+
import chalk59 from "chalk";
|
|
6743
6827
|
async function comments2(id2) {
|
|
6744
6828
|
const found = await findOneItem(id2);
|
|
6745
6829
|
if (!found) process.exit(1);
|
|
6746
6830
|
const { item } = found;
|
|
6747
6831
|
const entries = item.comments ?? [];
|
|
6748
6832
|
if (entries.length === 0) {
|
|
6749
|
-
console.log(
|
|
6833
|
+
console.log(chalk59.dim(`No comments on item #${id2}.`));
|
|
6750
6834
|
return;
|
|
6751
6835
|
}
|
|
6752
|
-
console.log(
|
|
6836
|
+
console.log(chalk59.bold(`Comments for #${id2}: ${item.name}
|
|
6753
6837
|
`));
|
|
6754
6838
|
for (const entry of entries) {
|
|
6755
6839
|
console.log(`${formatComment(entry)}
|
|
@@ -6758,7 +6842,7 @@ async function comments2(id2) {
|
|
|
6758
6842
|
}
|
|
6759
6843
|
|
|
6760
6844
|
// src/commands/backlog/delete-comment/index.ts
|
|
6761
|
-
import
|
|
6845
|
+
import chalk60 from "chalk";
|
|
6762
6846
|
async function deleteCommentCmd(id2, commentId) {
|
|
6763
6847
|
const found = await findOneItem(id2);
|
|
6764
6848
|
if (!found) process.exit(1);
|
|
@@ -6770,16 +6854,16 @@ async function deleteCommentCmd(id2, commentId) {
|
|
|
6770
6854
|
switch (outcome) {
|
|
6771
6855
|
case "deleted":
|
|
6772
6856
|
console.log(
|
|
6773
|
-
|
|
6857
|
+
chalk60.green(`Comment #${commentId} deleted from item #${id2}.`)
|
|
6774
6858
|
);
|
|
6775
6859
|
break;
|
|
6776
6860
|
case "not-found":
|
|
6777
|
-
console.log(
|
|
6861
|
+
console.log(chalk60.red(`Comment #${commentId} not found on item #${id2}.`));
|
|
6778
6862
|
process.exit(1);
|
|
6779
6863
|
break;
|
|
6780
6864
|
case "is-summary":
|
|
6781
6865
|
console.log(
|
|
6782
|
-
|
|
6866
|
+
chalk60.red(
|
|
6783
6867
|
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
6784
6868
|
)
|
|
6785
6869
|
);
|
|
@@ -6804,7 +6888,7 @@ function registerExportCommand(cmd) {
|
|
|
6804
6888
|
|
|
6805
6889
|
// src/commands/backlog/import/index.ts
|
|
6806
6890
|
import { readFile } from "fs/promises";
|
|
6807
|
-
import
|
|
6891
|
+
import chalk62 from "chalk";
|
|
6808
6892
|
|
|
6809
6893
|
// src/commands/backlog/dump/countCopyRows.ts
|
|
6810
6894
|
function countCopyRows(data) {
|
|
@@ -6876,7 +6960,7 @@ function validateDump({ header, sections }) {
|
|
|
6876
6960
|
}
|
|
6877
6961
|
|
|
6878
6962
|
// src/commands/backlog/import/confirmReplace.ts
|
|
6879
|
-
import
|
|
6963
|
+
import chalk61 from "chalk";
|
|
6880
6964
|
async function countRows(client, table) {
|
|
6881
6965
|
const { rows } = await client.query(
|
|
6882
6966
|
`SELECT count(*)::int AS n FROM ${table}`
|
|
@@ -6887,7 +6971,7 @@ function printSummary(tables, current, incoming) {
|
|
|
6887
6971
|
const lines = tables.map(
|
|
6888
6972
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
6889
6973
|
);
|
|
6890
|
-
console.error(
|
|
6974
|
+
console.error(chalk61.bold("\nThis will REPLACE all backlog data:"));
|
|
6891
6975
|
console.error(`${lines.join("\n")}
|
|
6892
6976
|
`);
|
|
6893
6977
|
}
|
|
@@ -6989,13 +7073,13 @@ async function importBacklog(file, options2 = {}) {
|
|
|
6989
7073
|
);
|
|
6990
7074
|
await withDbClient(async (client) => {
|
|
6991
7075
|
if (!options2.yes && !await confirmReplace(client, tables, incoming, !file)) {
|
|
6992
|
-
console.error(
|
|
7076
|
+
console.error(chalk62.yellow("Import cancelled; no changes made."));
|
|
6993
7077
|
return;
|
|
6994
7078
|
}
|
|
6995
7079
|
await restore(client, parsed);
|
|
6996
7080
|
const total = incoming.reduce((sum, n) => sum + n, 0);
|
|
6997
7081
|
console.error(
|
|
6998
|
-
|
|
7082
|
+
chalk62.green(
|
|
6999
7083
|
`Imported backlog: ${total} rows restored across ${tables.length} tables.`
|
|
7000
7084
|
)
|
|
7001
7085
|
);
|
|
@@ -7012,7 +7096,7 @@ function registerImportCommand(cmd) {
|
|
|
7012
7096
|
}
|
|
7013
7097
|
|
|
7014
7098
|
// src/commands/backlog/add/index.ts
|
|
7015
|
-
import
|
|
7099
|
+
import chalk63 from "chalk";
|
|
7016
7100
|
|
|
7017
7101
|
// src/commands/backlog/add/shared.ts
|
|
7018
7102
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -7103,29 +7187,29 @@ async function add(options2) {
|
|
|
7103
7187
|
},
|
|
7104
7188
|
getOrigin()
|
|
7105
7189
|
);
|
|
7106
|
-
console.log(
|
|
7190
|
+
console.log(chalk63.green(`Added item #${id2}: ${name}`));
|
|
7107
7191
|
}
|
|
7108
7192
|
|
|
7109
7193
|
// src/commands/backlog/addPhase.ts
|
|
7110
|
-
import
|
|
7194
|
+
import chalk65 from "chalk";
|
|
7111
7195
|
|
|
7112
7196
|
// src/commands/backlog/insertPhaseAt.ts
|
|
7113
|
-
import { count, eq as
|
|
7197
|
+
import { count, eq as eq19 } from "drizzle-orm";
|
|
7114
7198
|
|
|
7115
7199
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
7116
|
-
import { and as and5, desc as desc3, eq as
|
|
7200
|
+
import { and as and5, desc as desc3, eq as eq18, gte } from "drizzle-orm";
|
|
7117
7201
|
async function shiftPhasesUp(db, itemId, fromIdx) {
|
|
7118
|
-
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and5(
|
|
7202
|
+
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and5(eq18(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(desc3(planPhases.idx));
|
|
7119
7203
|
for (const p of toShift) {
|
|
7120
|
-
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and5(
|
|
7121
|
-
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and5(
|
|
7204
|
+
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and5(eq18(planTasks.itemId, itemId), eq18(planTasks.phaseIdx, p.idx)));
|
|
7205
|
+
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and5(eq18(planPhases.itemId, itemId), eq18(planPhases.idx, p.idx)));
|
|
7122
7206
|
}
|
|
7123
7207
|
}
|
|
7124
7208
|
|
|
7125
7209
|
// src/commands/backlog/insertPhaseAt.ts
|
|
7126
7210
|
async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, currentPhase) {
|
|
7127
7211
|
await orm.transaction(async (tx) => {
|
|
7128
|
-
const [row] = await tx.select({ cnt: count() }).from(planPhases).where(
|
|
7212
|
+
const [row] = await tx.select({ cnt: count() }).from(planPhases).where(eq19(planPhases.itemId, itemId));
|
|
7129
7213
|
const phaseCount = row?.cnt ?? 0;
|
|
7130
7214
|
await shiftPhasesUp(tx, itemId, phaseIdx);
|
|
7131
7215
|
await tx.insert(planPhases).values({ itemId, idx: phaseIdx, name, manualChecks });
|
|
@@ -7134,22 +7218,22 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
|
|
|
7134
7218
|
}
|
|
7135
7219
|
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
7136
7220
|
const atReviewSlot = currentPhase - 1 >= phaseCount;
|
|
7137
|
-
await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(
|
|
7221
|
+
await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(eq19(items.id, itemId));
|
|
7138
7222
|
}
|
|
7139
7223
|
});
|
|
7140
7224
|
}
|
|
7141
7225
|
|
|
7142
7226
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
7143
|
-
import
|
|
7144
|
-
import { count as count2, eq as
|
|
7227
|
+
import chalk64 from "chalk";
|
|
7228
|
+
import { count as count2, eq as eq20 } from "drizzle-orm";
|
|
7145
7229
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
7146
|
-
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(
|
|
7230
|
+
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq20(planPhases.itemId, itemId));
|
|
7147
7231
|
const phaseCount = row?.cnt ?? 0;
|
|
7148
7232
|
if (position === void 0) return phaseCount;
|
|
7149
7233
|
const pos = Number.parseInt(position, 10);
|
|
7150
7234
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
7151
7235
|
console.log(
|
|
7152
|
-
|
|
7236
|
+
chalk64.red(
|
|
7153
7237
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
7154
7238
|
)
|
|
7155
7239
|
);
|
|
@@ -7170,7 +7254,7 @@ async function addPhase(id2, name, options2) {
|
|
|
7170
7254
|
if (!found) return;
|
|
7171
7255
|
const tasks = options2.task ?? [];
|
|
7172
7256
|
if (tasks.length === 0) {
|
|
7173
|
-
console.log(
|
|
7257
|
+
console.log(chalk65.red("At least one --task is required."));
|
|
7174
7258
|
process.exitCode = 1;
|
|
7175
7259
|
return;
|
|
7176
7260
|
}
|
|
@@ -7189,14 +7273,14 @@ async function addPhase(id2, name, options2) {
|
|
|
7189
7273
|
);
|
|
7190
7274
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
7191
7275
|
console.log(
|
|
7192
|
-
|
|
7276
|
+
chalk65.green(
|
|
7193
7277
|
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
7194
7278
|
)
|
|
7195
7279
|
);
|
|
7196
7280
|
}
|
|
7197
7281
|
|
|
7198
7282
|
// src/commands/backlog/list/index.ts
|
|
7199
|
-
import
|
|
7283
|
+
import chalk66 from "chalk";
|
|
7200
7284
|
|
|
7201
7285
|
// src/commands/backlog/originDisplayName.ts
|
|
7202
7286
|
function originDisplayName(origin) {
|
|
@@ -7248,7 +7332,7 @@ async function list2(options2) {
|
|
|
7248
7332
|
const allItems = await loadBacklog(options2.allRepos);
|
|
7249
7333
|
const items2 = filterItems(allItems, options2);
|
|
7250
7334
|
if (items2.length === 0) {
|
|
7251
|
-
console.log(
|
|
7335
|
+
console.log(chalk66.dim("Backlog is empty."));
|
|
7252
7336
|
return;
|
|
7253
7337
|
}
|
|
7254
7338
|
const labels = originDisplayLabels(
|
|
@@ -7257,9 +7341,9 @@ async function list2(options2) {
|
|
|
7257
7341
|
const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
|
|
7258
7342
|
const prefixWidth = options2.allRepos ? Math.max(0, ...items2.map((i) => repoNameOf(i).length)) : 0;
|
|
7259
7343
|
for (const item of items2) {
|
|
7260
|
-
const repoPrefix = options2.allRepos ? `${
|
|
7344
|
+
const repoPrefix = options2.allRepos ? `${chalk66.dim(repoNameOf(item).padEnd(prefixWidth))} ` : "";
|
|
7261
7345
|
console.log(
|
|
7262
|
-
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
7346
|
+
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk66.dim(`#${item.id}`)} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
7263
7347
|
);
|
|
7264
7348
|
if (options2.verbose) {
|
|
7265
7349
|
printVerboseDetails(item);
|
|
@@ -7285,7 +7369,7 @@ function registerItemCommands(cmd) {
|
|
|
7285
7369
|
}
|
|
7286
7370
|
|
|
7287
7371
|
// src/commands/backlog/link.ts
|
|
7288
|
-
import
|
|
7372
|
+
import chalk68 from "chalk";
|
|
7289
7373
|
|
|
7290
7374
|
// src/commands/backlog/hasCycle.ts
|
|
7291
7375
|
function hasCycle(adjacency, fromId, toId) {
|
|
@@ -7304,9 +7388,9 @@ function hasCycle(adjacency, fromId, toId) {
|
|
|
7304
7388
|
}
|
|
7305
7389
|
|
|
7306
7390
|
// src/commands/backlog/loadDependencyGraph.ts
|
|
7307
|
-
import { eq as
|
|
7391
|
+
import { eq as eq21 } from "drizzle-orm";
|
|
7308
7392
|
async function loadDependencyGraph(orm) {
|
|
7309
|
-
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(
|
|
7393
|
+
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq21(links.type, "depends-on"));
|
|
7310
7394
|
const graph = /* @__PURE__ */ new Map();
|
|
7311
7395
|
for (const { itemId, targetId } of rows) {
|
|
7312
7396
|
const bucket = graph.get(itemId);
|
|
@@ -7317,14 +7401,14 @@ async function loadDependencyGraph(orm) {
|
|
|
7317
7401
|
}
|
|
7318
7402
|
|
|
7319
7403
|
// src/commands/backlog/validateLinkTarget.ts
|
|
7320
|
-
import
|
|
7404
|
+
import chalk67 from "chalk";
|
|
7321
7405
|
function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
7322
7406
|
const duplicate = (fromItem.links ?? []).some(
|
|
7323
7407
|
(l) => l.targetId === toNum && l.type === linkType
|
|
7324
7408
|
);
|
|
7325
7409
|
if (duplicate) {
|
|
7326
7410
|
console.log(
|
|
7327
|
-
|
|
7411
|
+
chalk67.yellow(`Link already exists: #${fromNum} ${linkType} #${toNum}`)
|
|
7328
7412
|
);
|
|
7329
7413
|
return false;
|
|
7330
7414
|
}
|
|
@@ -7333,7 +7417,7 @@ function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
|
7333
7417
|
|
|
7334
7418
|
// src/commands/backlog/link.ts
|
|
7335
7419
|
function fail2(message) {
|
|
7336
|
-
console.log(
|
|
7420
|
+
console.log(chalk68.red(message));
|
|
7337
7421
|
return void 0;
|
|
7338
7422
|
}
|
|
7339
7423
|
function parseLinkType(type) {
|
|
@@ -7363,32 +7447,32 @@ async function link(fromId, toId, opts) {
|
|
|
7363
7447
|
if (await createsCycle(orm, linkType, fromNum, toNum)) return;
|
|
7364
7448
|
await orm.insert(links).values({ itemId: fromNum, type: linkType, targetId: toNum });
|
|
7365
7449
|
console.log(
|
|
7366
|
-
|
|
7450
|
+
chalk68.green(`Linked #${fromNum} ${linkType} #${toNum} (${toItem.name})`)
|
|
7367
7451
|
);
|
|
7368
7452
|
}
|
|
7369
7453
|
|
|
7370
7454
|
// src/commands/backlog/unlink.ts
|
|
7371
|
-
import
|
|
7372
|
-
import { and as and6, eq as
|
|
7455
|
+
import chalk69 from "chalk";
|
|
7456
|
+
import { and as and6, eq as eq22 } from "drizzle-orm";
|
|
7373
7457
|
async function unlink(fromId, toId) {
|
|
7374
7458
|
const fromNum = Number.parseInt(fromId, 10);
|
|
7375
7459
|
const toNum = Number.parseInt(toId, 10);
|
|
7376
7460
|
const { orm } = await getReady();
|
|
7377
7461
|
const fromItem = await loadItem(orm, fromNum);
|
|
7378
7462
|
if (!fromItem) {
|
|
7379
|
-
console.log(
|
|
7463
|
+
console.log(chalk69.red(`Item #${fromId} not found.`));
|
|
7380
7464
|
return;
|
|
7381
7465
|
}
|
|
7382
7466
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
7383
|
-
console.log(
|
|
7467
|
+
console.log(chalk69.yellow(`No links found on item #${fromId}.`));
|
|
7384
7468
|
return;
|
|
7385
7469
|
}
|
|
7386
7470
|
if (!fromItem.links.some((l) => l.targetId === toNum)) {
|
|
7387
|
-
console.log(
|
|
7471
|
+
console.log(chalk69.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
7388
7472
|
return;
|
|
7389
7473
|
}
|
|
7390
|
-
await orm.delete(links).where(and6(
|
|
7391
|
-
console.log(
|
|
7474
|
+
await orm.delete(links).where(and6(eq22(links.itemId, fromNum), eq22(links.targetId, toNum)));
|
|
7475
|
+
console.log(chalk69.green(`Removed link from #${fromId} to #${toId}.`));
|
|
7392
7476
|
}
|
|
7393
7477
|
|
|
7394
7478
|
// src/commands/backlog/registerLinkCommands.ts
|
|
@@ -7402,25 +7486,25 @@ function registerLinkCommands(cmd) {
|
|
|
7402
7486
|
}
|
|
7403
7487
|
|
|
7404
7488
|
// src/commands/backlog/move-repo/index.ts
|
|
7405
|
-
import
|
|
7406
|
-
import { eq as
|
|
7489
|
+
import chalk71 from "chalk";
|
|
7490
|
+
import { eq as eq24 } from "drizzle-orm";
|
|
7407
7491
|
|
|
7408
7492
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
7409
|
-
import
|
|
7493
|
+
import chalk70 from "chalk";
|
|
7410
7494
|
function pluralItems(n) {
|
|
7411
7495
|
return `${n} item${n === 1 ? "" : "s"}`;
|
|
7412
7496
|
}
|
|
7413
7497
|
async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
7414
7498
|
console.log(
|
|
7415
|
-
`${pluralItems(cnt)}: ${
|
|
7499
|
+
`${pluralItems(cnt)}: ${chalk70.cyan(oldOrigin)} \u2192 ${chalk70.cyan(newOrigin)}`
|
|
7416
7500
|
);
|
|
7417
7501
|
return promptConfirm(`Retag ${pluralItems(cnt)}?`);
|
|
7418
7502
|
}
|
|
7419
7503
|
|
|
7420
7504
|
// src/commands/backlog/move-repo/countByOrigin.ts
|
|
7421
|
-
import { count as count3, eq as
|
|
7505
|
+
import { count as count3, eq as eq23 } from "drizzle-orm";
|
|
7422
7506
|
async function countByOrigin(orm, origin) {
|
|
7423
|
-
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(
|
|
7507
|
+
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(eq23(items.origin, origin));
|
|
7424
7508
|
return cnt;
|
|
7425
7509
|
}
|
|
7426
7510
|
|
|
@@ -7444,7 +7528,7 @@ Pass the full origin.`
|
|
|
7444
7528
|
|
|
7445
7529
|
// src/commands/backlog/move-repo/index.ts
|
|
7446
7530
|
function fail3(message) {
|
|
7447
|
-
console.log(
|
|
7531
|
+
console.log(chalk71.red(message));
|
|
7448
7532
|
process.exitCode = 1;
|
|
7449
7533
|
}
|
|
7450
7534
|
async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
@@ -7460,12 +7544,12 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
7460
7544
|
}
|
|
7461
7545
|
const cnt = await countByOrigin(orm, oldOrigin);
|
|
7462
7546
|
if (!options2.yes && !await confirmMove(cnt, oldOrigin, newOrigin)) {
|
|
7463
|
-
console.log(
|
|
7547
|
+
console.log(chalk71.yellow("Move cancelled; no changes made."));
|
|
7464
7548
|
return;
|
|
7465
7549
|
}
|
|
7466
|
-
await orm.update(items).set({ origin: newOrigin }).where(
|
|
7550
|
+
await orm.update(items).set({ origin: newOrigin }).where(eq24(items.origin, oldOrigin));
|
|
7467
7551
|
console.log(
|
|
7468
|
-
|
|
7552
|
+
chalk71.green(
|
|
7469
7553
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
7470
7554
|
)
|
|
7471
7555
|
);
|
|
@@ -7494,14 +7578,14 @@ function registerPlanCommands(cmd) {
|
|
|
7494
7578
|
}
|
|
7495
7579
|
|
|
7496
7580
|
// src/commands/backlog/refine.ts
|
|
7497
|
-
import
|
|
7581
|
+
import chalk74 from "chalk";
|
|
7498
7582
|
import enquirer7 from "enquirer";
|
|
7499
7583
|
|
|
7500
7584
|
// src/commands/backlog/launchMode.ts
|
|
7501
7585
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7502
7586
|
|
|
7503
7587
|
// src/commands/backlog/handleLaunchSignal.ts
|
|
7504
|
-
import
|
|
7588
|
+
import chalk73 from "chalk";
|
|
7505
7589
|
|
|
7506
7590
|
// src/commands/backlog/surfaceCreatedItem.ts
|
|
7507
7591
|
async function surfaceCreatedItem(slashCommand, id2) {
|
|
@@ -7519,31 +7603,31 @@ async function surfaceCreatedItem(slashCommand, id2) {
|
|
|
7519
7603
|
}
|
|
7520
7604
|
|
|
7521
7605
|
// src/commands/backlog/tryRunById.ts
|
|
7522
|
-
import
|
|
7606
|
+
import chalk72 from "chalk";
|
|
7523
7607
|
async function tryRunById(id2, options2) {
|
|
7524
7608
|
const numericId = Number.parseInt(id2, 10);
|
|
7525
7609
|
const { orm } = await getReady();
|
|
7526
7610
|
const item = Number.isNaN(numericId) ? void 0 : await loadItem(orm, numericId);
|
|
7527
7611
|
if (!item) {
|
|
7528
|
-
console.log(
|
|
7612
|
+
console.log(chalk72.red(`Item #${id2} not found.`));
|
|
7529
7613
|
return false;
|
|
7530
7614
|
}
|
|
7531
7615
|
if (item.status === "done") {
|
|
7532
|
-
console.log(
|
|
7616
|
+
console.log(chalk72.red(`Item #${id2} is already done.`));
|
|
7533
7617
|
return false;
|
|
7534
7618
|
}
|
|
7535
7619
|
if (item.status === "wontdo") {
|
|
7536
|
-
console.log(
|
|
7620
|
+
console.log(chalk72.red(`Item #${id2} is marked won't do.`));
|
|
7537
7621
|
return false;
|
|
7538
7622
|
}
|
|
7539
7623
|
const hasDeps = (item.links ?? []).some((l) => l.type === "depends-on");
|
|
7540
7624
|
if (hasDeps && isBlocked(item, await loadItemSummaries(orm, getOrigin()))) {
|
|
7541
7625
|
console.log(
|
|
7542
|
-
|
|
7626
|
+
chalk72.red(`Item #${id2} is blocked by unresolved dependencies.`)
|
|
7543
7627
|
);
|
|
7544
7628
|
return false;
|
|
7545
7629
|
}
|
|
7546
|
-
console.log(
|
|
7630
|
+
console.log(chalk72.bold(`
|
|
7547
7631
|
Running backlog item #${id2}...
|
|
7548
7632
|
`));
|
|
7549
7633
|
await run2(id2, options2);
|
|
@@ -7561,7 +7645,7 @@ async function handleLaunchSignal(slashCommand, once) {
|
|
|
7561
7645
|
if (typeof signal.id === "string" && signal.id) {
|
|
7562
7646
|
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
7563
7647
|
}
|
|
7564
|
-
console.log(
|
|
7648
|
+
console.log(chalk73.bold("\nChaining into assist next...\n"));
|
|
7565
7649
|
await next({ allowEdits: true, once });
|
|
7566
7650
|
}
|
|
7567
7651
|
}
|
|
@@ -7572,9 +7656,10 @@ function buildSlashCommand(slashCommand, description) {
|
|
|
7572
7656
|
return trimmed ? `/${slashCommand} ${trimmed}` : `/${slashCommand}`;
|
|
7573
7657
|
}
|
|
7574
7658
|
async function launchMode(slashCommand, options2) {
|
|
7575
|
-
|
|
7659
|
+
const resumeSessionId = options2?.resumeSessionId;
|
|
7660
|
+
if (!resumeSessionId) pullIfConfigured();
|
|
7576
7661
|
process.env.ASSIST_SESSION_ID ??= String(process.pid);
|
|
7577
|
-
const claudeSessionId = randomUUID2();
|
|
7662
|
+
const claudeSessionId = resumeSessionId ?? randomUUID2();
|
|
7578
7663
|
emitActivity({
|
|
7579
7664
|
kind: "command",
|
|
7580
7665
|
name: slashCommand,
|
|
@@ -7583,8 +7668,8 @@ async function launchMode(slashCommand, options2) {
|
|
|
7583
7668
|
claudeSessionId
|
|
7584
7669
|
});
|
|
7585
7670
|
const { child, done: done2 } = spawnClaude(
|
|
7586
|
-
buildSlashCommand(slashCommand, options2?.description),
|
|
7587
|
-
{ allowEdits: true, sessionId: claudeSessionId }
|
|
7671
|
+
resumeSessionId ? buildResumePrompt() : buildSlashCommand(slashCommand, options2?.description),
|
|
7672
|
+
{ allowEdits: true, sessionId: claudeSessionId, resumeSessionId }
|
|
7588
7673
|
);
|
|
7589
7674
|
watchForMarker(child, { actOnDone: options2?.once });
|
|
7590
7675
|
const launched = await awaitClaude(done2, `/${slashCommand}`);
|
|
@@ -7600,12 +7685,12 @@ async function pickItemForRefine() {
|
|
|
7600
7685
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
7601
7686
|
);
|
|
7602
7687
|
if (active.length === 0) {
|
|
7603
|
-
console.log(
|
|
7688
|
+
console.log(chalk74.yellow("No active backlog items to refine."));
|
|
7604
7689
|
return void 0;
|
|
7605
7690
|
}
|
|
7606
7691
|
if (active.length === 1) {
|
|
7607
7692
|
const item = active[0];
|
|
7608
|
-
console.log(
|
|
7693
|
+
console.log(chalk74.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
7609
7694
|
return String(item.id);
|
|
7610
7695
|
}
|
|
7611
7696
|
const { selected } = await exitOnCancel(
|
|
@@ -7640,7 +7725,7 @@ function registerRefineCommand(cmd) {
|
|
|
7640
7725
|
}
|
|
7641
7726
|
|
|
7642
7727
|
// src/commands/backlog/rewindPhase.ts
|
|
7643
|
-
import
|
|
7728
|
+
import chalk75 from "chalk";
|
|
7644
7729
|
function validateRewind2(item, plan2, phaseNumber) {
|
|
7645
7730
|
if (phaseNumber < 1 || phaseNumber > plan2.length) {
|
|
7646
7731
|
return `Phase ${phaseNumber} does not exist. Valid range: 1\u2013${plan2.length}.`;
|
|
@@ -7657,13 +7742,13 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
7657
7742
|
const { orm } = await getReady();
|
|
7658
7743
|
const item = await loadItem(orm, Number.parseInt(id2, 10));
|
|
7659
7744
|
if (!item) {
|
|
7660
|
-
console.log(
|
|
7745
|
+
console.log(chalk75.red(`Item #${id2} not found.`));
|
|
7661
7746
|
return;
|
|
7662
7747
|
}
|
|
7663
7748
|
const plan2 = resolveRewindPlan(item);
|
|
7664
7749
|
const error = validateRewind2(item, plan2, phaseNumber);
|
|
7665
7750
|
if (error) {
|
|
7666
|
-
console.log(
|
|
7751
|
+
console.log(chalk75.red(error));
|
|
7667
7752
|
process.exitCode = 1;
|
|
7668
7753
|
return;
|
|
7669
7754
|
}
|
|
@@ -7681,7 +7766,7 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
7681
7766
|
targetPhase: phaseIndex
|
|
7682
7767
|
});
|
|
7683
7768
|
console.log(
|
|
7684
|
-
|
|
7769
|
+
chalk75.green(`Rewound item #${id2} to phase ${phaseNumber} (${phaseName}).`)
|
|
7685
7770
|
);
|
|
7686
7771
|
}
|
|
7687
7772
|
|
|
@@ -7707,22 +7792,22 @@ function registerRunCommand(cmd) {
|
|
|
7707
7792
|
}
|
|
7708
7793
|
|
|
7709
7794
|
// src/commands/backlog/search/index.ts
|
|
7710
|
-
import
|
|
7795
|
+
import chalk76 from "chalk";
|
|
7711
7796
|
async function search(query) {
|
|
7712
7797
|
const items2 = await searchBacklog(query);
|
|
7713
7798
|
if (items2.length === 0) {
|
|
7714
|
-
console.log(
|
|
7799
|
+
console.log(chalk76.dim(`No items matching "${query}".`));
|
|
7715
7800
|
return;
|
|
7716
7801
|
}
|
|
7717
7802
|
console.log(
|
|
7718
|
-
|
|
7803
|
+
chalk76.dim(
|
|
7719
7804
|
`${items2.length} item${items2.length === 1 ? "" : "s"} matching "${query}":
|
|
7720
7805
|
`
|
|
7721
7806
|
)
|
|
7722
7807
|
);
|
|
7723
7808
|
for (const item of items2) {
|
|
7724
7809
|
console.log(
|
|
7725
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
7810
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk76.dim(`#${item.id}`)} ${item.name}`
|
|
7726
7811
|
);
|
|
7727
7812
|
}
|
|
7728
7813
|
}
|
|
@@ -7733,16 +7818,16 @@ function registerSearchCommand(cmd) {
|
|
|
7733
7818
|
}
|
|
7734
7819
|
|
|
7735
7820
|
// src/commands/backlog/delete/index.ts
|
|
7736
|
-
import
|
|
7821
|
+
import chalk77 from "chalk";
|
|
7737
7822
|
async function del(id2) {
|
|
7738
7823
|
const name = await removeItem(id2);
|
|
7739
7824
|
if (name) {
|
|
7740
|
-
console.log(
|
|
7825
|
+
console.log(chalk77.green(`Deleted item #${id2}: ${name}`));
|
|
7741
7826
|
}
|
|
7742
7827
|
}
|
|
7743
7828
|
|
|
7744
7829
|
// src/commands/backlog/done/index.ts
|
|
7745
|
-
import
|
|
7830
|
+
import chalk78 from "chalk";
|
|
7746
7831
|
async function done(id2, summary) {
|
|
7747
7832
|
const found = await findOneItem(id2);
|
|
7748
7833
|
if (!found) return;
|
|
@@ -7752,12 +7837,12 @@ async function done(id2, summary) {
|
|
|
7752
7837
|
const pending = item.plan.slice(completedCount);
|
|
7753
7838
|
if (pending.length > 0) {
|
|
7754
7839
|
console.log(
|
|
7755
|
-
|
|
7840
|
+
chalk78.red(
|
|
7756
7841
|
`Cannot complete item #${id2}: ${pending.length} pending phase(s):`
|
|
7757
7842
|
)
|
|
7758
7843
|
);
|
|
7759
7844
|
for (const phase of pending) {
|
|
7760
|
-
console.log(
|
|
7845
|
+
console.log(chalk78.yellow(` - ${phase.name}`));
|
|
7761
7846
|
}
|
|
7762
7847
|
process.exitCode = 1;
|
|
7763
7848
|
return;
|
|
@@ -7768,18 +7853,18 @@ async function done(id2, summary) {
|
|
|
7768
7853
|
const phase = item.currentPhase ?? 1;
|
|
7769
7854
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
7770
7855
|
}
|
|
7771
|
-
console.log(
|
|
7856
|
+
console.log(chalk78.green(`Completed item #${id2}: ${item.name}`));
|
|
7772
7857
|
}
|
|
7773
7858
|
|
|
7774
7859
|
// src/commands/backlog/star/index.ts
|
|
7775
|
-
import
|
|
7860
|
+
import chalk80 from "chalk";
|
|
7776
7861
|
|
|
7777
7862
|
// src/commands/backlog/setStarred.ts
|
|
7778
|
-
import
|
|
7863
|
+
import chalk79 from "chalk";
|
|
7779
7864
|
async function setStarred(id2, starred) {
|
|
7780
7865
|
const { orm } = await getReady();
|
|
7781
7866
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
7782
|
-
if (name === void 0) console.log(
|
|
7867
|
+
if (name === void 0) console.log(chalk79.red(`Item #${id2} not found.`));
|
|
7783
7868
|
return name;
|
|
7784
7869
|
}
|
|
7785
7870
|
|
|
@@ -7787,45 +7872,45 @@ async function setStarred(id2, starred) {
|
|
|
7787
7872
|
async function star(id2) {
|
|
7788
7873
|
const name = await setStarred(id2, true);
|
|
7789
7874
|
if (name) {
|
|
7790
|
-
console.log(
|
|
7875
|
+
console.log(chalk80.green(`Starred item #${id2}: ${name}`));
|
|
7791
7876
|
}
|
|
7792
7877
|
}
|
|
7793
7878
|
|
|
7794
7879
|
// src/commands/backlog/start/index.ts
|
|
7795
|
-
import
|
|
7880
|
+
import chalk81 from "chalk";
|
|
7796
7881
|
async function start(id2) {
|
|
7797
7882
|
const name = await setStatus(id2, "in-progress");
|
|
7798
7883
|
if (name) {
|
|
7799
|
-
console.log(
|
|
7884
|
+
console.log(chalk81.green(`Started item #${id2}: ${name}`));
|
|
7800
7885
|
}
|
|
7801
7886
|
}
|
|
7802
7887
|
|
|
7803
7888
|
// src/commands/backlog/stop/index.ts
|
|
7804
|
-
import
|
|
7805
|
-
import { and as and7, eq as
|
|
7889
|
+
import chalk82 from "chalk";
|
|
7890
|
+
import { and as and7, eq as eq25 } from "drizzle-orm";
|
|
7806
7891
|
async function stop() {
|
|
7807
7892
|
const { orm } = await getReady();
|
|
7808
|
-
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and7(
|
|
7893
|
+
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and7(eq25(items.status, "in-progress"), eq25(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
7809
7894
|
if (stopped.length === 0) {
|
|
7810
|
-
console.log(
|
|
7895
|
+
console.log(chalk82.yellow("No in-progress items to stop."));
|
|
7811
7896
|
return;
|
|
7812
7897
|
}
|
|
7813
7898
|
for (const item of stopped) {
|
|
7814
|
-
console.log(
|
|
7899
|
+
console.log(chalk82.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
7815
7900
|
}
|
|
7816
7901
|
}
|
|
7817
7902
|
|
|
7818
7903
|
// src/commands/backlog/unstar/index.ts
|
|
7819
|
-
import
|
|
7904
|
+
import chalk83 from "chalk";
|
|
7820
7905
|
async function unstar(id2) {
|
|
7821
7906
|
const name = await setStarred(id2, false);
|
|
7822
7907
|
if (name) {
|
|
7823
|
-
console.log(
|
|
7908
|
+
console.log(chalk83.green(`Unstarred item #${id2}: ${name}`));
|
|
7824
7909
|
}
|
|
7825
7910
|
}
|
|
7826
7911
|
|
|
7827
7912
|
// src/commands/backlog/wontdo/index.ts
|
|
7828
|
-
import
|
|
7913
|
+
import chalk84 from "chalk";
|
|
7829
7914
|
async function wontdo(id2, reason) {
|
|
7830
7915
|
const found = await findOneItem(id2);
|
|
7831
7916
|
if (!found) return;
|
|
@@ -7835,7 +7920,7 @@ async function wontdo(id2, reason) {
|
|
|
7835
7920
|
const phase = item.currentPhase ?? 1;
|
|
7836
7921
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
7837
7922
|
}
|
|
7838
|
-
console.log(
|
|
7923
|
+
console.log(chalk84.red(`Won't do item #${id2}: ${item.name}`));
|
|
7839
7924
|
}
|
|
7840
7925
|
|
|
7841
7926
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -7850,22 +7935,22 @@ function registerStatusCommands(cmd) {
|
|
|
7850
7935
|
}
|
|
7851
7936
|
|
|
7852
7937
|
// src/commands/backlog/removePhase.ts
|
|
7853
|
-
import
|
|
7854
|
-
import { and as and10, eq as
|
|
7938
|
+
import chalk86 from "chalk";
|
|
7939
|
+
import { and as and10, eq as eq28 } from "drizzle-orm";
|
|
7855
7940
|
|
|
7856
7941
|
// src/commands/backlog/findPhase.ts
|
|
7857
|
-
import
|
|
7858
|
-
import { and as and8, count as count4, eq as
|
|
7942
|
+
import chalk85 from "chalk";
|
|
7943
|
+
import { and as and8, count as count4, eq as eq26 } from "drizzle-orm";
|
|
7859
7944
|
async function findPhase(id2, phase) {
|
|
7860
7945
|
const found = await findOneItem(id2);
|
|
7861
7946
|
if (!found) return void 0;
|
|
7862
7947
|
const { orm, item } = found;
|
|
7863
7948
|
const itemId = item.id;
|
|
7864
7949
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
7865
|
-
const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and8(
|
|
7950
|
+
const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and8(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
|
|
7866
7951
|
if (!row || row.cnt === 0) {
|
|
7867
7952
|
console.log(
|
|
7868
|
-
|
|
7953
|
+
chalk85.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
7869
7954
|
);
|
|
7870
7955
|
process.exitCode = 1;
|
|
7871
7956
|
return void 0;
|
|
@@ -7874,14 +7959,14 @@ async function findPhase(id2, phase) {
|
|
|
7874
7959
|
}
|
|
7875
7960
|
|
|
7876
7961
|
// src/commands/backlog/reindexPhases.ts
|
|
7877
|
-
import { and as and9, asc as asc6, count as count5, eq as
|
|
7962
|
+
import { and as and9, asc as asc6, count as count5, eq as eq27 } from "drizzle-orm";
|
|
7878
7963
|
async function reindexPhases(db, itemId) {
|
|
7879
|
-
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
7964
|
+
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq27(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
|
|
7880
7965
|
for (let i = 0; i < remaining.length; i++) {
|
|
7881
7966
|
const oldIdx = remaining[i].idx;
|
|
7882
7967
|
if (oldIdx === i) continue;
|
|
7883
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(and9(
|
|
7884
|
-
await db.update(planPhases).set({ idx: i }).where(and9(
|
|
7968
|
+
await db.update(planTasks).set({ phaseIdx: i }).where(and9(eq27(planTasks.itemId, itemId), eq27(planTasks.phaseIdx, oldIdx)));
|
|
7969
|
+
await db.update(planPhases).set({ idx: i }).where(and9(eq27(planPhases.itemId, itemId), eq27(planPhases.idx, oldIdx)));
|
|
7885
7970
|
}
|
|
7886
7971
|
}
|
|
7887
7972
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -7889,13 +7974,13 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
7889
7974
|
if (currentPhase === void 0) return;
|
|
7890
7975
|
const currentIdx = currentPhase - 1;
|
|
7891
7976
|
if (removedIdx < currentIdx) {
|
|
7892
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
7977
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq27(items.id, item.id));
|
|
7893
7978
|
return;
|
|
7894
7979
|
}
|
|
7895
7980
|
if (removedIdx !== currentIdx) return;
|
|
7896
|
-
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(
|
|
7981
|
+
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq27(planPhases.itemId, item.id));
|
|
7897
7982
|
const cnt = row?.cnt ?? 0;
|
|
7898
|
-
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(
|
|
7983
|
+
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq27(items.id, item.id));
|
|
7899
7984
|
}
|
|
7900
7985
|
|
|
7901
7986
|
// src/commands/backlog/removePhase.ts
|
|
@@ -7905,20 +7990,20 @@ async function removePhase(id2, phase) {
|
|
|
7905
7990
|
const { item, orm, itemId, phaseIdx } = found;
|
|
7906
7991
|
await orm.transaction(async (tx) => {
|
|
7907
7992
|
await tx.delete(planTasks).where(
|
|
7908
|
-
and10(
|
|
7993
|
+
and10(eq28(planTasks.itemId, itemId), eq28(planTasks.phaseIdx, phaseIdx))
|
|
7909
7994
|
);
|
|
7910
|
-
await tx.delete(planPhases).where(and10(
|
|
7995
|
+
await tx.delete(planPhases).where(and10(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx)));
|
|
7911
7996
|
await reindexPhases(tx, itemId);
|
|
7912
7997
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
7913
7998
|
});
|
|
7914
7999
|
console.log(
|
|
7915
|
-
|
|
8000
|
+
chalk86.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
7916
8001
|
);
|
|
7917
8002
|
}
|
|
7918
8003
|
|
|
7919
8004
|
// src/commands/backlog/update/index.ts
|
|
7920
|
-
import
|
|
7921
|
-
import { eq as
|
|
8005
|
+
import chalk88 from "chalk";
|
|
8006
|
+
import { eq as eq29 } from "drizzle-orm";
|
|
7922
8007
|
|
|
7923
8008
|
// src/commands/backlog/update/parseListIndex.ts
|
|
7924
8009
|
function parseListIndex(raw, length, label2) {
|
|
@@ -7993,16 +8078,16 @@ function applyAcMutations(current, options2) {
|
|
|
7993
8078
|
}
|
|
7994
8079
|
|
|
7995
8080
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7996
|
-
import
|
|
8081
|
+
import chalk87 from "chalk";
|
|
7997
8082
|
function buildUpdateValues(options2) {
|
|
7998
8083
|
const { name, desc: desc6, type, ac } = options2;
|
|
7999
8084
|
if (!name && !desc6 && !type && !ac) {
|
|
8000
|
-
console.log(
|
|
8085
|
+
console.log(chalk87.red("Nothing to update. Provide at least one flag."));
|
|
8001
8086
|
process.exitCode = 1;
|
|
8002
8087
|
return void 0;
|
|
8003
8088
|
}
|
|
8004
8089
|
if (type && type !== "story" && type !== "bug") {
|
|
8005
|
-
console.log(
|
|
8090
|
+
console.log(chalk87.red('Invalid type. Must be "story" or "bug".'));
|
|
8006
8091
|
process.exitCode = 1;
|
|
8007
8092
|
return void 0;
|
|
8008
8093
|
}
|
|
@@ -8035,14 +8120,14 @@ async function update(id2, options2) {
|
|
|
8035
8120
|
if (hasAcMutations(options2)) {
|
|
8036
8121
|
if (options2.ac) {
|
|
8037
8122
|
console.log(
|
|
8038
|
-
|
|
8123
|
+
chalk88.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8039
8124
|
);
|
|
8040
8125
|
process.exitCode = 1;
|
|
8041
8126
|
return;
|
|
8042
8127
|
}
|
|
8043
8128
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8044
8129
|
if (!mutation.ok) {
|
|
8045
|
-
console.log(
|
|
8130
|
+
console.log(chalk88.red(mutation.error));
|
|
8046
8131
|
process.exitCode = 1;
|
|
8047
8132
|
return;
|
|
8048
8133
|
}
|
|
@@ -8052,30 +8137,30 @@ async function update(id2, options2) {
|
|
|
8052
8137
|
if (!built) return;
|
|
8053
8138
|
const { orm } = found;
|
|
8054
8139
|
const itemId = found.item.id;
|
|
8055
|
-
await orm.update(items).set(built.set).where(
|
|
8056
|
-
console.log(
|
|
8140
|
+
await orm.update(items).set(built.set).where(eq29(items.id, itemId));
|
|
8141
|
+
console.log(chalk88.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
8057
8142
|
}
|
|
8058
8143
|
|
|
8059
8144
|
// src/commands/backlog/updatePhase.ts
|
|
8060
|
-
import
|
|
8145
|
+
import chalk89 from "chalk";
|
|
8061
8146
|
|
|
8062
8147
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8063
|
-
import { and as and11, eq as
|
|
8148
|
+
import { and as and11, eq as eq30 } from "drizzle-orm";
|
|
8064
8149
|
async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
|
|
8065
8150
|
await orm.transaction(async (tx) => {
|
|
8066
8151
|
if (fields.name) {
|
|
8067
8152
|
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
8068
|
-
and11(
|
|
8153
|
+
and11(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8069
8154
|
);
|
|
8070
8155
|
}
|
|
8071
8156
|
if (fields.manualCheck) {
|
|
8072
8157
|
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
8073
|
-
and11(
|
|
8158
|
+
and11(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8074
8159
|
);
|
|
8075
8160
|
}
|
|
8076
8161
|
if (fields.task) {
|
|
8077
8162
|
await tx.delete(planTasks).where(
|
|
8078
|
-
and11(
|
|
8163
|
+
and11(eq30(planTasks.itemId, itemId), eq30(planTasks.phaseIdx, phaseIdx))
|
|
8079
8164
|
);
|
|
8080
8165
|
if (fields.task.length) {
|
|
8081
8166
|
await tx.insert(planTasks).values(
|
|
@@ -8161,7 +8246,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8161
8246
|
const { item, orm, itemId, phaseIdx } = found;
|
|
8162
8247
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
8163
8248
|
if (!resolved.ok) {
|
|
8164
|
-
console.log(
|
|
8249
|
+
console.log(chalk89.red(resolved.error));
|
|
8165
8250
|
process.exitCode = 1;
|
|
8166
8251
|
return;
|
|
8167
8252
|
}
|
|
@@ -8173,7 +8258,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8173
8258
|
manualCheck && "manual checks"
|
|
8174
8259
|
].filter(Boolean).join(", ");
|
|
8175
8260
|
console.log(
|
|
8176
|
-
|
|
8261
|
+
chalk89.green(
|
|
8177
8262
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8178
8263
|
)
|
|
8179
8264
|
);
|
|
@@ -8228,7 +8313,8 @@ var registrars = [
|
|
|
8228
8313
|
registerUpdateCommands,
|
|
8229
8314
|
registerExportCommand,
|
|
8230
8315
|
registerImportCommand,
|
|
8231
|
-
registerMoveRepoCommand
|
|
8316
|
+
registerMoveRepoCommand,
|
|
8317
|
+
registerAssociateJiraCommand
|
|
8232
8318
|
];
|
|
8233
8319
|
function registerBacklog(program2) {
|
|
8234
8320
|
const cmd = program2.command("backlog").description("Manage a backlog of work items").option("--dir <path>", "Override directory for backlog file discovery").option("--no-open", "Do not open a browser on startup").hook("preAction", (thisCommand) => {
|
|
@@ -8878,7 +8964,7 @@ import { homedir as homedir10 } from "os";
|
|
|
8878
8964
|
import { join as join24 } from "path";
|
|
8879
8965
|
|
|
8880
8966
|
// src/shared/checkCliAvailable.ts
|
|
8881
|
-
import { execSync as
|
|
8967
|
+
import { execSync as execSync23 } from "child_process";
|
|
8882
8968
|
function checkCliAvailable(cli) {
|
|
8883
8969
|
const binary = cli.split(/\s+/)[0];
|
|
8884
8970
|
const opts = {
|
|
@@ -8886,11 +8972,11 @@ function checkCliAvailable(cli) {
|
|
|
8886
8972
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8887
8973
|
};
|
|
8888
8974
|
try {
|
|
8889
|
-
|
|
8975
|
+
execSync23(`command -v ${binary}`, opts);
|
|
8890
8976
|
return true;
|
|
8891
8977
|
} catch {
|
|
8892
8978
|
try {
|
|
8893
|
-
|
|
8979
|
+
execSync23(`where ${binary}`, opts);
|
|
8894
8980
|
return true;
|
|
8895
8981
|
} catch {
|
|
8896
8982
|
return false;
|
|
@@ -8906,11 +8992,11 @@ function assertCliExists(cli) {
|
|
|
8906
8992
|
}
|
|
8907
8993
|
|
|
8908
8994
|
// src/commands/permitCliReads/colorize.ts
|
|
8909
|
-
import
|
|
8995
|
+
import chalk90 from "chalk";
|
|
8910
8996
|
function colorize(plainOutput) {
|
|
8911
8997
|
return plainOutput.split("\n").map((line) => {
|
|
8912
|
-
if (line.startsWith(" R ")) return
|
|
8913
|
-
if (line.startsWith(" W ")) return
|
|
8998
|
+
if (line.startsWith(" R ")) return chalk90.green(line);
|
|
8999
|
+
if (line.startsWith(" W ")) return chalk90.red(line);
|
|
8914
9000
|
return line;
|
|
8915
9001
|
}).join("\n");
|
|
8916
9002
|
}
|
|
@@ -9208,7 +9294,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
9208
9294
|
}
|
|
9209
9295
|
|
|
9210
9296
|
// src/commands/deny/denyAdd.ts
|
|
9211
|
-
import
|
|
9297
|
+
import chalk91 from "chalk";
|
|
9212
9298
|
|
|
9213
9299
|
// src/commands/deny/loadDenyConfig.ts
|
|
9214
9300
|
function loadDenyConfig(global) {
|
|
@@ -9228,16 +9314,16 @@ function loadDenyConfig(global) {
|
|
|
9228
9314
|
function denyAdd(pattern2, message, options2) {
|
|
9229
9315
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9230
9316
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
9231
|
-
console.log(
|
|
9317
|
+
console.log(chalk91.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
9232
9318
|
return;
|
|
9233
9319
|
}
|
|
9234
9320
|
deny.push({ pattern: pattern2, message });
|
|
9235
9321
|
saveDeny(deny);
|
|
9236
|
-
console.log(
|
|
9322
|
+
console.log(chalk91.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
9237
9323
|
}
|
|
9238
9324
|
|
|
9239
9325
|
// src/commands/deny/denyList.ts
|
|
9240
|
-
import
|
|
9326
|
+
import chalk92 from "chalk";
|
|
9241
9327
|
function denyList() {
|
|
9242
9328
|
const globalRaw = loadGlobalConfigRaw();
|
|
9243
9329
|
const projectRaw = loadProjectConfig();
|
|
@@ -9248,7 +9334,7 @@ function denyList() {
|
|
|
9248
9334
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
9249
9335
|
);
|
|
9250
9336
|
if (!merged || merged.length === 0) {
|
|
9251
|
-
console.log(
|
|
9337
|
+
console.log(chalk92.dim("No deny rules configured."));
|
|
9252
9338
|
return;
|
|
9253
9339
|
}
|
|
9254
9340
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -9256,23 +9342,23 @@ function denyList() {
|
|
|
9256
9342
|
for (const rule of merged) {
|
|
9257
9343
|
const inProject = projectPatterns.has(rule.pattern);
|
|
9258
9344
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
9259
|
-
const label2 = inProject && inGlobal ?
|
|
9260
|
-
console.log(`${
|
|
9345
|
+
const label2 = inProject && inGlobal ? chalk92.dim(" (project, overrides global)") : inGlobal ? chalk92.dim(" (global)") : "";
|
|
9346
|
+
console.log(`${chalk92.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
9261
9347
|
}
|
|
9262
9348
|
}
|
|
9263
9349
|
|
|
9264
9350
|
// src/commands/deny/denyRemove.ts
|
|
9265
|
-
import
|
|
9351
|
+
import chalk93 from "chalk";
|
|
9266
9352
|
function denyRemove(pattern2, options2) {
|
|
9267
9353
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9268
9354
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
9269
9355
|
if (index3 === -1) {
|
|
9270
|
-
console.log(
|
|
9356
|
+
console.log(chalk93.yellow(`No deny rule found for: ${pattern2}`));
|
|
9271
9357
|
return;
|
|
9272
9358
|
}
|
|
9273
9359
|
deny.splice(index3, 1);
|
|
9274
9360
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
9275
|
-
console.log(
|
|
9361
|
+
console.log(chalk93.green(`Removed deny rule: ${pattern2}`));
|
|
9276
9362
|
}
|
|
9277
9363
|
|
|
9278
9364
|
// src/commands/registerDeny.ts
|
|
@@ -9302,7 +9388,7 @@ function registerCliHook(program2) {
|
|
|
9302
9388
|
|
|
9303
9389
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9304
9390
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9305
|
-
import
|
|
9391
|
+
import chalk94 from "chalk";
|
|
9306
9392
|
|
|
9307
9393
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
9308
9394
|
import { homedir as homedir11 } from "os";
|
|
@@ -9352,12 +9438,12 @@ function codeCommentConfirm(pin) {
|
|
|
9352
9438
|
sweepRestrictedDir();
|
|
9353
9439
|
const state = readPinState(pin);
|
|
9354
9440
|
if (!state) {
|
|
9355
|
-
console.error(
|
|
9441
|
+
console.error(chalk94.red(`No pending comment for pin: ${pin}`));
|
|
9356
9442
|
process.exitCode = 1;
|
|
9357
9443
|
return;
|
|
9358
9444
|
}
|
|
9359
9445
|
if (!existsSync27(state.file)) {
|
|
9360
|
-
console.error(
|
|
9446
|
+
console.error(chalk94.red(`Target file no longer exists: ${state.file}`));
|
|
9361
9447
|
process.exitCode = 1;
|
|
9362
9448
|
return;
|
|
9363
9449
|
}
|
|
@@ -9366,7 +9452,7 @@ function codeCommentConfirm(pin) {
|
|
|
9366
9452
|
const index3 = state.line - 1;
|
|
9367
9453
|
if (index3 > lines.length) {
|
|
9368
9454
|
console.error(
|
|
9369
|
-
|
|
9455
|
+
chalk94.red(
|
|
9370
9456
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
9371
9457
|
)
|
|
9372
9458
|
);
|
|
@@ -9379,12 +9465,12 @@ function codeCommentConfirm(pin) {
|
|
|
9379
9465
|
writeFileSync22(state.file, lines.join("\n"));
|
|
9380
9466
|
unlinkSync8(getPinStatePath(pin));
|
|
9381
9467
|
console.log(
|
|
9382
|
-
|
|
9468
|
+
chalk94.green(`Inserted "// ${state.text}" at ${state.file}:${state.line}`)
|
|
9383
9469
|
);
|
|
9384
9470
|
}
|
|
9385
9471
|
|
|
9386
9472
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9387
|
-
import
|
|
9473
|
+
import chalk95 from "chalk";
|
|
9388
9474
|
|
|
9389
9475
|
// src/commands/codeComment/validateCommentText.ts
|
|
9390
9476
|
var MAX_COMMENT_LENGTH = 50;
|
|
@@ -9435,26 +9521,26 @@ function generatePin() {
|
|
|
9435
9521
|
function codeCommentSet(file, line, text6) {
|
|
9436
9522
|
const lineNumber = Number.parseInt(line, 10);
|
|
9437
9523
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
9438
|
-
console.error(
|
|
9524
|
+
console.error(chalk95.red(`Invalid line number: ${line}`));
|
|
9439
9525
|
process.exitCode = 1;
|
|
9440
9526
|
return;
|
|
9441
9527
|
}
|
|
9442
9528
|
const validation = validateCommentText(text6);
|
|
9443
9529
|
if (!validation.ok) {
|
|
9444
|
-
console.error(
|
|
9445
|
-
console.error(
|
|
9530
|
+
console.error(chalk95.red(`Refused: ${validation.reason}`));
|
|
9531
|
+
console.error(chalk95.red("No pin issued."));
|
|
9446
9532
|
process.exitCode = 1;
|
|
9447
9533
|
return;
|
|
9448
9534
|
}
|
|
9449
9535
|
console.error(
|
|
9450
|
-
|
|
9536
|
+
chalk95.yellow.bold(
|
|
9451
9537
|
"THIS IS YOUR LAST CHANCE TO RECONSIDER BEFORE INVOLVING A HUMAN.\nRequesting this pin pages a real person to approve a comment. DO NOT WASTE THEIR TIME.\nYou had BETTER BE RIGHT that this comment is genuinely necessary.\n\nComments are a last resort, not a habit. Almost every comment you reach for is a sign\nthe code should be clearer instead. Before a human is pulled in, ask whether a better\nname, a smaller function, or a test would make the comment redundant. ONLY if you are\ncertain this one line earns its keep should you proceed to the confirm step below."
|
|
9452
9538
|
)
|
|
9453
9539
|
);
|
|
9454
9540
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
9455
9541
|
if (!delivered) {
|
|
9456
9542
|
console.error(
|
|
9457
|
-
|
|
9543
|
+
chalk95.red(
|
|
9458
9544
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
9459
9545
|
)
|
|
9460
9546
|
);
|
|
@@ -9464,7 +9550,7 @@ function codeCommentSet(file, line, text6) {
|
|
|
9464
9550
|
console.log(
|
|
9465
9551
|
`A confirmation pin was sent to your desktop notifications.
|
|
9466
9552
|
To insert "// ${validation.text}" at ${file}:${lineNumber}, run:
|
|
9467
|
-
${
|
|
9553
|
+
${chalk95.cyan(" assist code-comment confirm <PIN>")}
|
|
9468
9554
|
using the pin from that notification.`
|
|
9469
9555
|
);
|
|
9470
9556
|
}
|
|
@@ -9484,15 +9570,15 @@ function registerCodeComment(parent) {
|
|
|
9484
9570
|
}
|
|
9485
9571
|
|
|
9486
9572
|
// src/commands/complexity/analyze.ts
|
|
9487
|
-
import
|
|
9573
|
+
import chalk104 from "chalk";
|
|
9488
9574
|
|
|
9489
9575
|
// src/commands/complexity/cyclomatic.ts
|
|
9490
|
-
import
|
|
9576
|
+
import chalk97 from "chalk";
|
|
9491
9577
|
|
|
9492
9578
|
// src/commands/complexity/shared/index.ts
|
|
9493
9579
|
import fs16 from "fs";
|
|
9494
9580
|
import path21 from "path";
|
|
9495
|
-
import
|
|
9581
|
+
import chalk96 from "chalk";
|
|
9496
9582
|
import ts5 from "typescript";
|
|
9497
9583
|
|
|
9498
9584
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -9743,7 +9829,7 @@ function createSourceFromFile(filePath) {
|
|
|
9743
9829
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
9744
9830
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
9745
9831
|
if (files.length === 0) {
|
|
9746
|
-
console.log(
|
|
9832
|
+
console.log(chalk96.yellow("No files found matching pattern"));
|
|
9747
9833
|
return void 0;
|
|
9748
9834
|
}
|
|
9749
9835
|
return callback(files);
|
|
@@ -9776,11 +9862,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9776
9862
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
9777
9863
|
for (const { file, name, complexity } of results) {
|
|
9778
9864
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
9779
|
-
const color = exceedsThreshold ?
|
|
9780
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
9865
|
+
const color = exceedsThreshold ? chalk97.red : chalk97.white;
|
|
9866
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk97.cyan(complexity)}`);
|
|
9781
9867
|
}
|
|
9782
9868
|
console.log(
|
|
9783
|
-
|
|
9869
|
+
chalk97.dim(
|
|
9784
9870
|
`
|
|
9785
9871
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
9786
9872
|
)
|
|
@@ -9792,7 +9878,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
9792
9878
|
}
|
|
9793
9879
|
|
|
9794
9880
|
// src/commands/complexity/halstead.ts
|
|
9795
|
-
import
|
|
9881
|
+
import chalk98 from "chalk";
|
|
9796
9882
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
9797
9883
|
withSourceFiles(pattern2, (files) => {
|
|
9798
9884
|
const results = [];
|
|
@@ -9807,13 +9893,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9807
9893
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
9808
9894
|
for (const { file, name, metrics } of results) {
|
|
9809
9895
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
9810
|
-
const color = exceedsThreshold ?
|
|
9896
|
+
const color = exceedsThreshold ? chalk98.red : chalk98.white;
|
|
9811
9897
|
console.log(
|
|
9812
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
9898
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk98.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk98.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk98.magenta(metrics.effort.toFixed(1))}`
|
|
9813
9899
|
);
|
|
9814
9900
|
}
|
|
9815
9901
|
console.log(
|
|
9816
|
-
|
|
9902
|
+
chalk98.dim(
|
|
9817
9903
|
`
|
|
9818
9904
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
9819
9905
|
)
|
|
@@ -9825,27 +9911,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
9825
9911
|
}
|
|
9826
9912
|
|
|
9827
9913
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
9828
|
-
import
|
|
9914
|
+
import chalk101 from "chalk";
|
|
9829
9915
|
|
|
9830
9916
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
9831
|
-
import
|
|
9917
|
+
import chalk99 from "chalk";
|
|
9832
9918
|
function formatResultLine(entry, failing) {
|
|
9833
9919
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
9834
|
-
const name = failing ?
|
|
9835
|
-
const suffix = override !== void 0 ?
|
|
9836
|
-
return `${name} \u2192 avg: ${
|
|
9920
|
+
const name = failing ? chalk99.red(file) : chalk99.white(file);
|
|
9921
|
+
const suffix = override !== void 0 ? chalk99.magenta(` (override: ${override})`) : "";
|
|
9922
|
+
return `${name} \u2192 avg: ${chalk99.cyan(avgMaintainability.toFixed(1))}, min: ${chalk99.yellow(minMaintainability.toFixed(1))}${suffix}`;
|
|
9837
9923
|
}
|
|
9838
9924
|
|
|
9839
9925
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
9840
|
-
import
|
|
9926
|
+
import chalk100 from "chalk";
|
|
9841
9927
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
9842
9928
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
9843
9929
|
console.error(
|
|
9844
|
-
|
|
9930
|
+
chalk100.red(
|
|
9845
9931
|
`
|
|
9846
9932
|
Fail: ${failingCount} file(s) below threshold${thresholdLabel} (files marked "(override: N)" were judged against their own marker). Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
9847
9933
|
|
|
9848
|
-
\u26A0\uFE0F ${
|
|
9934
|
+
\u26A0\uFE0F ${chalk100.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
|
|
9849
9935
|
|
|
9850
9936
|
The score is a property of the whole file, not your diff: any existing logic counts, so the fix is to shrink the file \u2014 not to revert or micro-optimize the lines you just changed. Identify the largest cohesive responsibility (often the biggest function, or a related group of functions) and move it to a new file with 'assist refactor extract'. Run 'assist complexity <file>' for per-function metrics only to locate that responsibility, not to tweak individual lines.`
|
|
9851
9937
|
)
|
|
@@ -9857,7 +9943,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
9857
9943
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
9858
9944
|
if (!gating) {
|
|
9859
9945
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
9860
|
-
console.log(
|
|
9946
|
+
console.log(chalk101.dim(`
|
|
9861
9947
|
Analyzed ${results.length} files`));
|
|
9862
9948
|
return;
|
|
9863
9949
|
}
|
|
@@ -9866,7 +9952,7 @@ Analyzed ${results.length} files`));
|
|
|
9866
9952
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
9867
9953
|
});
|
|
9868
9954
|
if (failing.length === 0) {
|
|
9869
|
-
console.log(
|
|
9955
|
+
console.log(chalk101.green("All files pass maintainability threshold"));
|
|
9870
9956
|
} else {
|
|
9871
9957
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
9872
9958
|
}
|
|
@@ -9875,7 +9961,7 @@ Analyzed ${results.length} files`));
|
|
|
9875
9961
|
);
|
|
9876
9962
|
for (const entry of passingOverrides)
|
|
9877
9963
|
console.log(formatResultLine(entry, false));
|
|
9878
|
-
console.log(
|
|
9964
|
+
console.log(chalk101.dim(`
|
|
9879
9965
|
Analyzed ${results.length} files`));
|
|
9880
9966
|
if (failing.length > 0) {
|
|
9881
9967
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -9884,10 +9970,10 @@ Analyzed ${results.length} files`));
|
|
|
9884
9970
|
}
|
|
9885
9971
|
|
|
9886
9972
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
9887
|
-
import
|
|
9973
|
+
import chalk102 from "chalk";
|
|
9888
9974
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
9889
9975
|
function printMaintainabilityFormula() {
|
|
9890
|
-
console.log(
|
|
9976
|
+
console.log(chalk102.dim(MI_FORMULA));
|
|
9891
9977
|
}
|
|
9892
9978
|
|
|
9893
9979
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -9963,7 +10049,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9963
10049
|
|
|
9964
10050
|
// src/commands/complexity/sloc.ts
|
|
9965
10051
|
import fs18 from "fs";
|
|
9966
|
-
import
|
|
10052
|
+
import chalk103 from "chalk";
|
|
9967
10053
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
9968
10054
|
withSourceFiles(pattern2, (files) => {
|
|
9969
10055
|
const results = [];
|
|
@@ -9979,12 +10065,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9979
10065
|
results.sort((a, b) => b.lines - a.lines);
|
|
9980
10066
|
for (const { file, lines } of results) {
|
|
9981
10067
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
9982
|
-
const color = exceedsThreshold ?
|
|
9983
|
-
console.log(`${color(file)} \u2192 ${
|
|
10068
|
+
const color = exceedsThreshold ? chalk103.red : chalk103.white;
|
|
10069
|
+
console.log(`${color(file)} \u2192 ${chalk103.cyan(lines)} lines`);
|
|
9984
10070
|
}
|
|
9985
10071
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
9986
10072
|
console.log(
|
|
9987
|
-
|
|
10073
|
+
chalk103.dim(`
|
|
9988
10074
|
Total: ${total} lines across ${files.length} files`)
|
|
9989
10075
|
);
|
|
9990
10076
|
if (hasViolation) {
|
|
@@ -9998,25 +10084,25 @@ async function analyze(pattern2) {
|
|
|
9998
10084
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
9999
10085
|
const files = findSourceFiles2(searchPattern);
|
|
10000
10086
|
if (files.length === 0) {
|
|
10001
|
-
console.log(
|
|
10087
|
+
console.log(chalk104.yellow("No files found matching pattern"));
|
|
10002
10088
|
return;
|
|
10003
10089
|
}
|
|
10004
10090
|
if (files.length === 1) {
|
|
10005
10091
|
const file = files[0];
|
|
10006
|
-
console.log(
|
|
10092
|
+
console.log(chalk104.bold.underline("SLOC"));
|
|
10007
10093
|
await sloc(file);
|
|
10008
10094
|
console.log();
|
|
10009
|
-
console.log(
|
|
10095
|
+
console.log(chalk104.bold.underline("Cyclomatic Complexity"));
|
|
10010
10096
|
await cyclomatic(file);
|
|
10011
10097
|
console.log();
|
|
10012
|
-
console.log(
|
|
10098
|
+
console.log(chalk104.bold.underline("Halstead Metrics"));
|
|
10013
10099
|
await halstead(file);
|
|
10014
10100
|
console.log();
|
|
10015
|
-
console.log(
|
|
10101
|
+
console.log(chalk104.bold.underline("Maintainability Index"));
|
|
10016
10102
|
await maintainability(file);
|
|
10017
10103
|
console.log();
|
|
10018
10104
|
console.log(
|
|
10019
|
-
|
|
10105
|
+
chalk104.dim(
|
|
10020
10106
|
"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."
|
|
10021
10107
|
)
|
|
10022
10108
|
);
|
|
@@ -10050,7 +10136,7 @@ function registerComplexity(program2) {
|
|
|
10050
10136
|
}
|
|
10051
10137
|
|
|
10052
10138
|
// src/commands/config/index.ts
|
|
10053
|
-
import
|
|
10139
|
+
import chalk105 from "chalk";
|
|
10054
10140
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
10055
10141
|
|
|
10056
10142
|
// src/commands/config/setNestedValue.ts
|
|
@@ -10113,7 +10199,7 @@ function formatIssuePath(issue, key) {
|
|
|
10113
10199
|
function printValidationErrors(issues, key) {
|
|
10114
10200
|
for (const issue of issues) {
|
|
10115
10201
|
console.error(
|
|
10116
|
-
|
|
10202
|
+
chalk105.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
10117
10203
|
);
|
|
10118
10204
|
}
|
|
10119
10205
|
}
|
|
@@ -10130,7 +10216,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
10130
10216
|
function assertNotGlobalOnly(key, global) {
|
|
10131
10217
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
10132
10218
|
console.error(
|
|
10133
|
-
|
|
10219
|
+
chalk105.red(
|
|
10134
10220
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
10135
10221
|
)
|
|
10136
10222
|
);
|
|
@@ -10153,7 +10239,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
10153
10239
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
10154
10240
|
const target = options2.global ? "global" : "project";
|
|
10155
10241
|
console.log(
|
|
10156
|
-
|
|
10242
|
+
chalk105.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
10157
10243
|
);
|
|
10158
10244
|
}
|
|
10159
10245
|
function configList() {
|
|
@@ -10162,7 +10248,7 @@ function configList() {
|
|
|
10162
10248
|
}
|
|
10163
10249
|
|
|
10164
10250
|
// src/commands/config/configGet.ts
|
|
10165
|
-
import
|
|
10251
|
+
import chalk106 from "chalk";
|
|
10166
10252
|
|
|
10167
10253
|
// src/commands/config/getNestedValue.ts
|
|
10168
10254
|
function isTraversable(value) {
|
|
@@ -10194,7 +10280,7 @@ function requireNestedValue(config, key) {
|
|
|
10194
10280
|
return value;
|
|
10195
10281
|
}
|
|
10196
10282
|
function exitKeyNotSet(key) {
|
|
10197
|
-
console.error(
|
|
10283
|
+
console.error(chalk106.red(`Key "${key}" is not set`));
|
|
10198
10284
|
process.exit(1);
|
|
10199
10285
|
}
|
|
10200
10286
|
|
|
@@ -10208,7 +10294,7 @@ function registerConfig(program2) {
|
|
|
10208
10294
|
|
|
10209
10295
|
// src/commands/deploy/redirect.ts
|
|
10210
10296
|
import { existsSync as existsSync28, readFileSync as readFileSync23, writeFileSync as writeFileSync24 } from "fs";
|
|
10211
|
-
import
|
|
10297
|
+
import chalk107 from "chalk";
|
|
10212
10298
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10213
10299
|
if (!window.location.pathname.endsWith('/')) {
|
|
10214
10300
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10217,23 +10303,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10217
10303
|
function redirect() {
|
|
10218
10304
|
const indexPath = "index.html";
|
|
10219
10305
|
if (!existsSync28(indexPath)) {
|
|
10220
|
-
console.log(
|
|
10306
|
+
console.log(chalk107.yellow("No index.html found"));
|
|
10221
10307
|
return;
|
|
10222
10308
|
}
|
|
10223
10309
|
const content = readFileSync23(indexPath, "utf8");
|
|
10224
10310
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10225
|
-
console.log(
|
|
10311
|
+
console.log(chalk107.dim("Trailing slash script already present"));
|
|
10226
10312
|
return;
|
|
10227
10313
|
}
|
|
10228
10314
|
const headCloseIndex = content.indexOf("</head>");
|
|
10229
10315
|
if (headCloseIndex === -1) {
|
|
10230
|
-
console.log(
|
|
10316
|
+
console.log(chalk107.red("Could not find </head> tag in index.html"));
|
|
10231
10317
|
return;
|
|
10232
10318
|
}
|
|
10233
10319
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10234
10320
|
${content.slice(headCloseIndex)}`;
|
|
10235
10321
|
writeFileSync24(indexPath, newContent);
|
|
10236
|
-
console.log(
|
|
10322
|
+
console.log(chalk107.green("Added trailing slash redirect to index.html"));
|
|
10237
10323
|
}
|
|
10238
10324
|
|
|
10239
10325
|
// src/commands/registerDeploy.ts
|
|
@@ -10259,8 +10345,8 @@ function loadBlogSkipDays(repoName) {
|
|
|
10259
10345
|
}
|
|
10260
10346
|
|
|
10261
10347
|
// src/commands/devlog/shared.ts
|
|
10262
|
-
import { execSync as
|
|
10263
|
-
import
|
|
10348
|
+
import { execSync as execSync24 } from "child_process";
|
|
10349
|
+
import chalk108 from "chalk";
|
|
10264
10350
|
|
|
10265
10351
|
// src/shared/getRepoName.ts
|
|
10266
10352
|
import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
|
|
@@ -10351,7 +10437,7 @@ function loadAllDevlogLatestDates() {
|
|
|
10351
10437
|
// src/commands/devlog/shared.ts
|
|
10352
10438
|
function getCommitFiles(hash) {
|
|
10353
10439
|
try {
|
|
10354
|
-
const output =
|
|
10440
|
+
const output = execSync24(`git show --name-only --format="" ${hash}`, {
|
|
10355
10441
|
encoding: "utf8"
|
|
10356
10442
|
});
|
|
10357
10443
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -10369,13 +10455,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10369
10455
|
}
|
|
10370
10456
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10371
10457
|
for (const commit2 of commits2) {
|
|
10372
|
-
console.log(` ${
|
|
10458
|
+
console.log(` ${chalk108.yellow(commit2.hash)} ${commit2.message}`);
|
|
10373
10459
|
if (verbose) {
|
|
10374
10460
|
const visibleFiles = commit2.files.filter(
|
|
10375
10461
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10376
10462
|
);
|
|
10377
10463
|
for (const file of visibleFiles) {
|
|
10378
|
-
console.log(` ${
|
|
10464
|
+
console.log(` ${chalk108.dim(file)}`);
|
|
10379
10465
|
}
|
|
10380
10466
|
}
|
|
10381
10467
|
}
|
|
@@ -10400,15 +10486,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10400
10486
|
}
|
|
10401
10487
|
|
|
10402
10488
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10403
|
-
import
|
|
10489
|
+
import chalk109 from "chalk";
|
|
10404
10490
|
function printDateHeader(date, isSkipped, entries) {
|
|
10405
10491
|
if (isSkipped) {
|
|
10406
|
-
console.log(`${
|
|
10492
|
+
console.log(`${chalk109.bold.blue(date)} ${chalk109.dim("skipped")}`);
|
|
10407
10493
|
} else if (entries && entries.length > 0) {
|
|
10408
|
-
const entryInfo = entries.map((e) => `${
|
|
10409
|
-
console.log(`${
|
|
10494
|
+
const entryInfo = entries.map((e) => `${chalk109.green(e.version)} ${e.title}`).join(" | ");
|
|
10495
|
+
console.log(`${chalk109.bold.blue(date)} ${entryInfo}`);
|
|
10410
10496
|
} else {
|
|
10411
|
-
console.log(`${
|
|
10497
|
+
console.log(`${chalk109.bold.blue(date)} ${chalk109.red("\u26A0 devlog missing")}`);
|
|
10412
10498
|
}
|
|
10413
10499
|
}
|
|
10414
10500
|
|
|
@@ -10447,11 +10533,11 @@ function list3(options2) {
|
|
|
10447
10533
|
}
|
|
10448
10534
|
|
|
10449
10535
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
10450
|
-
import { execFileSync as execFileSync3, execSync as
|
|
10536
|
+
import { execFileSync as execFileSync3, execSync as execSync25 } from "child_process";
|
|
10451
10537
|
import semver from "semver";
|
|
10452
10538
|
function getVersionAtCommit(hash) {
|
|
10453
10539
|
try {
|
|
10454
|
-
const content =
|
|
10540
|
+
const content = execSync25(`git show ${hash}:package.json`, {
|
|
10455
10541
|
encoding: "utf8"
|
|
10456
10542
|
});
|
|
10457
10543
|
const pkg = JSON.parse(content);
|
|
@@ -10512,24 +10598,24 @@ function bumpVersion(version2, type) {
|
|
|
10512
10598
|
|
|
10513
10599
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10514
10600
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10515
|
-
import
|
|
10601
|
+
import chalk111 from "chalk";
|
|
10516
10602
|
|
|
10517
10603
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10518
|
-
import
|
|
10604
|
+
import chalk110 from "chalk";
|
|
10519
10605
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10520
10606
|
if (conventional && firstHash) {
|
|
10521
10607
|
const version2 = getVersionAtCommit(firstHash);
|
|
10522
10608
|
if (version2) {
|
|
10523
|
-
console.log(`${
|
|
10609
|
+
console.log(`${chalk110.bold("version:")} ${stripToMinor(version2)}`);
|
|
10524
10610
|
} else {
|
|
10525
|
-
console.log(`${
|
|
10611
|
+
console.log(`${chalk110.bold("version:")} ${chalk110.red("unknown")}`);
|
|
10526
10612
|
}
|
|
10527
10613
|
} else if (patchVersion && minorVersion) {
|
|
10528
10614
|
console.log(
|
|
10529
|
-
`${
|
|
10615
|
+
`${chalk110.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10530
10616
|
);
|
|
10531
10617
|
} else {
|
|
10532
|
-
console.log(`${
|
|
10618
|
+
console.log(`${chalk110.bold("version:")} v0.1 (initial)`);
|
|
10533
10619
|
}
|
|
10534
10620
|
}
|
|
10535
10621
|
|
|
@@ -10577,16 +10663,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10577
10663
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10578
10664
|
}
|
|
10579
10665
|
function logName(repoName) {
|
|
10580
|
-
console.log(`${
|
|
10666
|
+
console.log(`${chalk111.bold("name:")} ${repoName}`);
|
|
10581
10667
|
}
|
|
10582
10668
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10583
10669
|
logName(ctx.repoName);
|
|
10584
10670
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10585
|
-
console.log(
|
|
10671
|
+
console.log(chalk111.bold.blue(targetDate));
|
|
10586
10672
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10587
10673
|
}
|
|
10588
10674
|
function logNoCommits(lastInfo) {
|
|
10589
|
-
console.log(
|
|
10675
|
+
console.log(chalk111.dim(noCommitsMessage(!!lastInfo)));
|
|
10590
10676
|
}
|
|
10591
10677
|
|
|
10592
10678
|
// src/commands/devlog/next/index.ts
|
|
@@ -10624,14 +10710,14 @@ function next2(options2) {
|
|
|
10624
10710
|
}
|
|
10625
10711
|
|
|
10626
10712
|
// src/commands/devlog/repos/index.ts
|
|
10627
|
-
import { execSync as
|
|
10713
|
+
import { execSync as execSync26 } from "child_process";
|
|
10628
10714
|
|
|
10629
10715
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10630
|
-
import
|
|
10716
|
+
import chalk112 from "chalk";
|
|
10631
10717
|
function colorStatus(status2) {
|
|
10632
|
-
if (status2 === "missing") return
|
|
10633
|
-
if (status2 === "outdated") return
|
|
10634
|
-
return
|
|
10718
|
+
if (status2 === "missing") return chalk112.red(status2);
|
|
10719
|
+
if (status2 === "outdated") return chalk112.yellow(status2);
|
|
10720
|
+
return chalk112.green(status2);
|
|
10635
10721
|
}
|
|
10636
10722
|
function formatRow(row, nameWidth) {
|
|
10637
10723
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10645,8 +10731,8 @@ function printReposTable(rows) {
|
|
|
10645
10731
|
"Last Devlog".padEnd(11),
|
|
10646
10732
|
"Status"
|
|
10647
10733
|
].join(" ");
|
|
10648
|
-
console.log(
|
|
10649
|
-
console.log(
|
|
10734
|
+
console.log(chalk112.dim(header));
|
|
10735
|
+
console.log(chalk112.dim("-".repeat(header.length)));
|
|
10650
10736
|
for (const row of rows) {
|
|
10651
10737
|
console.log(formatRow(row, nameWidth));
|
|
10652
10738
|
}
|
|
@@ -10659,7 +10745,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
10659
10745
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
10660
10746
|
}
|
|
10661
10747
|
function fetchRepos(days, all) {
|
|
10662
|
-
const json =
|
|
10748
|
+
const json = execSync26(
|
|
10663
10749
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
10664
10750
|
{ encoding: "utf8" }
|
|
10665
10751
|
);
|
|
@@ -10704,14 +10790,14 @@ function repos(options2) {
|
|
|
10704
10790
|
// src/commands/devlog/skip.ts
|
|
10705
10791
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
10706
10792
|
import { join as join30 } from "path";
|
|
10707
|
-
import
|
|
10793
|
+
import chalk113 from "chalk";
|
|
10708
10794
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10709
10795
|
function getBlogConfigPath() {
|
|
10710
10796
|
return join30(BLOG_REPO_ROOT, "assist.yml");
|
|
10711
10797
|
}
|
|
10712
10798
|
function skip(date) {
|
|
10713
10799
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10714
|
-
console.log(
|
|
10800
|
+
console.log(chalk113.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10715
10801
|
process.exit(1);
|
|
10716
10802
|
}
|
|
10717
10803
|
const repoName = getRepoName();
|
|
@@ -10722,7 +10808,7 @@ function skip(date) {
|
|
|
10722
10808
|
const skipDays = skip2[repoName] ?? [];
|
|
10723
10809
|
if (skipDays.includes(date)) {
|
|
10724
10810
|
console.log(
|
|
10725
|
-
|
|
10811
|
+
chalk113.yellow(`${date} is already in skip list for ${repoName}`)
|
|
10726
10812
|
);
|
|
10727
10813
|
return;
|
|
10728
10814
|
}
|
|
@@ -10732,20 +10818,20 @@ function skip(date) {
|
|
|
10732
10818
|
devlog.skip = skip2;
|
|
10733
10819
|
config.devlog = devlog;
|
|
10734
10820
|
writeFileSync25(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
10735
|
-
console.log(
|
|
10821
|
+
console.log(chalk113.green(`Added ${date} to skip list for ${repoName}`));
|
|
10736
10822
|
}
|
|
10737
10823
|
|
|
10738
10824
|
// src/commands/devlog/version.ts
|
|
10739
|
-
import
|
|
10825
|
+
import chalk114 from "chalk";
|
|
10740
10826
|
function version() {
|
|
10741
10827
|
const config = loadConfig();
|
|
10742
10828
|
const name = getRepoName();
|
|
10743
10829
|
const lastInfo = getLastVersionInfo(name, config);
|
|
10744
10830
|
const lastVersion = lastInfo?.version ?? null;
|
|
10745
10831
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
10746
|
-
console.log(`${
|
|
10747
|
-
console.log(`${
|
|
10748
|
-
console.log(`${
|
|
10832
|
+
console.log(`${chalk114.bold("name:")} ${name}`);
|
|
10833
|
+
console.log(`${chalk114.bold("last:")} ${lastVersion ?? chalk114.dim("none")}`);
|
|
10834
|
+
console.log(`${chalk114.bold("next:")} ${nextVersion ?? chalk114.dim("none")}`);
|
|
10749
10835
|
}
|
|
10750
10836
|
|
|
10751
10837
|
// src/commands/registerDevlog.ts
|
|
@@ -10769,7 +10855,7 @@ function registerDevlog(program2) {
|
|
|
10769
10855
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
10770
10856
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync3 } from "fs";
|
|
10771
10857
|
import { join as join31 } from "path";
|
|
10772
|
-
import
|
|
10858
|
+
import chalk115 from "chalk";
|
|
10773
10859
|
|
|
10774
10860
|
// src/shared/findRepoRoot.ts
|
|
10775
10861
|
import { existsSync as existsSync30 } from "fs";
|
|
@@ -10832,14 +10918,14 @@ function checkBuildLocks(startDir) {
|
|
|
10832
10918
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
10833
10919
|
if (locked) {
|
|
10834
10920
|
console.error(
|
|
10835
|
-
|
|
10921
|
+
chalk115.red("Build output locked (is VS debugging?): ") + locked
|
|
10836
10922
|
);
|
|
10837
10923
|
process.exit(1);
|
|
10838
10924
|
}
|
|
10839
10925
|
}
|
|
10840
10926
|
async function checkBuildLocksCommand() {
|
|
10841
10927
|
checkBuildLocks();
|
|
10842
|
-
console.log(
|
|
10928
|
+
console.log(chalk115.green("No build locks detected"));
|
|
10843
10929
|
}
|
|
10844
10930
|
|
|
10845
10931
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -10938,30 +11024,30 @@ function escapeRegex(s) {
|
|
|
10938
11024
|
}
|
|
10939
11025
|
|
|
10940
11026
|
// src/commands/dotnet/printTree.ts
|
|
10941
|
-
import
|
|
11027
|
+
import chalk116 from "chalk";
|
|
10942
11028
|
function printNodes(nodes, prefix2) {
|
|
10943
11029
|
for (let i = 0; i < nodes.length; i++) {
|
|
10944
11030
|
const isLast = i === nodes.length - 1;
|
|
10945
11031
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
10946
11032
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
10947
11033
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
10948
|
-
const label2 = isMissing ?
|
|
11034
|
+
const label2 = isMissing ? chalk116.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
10949
11035
|
console.log(`${prefix2}${connector}${label2}`);
|
|
10950
11036
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
10951
11037
|
}
|
|
10952
11038
|
}
|
|
10953
11039
|
function printTree(tree, totalCount, solutions) {
|
|
10954
|
-
console.log(
|
|
10955
|
-
console.log(
|
|
11040
|
+
console.log(chalk116.bold("\nProject Dependency Tree"));
|
|
11041
|
+
console.log(chalk116.cyan(tree.relativePath));
|
|
10956
11042
|
printNodes(tree.children, "");
|
|
10957
|
-
console.log(
|
|
11043
|
+
console.log(chalk116.dim(`
|
|
10958
11044
|
${totalCount} projects total (including root)`));
|
|
10959
|
-
console.log(
|
|
11045
|
+
console.log(chalk116.bold("\nSolution Membership"));
|
|
10960
11046
|
if (solutions.length === 0) {
|
|
10961
|
-
console.log(
|
|
11047
|
+
console.log(chalk116.yellow(" Not found in any .sln"));
|
|
10962
11048
|
} else {
|
|
10963
11049
|
for (const sln of solutions) {
|
|
10964
|
-
console.log(` ${
|
|
11050
|
+
console.log(` ${chalk116.green(sln)}`);
|
|
10965
11051
|
}
|
|
10966
11052
|
}
|
|
10967
11053
|
console.log();
|
|
@@ -10990,16 +11076,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
10990
11076
|
// src/commands/dotnet/resolveCsproj.ts
|
|
10991
11077
|
import { existsSync as existsSync31 } from "fs";
|
|
10992
11078
|
import path25 from "path";
|
|
10993
|
-
import
|
|
11079
|
+
import chalk117 from "chalk";
|
|
10994
11080
|
function resolveCsproj(csprojPath) {
|
|
10995
11081
|
const resolved = path25.resolve(csprojPath);
|
|
10996
11082
|
if (!existsSync31(resolved)) {
|
|
10997
|
-
console.error(
|
|
11083
|
+
console.error(chalk117.red(`File not found: ${resolved}`));
|
|
10998
11084
|
process.exit(1);
|
|
10999
11085
|
}
|
|
11000
11086
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
11001
11087
|
if (!repoRoot) {
|
|
11002
|
-
console.error(
|
|
11088
|
+
console.error(chalk117.red("Could not find git repository root"));
|
|
11003
11089
|
process.exit(1);
|
|
11004
11090
|
}
|
|
11005
11091
|
return { resolved, repoRoot };
|
|
@@ -11019,7 +11105,7 @@ async function deps(csprojPath, options2) {
|
|
|
11019
11105
|
}
|
|
11020
11106
|
|
|
11021
11107
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
11022
|
-
import { execSync as
|
|
11108
|
+
import { execSync as execSync27 } from "child_process";
|
|
11023
11109
|
var SCOPE_ALL = "all";
|
|
11024
11110
|
var SCOPE_BASE = "base:";
|
|
11025
11111
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -11043,18 +11129,18 @@ function getChangedCsFiles(scope) {
|
|
|
11043
11129
|
} else {
|
|
11044
11130
|
cmd = "git diff --name-only HEAD";
|
|
11045
11131
|
}
|
|
11046
|
-
const output =
|
|
11132
|
+
const output = execSync27(cmd, { encoding: "utf8" }).trim();
|
|
11047
11133
|
if (output === "") return [];
|
|
11048
11134
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
11049
11135
|
}
|
|
11050
11136
|
|
|
11051
11137
|
// src/commands/dotnet/inSln.ts
|
|
11052
|
-
import
|
|
11138
|
+
import chalk118 from "chalk";
|
|
11053
11139
|
async function inSln(csprojPath) {
|
|
11054
11140
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
11055
11141
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
11056
11142
|
if (solutions.length === 0) {
|
|
11057
|
-
console.log(
|
|
11143
|
+
console.log(chalk118.yellow("Not found in any .sln file"));
|
|
11058
11144
|
process.exit(1);
|
|
11059
11145
|
}
|
|
11060
11146
|
for (const sln of solutions) {
|
|
@@ -11063,7 +11149,7 @@ async function inSln(csprojPath) {
|
|
|
11063
11149
|
}
|
|
11064
11150
|
|
|
11065
11151
|
// src/commands/dotnet/inspect.ts
|
|
11066
|
-
import
|
|
11152
|
+
import chalk124 from "chalk";
|
|
11067
11153
|
|
|
11068
11154
|
// src/shared/formatElapsed.ts
|
|
11069
11155
|
function formatElapsed(ms) {
|
|
@@ -11075,12 +11161,12 @@ function formatElapsed(ms) {
|
|
|
11075
11161
|
}
|
|
11076
11162
|
|
|
11077
11163
|
// src/commands/dotnet/displayIssues.ts
|
|
11078
|
-
import
|
|
11164
|
+
import chalk119 from "chalk";
|
|
11079
11165
|
var SEVERITY_COLOR = {
|
|
11080
|
-
ERROR:
|
|
11081
|
-
WARNING:
|
|
11082
|
-
SUGGESTION:
|
|
11083
|
-
HINT:
|
|
11166
|
+
ERROR: chalk119.red,
|
|
11167
|
+
WARNING: chalk119.yellow,
|
|
11168
|
+
SUGGESTION: chalk119.cyan,
|
|
11169
|
+
HINT: chalk119.dim
|
|
11084
11170
|
};
|
|
11085
11171
|
function groupByFile(issues) {
|
|
11086
11172
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -11096,15 +11182,15 @@ function groupByFile(issues) {
|
|
|
11096
11182
|
}
|
|
11097
11183
|
function displayIssues(issues) {
|
|
11098
11184
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
11099
|
-
console.log(
|
|
11185
|
+
console.log(chalk119.bold(file));
|
|
11100
11186
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
11101
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
11187
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk119.white;
|
|
11102
11188
|
console.log(
|
|
11103
|
-
` ${
|
|
11189
|
+
` ${chalk119.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
11104
11190
|
);
|
|
11105
11191
|
}
|
|
11106
11192
|
}
|
|
11107
|
-
console.log(
|
|
11193
|
+
console.log(chalk119.dim(`
|
|
11108
11194
|
${issues.length} issue(s) found`));
|
|
11109
11195
|
}
|
|
11110
11196
|
|
|
@@ -11163,12 +11249,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11163
11249
|
// src/commands/dotnet/resolveSolution.ts
|
|
11164
11250
|
import { existsSync as existsSync32 } from "fs";
|
|
11165
11251
|
import path26 from "path";
|
|
11166
|
-
import
|
|
11252
|
+
import chalk121 from "chalk";
|
|
11167
11253
|
|
|
11168
11254
|
// src/commands/dotnet/findSolution.ts
|
|
11169
11255
|
import { readdirSync as readdirSync5 } from "fs";
|
|
11170
11256
|
import { dirname as dirname18, join as join32 } from "path";
|
|
11171
|
-
import
|
|
11257
|
+
import chalk120 from "chalk";
|
|
11172
11258
|
function findSlnInDir(dir) {
|
|
11173
11259
|
try {
|
|
11174
11260
|
return readdirSync5(dir).filter((f) => f.endsWith(".sln")).map((f) => join32(dir, f));
|
|
@@ -11184,17 +11270,17 @@ function findSolution() {
|
|
|
11184
11270
|
const slnFiles = findSlnInDir(current);
|
|
11185
11271
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
11186
11272
|
if (slnFiles.length > 1) {
|
|
11187
|
-
console.error(
|
|
11273
|
+
console.error(chalk120.red(`Multiple .sln files found in ${current}:`));
|
|
11188
11274
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
11189
11275
|
console.error(
|
|
11190
|
-
|
|
11276
|
+
chalk120.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
11191
11277
|
);
|
|
11192
11278
|
process.exit(1);
|
|
11193
11279
|
}
|
|
11194
11280
|
if (current === ceiling) break;
|
|
11195
11281
|
current = dirname18(current);
|
|
11196
11282
|
}
|
|
11197
|
-
console.error(
|
|
11283
|
+
console.error(chalk120.red("No .sln file found between cwd and repo root"));
|
|
11198
11284
|
process.exit(1);
|
|
11199
11285
|
}
|
|
11200
11286
|
|
|
@@ -11203,7 +11289,7 @@ function resolveSolution(sln) {
|
|
|
11203
11289
|
if (sln) {
|
|
11204
11290
|
const resolved = path26.resolve(sln);
|
|
11205
11291
|
if (!existsSync32(resolved)) {
|
|
11206
|
-
console.error(
|
|
11292
|
+
console.error(chalk121.red(`Solution file not found: ${resolved}`));
|
|
11207
11293
|
process.exit(1);
|
|
11208
11294
|
}
|
|
11209
11295
|
return resolved;
|
|
@@ -11241,18 +11327,18 @@ function parseInspectReport(json) {
|
|
|
11241
11327
|
}
|
|
11242
11328
|
|
|
11243
11329
|
// src/commands/dotnet/runInspectCode.ts
|
|
11244
|
-
import { execSync as
|
|
11330
|
+
import { execSync as execSync28 } from "child_process";
|
|
11245
11331
|
import { existsSync as existsSync33, readFileSync as readFileSync28, unlinkSync as unlinkSync9 } from "fs";
|
|
11246
11332
|
import { tmpdir as tmpdir3 } from "os";
|
|
11247
11333
|
import path27 from "path";
|
|
11248
|
-
import
|
|
11334
|
+
import chalk122 from "chalk";
|
|
11249
11335
|
function assertJbInstalled() {
|
|
11250
11336
|
try {
|
|
11251
|
-
|
|
11337
|
+
execSync28("jb inspectcode --version", { stdio: "pipe" });
|
|
11252
11338
|
} catch {
|
|
11253
|
-
console.error(
|
|
11339
|
+
console.error(chalk122.red("jb is not installed. Install with:"));
|
|
11254
11340
|
console.error(
|
|
11255
|
-
|
|
11341
|
+
chalk122.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11256
11342
|
);
|
|
11257
11343
|
process.exit(1);
|
|
11258
11344
|
}
|
|
@@ -11262,7 +11348,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11262
11348
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
11263
11349
|
const sweaFlag = swea ? " --swea" : "";
|
|
11264
11350
|
try {
|
|
11265
|
-
|
|
11351
|
+
execSync28(
|
|
11266
11352
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
11267
11353
|
{ stdio: "pipe" }
|
|
11268
11354
|
);
|
|
@@ -11270,11 +11356,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11270
11356
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11271
11357
|
process.stderr.write(error.stderr);
|
|
11272
11358
|
}
|
|
11273
|
-
console.error(
|
|
11359
|
+
console.error(chalk122.red("jb inspectcode failed"));
|
|
11274
11360
|
process.exit(1);
|
|
11275
11361
|
}
|
|
11276
11362
|
if (!existsSync33(reportPath)) {
|
|
11277
|
-
console.error(
|
|
11363
|
+
console.error(chalk122.red("Report file not generated"));
|
|
11278
11364
|
process.exit(1);
|
|
11279
11365
|
}
|
|
11280
11366
|
const xml = readFileSync28(reportPath, "utf8");
|
|
@@ -11283,8 +11369,8 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11283
11369
|
}
|
|
11284
11370
|
|
|
11285
11371
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11286
|
-
import { execSync as
|
|
11287
|
-
import
|
|
11372
|
+
import { execSync as execSync29 } from "child_process";
|
|
11373
|
+
import chalk123 from "chalk";
|
|
11288
11374
|
function resolveMsbuildPath() {
|
|
11289
11375
|
const { run: run4 } = loadConfig();
|
|
11290
11376
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11294,11 +11380,11 @@ function resolveMsbuildPath() {
|
|
|
11294
11380
|
function assertMsbuildInstalled() {
|
|
11295
11381
|
const msbuild = resolveMsbuildPath();
|
|
11296
11382
|
try {
|
|
11297
|
-
|
|
11383
|
+
execSync29(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11298
11384
|
} catch {
|
|
11299
|
-
console.error(
|
|
11385
|
+
console.error(chalk123.red(`msbuild not found at: ${msbuild}`));
|
|
11300
11386
|
console.error(
|
|
11301
|
-
|
|
11387
|
+
chalk123.yellow(
|
|
11302
11388
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11303
11389
|
)
|
|
11304
11390
|
);
|
|
@@ -11320,7 +11406,7 @@ function runRoslynInspect(slnPath) {
|
|
|
11320
11406
|
const msbuild = resolveMsbuildPath();
|
|
11321
11407
|
let output;
|
|
11322
11408
|
try {
|
|
11323
|
-
output =
|
|
11409
|
+
output = execSync29(
|
|
11324
11410
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
11325
11411
|
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
11326
11412
|
);
|
|
@@ -11345,17 +11431,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11345
11431
|
// src/commands/dotnet/inspect.ts
|
|
11346
11432
|
function logScope(changedFiles) {
|
|
11347
11433
|
if (changedFiles === null) {
|
|
11348
|
-
console.log(
|
|
11434
|
+
console.log(chalk124.dim("Inspecting full solution..."));
|
|
11349
11435
|
} else {
|
|
11350
11436
|
console.log(
|
|
11351
|
-
|
|
11437
|
+
chalk124.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11352
11438
|
);
|
|
11353
11439
|
}
|
|
11354
11440
|
}
|
|
11355
11441
|
function reportResults(issues, elapsed) {
|
|
11356
11442
|
if (issues.length > 0) displayIssues(issues);
|
|
11357
|
-
else console.log(
|
|
11358
|
-
console.log(
|
|
11443
|
+
else console.log(chalk124.green("No issues found"));
|
|
11444
|
+
console.log(chalk124.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11359
11445
|
if (issues.length > 0) process.exit(1);
|
|
11360
11446
|
}
|
|
11361
11447
|
async function inspect(sln, options2) {
|
|
@@ -11366,7 +11452,7 @@ async function inspect(sln, options2) {
|
|
|
11366
11452
|
const scope = parseScope(options2.scope);
|
|
11367
11453
|
const changedFiles = getChangedCsFiles(scope);
|
|
11368
11454
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11369
|
-
console.log(
|
|
11455
|
+
console.log(chalk124.green("No changed .cs files found"));
|
|
11370
11456
|
return;
|
|
11371
11457
|
}
|
|
11372
11458
|
logScope(changedFiles);
|
|
@@ -11659,25 +11745,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11659
11745
|
}
|
|
11660
11746
|
|
|
11661
11747
|
// src/commands/github/printCountTable.ts
|
|
11662
|
-
import
|
|
11748
|
+
import chalk125 from "chalk";
|
|
11663
11749
|
function printCountTable(labelHeader, rows) {
|
|
11664
11750
|
const labelWidth = Math.max(
|
|
11665
11751
|
labelHeader.length,
|
|
11666
11752
|
...rows.map((row) => row.label.length)
|
|
11667
11753
|
);
|
|
11668
11754
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11669
|
-
console.log(
|
|
11670
|
-
console.log(
|
|
11755
|
+
console.log(chalk125.dim(header));
|
|
11756
|
+
console.log(chalk125.dim("-".repeat(header.length)));
|
|
11671
11757
|
for (const row of rows) {
|
|
11672
11758
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11673
11759
|
}
|
|
11674
11760
|
}
|
|
11675
11761
|
|
|
11676
11762
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11677
|
-
import
|
|
11763
|
+
import chalk126 from "chalk";
|
|
11678
11764
|
function printRepoAuthorBreakdown(repos2) {
|
|
11679
11765
|
for (const repo of repos2) {
|
|
11680
|
-
console.log(
|
|
11766
|
+
console.log(chalk126.bold(repo.name));
|
|
11681
11767
|
const authorWidth = Math.max(
|
|
11682
11768
|
0,
|
|
11683
11769
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -11774,9 +11860,9 @@ function registerGithub(program2) {
|
|
|
11774
11860
|
}
|
|
11775
11861
|
|
|
11776
11862
|
// src/commands/handover/countPendingHandovers.ts
|
|
11777
|
-
import { and as and12, eq as
|
|
11863
|
+
import { and as and12, eq as eq31, isNull, sql as sql4 } from "drizzle-orm";
|
|
11778
11864
|
async function countPendingHandovers(orm, origin) {
|
|
11779
|
-
const [row] = await orm.select({ count: sql4`count(*)::int` }).from(handovers).where(and12(
|
|
11865
|
+
const [row] = await orm.select({ count: sql4`count(*)::int` }).from(handovers).where(and12(eq31(handovers.origin, origin), isNull(handovers.recalledAt)));
|
|
11780
11866
|
return row?.count ?? 0;
|
|
11781
11867
|
}
|
|
11782
11868
|
|
|
@@ -11916,13 +12002,13 @@ async function load2(options2 = {}) {
|
|
|
11916
12002
|
}
|
|
11917
12003
|
|
|
11918
12004
|
// src/commands/handover/listPendingHandovers.ts
|
|
11919
|
-
import { and as and13, desc as desc4, eq as
|
|
12005
|
+
import { and as and13, desc as desc4, eq as eq32, isNull as isNull2 } from "drizzle-orm";
|
|
11920
12006
|
async function listPendingHandovers(orm, origin) {
|
|
11921
12007
|
return orm.select({
|
|
11922
12008
|
id: handovers.id,
|
|
11923
12009
|
summary: handovers.summary,
|
|
11924
12010
|
createdAt: handovers.createdAt
|
|
11925
|
-
}).from(handovers).where(and13(
|
|
12011
|
+
}).from(handovers).where(and13(eq32(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc4(handovers.createdAt), desc4(handovers.id));
|
|
11926
12012
|
}
|
|
11927
12013
|
|
|
11928
12014
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -11935,17 +12021,17 @@ async function printPendingHandovers() {
|
|
|
11935
12021
|
}
|
|
11936
12022
|
|
|
11937
12023
|
// src/commands/handover/recallHandover.ts
|
|
11938
|
-
import { and as and14, desc as desc5, eq as
|
|
12024
|
+
import { and as and14, desc as desc5, eq as eq33, isNull as isNull3 } from "drizzle-orm";
|
|
11939
12025
|
async function recallHandover(orm, origin, id2) {
|
|
11940
12026
|
const [row] = await orm.select().from(handovers).where(
|
|
11941
12027
|
and14(
|
|
11942
|
-
|
|
12028
|
+
eq33(handovers.origin, origin),
|
|
11943
12029
|
isNull3(handovers.recalledAt),
|
|
11944
|
-
...id2 === void 0 ? [] : [
|
|
12030
|
+
...id2 === void 0 ? [] : [eq33(handovers.id, id2)]
|
|
11945
12031
|
)
|
|
11946
12032
|
).orderBy(desc5(handovers.createdAt), desc5(handovers.id)).limit(1);
|
|
11947
12033
|
if (!row) return void 0;
|
|
11948
|
-
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(
|
|
12034
|
+
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq33(handovers.id, row.id));
|
|
11949
12035
|
return row.content;
|
|
11950
12036
|
}
|
|
11951
12037
|
|
|
@@ -11995,7 +12081,7 @@ function registerHandover(program2) {
|
|
|
11995
12081
|
}
|
|
11996
12082
|
|
|
11997
12083
|
// src/commands/jira/acceptanceCriteria.ts
|
|
11998
|
-
import
|
|
12084
|
+
import chalk127 from "chalk";
|
|
11999
12085
|
|
|
12000
12086
|
// src/commands/jira/adfToText.ts
|
|
12001
12087
|
function renderInline(node) {
|
|
@@ -12054,35 +12140,6 @@ function adfToText(doc) {
|
|
|
12054
12140
|
return renderNodes([doc], 0);
|
|
12055
12141
|
}
|
|
12056
12142
|
|
|
12057
|
-
// src/commands/jira/fetchIssue.ts
|
|
12058
|
-
import { execSync as execSync29 } from "child_process";
|
|
12059
|
-
import chalk125 from "chalk";
|
|
12060
|
-
function fetchIssue(issueKey, fields) {
|
|
12061
|
-
let result;
|
|
12062
|
-
try {
|
|
12063
|
-
result = execSync29(
|
|
12064
|
-
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
12065
|
-
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
12066
|
-
);
|
|
12067
|
-
} catch (error) {
|
|
12068
|
-
if (error instanceof Error && "stderr" in error) {
|
|
12069
|
-
const stderr = error.stderr;
|
|
12070
|
-
if (stderr.includes("unauthorized")) {
|
|
12071
|
-
console.error(
|
|
12072
|
-
chalk125.red("Jira authentication expired."),
|
|
12073
|
-
"Run",
|
|
12074
|
-
chalk125.cyan("assist jira auth"),
|
|
12075
|
-
"to re-authenticate."
|
|
12076
|
-
);
|
|
12077
|
-
process.exit(1);
|
|
12078
|
-
}
|
|
12079
|
-
}
|
|
12080
|
-
console.error(chalk125.red(`Failed to fetch ${issueKey}.`));
|
|
12081
|
-
process.exit(1);
|
|
12082
|
-
}
|
|
12083
|
-
return JSON.parse(result);
|
|
12084
|
-
}
|
|
12085
|
-
|
|
12086
12143
|
// src/commands/jira/acceptanceCriteria.ts
|
|
12087
12144
|
var DEFAULT_AC_FIELD = "customfield_11937";
|
|
12088
12145
|
function acceptanceCriteria(issueKey) {
|
|
@@ -12091,7 +12148,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
12091
12148
|
const parsed = fetchIssue(issueKey, field);
|
|
12092
12149
|
const acValue = parsed?.fields?.[field];
|
|
12093
12150
|
if (!acValue) {
|
|
12094
|
-
console.log(
|
|
12151
|
+
console.log(chalk127.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
12095
12152
|
return;
|
|
12096
12153
|
}
|
|
12097
12154
|
if (typeof acValue === "string") {
|
|
@@ -12186,14 +12243,14 @@ async function jiraAuth() {
|
|
|
12186
12243
|
}
|
|
12187
12244
|
|
|
12188
12245
|
// src/commands/jira/viewIssue.ts
|
|
12189
|
-
import
|
|
12246
|
+
import chalk128 from "chalk";
|
|
12190
12247
|
function viewIssue(issueKey) {
|
|
12191
12248
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
12192
12249
|
const fields = parsed?.fields;
|
|
12193
12250
|
const summary = fields?.summary;
|
|
12194
12251
|
const description = fields?.description;
|
|
12195
12252
|
if (summary) {
|
|
12196
|
-
console.log(
|
|
12253
|
+
console.log(chalk128.bold(summary));
|
|
12197
12254
|
}
|
|
12198
12255
|
if (description) {
|
|
12199
12256
|
if (summary) console.log();
|
|
@@ -12207,7 +12264,7 @@ function viewIssue(issueKey) {
|
|
|
12207
12264
|
}
|
|
12208
12265
|
if (!summary && !description) {
|
|
12209
12266
|
console.log(
|
|
12210
|
-
|
|
12267
|
+
chalk128.yellow(`No summary or description found on ${issueKey}.`)
|
|
12211
12268
|
);
|
|
12212
12269
|
}
|
|
12213
12270
|
}
|
|
@@ -12223,13 +12280,13 @@ function registerJira(program2) {
|
|
|
12223
12280
|
// src/commands/reviewComments.ts
|
|
12224
12281
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
12225
12282
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
12226
|
-
import
|
|
12283
|
+
import chalk129 from "chalk";
|
|
12227
12284
|
async function reviewComments(number) {
|
|
12228
12285
|
if (number) {
|
|
12229
12286
|
try {
|
|
12230
12287
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
12231
12288
|
} catch {
|
|
12232
|
-
console.error(
|
|
12289
|
+
console.error(chalk129.red(`gh pr checkout ${number} failed; aborting.`));
|
|
12233
12290
|
process.exit(1);
|
|
12234
12291
|
}
|
|
12235
12292
|
}
|
|
@@ -12243,23 +12300,51 @@ async function reviewComments(number) {
|
|
|
12243
12300
|
}
|
|
12244
12301
|
|
|
12245
12302
|
// src/commands/registerLaunch.ts
|
|
12246
|
-
|
|
12303
|
+
var RESUME_SESSION_FLAG = "Resume an interrupted Claude session (used by the sessions daemon on restart)";
|
|
12304
|
+
function registerNext(program2) {
|
|
12247
12305
|
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(
|
|
12248
12306
|
(id2, opts) => next({ allowEdits: true, once: opts.once }, id2)
|
|
12249
12307
|
);
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
(
|
|
12308
|
+
}
|
|
12309
|
+
function registerDescriptionLaunch(program2, name, slashCommand, description, alias) {
|
|
12310
|
+
const command = program2.command(name).argument(
|
|
12311
|
+
"[description]",
|
|
12312
|
+
`Text to forward to the /${slashCommand} slash command`
|
|
12313
|
+
).description(description).option("--once", "Exit when the initial task completes").option("--resume-session <id>", RESUME_SESSION_FLAG).action(
|
|
12314
|
+
(text6, opts) => launchMode(slashCommand, {
|
|
12315
|
+
once: opts.once,
|
|
12316
|
+
description: text6,
|
|
12317
|
+
resumeSessionId: opts.resumeSession
|
|
12318
|
+
})
|
|
12257
12319
|
);
|
|
12320
|
+
if (alias) command.alias(alias);
|
|
12321
|
+
}
|
|
12322
|
+
function registerReviewComments(program2) {
|
|
12258
12323
|
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));
|
|
12259
|
-
|
|
12260
|
-
|
|
12324
|
+
}
|
|
12325
|
+
function registerRefine(program2) {
|
|
12326
|
+
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").option("--resume-session <id>", RESUME_SESSION_FLAG).action(
|
|
12327
|
+
(id2, opts) => refine(id2, { once: opts.once, resumeSessionId: opts.resumeSession })
|
|
12261
12328
|
);
|
|
12262
12329
|
}
|
|
12330
|
+
function registerLaunch(program2) {
|
|
12331
|
+
registerNext(program2);
|
|
12332
|
+
registerDescriptionLaunch(
|
|
12333
|
+
program2,
|
|
12334
|
+
"draft",
|
|
12335
|
+
"draft",
|
|
12336
|
+
"Launch Claude in /draft mode, chain into next on /next signal",
|
|
12337
|
+
"feat"
|
|
12338
|
+
);
|
|
12339
|
+
registerDescriptionLaunch(
|
|
12340
|
+
program2,
|
|
12341
|
+
"bug",
|
|
12342
|
+
"bug",
|
|
12343
|
+
"Launch Claude in /bug mode, chain into next on /next signal"
|
|
12344
|
+
);
|
|
12345
|
+
registerReviewComments(program2);
|
|
12346
|
+
registerRefine(program2);
|
|
12347
|
+
}
|
|
12263
12348
|
|
|
12264
12349
|
// src/commands/registerList.ts
|
|
12265
12350
|
function registerList(program2) {
|
|
@@ -12275,15 +12360,15 @@ function registerList(program2) {
|
|
|
12275
12360
|
// src/commands/mermaid/index.ts
|
|
12276
12361
|
import { mkdirSync as mkdirSync13, readdirSync as readdirSync7 } from "fs";
|
|
12277
12362
|
import { resolve as resolve11 } from "path";
|
|
12278
|
-
import
|
|
12363
|
+
import chalk132 from "chalk";
|
|
12279
12364
|
|
|
12280
12365
|
// src/commands/mermaid/exportFile.ts
|
|
12281
12366
|
import { readFileSync as readFileSync31, writeFileSync as writeFileSync28 } from "fs";
|
|
12282
12367
|
import { basename as basename6, extname, resolve as resolve10 } from "path";
|
|
12283
|
-
import
|
|
12368
|
+
import chalk131 from "chalk";
|
|
12284
12369
|
|
|
12285
12370
|
// src/commands/mermaid/renderBlock.ts
|
|
12286
|
-
import
|
|
12371
|
+
import chalk130 from "chalk";
|
|
12287
12372
|
async function renderBlock(krokiUrl, source) {
|
|
12288
12373
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
12289
12374
|
method: "POST",
|
|
@@ -12292,7 +12377,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12292
12377
|
});
|
|
12293
12378
|
if (!response.ok) {
|
|
12294
12379
|
console.error(
|
|
12295
|
-
|
|
12380
|
+
chalk130.red(
|
|
12296
12381
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
12297
12382
|
)
|
|
12298
12383
|
);
|
|
@@ -12310,19 +12395,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12310
12395
|
if (onlyIndex !== void 0) {
|
|
12311
12396
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
12312
12397
|
console.error(
|
|
12313
|
-
|
|
12398
|
+
chalk131.red(
|
|
12314
12399
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
12315
12400
|
)
|
|
12316
12401
|
);
|
|
12317
12402
|
process.exit(1);
|
|
12318
12403
|
}
|
|
12319
12404
|
console.log(
|
|
12320
|
-
|
|
12405
|
+
chalk131.gray(
|
|
12321
12406
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
12322
12407
|
)
|
|
12323
12408
|
);
|
|
12324
12409
|
} else {
|
|
12325
|
-
console.log(
|
|
12410
|
+
console.log(chalk131.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
12326
12411
|
}
|
|
12327
12412
|
for (const [i, source] of blocks.entries()) {
|
|
12328
12413
|
const idx = i + 1;
|
|
@@ -12330,7 +12415,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12330
12415
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
12331
12416
|
const svg = await renderBlock(krokiUrl, source);
|
|
12332
12417
|
writeFileSync28(outPath, svg, "utf8");
|
|
12333
|
-
console.log(
|
|
12418
|
+
console.log(chalk131.green(` \u2192 ${outPath}`));
|
|
12334
12419
|
}
|
|
12335
12420
|
}
|
|
12336
12421
|
function extractMermaidBlocks(markdown) {
|
|
@@ -12346,18 +12431,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
12346
12431
|
if (options2.index !== void 0) {
|
|
12347
12432
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
12348
12433
|
console.error(
|
|
12349
|
-
|
|
12434
|
+
chalk132.red(`--index must be a positive integer (got ${options2.index})`)
|
|
12350
12435
|
);
|
|
12351
12436
|
process.exit(1);
|
|
12352
12437
|
}
|
|
12353
12438
|
if (!file) {
|
|
12354
|
-
console.error(
|
|
12439
|
+
console.error(chalk132.red("--index requires a file argument"));
|
|
12355
12440
|
process.exit(1);
|
|
12356
12441
|
}
|
|
12357
12442
|
}
|
|
12358
12443
|
const files = file ? [file] : readdirSync7(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
12359
12444
|
if (files.length === 0) {
|
|
12360
|
-
console.log(
|
|
12445
|
+
console.log(chalk132.gray("No markdown files found in current directory."));
|
|
12361
12446
|
return;
|
|
12362
12447
|
}
|
|
12363
12448
|
for (const f of files) {
|
|
@@ -12383,7 +12468,7 @@ function registerMermaid(program2) {
|
|
|
12383
12468
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12384
12469
|
import { createServer as createServer2 } from "http";
|
|
12385
12470
|
import { dirname as dirname20 } from "path";
|
|
12386
|
-
import
|
|
12471
|
+
import chalk134 from "chalk";
|
|
12387
12472
|
|
|
12388
12473
|
// src/commands/netcap/corsHeaders.ts
|
|
12389
12474
|
var corsHeaders = {
|
|
@@ -12462,7 +12547,7 @@ function createNetcapHandler(options2) {
|
|
|
12462
12547
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12463
12548
|
import { networkInterfaces } from "os";
|
|
12464
12549
|
import { join as join39 } from "path";
|
|
12465
|
-
import
|
|
12550
|
+
import chalk133 from "chalk";
|
|
12466
12551
|
|
|
12467
12552
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12468
12553
|
import { dirname as dirname19, join as join38 } from "path";
|
|
@@ -12506,7 +12591,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12506
12591
|
const host = lanIPv4();
|
|
12507
12592
|
if (!host) {
|
|
12508
12593
|
console.log(
|
|
12509
|
-
|
|
12594
|
+
chalk133.yellow("could not determine the WSL IP for the extension")
|
|
12510
12595
|
);
|
|
12511
12596
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12512
12597
|
return source;
|
|
@@ -12517,7 +12602,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12517
12602
|
return WSL_WINDOWS_PATH;
|
|
12518
12603
|
} catch {
|
|
12519
12604
|
console.log(
|
|
12520
|
-
|
|
12605
|
+
chalk133.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12521
12606
|
);
|
|
12522
12607
|
return source;
|
|
12523
12608
|
}
|
|
@@ -12550,30 +12635,30 @@ async function netcap(options2) {
|
|
|
12550
12635
|
let count6 = 0;
|
|
12551
12636
|
const handler = createNetcapHandler({
|
|
12552
12637
|
outPath,
|
|
12553
|
-
onPing: () => console.log(
|
|
12638
|
+
onPing: () => console.log(chalk134.dim("ping from extension")),
|
|
12554
12639
|
onCapture: (entry) => {
|
|
12555
12640
|
count6 += 1;
|
|
12556
12641
|
console.log(
|
|
12557
|
-
|
|
12558
|
-
|
|
12642
|
+
chalk134.green(`captured #${count6}`),
|
|
12643
|
+
chalk134.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12559
12644
|
);
|
|
12560
12645
|
}
|
|
12561
12646
|
});
|
|
12562
12647
|
const server = createServer2(handler);
|
|
12563
12648
|
server.listen(port, () => {
|
|
12564
12649
|
console.log(
|
|
12565
|
-
|
|
12650
|
+
chalk134.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12566
12651
|
);
|
|
12567
|
-
console.log(
|
|
12652
|
+
console.log(chalk134.dim(`appending captures to ${outPath}`));
|
|
12568
12653
|
if (filter)
|
|
12569
|
-
console.log(
|
|
12570
|
-
console.log(
|
|
12571
|
-
console.log(
|
|
12654
|
+
console.log(chalk134.dim(`forwarding only URLs matching "${filter}"`));
|
|
12655
|
+
console.log(chalk134.dim(`load the unpacked extension from ${extensionPath}`));
|
|
12656
|
+
console.log(chalk134.dim("press Ctrl-C to stop"));
|
|
12572
12657
|
});
|
|
12573
12658
|
process.on("SIGINT", () => {
|
|
12574
12659
|
server.close();
|
|
12575
12660
|
console.log(
|
|
12576
|
-
|
|
12661
|
+
chalk134.bold(
|
|
12577
12662
|
`
|
|
12578
12663
|
netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12579
12664
|
)
|
|
@@ -12585,7 +12670,7 @@ netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} t
|
|
|
12585
12670
|
// src/commands/netcap/netcapExtract.ts
|
|
12586
12671
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
12587
12672
|
import { join as join42 } from "path";
|
|
12588
|
-
import
|
|
12673
|
+
import chalk135 from "chalk";
|
|
12589
12674
|
|
|
12590
12675
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12591
12676
|
import { readFileSync as readFileSync32 } from "fs";
|
|
@@ -13033,8 +13118,8 @@ function netcapExtract(file) {
|
|
|
13033
13118
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13034
13119
|
`);
|
|
13035
13120
|
console.log(
|
|
13036
|
-
|
|
13037
|
-
|
|
13121
|
+
chalk135.green(`extracted ${posts.length} posts`),
|
|
13122
|
+
chalk135.dim(`-> ${outFile}`)
|
|
13038
13123
|
);
|
|
13039
13124
|
}
|
|
13040
13125
|
|
|
@@ -13055,7 +13140,7 @@ function registerNetcap(program2) {
|
|
|
13055
13140
|
}
|
|
13056
13141
|
|
|
13057
13142
|
// src/commands/news/add/index.ts
|
|
13058
|
-
import
|
|
13143
|
+
import chalk136 from "chalk";
|
|
13059
13144
|
import enquirer8 from "enquirer";
|
|
13060
13145
|
async function add2(url) {
|
|
13061
13146
|
if (!url) {
|
|
@@ -13077,10 +13162,10 @@ async function add2(url) {
|
|
|
13077
13162
|
const { orm } = await getReady();
|
|
13078
13163
|
const added = await addFeed(orm, url);
|
|
13079
13164
|
if (!added) {
|
|
13080
|
-
console.log(
|
|
13165
|
+
console.log(chalk136.yellow("Feed already exists"));
|
|
13081
13166
|
return;
|
|
13082
13167
|
}
|
|
13083
|
-
console.log(
|
|
13168
|
+
console.log(chalk136.green(`Added feed: ${url}`));
|
|
13084
13169
|
}
|
|
13085
13170
|
|
|
13086
13171
|
// src/commands/registerNews.ts
|
|
@@ -13090,7 +13175,7 @@ function registerNews(program2) {
|
|
|
13090
13175
|
}
|
|
13091
13176
|
|
|
13092
13177
|
// src/commands/prompts/printPromptsTable.ts
|
|
13093
|
-
import
|
|
13178
|
+
import chalk137 from "chalk";
|
|
13094
13179
|
function truncate(str, max) {
|
|
13095
13180
|
if (str.length <= max) return str;
|
|
13096
13181
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -13108,14 +13193,14 @@ function printPromptsTable(rows) {
|
|
|
13108
13193
|
"Command".padEnd(commandWidth),
|
|
13109
13194
|
"Repos"
|
|
13110
13195
|
].join(" ");
|
|
13111
|
-
console.log(
|
|
13112
|
-
console.log(
|
|
13196
|
+
console.log(chalk137.dim(header));
|
|
13197
|
+
console.log(chalk137.dim("-".repeat(header.length)));
|
|
13113
13198
|
for (const row of rows) {
|
|
13114
13199
|
const count6 = String(row.count).padStart(countWidth);
|
|
13115
13200
|
const tool = row.tool.padEnd(toolWidth);
|
|
13116
13201
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
13117
13202
|
console.log(
|
|
13118
|
-
`${
|
|
13203
|
+
`${chalk137.yellow(count6)} ${tool} ${command} ${chalk137.dim(row.repos)}`
|
|
13119
13204
|
);
|
|
13120
13205
|
}
|
|
13121
13206
|
}
|
|
@@ -13664,20 +13749,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13664
13749
|
}
|
|
13665
13750
|
|
|
13666
13751
|
// src/commands/prs/listComments/printComments.ts
|
|
13667
|
-
import
|
|
13752
|
+
import chalk138 from "chalk";
|
|
13668
13753
|
function formatForHuman(comment3) {
|
|
13669
13754
|
if (comment3.type === "review") {
|
|
13670
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
13755
|
+
const stateColor = comment3.state === "APPROVED" ? chalk138.green : comment3.state === "CHANGES_REQUESTED" ? chalk138.red : chalk138.yellow;
|
|
13671
13756
|
return [
|
|
13672
|
-
`${
|
|
13757
|
+
`${chalk138.cyan("Review")} by ${chalk138.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13673
13758
|
comment3.body,
|
|
13674
13759
|
""
|
|
13675
13760
|
].join("\n");
|
|
13676
13761
|
}
|
|
13677
13762
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13678
13763
|
return [
|
|
13679
|
-
`${
|
|
13680
|
-
|
|
13764
|
+
`${chalk138.cyan("Line comment")} by ${chalk138.bold(comment3.user)} on ${chalk138.dim(`${comment3.path}${location}`)}`,
|
|
13765
|
+
chalk138.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
13681
13766
|
comment3.body,
|
|
13682
13767
|
""
|
|
13683
13768
|
].join("\n");
|
|
@@ -13767,13 +13852,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
13767
13852
|
import enquirer9 from "enquirer";
|
|
13768
13853
|
|
|
13769
13854
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
13770
|
-
import
|
|
13855
|
+
import chalk139 from "chalk";
|
|
13771
13856
|
var STATUS_MAP = {
|
|
13772
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
13773
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
13857
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk139.magenta("merged"), date: pr.mergedAt } : null,
|
|
13858
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk139.red("closed"), date: pr.closedAt } : null
|
|
13774
13859
|
};
|
|
13775
13860
|
function defaultStatus(pr) {
|
|
13776
|
-
return { label:
|
|
13861
|
+
return { label: chalk139.green("opened"), date: pr.createdAt };
|
|
13777
13862
|
}
|
|
13778
13863
|
function getStatus2(pr) {
|
|
13779
13864
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -13782,11 +13867,11 @@ function formatDate(dateStr) {
|
|
|
13782
13867
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
13783
13868
|
}
|
|
13784
13869
|
function formatPrHeader(pr, status2) {
|
|
13785
|
-
return `${
|
|
13870
|
+
return `${chalk139.cyan(`#${pr.number}`)} ${pr.title} ${chalk139.dim(`(${pr.author.login},`)} ${status2.label} ${chalk139.dim(`${formatDate(status2.date)})`)}`;
|
|
13786
13871
|
}
|
|
13787
13872
|
function logPrDetails(pr) {
|
|
13788
13873
|
console.log(
|
|
13789
|
-
|
|
13874
|
+
chalk139.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
13790
13875
|
);
|
|
13791
13876
|
console.log();
|
|
13792
13877
|
}
|
|
@@ -14093,10 +14178,10 @@ function registerPrs(program2) {
|
|
|
14093
14178
|
}
|
|
14094
14179
|
|
|
14095
14180
|
// src/commands/ravendb/ravendbAuth.ts
|
|
14096
|
-
import
|
|
14181
|
+
import chalk145 from "chalk";
|
|
14097
14182
|
|
|
14098
14183
|
// src/shared/createConnectionAuth.ts
|
|
14099
|
-
import
|
|
14184
|
+
import chalk140 from "chalk";
|
|
14100
14185
|
function listConnections(connections, format2) {
|
|
14101
14186
|
if (connections.length === 0) {
|
|
14102
14187
|
console.log("No connections configured.");
|
|
@@ -14109,7 +14194,7 @@ function listConnections(connections, format2) {
|
|
|
14109
14194
|
function removeConnection(connections, name, save) {
|
|
14110
14195
|
const filtered = connections.filter((c) => c.name !== name);
|
|
14111
14196
|
if (filtered.length === connections.length) {
|
|
14112
|
-
console.error(
|
|
14197
|
+
console.error(chalk140.red(`Connection "${name}" not found.`));
|
|
14113
14198
|
process.exit(1);
|
|
14114
14199
|
}
|
|
14115
14200
|
save(filtered);
|
|
@@ -14155,15 +14240,15 @@ function saveConnections(connections) {
|
|
|
14155
14240
|
}
|
|
14156
14241
|
|
|
14157
14242
|
// src/commands/ravendb/promptConnection.ts
|
|
14158
|
-
import
|
|
14243
|
+
import chalk143 from "chalk";
|
|
14159
14244
|
|
|
14160
14245
|
// src/commands/ravendb/selectOpSecret.ts
|
|
14161
|
-
import
|
|
14246
|
+
import chalk142 from "chalk";
|
|
14162
14247
|
import Enquirer2 from "enquirer";
|
|
14163
14248
|
|
|
14164
14249
|
// src/commands/ravendb/searchItems.ts
|
|
14165
14250
|
import { execSync as execSync41 } from "child_process";
|
|
14166
|
-
import
|
|
14251
|
+
import chalk141 from "chalk";
|
|
14167
14252
|
function opExec(args) {
|
|
14168
14253
|
return execSync41(`op ${args}`, {
|
|
14169
14254
|
encoding: "utf8",
|
|
@@ -14176,7 +14261,7 @@ function searchItems(search2) {
|
|
|
14176
14261
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
14177
14262
|
} catch {
|
|
14178
14263
|
console.error(
|
|
14179
|
-
|
|
14264
|
+
chalk141.red(
|
|
14180
14265
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
14181
14266
|
)
|
|
14182
14267
|
);
|
|
@@ -14190,7 +14275,7 @@ function getItemFields(itemId) {
|
|
|
14190
14275
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
14191
14276
|
return item.fields.filter((f) => f.reference && f.label);
|
|
14192
14277
|
} catch {
|
|
14193
|
-
console.error(
|
|
14278
|
+
console.error(chalk141.red("Failed to get item details from 1Password."));
|
|
14194
14279
|
process.exit(1);
|
|
14195
14280
|
}
|
|
14196
14281
|
}
|
|
@@ -14209,7 +14294,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14209
14294
|
}).run();
|
|
14210
14295
|
const items2 = searchItems(search2);
|
|
14211
14296
|
if (items2.length === 0) {
|
|
14212
|
-
console.error(
|
|
14297
|
+
console.error(chalk142.red(`No items found matching "${search2}".`));
|
|
14213
14298
|
process.exit(1);
|
|
14214
14299
|
}
|
|
14215
14300
|
const itemId = await selectOne(
|
|
@@ -14218,7 +14303,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14218
14303
|
);
|
|
14219
14304
|
const fields = getItemFields(itemId);
|
|
14220
14305
|
if (fields.length === 0) {
|
|
14221
|
-
console.error(
|
|
14306
|
+
console.error(chalk142.red("No fields with references found on this item."));
|
|
14222
14307
|
process.exit(1);
|
|
14223
14308
|
}
|
|
14224
14309
|
const ref = await selectOne(
|
|
@@ -14232,7 +14317,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14232
14317
|
async function promptConnection(existingNames) {
|
|
14233
14318
|
const name = await promptInput("name", "Connection name:");
|
|
14234
14319
|
if (existingNames.includes(name)) {
|
|
14235
|
-
console.error(
|
|
14320
|
+
console.error(chalk143.red(`Connection "${name}" already exists.`));
|
|
14236
14321
|
process.exit(1);
|
|
14237
14322
|
}
|
|
14238
14323
|
const url = await promptInput(
|
|
@@ -14241,22 +14326,22 @@ async function promptConnection(existingNames) {
|
|
|
14241
14326
|
);
|
|
14242
14327
|
const database = await promptInput("database", "Database name:");
|
|
14243
14328
|
if (!name || !url || !database) {
|
|
14244
|
-
console.error(
|
|
14329
|
+
console.error(chalk143.red("All fields are required."));
|
|
14245
14330
|
process.exit(1);
|
|
14246
14331
|
}
|
|
14247
14332
|
const apiKeyRef = await selectOpSecret();
|
|
14248
|
-
console.log(
|
|
14333
|
+
console.log(chalk143.dim(`Using: ${apiKeyRef}`));
|
|
14249
14334
|
return { name, url, database, apiKeyRef };
|
|
14250
14335
|
}
|
|
14251
14336
|
|
|
14252
14337
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
14253
|
-
import
|
|
14338
|
+
import chalk144 from "chalk";
|
|
14254
14339
|
function ravendbSetConnection(name) {
|
|
14255
14340
|
const raw = loadGlobalConfigRaw();
|
|
14256
14341
|
const ravendb = raw.ravendb ?? {};
|
|
14257
14342
|
const connections = ravendb.connections ?? [];
|
|
14258
14343
|
if (!connections.some((c) => c.name === name)) {
|
|
14259
|
-
console.error(
|
|
14344
|
+
console.error(chalk144.red(`Connection "${name}" not found.`));
|
|
14260
14345
|
console.error(
|
|
14261
14346
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14262
14347
|
);
|
|
@@ -14272,16 +14357,16 @@ function ravendbSetConnection(name) {
|
|
|
14272
14357
|
var ravendbAuth = createConnectionAuth({
|
|
14273
14358
|
load: loadConnections,
|
|
14274
14359
|
save: saveConnections,
|
|
14275
|
-
format: (c) => `${
|
|
14360
|
+
format: (c) => `${chalk145.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
14276
14361
|
promptNew: promptConnection,
|
|
14277
14362
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
14278
14363
|
});
|
|
14279
14364
|
|
|
14280
14365
|
// src/commands/ravendb/ravendbCollections.ts
|
|
14281
|
-
import
|
|
14366
|
+
import chalk149 from "chalk";
|
|
14282
14367
|
|
|
14283
14368
|
// src/commands/ravendb/ravenFetch.ts
|
|
14284
|
-
import
|
|
14369
|
+
import chalk147 from "chalk";
|
|
14285
14370
|
|
|
14286
14371
|
// src/commands/ravendb/getAccessToken.ts
|
|
14287
14372
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -14318,10 +14403,10 @@ ${errorText}`
|
|
|
14318
14403
|
|
|
14319
14404
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
14320
14405
|
import { execSync as execSync42 } from "child_process";
|
|
14321
|
-
import
|
|
14406
|
+
import chalk146 from "chalk";
|
|
14322
14407
|
function resolveOpSecret(reference) {
|
|
14323
14408
|
if (!reference.startsWith("op://")) {
|
|
14324
|
-
console.error(
|
|
14409
|
+
console.error(chalk146.red(`Invalid secret reference: must start with op://`));
|
|
14325
14410
|
process.exit(1);
|
|
14326
14411
|
}
|
|
14327
14412
|
try {
|
|
@@ -14331,7 +14416,7 @@ function resolveOpSecret(reference) {
|
|
|
14331
14416
|
}).trim();
|
|
14332
14417
|
} catch {
|
|
14333
14418
|
console.error(
|
|
14334
|
-
|
|
14419
|
+
chalk146.red(
|
|
14335
14420
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
14336
14421
|
)
|
|
14337
14422
|
);
|
|
@@ -14358,7 +14443,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14358
14443
|
if (!response.ok) {
|
|
14359
14444
|
const body = await response.text();
|
|
14360
14445
|
console.error(
|
|
14361
|
-
|
|
14446
|
+
chalk147.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
14362
14447
|
);
|
|
14363
14448
|
console.error(body.substring(0, 500));
|
|
14364
14449
|
process.exit(1);
|
|
@@ -14367,7 +14452,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14367
14452
|
}
|
|
14368
14453
|
|
|
14369
14454
|
// src/commands/ravendb/resolveConnection.ts
|
|
14370
|
-
import
|
|
14455
|
+
import chalk148 from "chalk";
|
|
14371
14456
|
function loadRavendb() {
|
|
14372
14457
|
const raw = loadGlobalConfigRaw();
|
|
14373
14458
|
const ravendb = raw.ravendb;
|
|
@@ -14381,7 +14466,7 @@ function resolveConnection(name) {
|
|
|
14381
14466
|
const connectionName = name ?? defaultConnection;
|
|
14382
14467
|
if (!connectionName) {
|
|
14383
14468
|
console.error(
|
|
14384
|
-
|
|
14469
|
+
chalk148.red(
|
|
14385
14470
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14386
14471
|
)
|
|
14387
14472
|
);
|
|
@@ -14389,7 +14474,7 @@ function resolveConnection(name) {
|
|
|
14389
14474
|
}
|
|
14390
14475
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14391
14476
|
if (!connection) {
|
|
14392
|
-
console.error(
|
|
14477
|
+
console.error(chalk148.red(`Connection "${connectionName}" not found.`));
|
|
14393
14478
|
console.error(
|
|
14394
14479
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14395
14480
|
);
|
|
@@ -14420,15 +14505,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14420
14505
|
return;
|
|
14421
14506
|
}
|
|
14422
14507
|
for (const c of collections) {
|
|
14423
|
-
console.log(`${
|
|
14508
|
+
console.log(`${chalk149.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14424
14509
|
}
|
|
14425
14510
|
}
|
|
14426
14511
|
|
|
14427
14512
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14428
|
-
import
|
|
14513
|
+
import chalk151 from "chalk";
|
|
14429
14514
|
|
|
14430
14515
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14431
|
-
import
|
|
14516
|
+
import chalk150 from "chalk";
|
|
14432
14517
|
|
|
14433
14518
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14434
14519
|
function buildQueryPath(opts) {
|
|
@@ -14466,7 +14551,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14466
14551
|
allResults.push(...results);
|
|
14467
14552
|
start3 += results.length;
|
|
14468
14553
|
process.stderr.write(
|
|
14469
|
-
`\r${
|
|
14554
|
+
`\r${chalk150.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14470
14555
|
);
|
|
14471
14556
|
if (start3 >= totalResults) break;
|
|
14472
14557
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14481,7 +14566,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14481
14566
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14482
14567
|
const resolved = resolveArgs(connectionName, collection);
|
|
14483
14568
|
if (!resolved.collection && !options2.query) {
|
|
14484
|
-
console.error(
|
|
14569
|
+
console.error(chalk151.red("Provide a collection name or --query filter."));
|
|
14485
14570
|
process.exit(1);
|
|
14486
14571
|
}
|
|
14487
14572
|
const { collection: col } = resolved;
|
|
@@ -14519,7 +14604,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14519
14604
|
import * as path28 from "path";
|
|
14520
14605
|
|
|
14521
14606
|
// src/commands/refactor/logViolations.ts
|
|
14522
|
-
import
|
|
14607
|
+
import chalk152 from "chalk";
|
|
14523
14608
|
var DEFAULT_MAX_LINES = 100;
|
|
14524
14609
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14525
14610
|
if (violations.length === 0) {
|
|
@@ -14528,43 +14613,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14528
14613
|
}
|
|
14529
14614
|
return;
|
|
14530
14615
|
}
|
|
14531
|
-
console.error(
|
|
14616
|
+
console.error(chalk152.red(`
|
|
14532
14617
|
Refactor check failed:
|
|
14533
14618
|
`));
|
|
14534
|
-
console.error(
|
|
14619
|
+
console.error(chalk152.red(` The following files exceed ${maxLines} lines:
|
|
14535
14620
|
`));
|
|
14536
14621
|
for (const violation of violations) {
|
|
14537
|
-
console.error(
|
|
14622
|
+
console.error(chalk152.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14538
14623
|
}
|
|
14539
14624
|
console.error(
|
|
14540
|
-
|
|
14625
|
+
chalk152.yellow(
|
|
14541
14626
|
`
|
|
14542
14627
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14543
14628
|
way to refactor it, ignore it with:
|
|
14544
14629
|
`
|
|
14545
14630
|
)
|
|
14546
14631
|
);
|
|
14547
|
-
console.error(
|
|
14632
|
+
console.error(chalk152.gray(` assist refactor ignore <file>
|
|
14548
14633
|
`));
|
|
14549
14634
|
if (process.env.CLAUDECODE) {
|
|
14550
|
-
console.error(
|
|
14635
|
+
console.error(chalk152.cyan(`
|
|
14551
14636
|
## Extracting Code to New Files
|
|
14552
14637
|
`));
|
|
14553
14638
|
console.error(
|
|
14554
|
-
|
|
14639
|
+
chalk152.cyan(
|
|
14555
14640
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14556
14641
|
`
|
|
14557
14642
|
)
|
|
14558
14643
|
);
|
|
14559
14644
|
console.error(
|
|
14560
|
-
|
|
14645
|
+
chalk152.cyan(
|
|
14561
14646
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14562
14647
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14563
14648
|
`
|
|
14564
14649
|
)
|
|
14565
14650
|
);
|
|
14566
14651
|
console.error(
|
|
14567
|
-
|
|
14652
|
+
chalk152.cyan(
|
|
14568
14653
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14569
14654
|
domains, move it to a common/shared folder.
|
|
14570
14655
|
`
|
|
@@ -14720,7 +14805,7 @@ async function check(pattern2, options2) {
|
|
|
14720
14805
|
|
|
14721
14806
|
// src/commands/refactor/extract/index.ts
|
|
14722
14807
|
import path35 from "path";
|
|
14723
|
-
import
|
|
14808
|
+
import chalk155 from "chalk";
|
|
14724
14809
|
|
|
14725
14810
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
14726
14811
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -15295,23 +15380,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
15295
15380
|
|
|
15296
15381
|
// src/commands/refactor/extract/displayPlan.ts
|
|
15297
15382
|
import path32 from "path";
|
|
15298
|
-
import
|
|
15383
|
+
import chalk153 from "chalk";
|
|
15299
15384
|
function section(title) {
|
|
15300
15385
|
return `
|
|
15301
|
-
${
|
|
15386
|
+
${chalk153.cyan(title)}`;
|
|
15302
15387
|
}
|
|
15303
15388
|
function displayImporters(plan2, cwd) {
|
|
15304
15389
|
if (plan2.importersToUpdate.length === 0) return;
|
|
15305
15390
|
console.log(section("Update importers:"));
|
|
15306
15391
|
for (const imp of plan2.importersToUpdate) {
|
|
15307
15392
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
15308
|
-
console.log(` ${
|
|
15393
|
+
console.log(` ${chalk153.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
15309
15394
|
}
|
|
15310
15395
|
}
|
|
15311
15396
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
15312
|
-
console.log(
|
|
15397
|
+
console.log(chalk153.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
15313
15398
|
`));
|
|
15314
|
-
console.log(` ${
|
|
15399
|
+
console.log(` ${chalk153.cyan("Functions to move:")}`);
|
|
15315
15400
|
for (const name of plan2.extractedNames) {
|
|
15316
15401
|
console.log(` ${name}`);
|
|
15317
15402
|
}
|
|
@@ -15345,7 +15430,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
15345
15430
|
|
|
15346
15431
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
15347
15432
|
import path34 from "path";
|
|
15348
|
-
import
|
|
15433
|
+
import chalk154 from "chalk";
|
|
15349
15434
|
import { Project as Project4 } from "ts-morph";
|
|
15350
15435
|
|
|
15351
15436
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -15405,7 +15490,7 @@ function loadProjectFile(file) {
|
|
|
15405
15490
|
});
|
|
15406
15491
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15407
15492
|
if (!sourceFile) {
|
|
15408
|
-
console.log(
|
|
15493
|
+
console.log(chalk154.red(`File not found in project: ${file}`));
|
|
15409
15494
|
process.exit(1);
|
|
15410
15495
|
}
|
|
15411
15496
|
return { project, sourceFile };
|
|
@@ -15428,19 +15513,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15428
15513
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15429
15514
|
if (options2.apply) {
|
|
15430
15515
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15431
|
-
console.log(
|
|
15516
|
+
console.log(chalk155.green("\nExtraction complete"));
|
|
15432
15517
|
} else {
|
|
15433
|
-
console.log(
|
|
15518
|
+
console.log(chalk155.dim("\nDry run. Use --apply to execute."));
|
|
15434
15519
|
}
|
|
15435
15520
|
}
|
|
15436
15521
|
|
|
15437
15522
|
// src/commands/refactor/ignore.ts
|
|
15438
15523
|
import fs23 from "fs";
|
|
15439
|
-
import
|
|
15524
|
+
import chalk156 from "chalk";
|
|
15440
15525
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15441
15526
|
function ignore(file) {
|
|
15442
15527
|
if (!fs23.existsSync(file)) {
|
|
15443
|
-
console.error(
|
|
15528
|
+
console.error(chalk156.red(`Error: File does not exist: ${file}`));
|
|
15444
15529
|
process.exit(1);
|
|
15445
15530
|
}
|
|
15446
15531
|
const content = fs23.readFileSync(file, "utf8");
|
|
@@ -15456,7 +15541,7 @@ function ignore(file) {
|
|
|
15456
15541
|
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15457
15542
|
}
|
|
15458
15543
|
console.log(
|
|
15459
|
-
|
|
15544
|
+
chalk156.green(
|
|
15460
15545
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15461
15546
|
)
|
|
15462
15547
|
);
|
|
@@ -15465,12 +15550,12 @@ function ignore(file) {
|
|
|
15465
15550
|
// src/commands/refactor/rename/index.ts
|
|
15466
15551
|
import fs26 from "fs";
|
|
15467
15552
|
import path40 from "path";
|
|
15468
|
-
import
|
|
15553
|
+
import chalk159 from "chalk";
|
|
15469
15554
|
|
|
15470
15555
|
// src/commands/refactor/rename/applyRename.ts
|
|
15471
15556
|
import fs25 from "fs";
|
|
15472
15557
|
import path37 from "path";
|
|
15473
|
-
import
|
|
15558
|
+
import chalk157 from "chalk";
|
|
15474
15559
|
|
|
15475
15560
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15476
15561
|
import path36 from "path";
|
|
@@ -15575,13 +15660,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
15575
15660
|
const updatedContents = applyRewrites(rewrites);
|
|
15576
15661
|
for (const [file, content] of updatedContents) {
|
|
15577
15662
|
fs25.writeFileSync(file, content, "utf8");
|
|
15578
|
-
console.log(
|
|
15663
|
+
console.log(chalk157.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15579
15664
|
}
|
|
15580
15665
|
const destDir = path37.dirname(destPath);
|
|
15581
15666
|
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15582
15667
|
fs25.renameSync(sourcePath, destPath);
|
|
15583
15668
|
console.log(
|
|
15584
|
-
|
|
15669
|
+
chalk157.white(
|
|
15585
15670
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15586
15671
|
)
|
|
15587
15672
|
);
|
|
@@ -15668,16 +15753,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15668
15753
|
|
|
15669
15754
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15670
15755
|
import path39 from "path";
|
|
15671
|
-
import
|
|
15756
|
+
import chalk158 from "chalk";
|
|
15672
15757
|
function printRenamePreview(rewrites, cwd) {
|
|
15673
15758
|
for (const rewrite of rewrites) {
|
|
15674
15759
|
console.log(
|
|
15675
|
-
|
|
15760
|
+
chalk158.dim(
|
|
15676
15761
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15677
15762
|
)
|
|
15678
15763
|
);
|
|
15679
15764
|
}
|
|
15680
|
-
console.log(
|
|
15765
|
+
console.log(chalk158.dim("Dry run. Use --apply to execute."));
|
|
15681
15766
|
}
|
|
15682
15767
|
|
|
15683
15768
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15688,20 +15773,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15688
15773
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15689
15774
|
const relDest = path40.relative(cwd, destPath);
|
|
15690
15775
|
if (!fs26.existsSync(sourcePath)) {
|
|
15691
|
-
console.log(
|
|
15776
|
+
console.log(chalk159.red(`File not found: ${source}`));
|
|
15692
15777
|
process.exit(1);
|
|
15693
15778
|
}
|
|
15694
15779
|
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15695
|
-
console.log(
|
|
15780
|
+
console.log(chalk159.red(`Destination already exists: ${destination}`));
|
|
15696
15781
|
process.exit(1);
|
|
15697
15782
|
}
|
|
15698
|
-
console.log(
|
|
15699
|
-
console.log(
|
|
15700
|
-
console.log(
|
|
15783
|
+
console.log(chalk159.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
15784
|
+
console.log(chalk159.dim("Loading project..."));
|
|
15785
|
+
console.log(chalk159.dim("Scanning imports across the project..."));
|
|
15701
15786
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15702
15787
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15703
15788
|
console.log(
|
|
15704
|
-
|
|
15789
|
+
chalk159.dim(
|
|
15705
15790
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15706
15791
|
)
|
|
15707
15792
|
);
|
|
@@ -15710,11 +15795,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15710
15795
|
return;
|
|
15711
15796
|
}
|
|
15712
15797
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
15713
|
-
console.log(
|
|
15798
|
+
console.log(chalk159.green("Done"));
|
|
15714
15799
|
}
|
|
15715
15800
|
|
|
15716
15801
|
// src/commands/refactor/renameSymbol/index.ts
|
|
15717
|
-
import
|
|
15802
|
+
import chalk160 from "chalk";
|
|
15718
15803
|
|
|
15719
15804
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
15720
15805
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -15760,33 +15845,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
15760
15845
|
const { project, sourceFile } = loadProjectFile(file);
|
|
15761
15846
|
const symbol = findSymbol(sourceFile, oldName);
|
|
15762
15847
|
if (!symbol) {
|
|
15763
|
-
console.log(
|
|
15848
|
+
console.log(chalk160.red(`Symbol "${oldName}" not found in ${file}`));
|
|
15764
15849
|
process.exit(1);
|
|
15765
15850
|
}
|
|
15766
15851
|
const grouped = groupReferences(symbol, cwd);
|
|
15767
15852
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
15768
15853
|
console.log(
|
|
15769
|
-
|
|
15854
|
+
chalk160.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
15770
15855
|
`)
|
|
15771
15856
|
);
|
|
15772
15857
|
for (const [refFile, lines] of grouped) {
|
|
15773
15858
|
console.log(
|
|
15774
|
-
` ${
|
|
15859
|
+
` ${chalk160.dim(refFile)}: lines ${chalk160.cyan(lines.join(", "))}`
|
|
15775
15860
|
);
|
|
15776
15861
|
}
|
|
15777
15862
|
if (options2.apply) {
|
|
15778
15863
|
symbol.rename(newName);
|
|
15779
15864
|
await project.save();
|
|
15780
|
-
console.log(
|
|
15865
|
+
console.log(chalk160.green(`
|
|
15781
15866
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
15782
15867
|
} else {
|
|
15783
|
-
console.log(
|
|
15868
|
+
console.log(chalk160.dim("\nDry run. Use --apply to execute."));
|
|
15784
15869
|
}
|
|
15785
15870
|
}
|
|
15786
15871
|
|
|
15787
15872
|
// src/commands/refactor/restructure/index.ts
|
|
15788
15873
|
import path48 from "path";
|
|
15789
|
-
import
|
|
15874
|
+
import chalk163 from "chalk";
|
|
15790
15875
|
|
|
15791
15876
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
15792
15877
|
import path42 from "path";
|
|
@@ -15865,50 +15950,50 @@ function clusterFiles(graph) {
|
|
|
15865
15950
|
|
|
15866
15951
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
15867
15952
|
import path44 from "path";
|
|
15868
|
-
import
|
|
15953
|
+
import chalk161 from "chalk";
|
|
15869
15954
|
function relPath(filePath) {
|
|
15870
15955
|
return path44.relative(process.cwd(), filePath);
|
|
15871
15956
|
}
|
|
15872
15957
|
function displayMoves(plan2) {
|
|
15873
15958
|
if (plan2.moves.length === 0) return;
|
|
15874
|
-
console.log(
|
|
15959
|
+
console.log(chalk161.bold("\nFile moves:"));
|
|
15875
15960
|
for (const move of plan2.moves) {
|
|
15876
15961
|
console.log(
|
|
15877
|
-
` ${
|
|
15962
|
+
` ${chalk161.red(relPath(move.from))} \u2192 ${chalk161.green(relPath(move.to))}`
|
|
15878
15963
|
);
|
|
15879
|
-
console.log(
|
|
15964
|
+
console.log(chalk161.dim(` ${move.reason}`));
|
|
15880
15965
|
}
|
|
15881
15966
|
}
|
|
15882
15967
|
function displayRewrites(rewrites) {
|
|
15883
15968
|
if (rewrites.length === 0) return;
|
|
15884
15969
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
15885
|
-
console.log(
|
|
15970
|
+
console.log(chalk161.bold(`
|
|
15886
15971
|
Import rewrites (${affectedFiles.size} files):`));
|
|
15887
15972
|
for (const file of affectedFiles) {
|
|
15888
|
-
console.log(` ${
|
|
15973
|
+
console.log(` ${chalk161.cyan(relPath(file))}:`);
|
|
15889
15974
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
15890
15975
|
(r) => r.file === file
|
|
15891
15976
|
)) {
|
|
15892
15977
|
console.log(
|
|
15893
|
-
` ${
|
|
15978
|
+
` ${chalk161.red(`"${oldSpecifier}"`)} \u2192 ${chalk161.green(`"${newSpecifier}"`)}`
|
|
15894
15979
|
);
|
|
15895
15980
|
}
|
|
15896
15981
|
}
|
|
15897
15982
|
}
|
|
15898
15983
|
function displayPlan2(plan2) {
|
|
15899
15984
|
if (plan2.warnings.length > 0) {
|
|
15900
|
-
console.log(
|
|
15901
|
-
for (const w of plan2.warnings) console.log(
|
|
15985
|
+
console.log(chalk161.yellow("\nWarnings:"));
|
|
15986
|
+
for (const w of plan2.warnings) console.log(chalk161.yellow(` ${w}`));
|
|
15902
15987
|
}
|
|
15903
15988
|
if (plan2.newDirectories.length > 0) {
|
|
15904
|
-
console.log(
|
|
15989
|
+
console.log(chalk161.bold("\nNew directories:"));
|
|
15905
15990
|
for (const dir of plan2.newDirectories)
|
|
15906
|
-
console.log(
|
|
15991
|
+
console.log(chalk161.green(` ${dir}/`));
|
|
15907
15992
|
}
|
|
15908
15993
|
displayMoves(plan2);
|
|
15909
15994
|
displayRewrites(plan2.rewrites);
|
|
15910
15995
|
console.log(
|
|
15911
|
-
|
|
15996
|
+
chalk161.dim(
|
|
15912
15997
|
`
|
|
15913
15998
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
15914
15999
|
)
|
|
@@ -15918,18 +16003,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
15918
16003
|
// src/commands/refactor/restructure/executePlan.ts
|
|
15919
16004
|
import fs27 from "fs";
|
|
15920
16005
|
import path45 from "path";
|
|
15921
|
-
import
|
|
16006
|
+
import chalk162 from "chalk";
|
|
15922
16007
|
function executePlan(plan2) {
|
|
15923
16008
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
15924
16009
|
for (const [file, content] of updatedContents) {
|
|
15925
16010
|
fs27.writeFileSync(file, content, "utf8");
|
|
15926
16011
|
console.log(
|
|
15927
|
-
|
|
16012
|
+
chalk162.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
15928
16013
|
);
|
|
15929
16014
|
}
|
|
15930
16015
|
for (const dir of plan2.newDirectories) {
|
|
15931
16016
|
fs27.mkdirSync(dir, { recursive: true });
|
|
15932
|
-
console.log(
|
|
16017
|
+
console.log(chalk162.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
15933
16018
|
}
|
|
15934
16019
|
for (const move of plan2.moves) {
|
|
15935
16020
|
const targetDir = path45.dirname(move.to);
|
|
@@ -15938,7 +16023,7 @@ function executePlan(plan2) {
|
|
|
15938
16023
|
}
|
|
15939
16024
|
fs27.renameSync(move.from, move.to);
|
|
15940
16025
|
console.log(
|
|
15941
|
-
|
|
16026
|
+
chalk162.white(
|
|
15942
16027
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
15943
16028
|
)
|
|
15944
16029
|
);
|
|
@@ -15953,7 +16038,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
15953
16038
|
if (entries.length === 0) {
|
|
15954
16039
|
fs27.rmdirSync(dir);
|
|
15955
16040
|
console.log(
|
|
15956
|
-
|
|
16041
|
+
chalk162.dim(
|
|
15957
16042
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
15958
16043
|
)
|
|
15959
16044
|
);
|
|
@@ -16086,22 +16171,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
16086
16171
|
const targetPattern = pattern2 ?? "src";
|
|
16087
16172
|
const files = findSourceFiles2(targetPattern);
|
|
16088
16173
|
if (files.length === 0) {
|
|
16089
|
-
console.log(
|
|
16174
|
+
console.log(chalk163.yellow("No files found matching pattern"));
|
|
16090
16175
|
return;
|
|
16091
16176
|
}
|
|
16092
16177
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
16093
16178
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
16094
16179
|
if (plan2.moves.length === 0) {
|
|
16095
|
-
console.log(
|
|
16180
|
+
console.log(chalk163.green("No restructuring needed"));
|
|
16096
16181
|
return;
|
|
16097
16182
|
}
|
|
16098
16183
|
displayPlan2(plan2);
|
|
16099
16184
|
if (options2.apply) {
|
|
16100
|
-
console.log(
|
|
16185
|
+
console.log(chalk163.bold("\nApplying changes..."));
|
|
16101
16186
|
executePlan(plan2);
|
|
16102
|
-
console.log(
|
|
16187
|
+
console.log(chalk163.green("\nRestructuring complete"));
|
|
16103
16188
|
} else {
|
|
16104
|
-
console.log(
|
|
16189
|
+
console.log(chalk163.dim("\nDry run. Use --apply to execute."));
|
|
16105
16190
|
}
|
|
16106
16191
|
}
|
|
16107
16192
|
|
|
@@ -16670,18 +16755,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16670
16755
|
}
|
|
16671
16756
|
|
|
16672
16757
|
// src/commands/review/warnOutOfDiff.ts
|
|
16673
|
-
import
|
|
16758
|
+
import chalk164 from "chalk";
|
|
16674
16759
|
function warnOutOfDiff(outOfDiff) {
|
|
16675
16760
|
if (outOfDiff.length === 0) return;
|
|
16676
16761
|
console.warn(
|
|
16677
|
-
|
|
16762
|
+
chalk164.yellow(
|
|
16678
16763
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16679
16764
|
)
|
|
16680
16765
|
);
|
|
16681
16766
|
for (const finding of outOfDiff) {
|
|
16682
16767
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16683
16768
|
console.warn(
|
|
16684
|
-
` ${
|
|
16769
|
+
` ${chalk164.yellow("\xB7")} ${finding.title} ${chalk164.dim(
|
|
16685
16770
|
`(${finding.file}:${range})`
|
|
16686
16771
|
)}`
|
|
16687
16772
|
);
|
|
@@ -16700,18 +16785,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16700
16785
|
}
|
|
16701
16786
|
|
|
16702
16787
|
// src/commands/review/warnUnlocated.ts
|
|
16703
|
-
import
|
|
16788
|
+
import chalk165 from "chalk";
|
|
16704
16789
|
function warnUnlocated(unlocated) {
|
|
16705
16790
|
if (unlocated.length === 0) return;
|
|
16706
16791
|
console.warn(
|
|
16707
|
-
|
|
16792
|
+
chalk165.yellow(
|
|
16708
16793
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
16709
16794
|
)
|
|
16710
16795
|
);
|
|
16711
16796
|
for (const finding of unlocated) {
|
|
16712
|
-
const where = finding.location ||
|
|
16797
|
+
const where = finding.location || chalk165.dim("missing");
|
|
16713
16798
|
console.warn(
|
|
16714
|
-
` ${
|
|
16799
|
+
` ${chalk165.yellow("\xB7")} ${finding.title} ${chalk165.dim(`(${where})`)}`
|
|
16715
16800
|
);
|
|
16716
16801
|
}
|
|
16717
16802
|
}
|
|
@@ -17882,7 +17967,7 @@ function registerReview(program2) {
|
|
|
17882
17967
|
}
|
|
17883
17968
|
|
|
17884
17969
|
// src/commands/seq/seqAuth.ts
|
|
17885
|
-
import
|
|
17970
|
+
import chalk167 from "chalk";
|
|
17886
17971
|
|
|
17887
17972
|
// src/commands/seq/loadConnections.ts
|
|
17888
17973
|
function loadConnections2() {
|
|
@@ -17911,10 +17996,10 @@ function setDefaultConnection(name) {
|
|
|
17911
17996
|
}
|
|
17912
17997
|
|
|
17913
17998
|
// src/shared/assertUniqueName.ts
|
|
17914
|
-
import
|
|
17999
|
+
import chalk166 from "chalk";
|
|
17915
18000
|
function assertUniqueName(existingNames, name) {
|
|
17916
18001
|
if (existingNames.includes(name)) {
|
|
17917
|
-
console.error(
|
|
18002
|
+
console.error(chalk166.red(`Connection "${name}" already exists.`));
|
|
17918
18003
|
process.exit(1);
|
|
17919
18004
|
}
|
|
17920
18005
|
}
|
|
@@ -17932,16 +18017,16 @@ async function promptConnection2(existingNames) {
|
|
|
17932
18017
|
var seqAuth = createConnectionAuth({
|
|
17933
18018
|
load: loadConnections2,
|
|
17934
18019
|
save: saveConnections2,
|
|
17935
|
-
format: (c) => `${
|
|
18020
|
+
format: (c) => `${chalk167.bold(c.name)} ${c.url}`,
|
|
17936
18021
|
promptNew: promptConnection2,
|
|
17937
18022
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
17938
18023
|
});
|
|
17939
18024
|
|
|
17940
18025
|
// src/commands/seq/seqQuery.ts
|
|
17941
|
-
import
|
|
18026
|
+
import chalk171 from "chalk";
|
|
17942
18027
|
|
|
17943
18028
|
// src/commands/seq/fetchSeq.ts
|
|
17944
|
-
import
|
|
18029
|
+
import chalk168 from "chalk";
|
|
17945
18030
|
async function fetchSeq(conn, path57, params) {
|
|
17946
18031
|
const url = `${conn.url}${path57}?${params}`;
|
|
17947
18032
|
const response = await fetch(url, {
|
|
@@ -17952,7 +18037,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
17952
18037
|
});
|
|
17953
18038
|
if (!response.ok) {
|
|
17954
18039
|
const body = await response.text();
|
|
17955
|
-
console.error(
|
|
18040
|
+
console.error(chalk168.red(`Seq returned ${response.status}: ${body}`));
|
|
17956
18041
|
process.exit(1);
|
|
17957
18042
|
}
|
|
17958
18043
|
return response;
|
|
@@ -18011,23 +18096,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
18011
18096
|
}
|
|
18012
18097
|
|
|
18013
18098
|
// src/commands/seq/formatEvent.ts
|
|
18014
|
-
import
|
|
18099
|
+
import chalk169 from "chalk";
|
|
18015
18100
|
function levelColor(level) {
|
|
18016
18101
|
switch (level) {
|
|
18017
18102
|
case "Fatal":
|
|
18018
|
-
return
|
|
18103
|
+
return chalk169.bgRed.white;
|
|
18019
18104
|
case "Error":
|
|
18020
|
-
return
|
|
18105
|
+
return chalk169.red;
|
|
18021
18106
|
case "Warning":
|
|
18022
|
-
return
|
|
18107
|
+
return chalk169.yellow;
|
|
18023
18108
|
case "Information":
|
|
18024
|
-
return
|
|
18109
|
+
return chalk169.cyan;
|
|
18025
18110
|
case "Debug":
|
|
18026
|
-
return
|
|
18111
|
+
return chalk169.gray;
|
|
18027
18112
|
case "Verbose":
|
|
18028
|
-
return
|
|
18113
|
+
return chalk169.dim;
|
|
18029
18114
|
default:
|
|
18030
|
-
return
|
|
18115
|
+
return chalk169.white;
|
|
18031
18116
|
}
|
|
18032
18117
|
}
|
|
18033
18118
|
function levelAbbrev(level) {
|
|
@@ -18068,12 +18153,12 @@ function formatTimestamp(iso) {
|
|
|
18068
18153
|
function formatEvent(event) {
|
|
18069
18154
|
const color = levelColor(event.Level);
|
|
18070
18155
|
const abbrev = levelAbbrev(event.Level);
|
|
18071
|
-
const ts8 =
|
|
18156
|
+
const ts8 = chalk169.dim(formatTimestamp(event.Timestamp));
|
|
18072
18157
|
const msg = renderMessage(event);
|
|
18073
18158
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
18074
18159
|
if (event.Exception) {
|
|
18075
18160
|
for (const line of event.Exception.split("\n")) {
|
|
18076
|
-
lines.push(
|
|
18161
|
+
lines.push(chalk169.red(` ${line}`));
|
|
18077
18162
|
}
|
|
18078
18163
|
}
|
|
18079
18164
|
return lines.join("\n");
|
|
@@ -18106,11 +18191,11 @@ function rejectTimestampFilter(filter) {
|
|
|
18106
18191
|
}
|
|
18107
18192
|
|
|
18108
18193
|
// src/shared/resolveNamedConnection.ts
|
|
18109
|
-
import
|
|
18194
|
+
import chalk170 from "chalk";
|
|
18110
18195
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
18111
18196
|
if (connections.length === 0) {
|
|
18112
18197
|
console.error(
|
|
18113
|
-
|
|
18198
|
+
chalk170.red(
|
|
18114
18199
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
18115
18200
|
)
|
|
18116
18201
|
);
|
|
@@ -18119,7 +18204,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
18119
18204
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
18120
18205
|
const connection = connections.find((c) => c.name === target);
|
|
18121
18206
|
if (!connection) {
|
|
18122
|
-
console.error(
|
|
18207
|
+
console.error(chalk170.red(`${kind} connection "${target}" not found.`));
|
|
18123
18208
|
process.exit(1);
|
|
18124
18209
|
}
|
|
18125
18210
|
return connection;
|
|
@@ -18148,7 +18233,7 @@ async function seqQuery(filter, options2) {
|
|
|
18148
18233
|
new URLSearchParams({ filter, count: String(count6) })
|
|
18149
18234
|
);
|
|
18150
18235
|
if (events.length === 0) {
|
|
18151
|
-
console.log(
|
|
18236
|
+
console.log(chalk171.yellow("No events found."));
|
|
18152
18237
|
return;
|
|
18153
18238
|
}
|
|
18154
18239
|
if (options2.json) {
|
|
@@ -18159,11 +18244,11 @@ async function seqQuery(filter, options2) {
|
|
|
18159
18244
|
for (const event of chronological) {
|
|
18160
18245
|
console.log(formatEvent(event));
|
|
18161
18246
|
}
|
|
18162
|
-
console.log(
|
|
18247
|
+
console.log(chalk171.dim(`
|
|
18163
18248
|
${events.length} events`));
|
|
18164
18249
|
if (events.length >= count6) {
|
|
18165
18250
|
console.log(
|
|
18166
|
-
|
|
18251
|
+
chalk171.yellow(
|
|
18167
18252
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
18168
18253
|
)
|
|
18169
18254
|
);
|
|
@@ -18171,10 +18256,10 @@ ${events.length} events`));
|
|
|
18171
18256
|
}
|
|
18172
18257
|
|
|
18173
18258
|
// src/shared/setNamedDefaultConnection.ts
|
|
18174
|
-
import
|
|
18259
|
+
import chalk172 from "chalk";
|
|
18175
18260
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
18176
18261
|
if (!connections.find((c) => c.name === name)) {
|
|
18177
|
-
console.error(
|
|
18262
|
+
console.error(chalk172.red(`Connection "${name}" not found.`));
|
|
18178
18263
|
process.exit(1);
|
|
18179
18264
|
}
|
|
18180
18265
|
setDefault(name);
|
|
@@ -18222,7 +18307,7 @@ function registerSignal(program2) {
|
|
|
18222
18307
|
}
|
|
18223
18308
|
|
|
18224
18309
|
// src/commands/sql/sqlAuth.ts
|
|
18225
|
-
import
|
|
18310
|
+
import chalk174 from "chalk";
|
|
18226
18311
|
|
|
18227
18312
|
// src/commands/sql/loadConnections.ts
|
|
18228
18313
|
function loadConnections3() {
|
|
@@ -18251,7 +18336,7 @@ function setDefaultConnection2(name) {
|
|
|
18251
18336
|
}
|
|
18252
18337
|
|
|
18253
18338
|
// src/commands/sql/promptConnection.ts
|
|
18254
|
-
import
|
|
18339
|
+
import chalk173 from "chalk";
|
|
18255
18340
|
async function promptConnection3(existingNames) {
|
|
18256
18341
|
const name = await promptInput("name", "Connection name:", "default");
|
|
18257
18342
|
assertUniqueName(existingNames, name);
|
|
@@ -18259,7 +18344,7 @@ async function promptConnection3(existingNames) {
|
|
|
18259
18344
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
18260
18345
|
const port = Number.parseInt(portStr, 10);
|
|
18261
18346
|
if (!Number.isFinite(port)) {
|
|
18262
|
-
console.error(
|
|
18347
|
+
console.error(chalk173.red(`Invalid port "${portStr}".`));
|
|
18263
18348
|
process.exit(1);
|
|
18264
18349
|
}
|
|
18265
18350
|
const user = await promptInput("user", "User:");
|
|
@@ -18272,13 +18357,13 @@ async function promptConnection3(existingNames) {
|
|
|
18272
18357
|
var sqlAuth = createConnectionAuth({
|
|
18273
18358
|
load: loadConnections3,
|
|
18274
18359
|
save: saveConnections3,
|
|
18275
|
-
format: (c) => `${
|
|
18360
|
+
format: (c) => `${chalk174.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
18276
18361
|
promptNew: promptConnection3,
|
|
18277
18362
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
18278
18363
|
});
|
|
18279
18364
|
|
|
18280
18365
|
// src/commands/sql/printTable.ts
|
|
18281
|
-
import
|
|
18366
|
+
import chalk175 from "chalk";
|
|
18282
18367
|
function formatCell(value) {
|
|
18283
18368
|
if (value === null || value === void 0) return "";
|
|
18284
18369
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -18287,7 +18372,7 @@ function formatCell(value) {
|
|
|
18287
18372
|
}
|
|
18288
18373
|
function printTable(rows) {
|
|
18289
18374
|
if (rows.length === 0) {
|
|
18290
|
-
console.log(
|
|
18375
|
+
console.log(chalk175.yellow("(no rows)"));
|
|
18291
18376
|
return;
|
|
18292
18377
|
}
|
|
18293
18378
|
const columns = Object.keys(rows[0]);
|
|
@@ -18295,13 +18380,13 @@ function printTable(rows) {
|
|
|
18295
18380
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
18296
18381
|
);
|
|
18297
18382
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
18298
|
-
console.log(
|
|
18299
|
-
console.log(
|
|
18383
|
+
console.log(chalk175.dim(header));
|
|
18384
|
+
console.log(chalk175.dim("-".repeat(header.length)));
|
|
18300
18385
|
for (const row of rows) {
|
|
18301
18386
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
18302
18387
|
console.log(line);
|
|
18303
18388
|
}
|
|
18304
|
-
console.log(
|
|
18389
|
+
console.log(chalk175.dim(`
|
|
18305
18390
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
18306
18391
|
}
|
|
18307
18392
|
|
|
@@ -18361,7 +18446,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
18361
18446
|
}
|
|
18362
18447
|
|
|
18363
18448
|
// src/commands/sql/sqlMutate.ts
|
|
18364
|
-
import
|
|
18449
|
+
import chalk176 from "chalk";
|
|
18365
18450
|
|
|
18366
18451
|
// src/commands/sql/isMutation.ts
|
|
18367
18452
|
var MUTATION_KEYWORDS = [
|
|
@@ -18395,7 +18480,7 @@ function isMutation(sql6) {
|
|
|
18395
18480
|
async function sqlMutate(query, connectionName) {
|
|
18396
18481
|
if (!isMutation(query)) {
|
|
18397
18482
|
console.error(
|
|
18398
|
-
|
|
18483
|
+
chalk176.red(
|
|
18399
18484
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18400
18485
|
)
|
|
18401
18486
|
);
|
|
@@ -18405,18 +18490,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18405
18490
|
const pool = await sqlConnect(conn);
|
|
18406
18491
|
try {
|
|
18407
18492
|
const result = await pool.request().query(query);
|
|
18408
|
-
console.log(
|
|
18493
|
+
console.log(chalk176.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18409
18494
|
} finally {
|
|
18410
18495
|
await pool.close();
|
|
18411
18496
|
}
|
|
18412
18497
|
}
|
|
18413
18498
|
|
|
18414
18499
|
// src/commands/sql/sqlQuery.ts
|
|
18415
|
-
import
|
|
18500
|
+
import chalk177 from "chalk";
|
|
18416
18501
|
async function sqlQuery(query, connectionName) {
|
|
18417
18502
|
if (isMutation(query)) {
|
|
18418
18503
|
console.error(
|
|
18419
|
-
|
|
18504
|
+
chalk177.red(
|
|
18420
18505
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18421
18506
|
)
|
|
18422
18507
|
);
|
|
@@ -18431,7 +18516,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18431
18516
|
printTable(rows);
|
|
18432
18517
|
} else {
|
|
18433
18518
|
console.log(
|
|
18434
|
-
|
|
18519
|
+
chalk177.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18435
18520
|
);
|
|
18436
18521
|
}
|
|
18437
18522
|
} finally {
|
|
@@ -19011,14 +19096,14 @@ import {
|
|
|
19011
19096
|
import { dirname as dirname24, join as join52 } from "path";
|
|
19012
19097
|
|
|
19013
19098
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
19014
|
-
import
|
|
19099
|
+
import chalk178 from "chalk";
|
|
19015
19100
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
19016
19101
|
function validateStagedContent(filename, content) {
|
|
19017
19102
|
const firstLine = content.split("\n")[0];
|
|
19018
19103
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
19019
19104
|
if (!match) {
|
|
19020
19105
|
console.error(
|
|
19021
|
-
|
|
19106
|
+
chalk178.red(
|
|
19022
19107
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
19023
19108
|
)
|
|
19024
19109
|
);
|
|
@@ -19027,7 +19112,7 @@ function validateStagedContent(filename, content) {
|
|
|
19027
19112
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
19028
19113
|
if (!contentAfterLink) {
|
|
19029
19114
|
console.error(
|
|
19030
|
-
|
|
19115
|
+
chalk178.red(
|
|
19031
19116
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
19032
19117
|
)
|
|
19033
19118
|
);
|
|
@@ -19431,7 +19516,7 @@ function registerVoice(program2) {
|
|
|
19431
19516
|
|
|
19432
19517
|
// src/commands/roam/auth.ts
|
|
19433
19518
|
import { randomBytes } from "crypto";
|
|
19434
|
-
import
|
|
19519
|
+
import chalk179 from "chalk";
|
|
19435
19520
|
|
|
19436
19521
|
// src/commands/roam/waitForCallback.ts
|
|
19437
19522
|
import { createServer as createServer3 } from "http";
|
|
@@ -19562,13 +19647,13 @@ async function auth() {
|
|
|
19562
19647
|
saveGlobalConfig(config);
|
|
19563
19648
|
const state = randomBytes(16).toString("hex");
|
|
19564
19649
|
console.log(
|
|
19565
|
-
|
|
19650
|
+
chalk179.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19566
19651
|
);
|
|
19567
|
-
console.log(
|
|
19568
|
-
console.log(
|
|
19569
|
-
console.log(
|
|
19652
|
+
console.log(chalk179.white("http://localhost:14523/callback\n"));
|
|
19653
|
+
console.log(chalk179.blue("Opening browser for authorization..."));
|
|
19654
|
+
console.log(chalk179.dim("Waiting for authorization callback..."));
|
|
19570
19655
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19571
|
-
console.log(
|
|
19656
|
+
console.log(chalk179.dim("Exchanging code for tokens..."));
|
|
19572
19657
|
const tokens = await exchangeToken({
|
|
19573
19658
|
code,
|
|
19574
19659
|
clientId,
|
|
@@ -19584,7 +19669,7 @@ async function auth() {
|
|
|
19584
19669
|
};
|
|
19585
19670
|
saveGlobalConfig(config);
|
|
19586
19671
|
console.log(
|
|
19587
|
-
|
|
19672
|
+
chalk179.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19588
19673
|
);
|
|
19589
19674
|
}
|
|
19590
19675
|
|
|
@@ -20036,7 +20121,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
20036
20121
|
import { existsSync as existsSync52, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20037
20122
|
import { tmpdir as tmpdir7 } from "os";
|
|
20038
20123
|
import { join as join63, resolve as resolve15 } from "path";
|
|
20039
|
-
import
|
|
20124
|
+
import chalk180 from "chalk";
|
|
20040
20125
|
|
|
20041
20126
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
20042
20127
|
var captureWindowPs1 = `
|
|
@@ -20187,13 +20272,13 @@ function screenshot(processName) {
|
|
|
20187
20272
|
const config = loadConfig();
|
|
20188
20273
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
20189
20274
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
20190
|
-
console.log(
|
|
20275
|
+
console.log(chalk180.gray(`Capturing window for process "${processName}" ...`));
|
|
20191
20276
|
try {
|
|
20192
20277
|
runPowerShellScript(processName, outputPath);
|
|
20193
|
-
console.log(
|
|
20278
|
+
console.log(chalk180.green(`Screenshot saved: ${outputPath}`));
|
|
20194
20279
|
} catch (error) {
|
|
20195
20280
|
const msg = error instanceof Error ? error.message : String(error);
|
|
20196
|
-
console.error(
|
|
20281
|
+
console.error(chalk180.red(`Failed to capture screenshot: ${msg}`));
|
|
20197
20282
|
process.exit(1);
|
|
20198
20283
|
}
|
|
20199
20284
|
}
|
|
@@ -20883,8 +20968,8 @@ function errorSession(id2, persisted, error) {
|
|
|
20883
20968
|
};
|
|
20884
20969
|
}
|
|
20885
20970
|
|
|
20886
|
-
// src/commands/sessions/daemon/
|
|
20887
|
-
function
|
|
20971
|
+
// src/commands/sessions/daemon/assistResumeArgs.ts
|
|
20972
|
+
function assistResumeArgs(persisted) {
|
|
20888
20973
|
const args = ["assist", ...persisted.assistArgs];
|
|
20889
20974
|
return persisted.claudeSessionId ? [...args, "--resume-session", persisted.claudeSessionId] : args;
|
|
20890
20975
|
}
|
|
@@ -20905,6 +20990,46 @@ function runningSession(base, persisted, pty2) {
|
|
|
20905
20990
|
};
|
|
20906
20991
|
}
|
|
20907
20992
|
|
|
20993
|
+
// src/commands/sessions/daemon/restoreInteractiveSession.ts
|
|
20994
|
+
function restoreInteractiveSession(id2, persisted, base) {
|
|
20995
|
+
if (persisted.commandType !== "run" && persisted.claudeSessionId) {
|
|
20996
|
+
return resumeViaClaude(id2, persisted, base);
|
|
20997
|
+
}
|
|
20998
|
+
if (persisted.commandType === "claude") {
|
|
20999
|
+
return unrecoverableClaude(id2, persisted);
|
|
21000
|
+
}
|
|
21001
|
+
return notRestoredStub(base, persisted);
|
|
21002
|
+
}
|
|
21003
|
+
function resumeViaClaude(id2, persisted, base) {
|
|
21004
|
+
const pty2 = spawnClaude2({
|
|
21005
|
+
resumeSessionId: persisted.claudeSessionId,
|
|
21006
|
+
prompt: buildResumePrompt(),
|
|
21007
|
+
cwd: persisted.cwd,
|
|
21008
|
+
sessionId: id2
|
|
21009
|
+
});
|
|
21010
|
+
return runningSession(base, persisted, pty2);
|
|
21011
|
+
}
|
|
21012
|
+
function unrecoverableClaude(id2, persisted) {
|
|
21013
|
+
return errorSession(
|
|
21014
|
+
id2,
|
|
21015
|
+
persisted,
|
|
21016
|
+
"no claude session id was recorded before the daemon stopped, so the conversation cannot be resumed"
|
|
21017
|
+
);
|
|
21018
|
+
}
|
|
21019
|
+
function notRestoredStub(base, persisted) {
|
|
21020
|
+
return {
|
|
21021
|
+
...base,
|
|
21022
|
+
status: "done",
|
|
21023
|
+
startedAt: persisted.startedAt,
|
|
21024
|
+
runningMs: persisted.runningMs ?? 0,
|
|
21025
|
+
runningSince: null,
|
|
21026
|
+
pty: null,
|
|
21027
|
+
runName: persisted.runName,
|
|
21028
|
+
runArgs: persisted.runArgs,
|
|
21029
|
+
restored: false
|
|
21030
|
+
};
|
|
21031
|
+
}
|
|
21032
|
+
|
|
20908
21033
|
// src/commands/sessions/daemon/updatedSession.ts
|
|
20909
21034
|
function updatedSession(id2, persisted) {
|
|
20910
21035
|
return {
|
|
@@ -20924,41 +21049,22 @@ function isUpdate(persisted) {
|
|
|
20924
21049
|
function restoreSession(id2, persisted) {
|
|
20925
21050
|
const base = restoreBase(id2, persisted);
|
|
20926
21051
|
if (isUpdate(persisted)) return updatedSession(id2, persisted);
|
|
20927
|
-
if (
|
|
20928
|
-
const pty2 = spawnPty(
|
|
20929
|
-
return runningSession(base, persisted, pty2);
|
|
20930
|
-
}
|
|
20931
|
-
if (persisted.commandType !== "run" && persisted.claudeSessionId) {
|
|
20932
|
-
const pty2 = spawnClaude2({
|
|
20933
|
-
resumeSessionId: persisted.claudeSessionId,
|
|
20934
|
-
prompt: buildResumePrompt(),
|
|
20935
|
-
cwd: persisted.cwd,
|
|
20936
|
-
sessionId: id2
|
|
20937
|
-
});
|
|
21052
|
+
if (needsWrapperRelaunch(persisted)) {
|
|
21053
|
+
const pty2 = spawnPty(assistResumeArgs(persisted), persisted.cwd, id2);
|
|
20938
21054
|
return runningSession(base, persisted, pty2);
|
|
20939
21055
|
}
|
|
20940
|
-
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
"no claude session id was recorded before the daemon stopped, so the conversation cannot be resumed"
|
|
20945
|
-
);
|
|
20946
|
-
}
|
|
20947
|
-
return {
|
|
20948
|
-
...base,
|
|
20949
|
-
status: "done",
|
|
20950
|
-
startedAt: persisted.startedAt,
|
|
20951
|
-
runningMs: persisted.runningMs ?? 0,
|
|
20952
|
-
runningSince: null,
|
|
20953
|
-
pty: null,
|
|
20954
|
-
runName: persisted.runName,
|
|
20955
|
-
runArgs: persisted.runArgs,
|
|
20956
|
-
restored: false
|
|
20957
|
-
};
|
|
21056
|
+
return restoreInteractiveSession(id2, persisted, base);
|
|
21057
|
+
}
|
|
21058
|
+
function needsWrapperRelaunch(persisted) {
|
|
21059
|
+
return isBacklogRun(persisted) || isOnceLaunch(persisted) && !!persisted.claudeSessionId;
|
|
20958
21060
|
}
|
|
20959
21061
|
function isBacklogRun(persisted) {
|
|
20960
21062
|
return persisted.commandType === "assist" && persisted.assistArgs?.[0] === "backlog" && persisted.assistArgs?.[1] === "run";
|
|
20961
21063
|
}
|
|
21064
|
+
var LAUNCH_COMMANDS = ["draft", "feat", "bug", "refine"];
|
|
21065
|
+
function isOnceLaunch(persisted) {
|
|
21066
|
+
return persisted.commandType === "assist" && !!persisted.assistArgs && LAUNCH_COMMANDS.includes(persisted.assistArgs[0]) && persisted.assistArgs.includes("--once");
|
|
21067
|
+
}
|
|
20962
21068
|
|
|
20963
21069
|
// src/commands/sessions/daemon/restoreOne.ts
|
|
20964
21070
|
function restoreOne(persisted, spawn12, sessions) {
|
|
@@ -22458,7 +22564,7 @@ function registerDaemon(program2) {
|
|
|
22458
22564
|
|
|
22459
22565
|
// src/commands/sessions/summarise/index.ts
|
|
22460
22566
|
import * as fs35 from "fs";
|
|
22461
|
-
import
|
|
22567
|
+
import chalk181 from "chalk";
|
|
22462
22568
|
|
|
22463
22569
|
// src/commands/sessions/summarise/shared.ts
|
|
22464
22570
|
import * as fs33 from "fs";
|
|
@@ -22612,22 +22718,22 @@ ${firstMessage}`);
|
|
|
22612
22718
|
async function summarise3(options2) {
|
|
22613
22719
|
const files = await discoverSessionFiles();
|
|
22614
22720
|
if (files.length === 0) {
|
|
22615
|
-
console.log(
|
|
22721
|
+
console.log(chalk181.yellow("No sessions found."));
|
|
22616
22722
|
return;
|
|
22617
22723
|
}
|
|
22618
22724
|
const toProcess = selectCandidates(files, options2);
|
|
22619
22725
|
if (toProcess.length === 0) {
|
|
22620
|
-
console.log(
|
|
22726
|
+
console.log(chalk181.green("All sessions already summarised."));
|
|
22621
22727
|
return;
|
|
22622
22728
|
}
|
|
22623
22729
|
console.log(
|
|
22624
|
-
|
|
22730
|
+
chalk181.cyan(
|
|
22625
22731
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22626
22732
|
)
|
|
22627
22733
|
);
|
|
22628
22734
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22629
22735
|
console.log(
|
|
22630
|
-
|
|
22736
|
+
chalk181.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk181.yellow(`, ${failed2} skipped`) : "")
|
|
22631
22737
|
);
|
|
22632
22738
|
}
|
|
22633
22739
|
function selectCandidates(files, options2) {
|
|
@@ -22647,16 +22753,16 @@ function processSessions(files) {
|
|
|
22647
22753
|
let failed2 = 0;
|
|
22648
22754
|
for (let i = 0; i < files.length; i++) {
|
|
22649
22755
|
const file = files[i];
|
|
22650
|
-
process.stdout.write(
|
|
22756
|
+
process.stdout.write(chalk181.dim(` [${i + 1}/${files.length}] `));
|
|
22651
22757
|
const summary = summariseSession(file);
|
|
22652
22758
|
if (summary) {
|
|
22653
22759
|
writeSummary(file, summary);
|
|
22654
22760
|
succeeded++;
|
|
22655
|
-
process.stdout.write(`${
|
|
22761
|
+
process.stdout.write(`${chalk181.green("\u2713")} ${summary}
|
|
22656
22762
|
`);
|
|
22657
22763
|
} else {
|
|
22658
22764
|
failed2++;
|
|
22659
|
-
process.stdout.write(` ${
|
|
22765
|
+
process.stdout.write(` ${chalk181.yellow("skip")}
|
|
22660
22766
|
`);
|
|
22661
22767
|
}
|
|
22662
22768
|
}
|
|
@@ -22674,10 +22780,10 @@ function registerSessions(program2) {
|
|
|
22674
22780
|
}
|
|
22675
22781
|
|
|
22676
22782
|
// src/commands/statusLine.ts
|
|
22677
|
-
import
|
|
22783
|
+
import chalk183 from "chalk";
|
|
22678
22784
|
|
|
22679
22785
|
// src/commands/buildLimitsSegment.ts
|
|
22680
|
-
import
|
|
22786
|
+
import chalk182 from "chalk";
|
|
22681
22787
|
|
|
22682
22788
|
// src/shared/rateLimitLevel.ts
|
|
22683
22789
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22708,9 +22814,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22708
22814
|
|
|
22709
22815
|
// src/commands/buildLimitsSegment.ts
|
|
22710
22816
|
var LEVEL_COLOR = {
|
|
22711
|
-
ok:
|
|
22712
|
-
warn:
|
|
22713
|
-
over:
|
|
22817
|
+
ok: chalk182.green,
|
|
22818
|
+
warn: chalk182.yellow,
|
|
22819
|
+
over: chalk182.red
|
|
22714
22820
|
};
|
|
22715
22821
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22716
22822
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22750,14 +22856,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
22750
22856
|
}
|
|
22751
22857
|
|
|
22752
22858
|
// src/commands/statusLine.ts
|
|
22753
|
-
|
|
22859
|
+
chalk183.level = 3;
|
|
22754
22860
|
function formatNumber(num) {
|
|
22755
22861
|
return num.toLocaleString("en-US");
|
|
22756
22862
|
}
|
|
22757
22863
|
function colorizePercent(pct) {
|
|
22758
22864
|
const label2 = `${Math.round(pct)}%`;
|
|
22759
|
-
if (pct > 80) return
|
|
22760
|
-
if (pct > 40) return
|
|
22865
|
+
if (pct > 80) return chalk183.red(label2);
|
|
22866
|
+
if (pct > 40) return chalk183.yellow(label2);
|
|
22761
22867
|
return label2;
|
|
22762
22868
|
}
|
|
22763
22869
|
async function statusLine() {
|
|
@@ -22781,7 +22887,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
22781
22887
|
// src/commands/sync/syncClaudeMd.ts
|
|
22782
22888
|
import * as fs36 from "fs";
|
|
22783
22889
|
import * as path53 from "path";
|
|
22784
|
-
import
|
|
22890
|
+
import chalk184 from "chalk";
|
|
22785
22891
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22786
22892
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22787
22893
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
@@ -22790,12 +22896,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22790
22896
|
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22791
22897
|
if (sourceContent !== targetContent) {
|
|
22792
22898
|
console.log(
|
|
22793
|
-
|
|
22899
|
+
chalk184.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22794
22900
|
);
|
|
22795
22901
|
console.log();
|
|
22796
22902
|
printDiff(targetContent, sourceContent);
|
|
22797
22903
|
const confirm = options2?.yes || await promptConfirm(
|
|
22798
|
-
|
|
22904
|
+
chalk184.red("Overwrite existing CLAUDE.md?"),
|
|
22799
22905
|
false
|
|
22800
22906
|
);
|
|
22801
22907
|
if (!confirm) {
|
|
@@ -22811,7 +22917,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22811
22917
|
// src/commands/sync/syncSettings.ts
|
|
22812
22918
|
import * as fs37 from "fs";
|
|
22813
22919
|
import * as path54 from "path";
|
|
22814
|
-
import
|
|
22920
|
+
import chalk185 from "chalk";
|
|
22815
22921
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22816
22922
|
const source = path54.join(claudeDir, "settings.json");
|
|
22817
22923
|
const target = path54.join(targetBase, "settings.json");
|
|
@@ -22827,14 +22933,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22827
22933
|
if (mergedContent !== normalizedTarget) {
|
|
22828
22934
|
if (!options2?.yes) {
|
|
22829
22935
|
console.log(
|
|
22830
|
-
|
|
22936
|
+
chalk185.yellow(
|
|
22831
22937
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22832
22938
|
)
|
|
22833
22939
|
);
|
|
22834
22940
|
console.log();
|
|
22835
22941
|
printDiff(targetContent, mergedContent);
|
|
22836
22942
|
const confirm = await promptConfirm(
|
|
22837
|
-
|
|
22943
|
+
chalk185.red("Overwrite existing settings.json?"),
|
|
22838
22944
|
false
|
|
22839
22945
|
);
|
|
22840
22946
|
if (!confirm) {
|