@staff0rd/assist 0.327.1 → 0.329.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/claude/commands/associate-jira.md +34 -0
- package/dist/index.js +651 -585
- 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.329.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
|
}
|
|
@@ -7601,12 +7685,12 @@ async function pickItemForRefine() {
|
|
|
7601
7685
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
7602
7686
|
);
|
|
7603
7687
|
if (active.length === 0) {
|
|
7604
|
-
console.log(
|
|
7688
|
+
console.log(chalk74.yellow("No active backlog items to refine."));
|
|
7605
7689
|
return void 0;
|
|
7606
7690
|
}
|
|
7607
7691
|
if (active.length === 1) {
|
|
7608
7692
|
const item = active[0];
|
|
7609
|
-
console.log(
|
|
7693
|
+
console.log(chalk74.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
7610
7694
|
return String(item.id);
|
|
7611
7695
|
}
|
|
7612
7696
|
const { selected } = await exitOnCancel(
|
|
@@ -7641,7 +7725,7 @@ function registerRefineCommand(cmd) {
|
|
|
7641
7725
|
}
|
|
7642
7726
|
|
|
7643
7727
|
// src/commands/backlog/rewindPhase.ts
|
|
7644
|
-
import
|
|
7728
|
+
import chalk75 from "chalk";
|
|
7645
7729
|
function validateRewind2(item, plan2, phaseNumber) {
|
|
7646
7730
|
if (phaseNumber < 1 || phaseNumber > plan2.length) {
|
|
7647
7731
|
return `Phase ${phaseNumber} does not exist. Valid range: 1\u2013${plan2.length}.`;
|
|
@@ -7658,13 +7742,13 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
7658
7742
|
const { orm } = await getReady();
|
|
7659
7743
|
const item = await loadItem(orm, Number.parseInt(id2, 10));
|
|
7660
7744
|
if (!item) {
|
|
7661
|
-
console.log(
|
|
7745
|
+
console.log(chalk75.red(`Item #${id2} not found.`));
|
|
7662
7746
|
return;
|
|
7663
7747
|
}
|
|
7664
7748
|
const plan2 = resolveRewindPlan(item);
|
|
7665
7749
|
const error = validateRewind2(item, plan2, phaseNumber);
|
|
7666
7750
|
if (error) {
|
|
7667
|
-
console.log(
|
|
7751
|
+
console.log(chalk75.red(error));
|
|
7668
7752
|
process.exitCode = 1;
|
|
7669
7753
|
return;
|
|
7670
7754
|
}
|
|
@@ -7682,7 +7766,7 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
7682
7766
|
targetPhase: phaseIndex
|
|
7683
7767
|
});
|
|
7684
7768
|
console.log(
|
|
7685
|
-
|
|
7769
|
+
chalk75.green(`Rewound item #${id2} to phase ${phaseNumber} (${phaseName}).`)
|
|
7686
7770
|
);
|
|
7687
7771
|
}
|
|
7688
7772
|
|
|
@@ -7708,22 +7792,22 @@ function registerRunCommand(cmd) {
|
|
|
7708
7792
|
}
|
|
7709
7793
|
|
|
7710
7794
|
// src/commands/backlog/search/index.ts
|
|
7711
|
-
import
|
|
7795
|
+
import chalk76 from "chalk";
|
|
7712
7796
|
async function search(query) {
|
|
7713
7797
|
const items2 = await searchBacklog(query);
|
|
7714
7798
|
if (items2.length === 0) {
|
|
7715
|
-
console.log(
|
|
7799
|
+
console.log(chalk76.dim(`No items matching "${query}".`));
|
|
7716
7800
|
return;
|
|
7717
7801
|
}
|
|
7718
7802
|
console.log(
|
|
7719
|
-
|
|
7803
|
+
chalk76.dim(
|
|
7720
7804
|
`${items2.length} item${items2.length === 1 ? "" : "s"} matching "${query}":
|
|
7721
7805
|
`
|
|
7722
7806
|
)
|
|
7723
7807
|
);
|
|
7724
7808
|
for (const item of items2) {
|
|
7725
7809
|
console.log(
|
|
7726
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
7810
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk76.dim(`#${item.id}`)} ${item.name}`
|
|
7727
7811
|
);
|
|
7728
7812
|
}
|
|
7729
7813
|
}
|
|
@@ -7734,16 +7818,16 @@ function registerSearchCommand(cmd) {
|
|
|
7734
7818
|
}
|
|
7735
7819
|
|
|
7736
7820
|
// src/commands/backlog/delete/index.ts
|
|
7737
|
-
import
|
|
7821
|
+
import chalk77 from "chalk";
|
|
7738
7822
|
async function del(id2) {
|
|
7739
7823
|
const name = await removeItem(id2);
|
|
7740
7824
|
if (name) {
|
|
7741
|
-
console.log(
|
|
7825
|
+
console.log(chalk77.green(`Deleted item #${id2}: ${name}`));
|
|
7742
7826
|
}
|
|
7743
7827
|
}
|
|
7744
7828
|
|
|
7745
7829
|
// src/commands/backlog/done/index.ts
|
|
7746
|
-
import
|
|
7830
|
+
import chalk78 from "chalk";
|
|
7747
7831
|
async function done(id2, summary) {
|
|
7748
7832
|
const found = await findOneItem(id2);
|
|
7749
7833
|
if (!found) return;
|
|
@@ -7753,12 +7837,12 @@ async function done(id2, summary) {
|
|
|
7753
7837
|
const pending = item.plan.slice(completedCount);
|
|
7754
7838
|
if (pending.length > 0) {
|
|
7755
7839
|
console.log(
|
|
7756
|
-
|
|
7840
|
+
chalk78.red(
|
|
7757
7841
|
`Cannot complete item #${id2}: ${pending.length} pending phase(s):`
|
|
7758
7842
|
)
|
|
7759
7843
|
);
|
|
7760
7844
|
for (const phase of pending) {
|
|
7761
|
-
console.log(
|
|
7845
|
+
console.log(chalk78.yellow(` - ${phase.name}`));
|
|
7762
7846
|
}
|
|
7763
7847
|
process.exitCode = 1;
|
|
7764
7848
|
return;
|
|
@@ -7769,18 +7853,18 @@ async function done(id2, summary) {
|
|
|
7769
7853
|
const phase = item.currentPhase ?? 1;
|
|
7770
7854
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
7771
7855
|
}
|
|
7772
|
-
console.log(
|
|
7856
|
+
console.log(chalk78.green(`Completed item #${id2}: ${item.name}`));
|
|
7773
7857
|
}
|
|
7774
7858
|
|
|
7775
7859
|
// src/commands/backlog/star/index.ts
|
|
7776
|
-
import
|
|
7860
|
+
import chalk80 from "chalk";
|
|
7777
7861
|
|
|
7778
7862
|
// src/commands/backlog/setStarred.ts
|
|
7779
|
-
import
|
|
7863
|
+
import chalk79 from "chalk";
|
|
7780
7864
|
async function setStarred(id2, starred) {
|
|
7781
7865
|
const { orm } = await getReady();
|
|
7782
7866
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
7783
|
-
if (name === void 0) console.log(
|
|
7867
|
+
if (name === void 0) console.log(chalk79.red(`Item #${id2} not found.`));
|
|
7784
7868
|
return name;
|
|
7785
7869
|
}
|
|
7786
7870
|
|
|
@@ -7788,45 +7872,45 @@ async function setStarred(id2, starred) {
|
|
|
7788
7872
|
async function star(id2) {
|
|
7789
7873
|
const name = await setStarred(id2, true);
|
|
7790
7874
|
if (name) {
|
|
7791
|
-
console.log(
|
|
7875
|
+
console.log(chalk80.green(`Starred item #${id2}: ${name}`));
|
|
7792
7876
|
}
|
|
7793
7877
|
}
|
|
7794
7878
|
|
|
7795
7879
|
// src/commands/backlog/start/index.ts
|
|
7796
|
-
import
|
|
7880
|
+
import chalk81 from "chalk";
|
|
7797
7881
|
async function start(id2) {
|
|
7798
7882
|
const name = await setStatus(id2, "in-progress");
|
|
7799
7883
|
if (name) {
|
|
7800
|
-
console.log(
|
|
7884
|
+
console.log(chalk81.green(`Started item #${id2}: ${name}`));
|
|
7801
7885
|
}
|
|
7802
7886
|
}
|
|
7803
7887
|
|
|
7804
7888
|
// src/commands/backlog/stop/index.ts
|
|
7805
|
-
import
|
|
7806
|
-
import { and as and7, eq as
|
|
7889
|
+
import chalk82 from "chalk";
|
|
7890
|
+
import { and as and7, eq as eq25 } from "drizzle-orm";
|
|
7807
7891
|
async function stop() {
|
|
7808
7892
|
const { orm } = await getReady();
|
|
7809
|
-
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 });
|
|
7810
7894
|
if (stopped.length === 0) {
|
|
7811
|
-
console.log(
|
|
7895
|
+
console.log(chalk82.yellow("No in-progress items to stop."));
|
|
7812
7896
|
return;
|
|
7813
7897
|
}
|
|
7814
7898
|
for (const item of stopped) {
|
|
7815
|
-
console.log(
|
|
7899
|
+
console.log(chalk82.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
7816
7900
|
}
|
|
7817
7901
|
}
|
|
7818
7902
|
|
|
7819
7903
|
// src/commands/backlog/unstar/index.ts
|
|
7820
|
-
import
|
|
7904
|
+
import chalk83 from "chalk";
|
|
7821
7905
|
async function unstar(id2) {
|
|
7822
7906
|
const name = await setStarred(id2, false);
|
|
7823
7907
|
if (name) {
|
|
7824
|
-
console.log(
|
|
7908
|
+
console.log(chalk83.green(`Unstarred item #${id2}: ${name}`));
|
|
7825
7909
|
}
|
|
7826
7910
|
}
|
|
7827
7911
|
|
|
7828
7912
|
// src/commands/backlog/wontdo/index.ts
|
|
7829
|
-
import
|
|
7913
|
+
import chalk84 from "chalk";
|
|
7830
7914
|
async function wontdo(id2, reason) {
|
|
7831
7915
|
const found = await findOneItem(id2);
|
|
7832
7916
|
if (!found) return;
|
|
@@ -7836,7 +7920,7 @@ async function wontdo(id2, reason) {
|
|
|
7836
7920
|
const phase = item.currentPhase ?? 1;
|
|
7837
7921
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
7838
7922
|
}
|
|
7839
|
-
console.log(
|
|
7923
|
+
console.log(chalk84.red(`Won't do item #${id2}: ${item.name}`));
|
|
7840
7924
|
}
|
|
7841
7925
|
|
|
7842
7926
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -7851,22 +7935,22 @@ function registerStatusCommands(cmd) {
|
|
|
7851
7935
|
}
|
|
7852
7936
|
|
|
7853
7937
|
// src/commands/backlog/removePhase.ts
|
|
7854
|
-
import
|
|
7855
|
-
import { and as and10, eq as
|
|
7938
|
+
import chalk86 from "chalk";
|
|
7939
|
+
import { and as and10, eq as eq28 } from "drizzle-orm";
|
|
7856
7940
|
|
|
7857
7941
|
// src/commands/backlog/findPhase.ts
|
|
7858
|
-
import
|
|
7859
|
-
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";
|
|
7860
7944
|
async function findPhase(id2, phase) {
|
|
7861
7945
|
const found = await findOneItem(id2);
|
|
7862
7946
|
if (!found) return void 0;
|
|
7863
7947
|
const { orm, item } = found;
|
|
7864
7948
|
const itemId = item.id;
|
|
7865
7949
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
7866
|
-
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)));
|
|
7867
7951
|
if (!row || row.cnt === 0) {
|
|
7868
7952
|
console.log(
|
|
7869
|
-
|
|
7953
|
+
chalk85.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
7870
7954
|
);
|
|
7871
7955
|
process.exitCode = 1;
|
|
7872
7956
|
return void 0;
|
|
@@ -7875,14 +7959,14 @@ async function findPhase(id2, phase) {
|
|
|
7875
7959
|
}
|
|
7876
7960
|
|
|
7877
7961
|
// src/commands/backlog/reindexPhases.ts
|
|
7878
|
-
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";
|
|
7879
7963
|
async function reindexPhases(db, itemId) {
|
|
7880
|
-
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));
|
|
7881
7965
|
for (let i = 0; i < remaining.length; i++) {
|
|
7882
7966
|
const oldIdx = remaining[i].idx;
|
|
7883
7967
|
if (oldIdx === i) continue;
|
|
7884
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(and9(
|
|
7885
|
-
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)));
|
|
7886
7970
|
}
|
|
7887
7971
|
}
|
|
7888
7972
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -7890,13 +7974,13 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
7890
7974
|
if (currentPhase === void 0) return;
|
|
7891
7975
|
const currentIdx = currentPhase - 1;
|
|
7892
7976
|
if (removedIdx < currentIdx) {
|
|
7893
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
7977
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq27(items.id, item.id));
|
|
7894
7978
|
return;
|
|
7895
7979
|
}
|
|
7896
7980
|
if (removedIdx !== currentIdx) return;
|
|
7897
|
-
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));
|
|
7898
7982
|
const cnt = row?.cnt ?? 0;
|
|
7899
|
-
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));
|
|
7900
7984
|
}
|
|
7901
7985
|
|
|
7902
7986
|
// src/commands/backlog/removePhase.ts
|
|
@@ -7906,20 +7990,20 @@ async function removePhase(id2, phase) {
|
|
|
7906
7990
|
const { item, orm, itemId, phaseIdx } = found;
|
|
7907
7991
|
await orm.transaction(async (tx) => {
|
|
7908
7992
|
await tx.delete(planTasks).where(
|
|
7909
|
-
and10(
|
|
7993
|
+
and10(eq28(planTasks.itemId, itemId), eq28(planTasks.phaseIdx, phaseIdx))
|
|
7910
7994
|
);
|
|
7911
|
-
await tx.delete(planPhases).where(and10(
|
|
7995
|
+
await tx.delete(planPhases).where(and10(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx)));
|
|
7912
7996
|
await reindexPhases(tx, itemId);
|
|
7913
7997
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
7914
7998
|
});
|
|
7915
7999
|
console.log(
|
|
7916
|
-
|
|
8000
|
+
chalk86.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
7917
8001
|
);
|
|
7918
8002
|
}
|
|
7919
8003
|
|
|
7920
8004
|
// src/commands/backlog/update/index.ts
|
|
7921
|
-
import
|
|
7922
|
-
import { eq as
|
|
8005
|
+
import chalk88 from "chalk";
|
|
8006
|
+
import { eq as eq29 } from "drizzle-orm";
|
|
7923
8007
|
|
|
7924
8008
|
// src/commands/backlog/update/parseListIndex.ts
|
|
7925
8009
|
function parseListIndex(raw, length, label2) {
|
|
@@ -7994,16 +8078,16 @@ function applyAcMutations(current, options2) {
|
|
|
7994
8078
|
}
|
|
7995
8079
|
|
|
7996
8080
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7997
|
-
import
|
|
8081
|
+
import chalk87 from "chalk";
|
|
7998
8082
|
function buildUpdateValues(options2) {
|
|
7999
8083
|
const { name, desc: desc6, type, ac } = options2;
|
|
8000
8084
|
if (!name && !desc6 && !type && !ac) {
|
|
8001
|
-
console.log(
|
|
8085
|
+
console.log(chalk87.red("Nothing to update. Provide at least one flag."));
|
|
8002
8086
|
process.exitCode = 1;
|
|
8003
8087
|
return void 0;
|
|
8004
8088
|
}
|
|
8005
8089
|
if (type && type !== "story" && type !== "bug") {
|
|
8006
|
-
console.log(
|
|
8090
|
+
console.log(chalk87.red('Invalid type. Must be "story" or "bug".'));
|
|
8007
8091
|
process.exitCode = 1;
|
|
8008
8092
|
return void 0;
|
|
8009
8093
|
}
|
|
@@ -8036,14 +8120,14 @@ async function update(id2, options2) {
|
|
|
8036
8120
|
if (hasAcMutations(options2)) {
|
|
8037
8121
|
if (options2.ac) {
|
|
8038
8122
|
console.log(
|
|
8039
|
-
|
|
8123
|
+
chalk88.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8040
8124
|
);
|
|
8041
8125
|
process.exitCode = 1;
|
|
8042
8126
|
return;
|
|
8043
8127
|
}
|
|
8044
8128
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8045
8129
|
if (!mutation.ok) {
|
|
8046
|
-
console.log(
|
|
8130
|
+
console.log(chalk88.red(mutation.error));
|
|
8047
8131
|
process.exitCode = 1;
|
|
8048
8132
|
return;
|
|
8049
8133
|
}
|
|
@@ -8053,30 +8137,30 @@ async function update(id2, options2) {
|
|
|
8053
8137
|
if (!built) return;
|
|
8054
8138
|
const { orm } = found;
|
|
8055
8139
|
const itemId = found.item.id;
|
|
8056
|
-
await orm.update(items).set(built.set).where(
|
|
8057
|
-
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}.`));
|
|
8058
8142
|
}
|
|
8059
8143
|
|
|
8060
8144
|
// src/commands/backlog/updatePhase.ts
|
|
8061
|
-
import
|
|
8145
|
+
import chalk89 from "chalk";
|
|
8062
8146
|
|
|
8063
8147
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8064
|
-
import { and as and11, eq as
|
|
8148
|
+
import { and as and11, eq as eq30 } from "drizzle-orm";
|
|
8065
8149
|
async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
|
|
8066
8150
|
await orm.transaction(async (tx) => {
|
|
8067
8151
|
if (fields.name) {
|
|
8068
8152
|
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
8069
|
-
and11(
|
|
8153
|
+
and11(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8070
8154
|
);
|
|
8071
8155
|
}
|
|
8072
8156
|
if (fields.manualCheck) {
|
|
8073
8157
|
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
8074
|
-
and11(
|
|
8158
|
+
and11(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8075
8159
|
);
|
|
8076
8160
|
}
|
|
8077
8161
|
if (fields.task) {
|
|
8078
8162
|
await tx.delete(planTasks).where(
|
|
8079
|
-
and11(
|
|
8163
|
+
and11(eq30(planTasks.itemId, itemId), eq30(planTasks.phaseIdx, phaseIdx))
|
|
8080
8164
|
);
|
|
8081
8165
|
if (fields.task.length) {
|
|
8082
8166
|
await tx.insert(planTasks).values(
|
|
@@ -8162,7 +8246,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8162
8246
|
const { item, orm, itemId, phaseIdx } = found;
|
|
8163
8247
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
8164
8248
|
if (!resolved.ok) {
|
|
8165
|
-
console.log(
|
|
8249
|
+
console.log(chalk89.red(resolved.error));
|
|
8166
8250
|
process.exitCode = 1;
|
|
8167
8251
|
return;
|
|
8168
8252
|
}
|
|
@@ -8174,7 +8258,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8174
8258
|
manualCheck && "manual checks"
|
|
8175
8259
|
].filter(Boolean).join(", ");
|
|
8176
8260
|
console.log(
|
|
8177
|
-
|
|
8261
|
+
chalk89.green(
|
|
8178
8262
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8179
8263
|
)
|
|
8180
8264
|
);
|
|
@@ -8229,7 +8313,8 @@ var registrars = [
|
|
|
8229
8313
|
registerUpdateCommands,
|
|
8230
8314
|
registerExportCommand,
|
|
8231
8315
|
registerImportCommand,
|
|
8232
|
-
registerMoveRepoCommand
|
|
8316
|
+
registerMoveRepoCommand,
|
|
8317
|
+
registerAssociateJiraCommand
|
|
8233
8318
|
];
|
|
8234
8319
|
function registerBacklog(program2) {
|
|
8235
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) => {
|
|
@@ -8879,7 +8964,7 @@ import { homedir as homedir10 } from "os";
|
|
|
8879
8964
|
import { join as join24 } from "path";
|
|
8880
8965
|
|
|
8881
8966
|
// src/shared/checkCliAvailable.ts
|
|
8882
|
-
import { execSync as
|
|
8967
|
+
import { execSync as execSync23 } from "child_process";
|
|
8883
8968
|
function checkCliAvailable(cli) {
|
|
8884
8969
|
const binary = cli.split(/\s+/)[0];
|
|
8885
8970
|
const opts = {
|
|
@@ -8887,11 +8972,11 @@ function checkCliAvailable(cli) {
|
|
|
8887
8972
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8888
8973
|
};
|
|
8889
8974
|
try {
|
|
8890
|
-
|
|
8975
|
+
execSync23(`command -v ${binary}`, opts);
|
|
8891
8976
|
return true;
|
|
8892
8977
|
} catch {
|
|
8893
8978
|
try {
|
|
8894
|
-
|
|
8979
|
+
execSync23(`where ${binary}`, opts);
|
|
8895
8980
|
return true;
|
|
8896
8981
|
} catch {
|
|
8897
8982
|
return false;
|
|
@@ -8907,11 +8992,11 @@ function assertCliExists(cli) {
|
|
|
8907
8992
|
}
|
|
8908
8993
|
|
|
8909
8994
|
// src/commands/permitCliReads/colorize.ts
|
|
8910
|
-
import
|
|
8995
|
+
import chalk90 from "chalk";
|
|
8911
8996
|
function colorize(plainOutput) {
|
|
8912
8997
|
return plainOutput.split("\n").map((line) => {
|
|
8913
|
-
if (line.startsWith(" R ")) return
|
|
8914
|
-
if (line.startsWith(" W ")) return
|
|
8998
|
+
if (line.startsWith(" R ")) return chalk90.green(line);
|
|
8999
|
+
if (line.startsWith(" W ")) return chalk90.red(line);
|
|
8915
9000
|
return line;
|
|
8916
9001
|
}).join("\n");
|
|
8917
9002
|
}
|
|
@@ -9209,7 +9294,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
9209
9294
|
}
|
|
9210
9295
|
|
|
9211
9296
|
// src/commands/deny/denyAdd.ts
|
|
9212
|
-
import
|
|
9297
|
+
import chalk91 from "chalk";
|
|
9213
9298
|
|
|
9214
9299
|
// src/commands/deny/loadDenyConfig.ts
|
|
9215
9300
|
function loadDenyConfig(global) {
|
|
@@ -9229,16 +9314,16 @@ function loadDenyConfig(global) {
|
|
|
9229
9314
|
function denyAdd(pattern2, message, options2) {
|
|
9230
9315
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9231
9316
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
9232
|
-
console.log(
|
|
9317
|
+
console.log(chalk91.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
9233
9318
|
return;
|
|
9234
9319
|
}
|
|
9235
9320
|
deny.push({ pattern: pattern2, message });
|
|
9236
9321
|
saveDeny(deny);
|
|
9237
|
-
console.log(
|
|
9322
|
+
console.log(chalk91.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
9238
9323
|
}
|
|
9239
9324
|
|
|
9240
9325
|
// src/commands/deny/denyList.ts
|
|
9241
|
-
import
|
|
9326
|
+
import chalk92 from "chalk";
|
|
9242
9327
|
function denyList() {
|
|
9243
9328
|
const globalRaw = loadGlobalConfigRaw();
|
|
9244
9329
|
const projectRaw = loadProjectConfig();
|
|
@@ -9249,7 +9334,7 @@ function denyList() {
|
|
|
9249
9334
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
9250
9335
|
);
|
|
9251
9336
|
if (!merged || merged.length === 0) {
|
|
9252
|
-
console.log(
|
|
9337
|
+
console.log(chalk92.dim("No deny rules configured."));
|
|
9253
9338
|
return;
|
|
9254
9339
|
}
|
|
9255
9340
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -9257,23 +9342,23 @@ function denyList() {
|
|
|
9257
9342
|
for (const rule of merged) {
|
|
9258
9343
|
const inProject = projectPatterns.has(rule.pattern);
|
|
9259
9344
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
9260
|
-
const label2 = inProject && inGlobal ?
|
|
9261
|
-
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}`);
|
|
9262
9347
|
}
|
|
9263
9348
|
}
|
|
9264
9349
|
|
|
9265
9350
|
// src/commands/deny/denyRemove.ts
|
|
9266
|
-
import
|
|
9351
|
+
import chalk93 from "chalk";
|
|
9267
9352
|
function denyRemove(pattern2, options2) {
|
|
9268
9353
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9269
9354
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
9270
9355
|
if (index3 === -1) {
|
|
9271
|
-
console.log(
|
|
9356
|
+
console.log(chalk93.yellow(`No deny rule found for: ${pattern2}`));
|
|
9272
9357
|
return;
|
|
9273
9358
|
}
|
|
9274
9359
|
deny.splice(index3, 1);
|
|
9275
9360
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
9276
|
-
console.log(
|
|
9361
|
+
console.log(chalk93.green(`Removed deny rule: ${pattern2}`));
|
|
9277
9362
|
}
|
|
9278
9363
|
|
|
9279
9364
|
// src/commands/registerDeny.ts
|
|
@@ -9303,7 +9388,7 @@ function registerCliHook(program2) {
|
|
|
9303
9388
|
|
|
9304
9389
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9305
9390
|
import { existsSync as existsSync27, readFileSync as readFileSync22, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9306
|
-
import
|
|
9391
|
+
import chalk94 from "chalk";
|
|
9307
9392
|
|
|
9308
9393
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
9309
9394
|
import { homedir as homedir11 } from "os";
|
|
@@ -9353,12 +9438,12 @@ function codeCommentConfirm(pin) {
|
|
|
9353
9438
|
sweepRestrictedDir();
|
|
9354
9439
|
const state = readPinState(pin);
|
|
9355
9440
|
if (!state) {
|
|
9356
|
-
console.error(
|
|
9441
|
+
console.error(chalk94.red(`No pending comment for pin: ${pin}`));
|
|
9357
9442
|
process.exitCode = 1;
|
|
9358
9443
|
return;
|
|
9359
9444
|
}
|
|
9360
9445
|
if (!existsSync27(state.file)) {
|
|
9361
|
-
console.error(
|
|
9446
|
+
console.error(chalk94.red(`Target file no longer exists: ${state.file}`));
|
|
9362
9447
|
process.exitCode = 1;
|
|
9363
9448
|
return;
|
|
9364
9449
|
}
|
|
@@ -9367,7 +9452,7 @@ function codeCommentConfirm(pin) {
|
|
|
9367
9452
|
const index3 = state.line - 1;
|
|
9368
9453
|
if (index3 > lines.length) {
|
|
9369
9454
|
console.error(
|
|
9370
|
-
|
|
9455
|
+
chalk94.red(
|
|
9371
9456
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
9372
9457
|
)
|
|
9373
9458
|
);
|
|
@@ -9380,12 +9465,12 @@ function codeCommentConfirm(pin) {
|
|
|
9380
9465
|
writeFileSync22(state.file, lines.join("\n"));
|
|
9381
9466
|
unlinkSync8(getPinStatePath(pin));
|
|
9382
9467
|
console.log(
|
|
9383
|
-
|
|
9468
|
+
chalk94.green(`Inserted "// ${state.text}" at ${state.file}:${state.line}`)
|
|
9384
9469
|
);
|
|
9385
9470
|
}
|
|
9386
9471
|
|
|
9387
9472
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9388
|
-
import
|
|
9473
|
+
import chalk95 from "chalk";
|
|
9389
9474
|
|
|
9390
9475
|
// src/commands/codeComment/validateCommentText.ts
|
|
9391
9476
|
var MAX_COMMENT_LENGTH = 50;
|
|
@@ -9436,26 +9521,26 @@ function generatePin() {
|
|
|
9436
9521
|
function codeCommentSet(file, line, text6) {
|
|
9437
9522
|
const lineNumber = Number.parseInt(line, 10);
|
|
9438
9523
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
9439
|
-
console.error(
|
|
9524
|
+
console.error(chalk95.red(`Invalid line number: ${line}`));
|
|
9440
9525
|
process.exitCode = 1;
|
|
9441
9526
|
return;
|
|
9442
9527
|
}
|
|
9443
9528
|
const validation = validateCommentText(text6);
|
|
9444
9529
|
if (!validation.ok) {
|
|
9445
|
-
console.error(
|
|
9446
|
-
console.error(
|
|
9530
|
+
console.error(chalk95.red(`Refused: ${validation.reason}`));
|
|
9531
|
+
console.error(chalk95.red("No pin issued."));
|
|
9447
9532
|
process.exitCode = 1;
|
|
9448
9533
|
return;
|
|
9449
9534
|
}
|
|
9450
9535
|
console.error(
|
|
9451
|
-
|
|
9536
|
+
chalk95.yellow.bold(
|
|
9452
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."
|
|
9453
9538
|
)
|
|
9454
9539
|
);
|
|
9455
9540
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
9456
9541
|
if (!delivered) {
|
|
9457
9542
|
console.error(
|
|
9458
|
-
|
|
9543
|
+
chalk95.red(
|
|
9459
9544
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
9460
9545
|
)
|
|
9461
9546
|
);
|
|
@@ -9465,7 +9550,7 @@ function codeCommentSet(file, line, text6) {
|
|
|
9465
9550
|
console.log(
|
|
9466
9551
|
`A confirmation pin was sent to your desktop notifications.
|
|
9467
9552
|
To insert "// ${validation.text}" at ${file}:${lineNumber}, run:
|
|
9468
|
-
${
|
|
9553
|
+
${chalk95.cyan(" assist code-comment confirm <PIN>")}
|
|
9469
9554
|
using the pin from that notification.`
|
|
9470
9555
|
);
|
|
9471
9556
|
}
|
|
@@ -9485,15 +9570,15 @@ function registerCodeComment(parent) {
|
|
|
9485
9570
|
}
|
|
9486
9571
|
|
|
9487
9572
|
// src/commands/complexity/analyze.ts
|
|
9488
|
-
import
|
|
9573
|
+
import chalk104 from "chalk";
|
|
9489
9574
|
|
|
9490
9575
|
// src/commands/complexity/cyclomatic.ts
|
|
9491
|
-
import
|
|
9576
|
+
import chalk97 from "chalk";
|
|
9492
9577
|
|
|
9493
9578
|
// src/commands/complexity/shared/index.ts
|
|
9494
9579
|
import fs16 from "fs";
|
|
9495
9580
|
import path21 from "path";
|
|
9496
|
-
import
|
|
9581
|
+
import chalk96 from "chalk";
|
|
9497
9582
|
import ts5 from "typescript";
|
|
9498
9583
|
|
|
9499
9584
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -9744,7 +9829,7 @@ function createSourceFromFile(filePath) {
|
|
|
9744
9829
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
9745
9830
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
9746
9831
|
if (files.length === 0) {
|
|
9747
|
-
console.log(
|
|
9832
|
+
console.log(chalk96.yellow("No files found matching pattern"));
|
|
9748
9833
|
return void 0;
|
|
9749
9834
|
}
|
|
9750
9835
|
return callback(files);
|
|
@@ -9777,11 +9862,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9777
9862
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
9778
9863
|
for (const { file, name, complexity } of results) {
|
|
9779
9864
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
9780
|
-
const color = exceedsThreshold ?
|
|
9781
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
9865
|
+
const color = exceedsThreshold ? chalk97.red : chalk97.white;
|
|
9866
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk97.cyan(complexity)}`);
|
|
9782
9867
|
}
|
|
9783
9868
|
console.log(
|
|
9784
|
-
|
|
9869
|
+
chalk97.dim(
|
|
9785
9870
|
`
|
|
9786
9871
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
9787
9872
|
)
|
|
@@ -9793,7 +9878,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
9793
9878
|
}
|
|
9794
9879
|
|
|
9795
9880
|
// src/commands/complexity/halstead.ts
|
|
9796
|
-
import
|
|
9881
|
+
import chalk98 from "chalk";
|
|
9797
9882
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
9798
9883
|
withSourceFiles(pattern2, (files) => {
|
|
9799
9884
|
const results = [];
|
|
@@ -9808,13 +9893,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9808
9893
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
9809
9894
|
for (const { file, name, metrics } of results) {
|
|
9810
9895
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
9811
|
-
const color = exceedsThreshold ?
|
|
9896
|
+
const color = exceedsThreshold ? chalk98.red : chalk98.white;
|
|
9812
9897
|
console.log(
|
|
9813
|
-
`${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))}`
|
|
9814
9899
|
);
|
|
9815
9900
|
}
|
|
9816
9901
|
console.log(
|
|
9817
|
-
|
|
9902
|
+
chalk98.dim(
|
|
9818
9903
|
`
|
|
9819
9904
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
9820
9905
|
)
|
|
@@ -9826,27 +9911,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
9826
9911
|
}
|
|
9827
9912
|
|
|
9828
9913
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
9829
|
-
import
|
|
9914
|
+
import chalk101 from "chalk";
|
|
9830
9915
|
|
|
9831
9916
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
9832
|
-
import
|
|
9917
|
+
import chalk99 from "chalk";
|
|
9833
9918
|
function formatResultLine(entry, failing) {
|
|
9834
9919
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
9835
|
-
const name = failing ?
|
|
9836
|
-
const suffix = override !== void 0 ?
|
|
9837
|
-
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}`;
|
|
9838
9923
|
}
|
|
9839
9924
|
|
|
9840
9925
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
9841
|
-
import
|
|
9926
|
+
import chalk100 from "chalk";
|
|
9842
9927
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
9843
9928
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
9844
9929
|
console.error(
|
|
9845
|
-
|
|
9930
|
+
chalk100.red(
|
|
9846
9931
|
`
|
|
9847
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.
|
|
9848
9933
|
|
|
9849
|
-
\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.
|
|
9850
9935
|
|
|
9851
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.`
|
|
9852
9937
|
)
|
|
@@ -9858,7 +9943,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
9858
9943
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
9859
9944
|
if (!gating) {
|
|
9860
9945
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
9861
|
-
console.log(
|
|
9946
|
+
console.log(chalk101.dim(`
|
|
9862
9947
|
Analyzed ${results.length} files`));
|
|
9863
9948
|
return;
|
|
9864
9949
|
}
|
|
@@ -9867,7 +9952,7 @@ Analyzed ${results.length} files`));
|
|
|
9867
9952
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
9868
9953
|
});
|
|
9869
9954
|
if (failing.length === 0) {
|
|
9870
|
-
console.log(
|
|
9955
|
+
console.log(chalk101.green("All files pass maintainability threshold"));
|
|
9871
9956
|
} else {
|
|
9872
9957
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
9873
9958
|
}
|
|
@@ -9876,7 +9961,7 @@ Analyzed ${results.length} files`));
|
|
|
9876
9961
|
);
|
|
9877
9962
|
for (const entry of passingOverrides)
|
|
9878
9963
|
console.log(formatResultLine(entry, false));
|
|
9879
|
-
console.log(
|
|
9964
|
+
console.log(chalk101.dim(`
|
|
9880
9965
|
Analyzed ${results.length} files`));
|
|
9881
9966
|
if (failing.length > 0) {
|
|
9882
9967
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -9885,10 +9970,10 @@ Analyzed ${results.length} files`));
|
|
|
9885
9970
|
}
|
|
9886
9971
|
|
|
9887
9972
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
9888
|
-
import
|
|
9973
|
+
import chalk102 from "chalk";
|
|
9889
9974
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
9890
9975
|
function printMaintainabilityFormula() {
|
|
9891
|
-
console.log(
|
|
9976
|
+
console.log(chalk102.dim(MI_FORMULA));
|
|
9892
9977
|
}
|
|
9893
9978
|
|
|
9894
9979
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -9964,7 +10049,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9964
10049
|
|
|
9965
10050
|
// src/commands/complexity/sloc.ts
|
|
9966
10051
|
import fs18 from "fs";
|
|
9967
|
-
import
|
|
10052
|
+
import chalk103 from "chalk";
|
|
9968
10053
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
9969
10054
|
withSourceFiles(pattern2, (files) => {
|
|
9970
10055
|
const results = [];
|
|
@@ -9980,12 +10065,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
9980
10065
|
results.sort((a, b) => b.lines - a.lines);
|
|
9981
10066
|
for (const { file, lines } of results) {
|
|
9982
10067
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
9983
|
-
const color = exceedsThreshold ?
|
|
9984
|
-
console.log(`${color(file)} \u2192 ${
|
|
10068
|
+
const color = exceedsThreshold ? chalk103.red : chalk103.white;
|
|
10069
|
+
console.log(`${color(file)} \u2192 ${chalk103.cyan(lines)} lines`);
|
|
9985
10070
|
}
|
|
9986
10071
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
9987
10072
|
console.log(
|
|
9988
|
-
|
|
10073
|
+
chalk103.dim(`
|
|
9989
10074
|
Total: ${total} lines across ${files.length} files`)
|
|
9990
10075
|
);
|
|
9991
10076
|
if (hasViolation) {
|
|
@@ -9999,25 +10084,25 @@ async function analyze(pattern2) {
|
|
|
9999
10084
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
10000
10085
|
const files = findSourceFiles2(searchPattern);
|
|
10001
10086
|
if (files.length === 0) {
|
|
10002
|
-
console.log(
|
|
10087
|
+
console.log(chalk104.yellow("No files found matching pattern"));
|
|
10003
10088
|
return;
|
|
10004
10089
|
}
|
|
10005
10090
|
if (files.length === 1) {
|
|
10006
10091
|
const file = files[0];
|
|
10007
|
-
console.log(
|
|
10092
|
+
console.log(chalk104.bold.underline("SLOC"));
|
|
10008
10093
|
await sloc(file);
|
|
10009
10094
|
console.log();
|
|
10010
|
-
console.log(
|
|
10095
|
+
console.log(chalk104.bold.underline("Cyclomatic Complexity"));
|
|
10011
10096
|
await cyclomatic(file);
|
|
10012
10097
|
console.log();
|
|
10013
|
-
console.log(
|
|
10098
|
+
console.log(chalk104.bold.underline("Halstead Metrics"));
|
|
10014
10099
|
await halstead(file);
|
|
10015
10100
|
console.log();
|
|
10016
|
-
console.log(
|
|
10101
|
+
console.log(chalk104.bold.underline("Maintainability Index"));
|
|
10017
10102
|
await maintainability(file);
|
|
10018
10103
|
console.log();
|
|
10019
10104
|
console.log(
|
|
10020
|
-
|
|
10105
|
+
chalk104.dim(
|
|
10021
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."
|
|
10022
10107
|
)
|
|
10023
10108
|
);
|
|
@@ -10051,7 +10136,7 @@ function registerComplexity(program2) {
|
|
|
10051
10136
|
}
|
|
10052
10137
|
|
|
10053
10138
|
// src/commands/config/index.ts
|
|
10054
|
-
import
|
|
10139
|
+
import chalk105 from "chalk";
|
|
10055
10140
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
10056
10141
|
|
|
10057
10142
|
// src/commands/config/setNestedValue.ts
|
|
@@ -10114,7 +10199,7 @@ function formatIssuePath(issue, key) {
|
|
|
10114
10199
|
function printValidationErrors(issues, key) {
|
|
10115
10200
|
for (const issue of issues) {
|
|
10116
10201
|
console.error(
|
|
10117
|
-
|
|
10202
|
+
chalk105.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
10118
10203
|
);
|
|
10119
10204
|
}
|
|
10120
10205
|
}
|
|
@@ -10131,7 +10216,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
10131
10216
|
function assertNotGlobalOnly(key, global) {
|
|
10132
10217
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
10133
10218
|
console.error(
|
|
10134
|
-
|
|
10219
|
+
chalk105.red(
|
|
10135
10220
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
10136
10221
|
)
|
|
10137
10222
|
);
|
|
@@ -10154,7 +10239,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
10154
10239
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
10155
10240
|
const target = options2.global ? "global" : "project";
|
|
10156
10241
|
console.log(
|
|
10157
|
-
|
|
10242
|
+
chalk105.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
10158
10243
|
);
|
|
10159
10244
|
}
|
|
10160
10245
|
function configList() {
|
|
@@ -10163,7 +10248,7 @@ function configList() {
|
|
|
10163
10248
|
}
|
|
10164
10249
|
|
|
10165
10250
|
// src/commands/config/configGet.ts
|
|
10166
|
-
import
|
|
10251
|
+
import chalk106 from "chalk";
|
|
10167
10252
|
|
|
10168
10253
|
// src/commands/config/getNestedValue.ts
|
|
10169
10254
|
function isTraversable(value) {
|
|
@@ -10195,7 +10280,7 @@ function requireNestedValue(config, key) {
|
|
|
10195
10280
|
return value;
|
|
10196
10281
|
}
|
|
10197
10282
|
function exitKeyNotSet(key) {
|
|
10198
|
-
console.error(
|
|
10283
|
+
console.error(chalk106.red(`Key "${key}" is not set`));
|
|
10199
10284
|
process.exit(1);
|
|
10200
10285
|
}
|
|
10201
10286
|
|
|
@@ -10209,7 +10294,7 @@ function registerConfig(program2) {
|
|
|
10209
10294
|
|
|
10210
10295
|
// src/commands/deploy/redirect.ts
|
|
10211
10296
|
import { existsSync as existsSync28, readFileSync as readFileSync23, writeFileSync as writeFileSync24 } from "fs";
|
|
10212
|
-
import
|
|
10297
|
+
import chalk107 from "chalk";
|
|
10213
10298
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10214
10299
|
if (!window.location.pathname.endsWith('/')) {
|
|
10215
10300
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10218,23 +10303,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10218
10303
|
function redirect() {
|
|
10219
10304
|
const indexPath = "index.html";
|
|
10220
10305
|
if (!existsSync28(indexPath)) {
|
|
10221
|
-
console.log(
|
|
10306
|
+
console.log(chalk107.yellow("No index.html found"));
|
|
10222
10307
|
return;
|
|
10223
10308
|
}
|
|
10224
10309
|
const content = readFileSync23(indexPath, "utf8");
|
|
10225
10310
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10226
|
-
console.log(
|
|
10311
|
+
console.log(chalk107.dim("Trailing slash script already present"));
|
|
10227
10312
|
return;
|
|
10228
10313
|
}
|
|
10229
10314
|
const headCloseIndex = content.indexOf("</head>");
|
|
10230
10315
|
if (headCloseIndex === -1) {
|
|
10231
|
-
console.log(
|
|
10316
|
+
console.log(chalk107.red("Could not find </head> tag in index.html"));
|
|
10232
10317
|
return;
|
|
10233
10318
|
}
|
|
10234
10319
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10235
10320
|
${content.slice(headCloseIndex)}`;
|
|
10236
10321
|
writeFileSync24(indexPath, newContent);
|
|
10237
|
-
console.log(
|
|
10322
|
+
console.log(chalk107.green("Added trailing slash redirect to index.html"));
|
|
10238
10323
|
}
|
|
10239
10324
|
|
|
10240
10325
|
// src/commands/registerDeploy.ts
|
|
@@ -10260,8 +10345,8 @@ function loadBlogSkipDays(repoName) {
|
|
|
10260
10345
|
}
|
|
10261
10346
|
|
|
10262
10347
|
// src/commands/devlog/shared.ts
|
|
10263
|
-
import { execSync as
|
|
10264
|
-
import
|
|
10348
|
+
import { execSync as execSync24 } from "child_process";
|
|
10349
|
+
import chalk108 from "chalk";
|
|
10265
10350
|
|
|
10266
10351
|
// src/shared/getRepoName.ts
|
|
10267
10352
|
import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
|
|
@@ -10352,7 +10437,7 @@ function loadAllDevlogLatestDates() {
|
|
|
10352
10437
|
// src/commands/devlog/shared.ts
|
|
10353
10438
|
function getCommitFiles(hash) {
|
|
10354
10439
|
try {
|
|
10355
|
-
const output =
|
|
10440
|
+
const output = execSync24(`git show --name-only --format="" ${hash}`, {
|
|
10356
10441
|
encoding: "utf8"
|
|
10357
10442
|
});
|
|
10358
10443
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -10370,13 +10455,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10370
10455
|
}
|
|
10371
10456
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10372
10457
|
for (const commit2 of commits2) {
|
|
10373
|
-
console.log(` ${
|
|
10458
|
+
console.log(` ${chalk108.yellow(commit2.hash)} ${commit2.message}`);
|
|
10374
10459
|
if (verbose) {
|
|
10375
10460
|
const visibleFiles = commit2.files.filter(
|
|
10376
10461
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10377
10462
|
);
|
|
10378
10463
|
for (const file of visibleFiles) {
|
|
10379
|
-
console.log(` ${
|
|
10464
|
+
console.log(` ${chalk108.dim(file)}`);
|
|
10380
10465
|
}
|
|
10381
10466
|
}
|
|
10382
10467
|
}
|
|
@@ -10401,15 +10486,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10401
10486
|
}
|
|
10402
10487
|
|
|
10403
10488
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10404
|
-
import
|
|
10489
|
+
import chalk109 from "chalk";
|
|
10405
10490
|
function printDateHeader(date, isSkipped, entries) {
|
|
10406
10491
|
if (isSkipped) {
|
|
10407
|
-
console.log(`${
|
|
10492
|
+
console.log(`${chalk109.bold.blue(date)} ${chalk109.dim("skipped")}`);
|
|
10408
10493
|
} else if (entries && entries.length > 0) {
|
|
10409
|
-
const entryInfo = entries.map((e) => `${
|
|
10410
|
-
console.log(`${
|
|
10494
|
+
const entryInfo = entries.map((e) => `${chalk109.green(e.version)} ${e.title}`).join(" | ");
|
|
10495
|
+
console.log(`${chalk109.bold.blue(date)} ${entryInfo}`);
|
|
10411
10496
|
} else {
|
|
10412
|
-
console.log(`${
|
|
10497
|
+
console.log(`${chalk109.bold.blue(date)} ${chalk109.red("\u26A0 devlog missing")}`);
|
|
10413
10498
|
}
|
|
10414
10499
|
}
|
|
10415
10500
|
|
|
@@ -10448,11 +10533,11 @@ function list3(options2) {
|
|
|
10448
10533
|
}
|
|
10449
10534
|
|
|
10450
10535
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
10451
|
-
import { execFileSync as execFileSync3, execSync as
|
|
10536
|
+
import { execFileSync as execFileSync3, execSync as execSync25 } from "child_process";
|
|
10452
10537
|
import semver from "semver";
|
|
10453
10538
|
function getVersionAtCommit(hash) {
|
|
10454
10539
|
try {
|
|
10455
|
-
const content =
|
|
10540
|
+
const content = execSync25(`git show ${hash}:package.json`, {
|
|
10456
10541
|
encoding: "utf8"
|
|
10457
10542
|
});
|
|
10458
10543
|
const pkg = JSON.parse(content);
|
|
@@ -10513,24 +10598,24 @@ function bumpVersion(version2, type) {
|
|
|
10513
10598
|
|
|
10514
10599
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10515
10600
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10516
|
-
import
|
|
10601
|
+
import chalk111 from "chalk";
|
|
10517
10602
|
|
|
10518
10603
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10519
|
-
import
|
|
10604
|
+
import chalk110 from "chalk";
|
|
10520
10605
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10521
10606
|
if (conventional && firstHash) {
|
|
10522
10607
|
const version2 = getVersionAtCommit(firstHash);
|
|
10523
10608
|
if (version2) {
|
|
10524
|
-
console.log(`${
|
|
10609
|
+
console.log(`${chalk110.bold("version:")} ${stripToMinor(version2)}`);
|
|
10525
10610
|
} else {
|
|
10526
|
-
console.log(`${
|
|
10611
|
+
console.log(`${chalk110.bold("version:")} ${chalk110.red("unknown")}`);
|
|
10527
10612
|
}
|
|
10528
10613
|
} else if (patchVersion && minorVersion) {
|
|
10529
10614
|
console.log(
|
|
10530
|
-
`${
|
|
10615
|
+
`${chalk110.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10531
10616
|
);
|
|
10532
10617
|
} else {
|
|
10533
|
-
console.log(`${
|
|
10618
|
+
console.log(`${chalk110.bold("version:")} v0.1 (initial)`);
|
|
10534
10619
|
}
|
|
10535
10620
|
}
|
|
10536
10621
|
|
|
@@ -10578,16 +10663,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10578
10663
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10579
10664
|
}
|
|
10580
10665
|
function logName(repoName) {
|
|
10581
|
-
console.log(`${
|
|
10666
|
+
console.log(`${chalk111.bold("name:")} ${repoName}`);
|
|
10582
10667
|
}
|
|
10583
10668
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10584
10669
|
logName(ctx.repoName);
|
|
10585
10670
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10586
|
-
console.log(
|
|
10671
|
+
console.log(chalk111.bold.blue(targetDate));
|
|
10587
10672
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10588
10673
|
}
|
|
10589
10674
|
function logNoCommits(lastInfo) {
|
|
10590
|
-
console.log(
|
|
10675
|
+
console.log(chalk111.dim(noCommitsMessage(!!lastInfo)));
|
|
10591
10676
|
}
|
|
10592
10677
|
|
|
10593
10678
|
// src/commands/devlog/next/index.ts
|
|
@@ -10625,14 +10710,14 @@ function next2(options2) {
|
|
|
10625
10710
|
}
|
|
10626
10711
|
|
|
10627
10712
|
// src/commands/devlog/repos/index.ts
|
|
10628
|
-
import { execSync as
|
|
10713
|
+
import { execSync as execSync26 } from "child_process";
|
|
10629
10714
|
|
|
10630
10715
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10631
|
-
import
|
|
10716
|
+
import chalk112 from "chalk";
|
|
10632
10717
|
function colorStatus(status2) {
|
|
10633
|
-
if (status2 === "missing") return
|
|
10634
|
-
if (status2 === "outdated") return
|
|
10635
|
-
return
|
|
10718
|
+
if (status2 === "missing") return chalk112.red(status2);
|
|
10719
|
+
if (status2 === "outdated") return chalk112.yellow(status2);
|
|
10720
|
+
return chalk112.green(status2);
|
|
10636
10721
|
}
|
|
10637
10722
|
function formatRow(row, nameWidth) {
|
|
10638
10723
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10646,8 +10731,8 @@ function printReposTable(rows) {
|
|
|
10646
10731
|
"Last Devlog".padEnd(11),
|
|
10647
10732
|
"Status"
|
|
10648
10733
|
].join(" ");
|
|
10649
|
-
console.log(
|
|
10650
|
-
console.log(
|
|
10734
|
+
console.log(chalk112.dim(header));
|
|
10735
|
+
console.log(chalk112.dim("-".repeat(header.length)));
|
|
10651
10736
|
for (const row of rows) {
|
|
10652
10737
|
console.log(formatRow(row, nameWidth));
|
|
10653
10738
|
}
|
|
@@ -10660,7 +10745,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
10660
10745
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
10661
10746
|
}
|
|
10662
10747
|
function fetchRepos(days, all) {
|
|
10663
|
-
const json =
|
|
10748
|
+
const json = execSync26(
|
|
10664
10749
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
10665
10750
|
{ encoding: "utf8" }
|
|
10666
10751
|
);
|
|
@@ -10705,14 +10790,14 @@ function repos(options2) {
|
|
|
10705
10790
|
// src/commands/devlog/skip.ts
|
|
10706
10791
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
10707
10792
|
import { join as join30 } from "path";
|
|
10708
|
-
import
|
|
10793
|
+
import chalk113 from "chalk";
|
|
10709
10794
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10710
10795
|
function getBlogConfigPath() {
|
|
10711
10796
|
return join30(BLOG_REPO_ROOT, "assist.yml");
|
|
10712
10797
|
}
|
|
10713
10798
|
function skip(date) {
|
|
10714
10799
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10715
|
-
console.log(
|
|
10800
|
+
console.log(chalk113.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10716
10801
|
process.exit(1);
|
|
10717
10802
|
}
|
|
10718
10803
|
const repoName = getRepoName();
|
|
@@ -10723,7 +10808,7 @@ function skip(date) {
|
|
|
10723
10808
|
const skipDays = skip2[repoName] ?? [];
|
|
10724
10809
|
if (skipDays.includes(date)) {
|
|
10725
10810
|
console.log(
|
|
10726
|
-
|
|
10811
|
+
chalk113.yellow(`${date} is already in skip list for ${repoName}`)
|
|
10727
10812
|
);
|
|
10728
10813
|
return;
|
|
10729
10814
|
}
|
|
@@ -10733,20 +10818,20 @@ function skip(date) {
|
|
|
10733
10818
|
devlog.skip = skip2;
|
|
10734
10819
|
config.devlog = devlog;
|
|
10735
10820
|
writeFileSync25(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
10736
|
-
console.log(
|
|
10821
|
+
console.log(chalk113.green(`Added ${date} to skip list for ${repoName}`));
|
|
10737
10822
|
}
|
|
10738
10823
|
|
|
10739
10824
|
// src/commands/devlog/version.ts
|
|
10740
|
-
import
|
|
10825
|
+
import chalk114 from "chalk";
|
|
10741
10826
|
function version() {
|
|
10742
10827
|
const config = loadConfig();
|
|
10743
10828
|
const name = getRepoName();
|
|
10744
10829
|
const lastInfo = getLastVersionInfo(name, config);
|
|
10745
10830
|
const lastVersion = lastInfo?.version ?? null;
|
|
10746
10831
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
10747
|
-
console.log(`${
|
|
10748
|
-
console.log(`${
|
|
10749
|
-
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")}`);
|
|
10750
10835
|
}
|
|
10751
10836
|
|
|
10752
10837
|
// src/commands/registerDevlog.ts
|
|
@@ -10770,7 +10855,7 @@ function registerDevlog(program2) {
|
|
|
10770
10855
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
10771
10856
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync3 } from "fs";
|
|
10772
10857
|
import { join as join31 } from "path";
|
|
10773
|
-
import
|
|
10858
|
+
import chalk115 from "chalk";
|
|
10774
10859
|
|
|
10775
10860
|
// src/shared/findRepoRoot.ts
|
|
10776
10861
|
import { existsSync as existsSync30 } from "fs";
|
|
@@ -10833,14 +10918,14 @@ function checkBuildLocks(startDir) {
|
|
|
10833
10918
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
10834
10919
|
if (locked) {
|
|
10835
10920
|
console.error(
|
|
10836
|
-
|
|
10921
|
+
chalk115.red("Build output locked (is VS debugging?): ") + locked
|
|
10837
10922
|
);
|
|
10838
10923
|
process.exit(1);
|
|
10839
10924
|
}
|
|
10840
10925
|
}
|
|
10841
10926
|
async function checkBuildLocksCommand() {
|
|
10842
10927
|
checkBuildLocks();
|
|
10843
|
-
console.log(
|
|
10928
|
+
console.log(chalk115.green("No build locks detected"));
|
|
10844
10929
|
}
|
|
10845
10930
|
|
|
10846
10931
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -10939,30 +11024,30 @@ function escapeRegex(s) {
|
|
|
10939
11024
|
}
|
|
10940
11025
|
|
|
10941
11026
|
// src/commands/dotnet/printTree.ts
|
|
10942
|
-
import
|
|
11027
|
+
import chalk116 from "chalk";
|
|
10943
11028
|
function printNodes(nodes, prefix2) {
|
|
10944
11029
|
for (let i = 0; i < nodes.length; i++) {
|
|
10945
11030
|
const isLast = i === nodes.length - 1;
|
|
10946
11031
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
10947
11032
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
10948
11033
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
10949
|
-
const label2 = isMissing ?
|
|
11034
|
+
const label2 = isMissing ? chalk116.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
10950
11035
|
console.log(`${prefix2}${connector}${label2}`);
|
|
10951
11036
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
10952
11037
|
}
|
|
10953
11038
|
}
|
|
10954
11039
|
function printTree(tree, totalCount, solutions) {
|
|
10955
|
-
console.log(
|
|
10956
|
-
console.log(
|
|
11040
|
+
console.log(chalk116.bold("\nProject Dependency Tree"));
|
|
11041
|
+
console.log(chalk116.cyan(tree.relativePath));
|
|
10957
11042
|
printNodes(tree.children, "");
|
|
10958
|
-
console.log(
|
|
11043
|
+
console.log(chalk116.dim(`
|
|
10959
11044
|
${totalCount} projects total (including root)`));
|
|
10960
|
-
console.log(
|
|
11045
|
+
console.log(chalk116.bold("\nSolution Membership"));
|
|
10961
11046
|
if (solutions.length === 0) {
|
|
10962
|
-
console.log(
|
|
11047
|
+
console.log(chalk116.yellow(" Not found in any .sln"));
|
|
10963
11048
|
} else {
|
|
10964
11049
|
for (const sln of solutions) {
|
|
10965
|
-
console.log(` ${
|
|
11050
|
+
console.log(` ${chalk116.green(sln)}`);
|
|
10966
11051
|
}
|
|
10967
11052
|
}
|
|
10968
11053
|
console.log();
|
|
@@ -10991,16 +11076,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
10991
11076
|
// src/commands/dotnet/resolveCsproj.ts
|
|
10992
11077
|
import { existsSync as existsSync31 } from "fs";
|
|
10993
11078
|
import path25 from "path";
|
|
10994
|
-
import
|
|
11079
|
+
import chalk117 from "chalk";
|
|
10995
11080
|
function resolveCsproj(csprojPath) {
|
|
10996
11081
|
const resolved = path25.resolve(csprojPath);
|
|
10997
11082
|
if (!existsSync31(resolved)) {
|
|
10998
|
-
console.error(
|
|
11083
|
+
console.error(chalk117.red(`File not found: ${resolved}`));
|
|
10999
11084
|
process.exit(1);
|
|
11000
11085
|
}
|
|
11001
11086
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
11002
11087
|
if (!repoRoot) {
|
|
11003
|
-
console.error(
|
|
11088
|
+
console.error(chalk117.red("Could not find git repository root"));
|
|
11004
11089
|
process.exit(1);
|
|
11005
11090
|
}
|
|
11006
11091
|
return { resolved, repoRoot };
|
|
@@ -11020,7 +11105,7 @@ async function deps(csprojPath, options2) {
|
|
|
11020
11105
|
}
|
|
11021
11106
|
|
|
11022
11107
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
11023
|
-
import { execSync as
|
|
11108
|
+
import { execSync as execSync27 } from "child_process";
|
|
11024
11109
|
var SCOPE_ALL = "all";
|
|
11025
11110
|
var SCOPE_BASE = "base:";
|
|
11026
11111
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -11044,18 +11129,18 @@ function getChangedCsFiles(scope) {
|
|
|
11044
11129
|
} else {
|
|
11045
11130
|
cmd = "git diff --name-only HEAD";
|
|
11046
11131
|
}
|
|
11047
|
-
const output =
|
|
11132
|
+
const output = execSync27(cmd, { encoding: "utf8" }).trim();
|
|
11048
11133
|
if (output === "") return [];
|
|
11049
11134
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
11050
11135
|
}
|
|
11051
11136
|
|
|
11052
11137
|
// src/commands/dotnet/inSln.ts
|
|
11053
|
-
import
|
|
11138
|
+
import chalk118 from "chalk";
|
|
11054
11139
|
async function inSln(csprojPath) {
|
|
11055
11140
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
11056
11141
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
11057
11142
|
if (solutions.length === 0) {
|
|
11058
|
-
console.log(
|
|
11143
|
+
console.log(chalk118.yellow("Not found in any .sln file"));
|
|
11059
11144
|
process.exit(1);
|
|
11060
11145
|
}
|
|
11061
11146
|
for (const sln of solutions) {
|
|
@@ -11064,7 +11149,7 @@ async function inSln(csprojPath) {
|
|
|
11064
11149
|
}
|
|
11065
11150
|
|
|
11066
11151
|
// src/commands/dotnet/inspect.ts
|
|
11067
|
-
import
|
|
11152
|
+
import chalk124 from "chalk";
|
|
11068
11153
|
|
|
11069
11154
|
// src/shared/formatElapsed.ts
|
|
11070
11155
|
function formatElapsed(ms) {
|
|
@@ -11076,12 +11161,12 @@ function formatElapsed(ms) {
|
|
|
11076
11161
|
}
|
|
11077
11162
|
|
|
11078
11163
|
// src/commands/dotnet/displayIssues.ts
|
|
11079
|
-
import
|
|
11164
|
+
import chalk119 from "chalk";
|
|
11080
11165
|
var SEVERITY_COLOR = {
|
|
11081
|
-
ERROR:
|
|
11082
|
-
WARNING:
|
|
11083
|
-
SUGGESTION:
|
|
11084
|
-
HINT:
|
|
11166
|
+
ERROR: chalk119.red,
|
|
11167
|
+
WARNING: chalk119.yellow,
|
|
11168
|
+
SUGGESTION: chalk119.cyan,
|
|
11169
|
+
HINT: chalk119.dim
|
|
11085
11170
|
};
|
|
11086
11171
|
function groupByFile(issues) {
|
|
11087
11172
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -11097,15 +11182,15 @@ function groupByFile(issues) {
|
|
|
11097
11182
|
}
|
|
11098
11183
|
function displayIssues(issues) {
|
|
11099
11184
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
11100
|
-
console.log(
|
|
11185
|
+
console.log(chalk119.bold(file));
|
|
11101
11186
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
11102
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
11187
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk119.white;
|
|
11103
11188
|
console.log(
|
|
11104
|
-
` ${
|
|
11189
|
+
` ${chalk119.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
11105
11190
|
);
|
|
11106
11191
|
}
|
|
11107
11192
|
}
|
|
11108
|
-
console.log(
|
|
11193
|
+
console.log(chalk119.dim(`
|
|
11109
11194
|
${issues.length} issue(s) found`));
|
|
11110
11195
|
}
|
|
11111
11196
|
|
|
@@ -11164,12 +11249,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11164
11249
|
// src/commands/dotnet/resolveSolution.ts
|
|
11165
11250
|
import { existsSync as existsSync32 } from "fs";
|
|
11166
11251
|
import path26 from "path";
|
|
11167
|
-
import
|
|
11252
|
+
import chalk121 from "chalk";
|
|
11168
11253
|
|
|
11169
11254
|
// src/commands/dotnet/findSolution.ts
|
|
11170
11255
|
import { readdirSync as readdirSync5 } from "fs";
|
|
11171
11256
|
import { dirname as dirname18, join as join32 } from "path";
|
|
11172
|
-
import
|
|
11257
|
+
import chalk120 from "chalk";
|
|
11173
11258
|
function findSlnInDir(dir) {
|
|
11174
11259
|
try {
|
|
11175
11260
|
return readdirSync5(dir).filter((f) => f.endsWith(".sln")).map((f) => join32(dir, f));
|
|
@@ -11185,17 +11270,17 @@ function findSolution() {
|
|
|
11185
11270
|
const slnFiles = findSlnInDir(current);
|
|
11186
11271
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
11187
11272
|
if (slnFiles.length > 1) {
|
|
11188
|
-
console.error(
|
|
11273
|
+
console.error(chalk120.red(`Multiple .sln files found in ${current}:`));
|
|
11189
11274
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
11190
11275
|
console.error(
|
|
11191
|
-
|
|
11276
|
+
chalk120.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
11192
11277
|
);
|
|
11193
11278
|
process.exit(1);
|
|
11194
11279
|
}
|
|
11195
11280
|
if (current === ceiling) break;
|
|
11196
11281
|
current = dirname18(current);
|
|
11197
11282
|
}
|
|
11198
|
-
console.error(
|
|
11283
|
+
console.error(chalk120.red("No .sln file found between cwd and repo root"));
|
|
11199
11284
|
process.exit(1);
|
|
11200
11285
|
}
|
|
11201
11286
|
|
|
@@ -11204,7 +11289,7 @@ function resolveSolution(sln) {
|
|
|
11204
11289
|
if (sln) {
|
|
11205
11290
|
const resolved = path26.resolve(sln);
|
|
11206
11291
|
if (!existsSync32(resolved)) {
|
|
11207
|
-
console.error(
|
|
11292
|
+
console.error(chalk121.red(`Solution file not found: ${resolved}`));
|
|
11208
11293
|
process.exit(1);
|
|
11209
11294
|
}
|
|
11210
11295
|
return resolved;
|
|
@@ -11242,18 +11327,18 @@ function parseInspectReport(json) {
|
|
|
11242
11327
|
}
|
|
11243
11328
|
|
|
11244
11329
|
// src/commands/dotnet/runInspectCode.ts
|
|
11245
|
-
import { execSync as
|
|
11330
|
+
import { execSync as execSync28 } from "child_process";
|
|
11246
11331
|
import { existsSync as existsSync33, readFileSync as readFileSync28, unlinkSync as unlinkSync9 } from "fs";
|
|
11247
11332
|
import { tmpdir as tmpdir3 } from "os";
|
|
11248
11333
|
import path27 from "path";
|
|
11249
|
-
import
|
|
11334
|
+
import chalk122 from "chalk";
|
|
11250
11335
|
function assertJbInstalled() {
|
|
11251
11336
|
try {
|
|
11252
|
-
|
|
11337
|
+
execSync28("jb inspectcode --version", { stdio: "pipe" });
|
|
11253
11338
|
} catch {
|
|
11254
|
-
console.error(
|
|
11339
|
+
console.error(chalk122.red("jb is not installed. Install with:"));
|
|
11255
11340
|
console.error(
|
|
11256
|
-
|
|
11341
|
+
chalk122.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11257
11342
|
);
|
|
11258
11343
|
process.exit(1);
|
|
11259
11344
|
}
|
|
@@ -11263,7 +11348,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11263
11348
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
11264
11349
|
const sweaFlag = swea ? " --swea" : "";
|
|
11265
11350
|
try {
|
|
11266
|
-
|
|
11351
|
+
execSync28(
|
|
11267
11352
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
11268
11353
|
{ stdio: "pipe" }
|
|
11269
11354
|
);
|
|
@@ -11271,11 +11356,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11271
11356
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11272
11357
|
process.stderr.write(error.stderr);
|
|
11273
11358
|
}
|
|
11274
|
-
console.error(
|
|
11359
|
+
console.error(chalk122.red("jb inspectcode failed"));
|
|
11275
11360
|
process.exit(1);
|
|
11276
11361
|
}
|
|
11277
11362
|
if (!existsSync33(reportPath)) {
|
|
11278
|
-
console.error(
|
|
11363
|
+
console.error(chalk122.red("Report file not generated"));
|
|
11279
11364
|
process.exit(1);
|
|
11280
11365
|
}
|
|
11281
11366
|
const xml = readFileSync28(reportPath, "utf8");
|
|
@@ -11284,8 +11369,8 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11284
11369
|
}
|
|
11285
11370
|
|
|
11286
11371
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11287
|
-
import { execSync as
|
|
11288
|
-
import
|
|
11372
|
+
import { execSync as execSync29 } from "child_process";
|
|
11373
|
+
import chalk123 from "chalk";
|
|
11289
11374
|
function resolveMsbuildPath() {
|
|
11290
11375
|
const { run: run4 } = loadConfig();
|
|
11291
11376
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11295,11 +11380,11 @@ function resolveMsbuildPath() {
|
|
|
11295
11380
|
function assertMsbuildInstalled() {
|
|
11296
11381
|
const msbuild = resolveMsbuildPath();
|
|
11297
11382
|
try {
|
|
11298
|
-
|
|
11383
|
+
execSync29(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11299
11384
|
} catch {
|
|
11300
|
-
console.error(
|
|
11385
|
+
console.error(chalk123.red(`msbuild not found at: ${msbuild}`));
|
|
11301
11386
|
console.error(
|
|
11302
|
-
|
|
11387
|
+
chalk123.yellow(
|
|
11303
11388
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11304
11389
|
)
|
|
11305
11390
|
);
|
|
@@ -11321,7 +11406,7 @@ function runRoslynInspect(slnPath) {
|
|
|
11321
11406
|
const msbuild = resolveMsbuildPath();
|
|
11322
11407
|
let output;
|
|
11323
11408
|
try {
|
|
11324
|
-
output =
|
|
11409
|
+
output = execSync29(
|
|
11325
11410
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
11326
11411
|
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
11327
11412
|
);
|
|
@@ -11346,17 +11431,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11346
11431
|
// src/commands/dotnet/inspect.ts
|
|
11347
11432
|
function logScope(changedFiles) {
|
|
11348
11433
|
if (changedFiles === null) {
|
|
11349
|
-
console.log(
|
|
11434
|
+
console.log(chalk124.dim("Inspecting full solution..."));
|
|
11350
11435
|
} else {
|
|
11351
11436
|
console.log(
|
|
11352
|
-
|
|
11437
|
+
chalk124.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11353
11438
|
);
|
|
11354
11439
|
}
|
|
11355
11440
|
}
|
|
11356
11441
|
function reportResults(issues, elapsed) {
|
|
11357
11442
|
if (issues.length > 0) displayIssues(issues);
|
|
11358
|
-
else console.log(
|
|
11359
|
-
console.log(
|
|
11443
|
+
else console.log(chalk124.green("No issues found"));
|
|
11444
|
+
console.log(chalk124.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11360
11445
|
if (issues.length > 0) process.exit(1);
|
|
11361
11446
|
}
|
|
11362
11447
|
async function inspect(sln, options2) {
|
|
@@ -11367,7 +11452,7 @@ async function inspect(sln, options2) {
|
|
|
11367
11452
|
const scope = parseScope(options2.scope);
|
|
11368
11453
|
const changedFiles = getChangedCsFiles(scope);
|
|
11369
11454
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11370
|
-
console.log(
|
|
11455
|
+
console.log(chalk124.green("No changed .cs files found"));
|
|
11371
11456
|
return;
|
|
11372
11457
|
}
|
|
11373
11458
|
logScope(changedFiles);
|
|
@@ -11429,6 +11514,29 @@ function extractComments(text6) {
|
|
|
11429
11514
|
return comments3.map((comment3) => comment3.replace(/\s+/g, " ").trim()).filter((comment3) => comment3.length > 0).filter((comment3) => !isCommentExempt(comment3));
|
|
11430
11515
|
}
|
|
11431
11516
|
|
|
11517
|
+
// src/commands/editHook/introducedComments.ts
|
|
11518
|
+
function introducedComments(added, removed) {
|
|
11519
|
+
const counts = /* @__PURE__ */ new Map();
|
|
11520
|
+
for (const comment3 of removed) {
|
|
11521
|
+
counts.set(comment3, (counts.get(comment3) ?? 0) + 1);
|
|
11522
|
+
}
|
|
11523
|
+
const candidates = [];
|
|
11524
|
+
for (const comment3 of added) {
|
|
11525
|
+
const remaining = counts.get(comment3) ?? 0;
|
|
11526
|
+
if (remaining > 0) counts.set(comment3, remaining - 1);
|
|
11527
|
+
else candidates.push(comment3);
|
|
11528
|
+
}
|
|
11529
|
+
const removedWords = new Set(removed.flatMap(commentWords));
|
|
11530
|
+
return candidates.filter((comment3) => {
|
|
11531
|
+
const words = commentWords(comment3);
|
|
11532
|
+
if (words.length === 0) return true;
|
|
11533
|
+
return !words.every((word) => removedWords.has(word));
|
|
11534
|
+
});
|
|
11535
|
+
}
|
|
11536
|
+
function commentWords(comment3) {
|
|
11537
|
+
return comment3.toLowerCase().split(/[^a-z0-9]+/).filter((word) => word.length > 0);
|
|
11538
|
+
}
|
|
11539
|
+
|
|
11432
11540
|
// src/commands/editHook/decideCommentGuard.ts
|
|
11433
11541
|
var DENY_REASON = 'This edit introduces a code comment, which is blocked by the comment gate. Comments are a last resort \u2014 prefer a clearer name, a smaller function, or a test that makes the comment unnecessary. The comment must not appear in your edit itself. If this one line genuinely earns its keep, use the escape hatch: run `assist code-comment set <file> <line> "<text>"` (single line, max 50 chars, no block comments) to get a pin, then `assist code-comment confirm <pin>` to insert it.';
|
|
11434
11542
|
function defined(values) {
|
|
@@ -11458,19 +11566,6 @@ function partitionStrings(input, existingContent) {
|
|
|
11458
11566
|
return { added: [], removed: [] };
|
|
11459
11567
|
}
|
|
11460
11568
|
}
|
|
11461
|
-
function introducedComments(added, removed) {
|
|
11462
|
-
const counts = /* @__PURE__ */ new Map();
|
|
11463
|
-
for (const comment3 of removed) {
|
|
11464
|
-
counts.set(comment3, (counts.get(comment3) ?? 0) + 1);
|
|
11465
|
-
}
|
|
11466
|
-
const introduced = [];
|
|
11467
|
-
for (const comment3 of added) {
|
|
11468
|
-
const remaining = counts.get(comment3) ?? 0;
|
|
11469
|
-
if (remaining > 0) counts.set(comment3, remaining - 1);
|
|
11470
|
-
else introduced.push(comment3);
|
|
11471
|
-
}
|
|
11472
|
-
return introduced;
|
|
11473
|
-
}
|
|
11474
11569
|
function decideCommentGuard(input, existingContent) {
|
|
11475
11570
|
if (!isSourceFile(input.tool_input.file_path)) return void 0;
|
|
11476
11571
|
const { added, removed } = partitionStrings(input, existingContent);
|
|
@@ -11660,25 +11755,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11660
11755
|
}
|
|
11661
11756
|
|
|
11662
11757
|
// src/commands/github/printCountTable.ts
|
|
11663
|
-
import
|
|
11758
|
+
import chalk125 from "chalk";
|
|
11664
11759
|
function printCountTable(labelHeader, rows) {
|
|
11665
11760
|
const labelWidth = Math.max(
|
|
11666
11761
|
labelHeader.length,
|
|
11667
11762
|
...rows.map((row) => row.label.length)
|
|
11668
11763
|
);
|
|
11669
11764
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11670
|
-
console.log(
|
|
11671
|
-
console.log(
|
|
11765
|
+
console.log(chalk125.dim(header));
|
|
11766
|
+
console.log(chalk125.dim("-".repeat(header.length)));
|
|
11672
11767
|
for (const row of rows) {
|
|
11673
11768
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11674
11769
|
}
|
|
11675
11770
|
}
|
|
11676
11771
|
|
|
11677
11772
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11678
|
-
import
|
|
11773
|
+
import chalk126 from "chalk";
|
|
11679
11774
|
function printRepoAuthorBreakdown(repos2) {
|
|
11680
11775
|
for (const repo of repos2) {
|
|
11681
|
-
console.log(
|
|
11776
|
+
console.log(chalk126.bold(repo.name));
|
|
11682
11777
|
const authorWidth = Math.max(
|
|
11683
11778
|
0,
|
|
11684
11779
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -11775,9 +11870,9 @@ function registerGithub(program2) {
|
|
|
11775
11870
|
}
|
|
11776
11871
|
|
|
11777
11872
|
// src/commands/handover/countPendingHandovers.ts
|
|
11778
|
-
import { and as and12, eq as
|
|
11873
|
+
import { and as and12, eq as eq31, isNull, sql as sql4 } from "drizzle-orm";
|
|
11779
11874
|
async function countPendingHandovers(orm, origin) {
|
|
11780
|
-
const [row] = await orm.select({ count: sql4`count(*)::int` }).from(handovers).where(and12(
|
|
11875
|
+
const [row] = await orm.select({ count: sql4`count(*)::int` }).from(handovers).where(and12(eq31(handovers.origin, origin), isNull(handovers.recalledAt)));
|
|
11781
11876
|
return row?.count ?? 0;
|
|
11782
11877
|
}
|
|
11783
11878
|
|
|
@@ -11917,13 +12012,13 @@ async function load2(options2 = {}) {
|
|
|
11917
12012
|
}
|
|
11918
12013
|
|
|
11919
12014
|
// src/commands/handover/listPendingHandovers.ts
|
|
11920
|
-
import { and as and13, desc as desc4, eq as
|
|
12015
|
+
import { and as and13, desc as desc4, eq as eq32, isNull as isNull2 } from "drizzle-orm";
|
|
11921
12016
|
async function listPendingHandovers(orm, origin) {
|
|
11922
12017
|
return orm.select({
|
|
11923
12018
|
id: handovers.id,
|
|
11924
12019
|
summary: handovers.summary,
|
|
11925
12020
|
createdAt: handovers.createdAt
|
|
11926
|
-
}).from(handovers).where(and13(
|
|
12021
|
+
}).from(handovers).where(and13(eq32(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc4(handovers.createdAt), desc4(handovers.id));
|
|
11927
12022
|
}
|
|
11928
12023
|
|
|
11929
12024
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -11936,17 +12031,17 @@ async function printPendingHandovers() {
|
|
|
11936
12031
|
}
|
|
11937
12032
|
|
|
11938
12033
|
// src/commands/handover/recallHandover.ts
|
|
11939
|
-
import { and as and14, desc as desc5, eq as
|
|
12034
|
+
import { and as and14, desc as desc5, eq as eq33, isNull as isNull3 } from "drizzle-orm";
|
|
11940
12035
|
async function recallHandover(orm, origin, id2) {
|
|
11941
12036
|
const [row] = await orm.select().from(handovers).where(
|
|
11942
12037
|
and14(
|
|
11943
|
-
|
|
12038
|
+
eq33(handovers.origin, origin),
|
|
11944
12039
|
isNull3(handovers.recalledAt),
|
|
11945
|
-
...id2 === void 0 ? [] : [
|
|
12040
|
+
...id2 === void 0 ? [] : [eq33(handovers.id, id2)]
|
|
11946
12041
|
)
|
|
11947
12042
|
).orderBy(desc5(handovers.createdAt), desc5(handovers.id)).limit(1);
|
|
11948
12043
|
if (!row) return void 0;
|
|
11949
|
-
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(
|
|
12044
|
+
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq33(handovers.id, row.id));
|
|
11950
12045
|
return row.content;
|
|
11951
12046
|
}
|
|
11952
12047
|
|
|
@@ -11996,7 +12091,7 @@ function registerHandover(program2) {
|
|
|
11996
12091
|
}
|
|
11997
12092
|
|
|
11998
12093
|
// src/commands/jira/acceptanceCriteria.ts
|
|
11999
|
-
import
|
|
12094
|
+
import chalk127 from "chalk";
|
|
12000
12095
|
|
|
12001
12096
|
// src/commands/jira/adfToText.ts
|
|
12002
12097
|
function renderInline(node) {
|
|
@@ -12055,35 +12150,6 @@ function adfToText(doc) {
|
|
|
12055
12150
|
return renderNodes([doc], 0);
|
|
12056
12151
|
}
|
|
12057
12152
|
|
|
12058
|
-
// src/commands/jira/fetchIssue.ts
|
|
12059
|
-
import { execSync as execSync29 } from "child_process";
|
|
12060
|
-
import chalk125 from "chalk";
|
|
12061
|
-
function fetchIssue(issueKey, fields) {
|
|
12062
|
-
let result;
|
|
12063
|
-
try {
|
|
12064
|
-
result = execSync29(
|
|
12065
|
-
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
12066
|
-
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
12067
|
-
);
|
|
12068
|
-
} catch (error) {
|
|
12069
|
-
if (error instanceof Error && "stderr" in error) {
|
|
12070
|
-
const stderr = error.stderr;
|
|
12071
|
-
if (stderr.includes("unauthorized")) {
|
|
12072
|
-
console.error(
|
|
12073
|
-
chalk125.red("Jira authentication expired."),
|
|
12074
|
-
"Run",
|
|
12075
|
-
chalk125.cyan("assist jira auth"),
|
|
12076
|
-
"to re-authenticate."
|
|
12077
|
-
);
|
|
12078
|
-
process.exit(1);
|
|
12079
|
-
}
|
|
12080
|
-
}
|
|
12081
|
-
console.error(chalk125.red(`Failed to fetch ${issueKey}.`));
|
|
12082
|
-
process.exit(1);
|
|
12083
|
-
}
|
|
12084
|
-
return JSON.parse(result);
|
|
12085
|
-
}
|
|
12086
|
-
|
|
12087
12153
|
// src/commands/jira/acceptanceCriteria.ts
|
|
12088
12154
|
var DEFAULT_AC_FIELD = "customfield_11937";
|
|
12089
12155
|
function acceptanceCriteria(issueKey) {
|
|
@@ -12092,7 +12158,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
12092
12158
|
const parsed = fetchIssue(issueKey, field);
|
|
12093
12159
|
const acValue = parsed?.fields?.[field];
|
|
12094
12160
|
if (!acValue) {
|
|
12095
|
-
console.log(
|
|
12161
|
+
console.log(chalk127.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
12096
12162
|
return;
|
|
12097
12163
|
}
|
|
12098
12164
|
if (typeof acValue === "string") {
|
|
@@ -12187,14 +12253,14 @@ async function jiraAuth() {
|
|
|
12187
12253
|
}
|
|
12188
12254
|
|
|
12189
12255
|
// src/commands/jira/viewIssue.ts
|
|
12190
|
-
import
|
|
12256
|
+
import chalk128 from "chalk";
|
|
12191
12257
|
function viewIssue(issueKey) {
|
|
12192
12258
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
12193
12259
|
const fields = parsed?.fields;
|
|
12194
12260
|
const summary = fields?.summary;
|
|
12195
12261
|
const description = fields?.description;
|
|
12196
12262
|
if (summary) {
|
|
12197
|
-
console.log(
|
|
12263
|
+
console.log(chalk128.bold(summary));
|
|
12198
12264
|
}
|
|
12199
12265
|
if (description) {
|
|
12200
12266
|
if (summary) console.log();
|
|
@@ -12208,7 +12274,7 @@ function viewIssue(issueKey) {
|
|
|
12208
12274
|
}
|
|
12209
12275
|
if (!summary && !description) {
|
|
12210
12276
|
console.log(
|
|
12211
|
-
|
|
12277
|
+
chalk128.yellow(`No summary or description found on ${issueKey}.`)
|
|
12212
12278
|
);
|
|
12213
12279
|
}
|
|
12214
12280
|
}
|
|
@@ -12224,13 +12290,13 @@ function registerJira(program2) {
|
|
|
12224
12290
|
// src/commands/reviewComments.ts
|
|
12225
12291
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
12226
12292
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
12227
|
-
import
|
|
12293
|
+
import chalk129 from "chalk";
|
|
12228
12294
|
async function reviewComments(number) {
|
|
12229
12295
|
if (number) {
|
|
12230
12296
|
try {
|
|
12231
12297
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
12232
12298
|
} catch {
|
|
12233
|
-
console.error(
|
|
12299
|
+
console.error(chalk129.red(`gh pr checkout ${number} failed; aborting.`));
|
|
12234
12300
|
process.exit(1);
|
|
12235
12301
|
}
|
|
12236
12302
|
}
|
|
@@ -12304,15 +12370,15 @@ function registerList(program2) {
|
|
|
12304
12370
|
// src/commands/mermaid/index.ts
|
|
12305
12371
|
import { mkdirSync as mkdirSync13, readdirSync as readdirSync7 } from "fs";
|
|
12306
12372
|
import { resolve as resolve11 } from "path";
|
|
12307
|
-
import
|
|
12373
|
+
import chalk132 from "chalk";
|
|
12308
12374
|
|
|
12309
12375
|
// src/commands/mermaid/exportFile.ts
|
|
12310
12376
|
import { readFileSync as readFileSync31, writeFileSync as writeFileSync28 } from "fs";
|
|
12311
12377
|
import { basename as basename6, extname, resolve as resolve10 } from "path";
|
|
12312
|
-
import
|
|
12378
|
+
import chalk131 from "chalk";
|
|
12313
12379
|
|
|
12314
12380
|
// src/commands/mermaid/renderBlock.ts
|
|
12315
|
-
import
|
|
12381
|
+
import chalk130 from "chalk";
|
|
12316
12382
|
async function renderBlock(krokiUrl, source) {
|
|
12317
12383
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
12318
12384
|
method: "POST",
|
|
@@ -12321,7 +12387,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12321
12387
|
});
|
|
12322
12388
|
if (!response.ok) {
|
|
12323
12389
|
console.error(
|
|
12324
|
-
|
|
12390
|
+
chalk130.red(
|
|
12325
12391
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
12326
12392
|
)
|
|
12327
12393
|
);
|
|
@@ -12339,19 +12405,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12339
12405
|
if (onlyIndex !== void 0) {
|
|
12340
12406
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
12341
12407
|
console.error(
|
|
12342
|
-
|
|
12408
|
+
chalk131.red(
|
|
12343
12409
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
12344
12410
|
)
|
|
12345
12411
|
);
|
|
12346
12412
|
process.exit(1);
|
|
12347
12413
|
}
|
|
12348
12414
|
console.log(
|
|
12349
|
-
|
|
12415
|
+
chalk131.gray(
|
|
12350
12416
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
12351
12417
|
)
|
|
12352
12418
|
);
|
|
12353
12419
|
} else {
|
|
12354
|
-
console.log(
|
|
12420
|
+
console.log(chalk131.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
12355
12421
|
}
|
|
12356
12422
|
for (const [i, source] of blocks.entries()) {
|
|
12357
12423
|
const idx = i + 1;
|
|
@@ -12359,7 +12425,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12359
12425
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
12360
12426
|
const svg = await renderBlock(krokiUrl, source);
|
|
12361
12427
|
writeFileSync28(outPath, svg, "utf8");
|
|
12362
|
-
console.log(
|
|
12428
|
+
console.log(chalk131.green(` \u2192 ${outPath}`));
|
|
12363
12429
|
}
|
|
12364
12430
|
}
|
|
12365
12431
|
function extractMermaidBlocks(markdown) {
|
|
@@ -12375,18 +12441,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
12375
12441
|
if (options2.index !== void 0) {
|
|
12376
12442
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
12377
12443
|
console.error(
|
|
12378
|
-
|
|
12444
|
+
chalk132.red(`--index must be a positive integer (got ${options2.index})`)
|
|
12379
12445
|
);
|
|
12380
12446
|
process.exit(1);
|
|
12381
12447
|
}
|
|
12382
12448
|
if (!file) {
|
|
12383
|
-
console.error(
|
|
12449
|
+
console.error(chalk132.red("--index requires a file argument"));
|
|
12384
12450
|
process.exit(1);
|
|
12385
12451
|
}
|
|
12386
12452
|
}
|
|
12387
12453
|
const files = file ? [file] : readdirSync7(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
12388
12454
|
if (files.length === 0) {
|
|
12389
|
-
console.log(
|
|
12455
|
+
console.log(chalk132.gray("No markdown files found in current directory."));
|
|
12390
12456
|
return;
|
|
12391
12457
|
}
|
|
12392
12458
|
for (const f of files) {
|
|
@@ -12412,7 +12478,7 @@ function registerMermaid(program2) {
|
|
|
12412
12478
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12413
12479
|
import { createServer as createServer2 } from "http";
|
|
12414
12480
|
import { dirname as dirname20 } from "path";
|
|
12415
|
-
import
|
|
12481
|
+
import chalk134 from "chalk";
|
|
12416
12482
|
|
|
12417
12483
|
// src/commands/netcap/corsHeaders.ts
|
|
12418
12484
|
var corsHeaders = {
|
|
@@ -12491,7 +12557,7 @@ function createNetcapHandler(options2) {
|
|
|
12491
12557
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12492
12558
|
import { networkInterfaces } from "os";
|
|
12493
12559
|
import { join as join39 } from "path";
|
|
12494
|
-
import
|
|
12560
|
+
import chalk133 from "chalk";
|
|
12495
12561
|
|
|
12496
12562
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12497
12563
|
import { dirname as dirname19, join as join38 } from "path";
|
|
@@ -12535,7 +12601,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12535
12601
|
const host = lanIPv4();
|
|
12536
12602
|
if (!host) {
|
|
12537
12603
|
console.log(
|
|
12538
|
-
|
|
12604
|
+
chalk133.yellow("could not determine the WSL IP for the extension")
|
|
12539
12605
|
);
|
|
12540
12606
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12541
12607
|
return source;
|
|
@@ -12546,7 +12612,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12546
12612
|
return WSL_WINDOWS_PATH;
|
|
12547
12613
|
} catch {
|
|
12548
12614
|
console.log(
|
|
12549
|
-
|
|
12615
|
+
chalk133.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12550
12616
|
);
|
|
12551
12617
|
return source;
|
|
12552
12618
|
}
|
|
@@ -12579,30 +12645,30 @@ async function netcap(options2) {
|
|
|
12579
12645
|
let count6 = 0;
|
|
12580
12646
|
const handler = createNetcapHandler({
|
|
12581
12647
|
outPath,
|
|
12582
|
-
onPing: () => console.log(
|
|
12648
|
+
onPing: () => console.log(chalk134.dim("ping from extension")),
|
|
12583
12649
|
onCapture: (entry) => {
|
|
12584
12650
|
count6 += 1;
|
|
12585
12651
|
console.log(
|
|
12586
|
-
|
|
12587
|
-
|
|
12652
|
+
chalk134.green(`captured #${count6}`),
|
|
12653
|
+
chalk134.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12588
12654
|
);
|
|
12589
12655
|
}
|
|
12590
12656
|
});
|
|
12591
12657
|
const server = createServer2(handler);
|
|
12592
12658
|
server.listen(port, () => {
|
|
12593
12659
|
console.log(
|
|
12594
|
-
|
|
12660
|
+
chalk134.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12595
12661
|
);
|
|
12596
|
-
console.log(
|
|
12662
|
+
console.log(chalk134.dim(`appending captures to ${outPath}`));
|
|
12597
12663
|
if (filter)
|
|
12598
|
-
console.log(
|
|
12599
|
-
console.log(
|
|
12600
|
-
console.log(
|
|
12664
|
+
console.log(chalk134.dim(`forwarding only URLs matching "${filter}"`));
|
|
12665
|
+
console.log(chalk134.dim(`load the unpacked extension from ${extensionPath}`));
|
|
12666
|
+
console.log(chalk134.dim("press Ctrl-C to stop"));
|
|
12601
12667
|
});
|
|
12602
12668
|
process.on("SIGINT", () => {
|
|
12603
12669
|
server.close();
|
|
12604
12670
|
console.log(
|
|
12605
|
-
|
|
12671
|
+
chalk134.bold(
|
|
12606
12672
|
`
|
|
12607
12673
|
netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12608
12674
|
)
|
|
@@ -12614,7 +12680,7 @@ netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} t
|
|
|
12614
12680
|
// src/commands/netcap/netcapExtract.ts
|
|
12615
12681
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
12616
12682
|
import { join as join42 } from "path";
|
|
12617
|
-
import
|
|
12683
|
+
import chalk135 from "chalk";
|
|
12618
12684
|
|
|
12619
12685
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12620
12686
|
import { readFileSync as readFileSync32 } from "fs";
|
|
@@ -13062,8 +13128,8 @@ function netcapExtract(file) {
|
|
|
13062
13128
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13063
13129
|
`);
|
|
13064
13130
|
console.log(
|
|
13065
|
-
|
|
13066
|
-
|
|
13131
|
+
chalk135.green(`extracted ${posts.length} posts`),
|
|
13132
|
+
chalk135.dim(`-> ${outFile}`)
|
|
13067
13133
|
);
|
|
13068
13134
|
}
|
|
13069
13135
|
|
|
@@ -13084,7 +13150,7 @@ function registerNetcap(program2) {
|
|
|
13084
13150
|
}
|
|
13085
13151
|
|
|
13086
13152
|
// src/commands/news/add/index.ts
|
|
13087
|
-
import
|
|
13153
|
+
import chalk136 from "chalk";
|
|
13088
13154
|
import enquirer8 from "enquirer";
|
|
13089
13155
|
async function add2(url) {
|
|
13090
13156
|
if (!url) {
|
|
@@ -13106,10 +13172,10 @@ async function add2(url) {
|
|
|
13106
13172
|
const { orm } = await getReady();
|
|
13107
13173
|
const added = await addFeed(orm, url);
|
|
13108
13174
|
if (!added) {
|
|
13109
|
-
console.log(
|
|
13175
|
+
console.log(chalk136.yellow("Feed already exists"));
|
|
13110
13176
|
return;
|
|
13111
13177
|
}
|
|
13112
|
-
console.log(
|
|
13178
|
+
console.log(chalk136.green(`Added feed: ${url}`));
|
|
13113
13179
|
}
|
|
13114
13180
|
|
|
13115
13181
|
// src/commands/registerNews.ts
|
|
@@ -13119,7 +13185,7 @@ function registerNews(program2) {
|
|
|
13119
13185
|
}
|
|
13120
13186
|
|
|
13121
13187
|
// src/commands/prompts/printPromptsTable.ts
|
|
13122
|
-
import
|
|
13188
|
+
import chalk137 from "chalk";
|
|
13123
13189
|
function truncate(str, max) {
|
|
13124
13190
|
if (str.length <= max) return str;
|
|
13125
13191
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -13137,14 +13203,14 @@ function printPromptsTable(rows) {
|
|
|
13137
13203
|
"Command".padEnd(commandWidth),
|
|
13138
13204
|
"Repos"
|
|
13139
13205
|
].join(" ");
|
|
13140
|
-
console.log(
|
|
13141
|
-
console.log(
|
|
13206
|
+
console.log(chalk137.dim(header));
|
|
13207
|
+
console.log(chalk137.dim("-".repeat(header.length)));
|
|
13142
13208
|
for (const row of rows) {
|
|
13143
13209
|
const count6 = String(row.count).padStart(countWidth);
|
|
13144
13210
|
const tool = row.tool.padEnd(toolWidth);
|
|
13145
13211
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
13146
13212
|
console.log(
|
|
13147
|
-
`${
|
|
13213
|
+
`${chalk137.yellow(count6)} ${tool} ${command} ${chalk137.dim(row.repos)}`
|
|
13148
13214
|
);
|
|
13149
13215
|
}
|
|
13150
13216
|
}
|
|
@@ -13693,20 +13759,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13693
13759
|
}
|
|
13694
13760
|
|
|
13695
13761
|
// src/commands/prs/listComments/printComments.ts
|
|
13696
|
-
import
|
|
13762
|
+
import chalk138 from "chalk";
|
|
13697
13763
|
function formatForHuman(comment3) {
|
|
13698
13764
|
if (comment3.type === "review") {
|
|
13699
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
13765
|
+
const stateColor = comment3.state === "APPROVED" ? chalk138.green : comment3.state === "CHANGES_REQUESTED" ? chalk138.red : chalk138.yellow;
|
|
13700
13766
|
return [
|
|
13701
|
-
`${
|
|
13767
|
+
`${chalk138.cyan("Review")} by ${chalk138.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13702
13768
|
comment3.body,
|
|
13703
13769
|
""
|
|
13704
13770
|
].join("\n");
|
|
13705
13771
|
}
|
|
13706
13772
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13707
13773
|
return [
|
|
13708
|
-
`${
|
|
13709
|
-
|
|
13774
|
+
`${chalk138.cyan("Line comment")} by ${chalk138.bold(comment3.user)} on ${chalk138.dim(`${comment3.path}${location}`)}`,
|
|
13775
|
+
chalk138.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
13710
13776
|
comment3.body,
|
|
13711
13777
|
""
|
|
13712
13778
|
].join("\n");
|
|
@@ -13796,13 +13862,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
13796
13862
|
import enquirer9 from "enquirer";
|
|
13797
13863
|
|
|
13798
13864
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
13799
|
-
import
|
|
13865
|
+
import chalk139 from "chalk";
|
|
13800
13866
|
var STATUS_MAP = {
|
|
13801
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
13802
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
13867
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk139.magenta("merged"), date: pr.mergedAt } : null,
|
|
13868
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk139.red("closed"), date: pr.closedAt } : null
|
|
13803
13869
|
};
|
|
13804
13870
|
function defaultStatus(pr) {
|
|
13805
|
-
return { label:
|
|
13871
|
+
return { label: chalk139.green("opened"), date: pr.createdAt };
|
|
13806
13872
|
}
|
|
13807
13873
|
function getStatus2(pr) {
|
|
13808
13874
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -13811,11 +13877,11 @@ function formatDate(dateStr) {
|
|
|
13811
13877
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
13812
13878
|
}
|
|
13813
13879
|
function formatPrHeader(pr, status2) {
|
|
13814
|
-
return `${
|
|
13880
|
+
return `${chalk139.cyan(`#${pr.number}`)} ${pr.title} ${chalk139.dim(`(${pr.author.login},`)} ${status2.label} ${chalk139.dim(`${formatDate(status2.date)})`)}`;
|
|
13815
13881
|
}
|
|
13816
13882
|
function logPrDetails(pr) {
|
|
13817
13883
|
console.log(
|
|
13818
|
-
|
|
13884
|
+
chalk139.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
13819
13885
|
);
|
|
13820
13886
|
console.log();
|
|
13821
13887
|
}
|
|
@@ -14122,10 +14188,10 @@ function registerPrs(program2) {
|
|
|
14122
14188
|
}
|
|
14123
14189
|
|
|
14124
14190
|
// src/commands/ravendb/ravendbAuth.ts
|
|
14125
|
-
import
|
|
14191
|
+
import chalk145 from "chalk";
|
|
14126
14192
|
|
|
14127
14193
|
// src/shared/createConnectionAuth.ts
|
|
14128
|
-
import
|
|
14194
|
+
import chalk140 from "chalk";
|
|
14129
14195
|
function listConnections(connections, format2) {
|
|
14130
14196
|
if (connections.length === 0) {
|
|
14131
14197
|
console.log("No connections configured.");
|
|
@@ -14138,7 +14204,7 @@ function listConnections(connections, format2) {
|
|
|
14138
14204
|
function removeConnection(connections, name, save) {
|
|
14139
14205
|
const filtered = connections.filter((c) => c.name !== name);
|
|
14140
14206
|
if (filtered.length === connections.length) {
|
|
14141
|
-
console.error(
|
|
14207
|
+
console.error(chalk140.red(`Connection "${name}" not found.`));
|
|
14142
14208
|
process.exit(1);
|
|
14143
14209
|
}
|
|
14144
14210
|
save(filtered);
|
|
@@ -14184,15 +14250,15 @@ function saveConnections(connections) {
|
|
|
14184
14250
|
}
|
|
14185
14251
|
|
|
14186
14252
|
// src/commands/ravendb/promptConnection.ts
|
|
14187
|
-
import
|
|
14253
|
+
import chalk143 from "chalk";
|
|
14188
14254
|
|
|
14189
14255
|
// src/commands/ravendb/selectOpSecret.ts
|
|
14190
|
-
import
|
|
14256
|
+
import chalk142 from "chalk";
|
|
14191
14257
|
import Enquirer2 from "enquirer";
|
|
14192
14258
|
|
|
14193
14259
|
// src/commands/ravendb/searchItems.ts
|
|
14194
14260
|
import { execSync as execSync41 } from "child_process";
|
|
14195
|
-
import
|
|
14261
|
+
import chalk141 from "chalk";
|
|
14196
14262
|
function opExec(args) {
|
|
14197
14263
|
return execSync41(`op ${args}`, {
|
|
14198
14264
|
encoding: "utf8",
|
|
@@ -14205,7 +14271,7 @@ function searchItems(search2) {
|
|
|
14205
14271
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
14206
14272
|
} catch {
|
|
14207
14273
|
console.error(
|
|
14208
|
-
|
|
14274
|
+
chalk141.red(
|
|
14209
14275
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
14210
14276
|
)
|
|
14211
14277
|
);
|
|
@@ -14219,7 +14285,7 @@ function getItemFields(itemId) {
|
|
|
14219
14285
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
14220
14286
|
return item.fields.filter((f) => f.reference && f.label);
|
|
14221
14287
|
} catch {
|
|
14222
|
-
console.error(
|
|
14288
|
+
console.error(chalk141.red("Failed to get item details from 1Password."));
|
|
14223
14289
|
process.exit(1);
|
|
14224
14290
|
}
|
|
14225
14291
|
}
|
|
@@ -14238,7 +14304,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14238
14304
|
}).run();
|
|
14239
14305
|
const items2 = searchItems(search2);
|
|
14240
14306
|
if (items2.length === 0) {
|
|
14241
|
-
console.error(
|
|
14307
|
+
console.error(chalk142.red(`No items found matching "${search2}".`));
|
|
14242
14308
|
process.exit(1);
|
|
14243
14309
|
}
|
|
14244
14310
|
const itemId = await selectOne(
|
|
@@ -14247,7 +14313,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14247
14313
|
);
|
|
14248
14314
|
const fields = getItemFields(itemId);
|
|
14249
14315
|
if (fields.length === 0) {
|
|
14250
|
-
console.error(
|
|
14316
|
+
console.error(chalk142.red("No fields with references found on this item."));
|
|
14251
14317
|
process.exit(1);
|
|
14252
14318
|
}
|
|
14253
14319
|
const ref = await selectOne(
|
|
@@ -14261,7 +14327,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14261
14327
|
async function promptConnection(existingNames) {
|
|
14262
14328
|
const name = await promptInput("name", "Connection name:");
|
|
14263
14329
|
if (existingNames.includes(name)) {
|
|
14264
|
-
console.error(
|
|
14330
|
+
console.error(chalk143.red(`Connection "${name}" already exists.`));
|
|
14265
14331
|
process.exit(1);
|
|
14266
14332
|
}
|
|
14267
14333
|
const url = await promptInput(
|
|
@@ -14270,22 +14336,22 @@ async function promptConnection(existingNames) {
|
|
|
14270
14336
|
);
|
|
14271
14337
|
const database = await promptInput("database", "Database name:");
|
|
14272
14338
|
if (!name || !url || !database) {
|
|
14273
|
-
console.error(
|
|
14339
|
+
console.error(chalk143.red("All fields are required."));
|
|
14274
14340
|
process.exit(1);
|
|
14275
14341
|
}
|
|
14276
14342
|
const apiKeyRef = await selectOpSecret();
|
|
14277
|
-
console.log(
|
|
14343
|
+
console.log(chalk143.dim(`Using: ${apiKeyRef}`));
|
|
14278
14344
|
return { name, url, database, apiKeyRef };
|
|
14279
14345
|
}
|
|
14280
14346
|
|
|
14281
14347
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
14282
|
-
import
|
|
14348
|
+
import chalk144 from "chalk";
|
|
14283
14349
|
function ravendbSetConnection(name) {
|
|
14284
14350
|
const raw = loadGlobalConfigRaw();
|
|
14285
14351
|
const ravendb = raw.ravendb ?? {};
|
|
14286
14352
|
const connections = ravendb.connections ?? [];
|
|
14287
14353
|
if (!connections.some((c) => c.name === name)) {
|
|
14288
|
-
console.error(
|
|
14354
|
+
console.error(chalk144.red(`Connection "${name}" not found.`));
|
|
14289
14355
|
console.error(
|
|
14290
14356
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14291
14357
|
);
|
|
@@ -14301,16 +14367,16 @@ function ravendbSetConnection(name) {
|
|
|
14301
14367
|
var ravendbAuth = createConnectionAuth({
|
|
14302
14368
|
load: loadConnections,
|
|
14303
14369
|
save: saveConnections,
|
|
14304
|
-
format: (c) => `${
|
|
14370
|
+
format: (c) => `${chalk145.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
14305
14371
|
promptNew: promptConnection,
|
|
14306
14372
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
14307
14373
|
});
|
|
14308
14374
|
|
|
14309
14375
|
// src/commands/ravendb/ravendbCollections.ts
|
|
14310
|
-
import
|
|
14376
|
+
import chalk149 from "chalk";
|
|
14311
14377
|
|
|
14312
14378
|
// src/commands/ravendb/ravenFetch.ts
|
|
14313
|
-
import
|
|
14379
|
+
import chalk147 from "chalk";
|
|
14314
14380
|
|
|
14315
14381
|
// src/commands/ravendb/getAccessToken.ts
|
|
14316
14382
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -14347,10 +14413,10 @@ ${errorText}`
|
|
|
14347
14413
|
|
|
14348
14414
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
14349
14415
|
import { execSync as execSync42 } from "child_process";
|
|
14350
|
-
import
|
|
14416
|
+
import chalk146 from "chalk";
|
|
14351
14417
|
function resolveOpSecret(reference) {
|
|
14352
14418
|
if (!reference.startsWith("op://")) {
|
|
14353
|
-
console.error(
|
|
14419
|
+
console.error(chalk146.red(`Invalid secret reference: must start with op://`));
|
|
14354
14420
|
process.exit(1);
|
|
14355
14421
|
}
|
|
14356
14422
|
try {
|
|
@@ -14360,7 +14426,7 @@ function resolveOpSecret(reference) {
|
|
|
14360
14426
|
}).trim();
|
|
14361
14427
|
} catch {
|
|
14362
14428
|
console.error(
|
|
14363
|
-
|
|
14429
|
+
chalk146.red(
|
|
14364
14430
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
14365
14431
|
)
|
|
14366
14432
|
);
|
|
@@ -14387,7 +14453,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14387
14453
|
if (!response.ok) {
|
|
14388
14454
|
const body = await response.text();
|
|
14389
14455
|
console.error(
|
|
14390
|
-
|
|
14456
|
+
chalk147.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
14391
14457
|
);
|
|
14392
14458
|
console.error(body.substring(0, 500));
|
|
14393
14459
|
process.exit(1);
|
|
@@ -14396,7 +14462,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14396
14462
|
}
|
|
14397
14463
|
|
|
14398
14464
|
// src/commands/ravendb/resolveConnection.ts
|
|
14399
|
-
import
|
|
14465
|
+
import chalk148 from "chalk";
|
|
14400
14466
|
function loadRavendb() {
|
|
14401
14467
|
const raw = loadGlobalConfigRaw();
|
|
14402
14468
|
const ravendb = raw.ravendb;
|
|
@@ -14410,7 +14476,7 @@ function resolveConnection(name) {
|
|
|
14410
14476
|
const connectionName = name ?? defaultConnection;
|
|
14411
14477
|
if (!connectionName) {
|
|
14412
14478
|
console.error(
|
|
14413
|
-
|
|
14479
|
+
chalk148.red(
|
|
14414
14480
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14415
14481
|
)
|
|
14416
14482
|
);
|
|
@@ -14418,7 +14484,7 @@ function resolveConnection(name) {
|
|
|
14418
14484
|
}
|
|
14419
14485
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14420
14486
|
if (!connection) {
|
|
14421
|
-
console.error(
|
|
14487
|
+
console.error(chalk148.red(`Connection "${connectionName}" not found.`));
|
|
14422
14488
|
console.error(
|
|
14423
14489
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14424
14490
|
);
|
|
@@ -14449,15 +14515,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14449
14515
|
return;
|
|
14450
14516
|
}
|
|
14451
14517
|
for (const c of collections) {
|
|
14452
|
-
console.log(`${
|
|
14518
|
+
console.log(`${chalk149.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14453
14519
|
}
|
|
14454
14520
|
}
|
|
14455
14521
|
|
|
14456
14522
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14457
|
-
import
|
|
14523
|
+
import chalk151 from "chalk";
|
|
14458
14524
|
|
|
14459
14525
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14460
|
-
import
|
|
14526
|
+
import chalk150 from "chalk";
|
|
14461
14527
|
|
|
14462
14528
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14463
14529
|
function buildQueryPath(opts) {
|
|
@@ -14495,7 +14561,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14495
14561
|
allResults.push(...results);
|
|
14496
14562
|
start3 += results.length;
|
|
14497
14563
|
process.stderr.write(
|
|
14498
|
-
`\r${
|
|
14564
|
+
`\r${chalk150.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14499
14565
|
);
|
|
14500
14566
|
if (start3 >= totalResults) break;
|
|
14501
14567
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14510,7 +14576,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14510
14576
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14511
14577
|
const resolved = resolveArgs(connectionName, collection);
|
|
14512
14578
|
if (!resolved.collection && !options2.query) {
|
|
14513
|
-
console.error(
|
|
14579
|
+
console.error(chalk151.red("Provide a collection name or --query filter."));
|
|
14514
14580
|
process.exit(1);
|
|
14515
14581
|
}
|
|
14516
14582
|
const { collection: col } = resolved;
|
|
@@ -14548,7 +14614,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14548
14614
|
import * as path28 from "path";
|
|
14549
14615
|
|
|
14550
14616
|
// src/commands/refactor/logViolations.ts
|
|
14551
|
-
import
|
|
14617
|
+
import chalk152 from "chalk";
|
|
14552
14618
|
var DEFAULT_MAX_LINES = 100;
|
|
14553
14619
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14554
14620
|
if (violations.length === 0) {
|
|
@@ -14557,43 +14623,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14557
14623
|
}
|
|
14558
14624
|
return;
|
|
14559
14625
|
}
|
|
14560
|
-
console.error(
|
|
14626
|
+
console.error(chalk152.red(`
|
|
14561
14627
|
Refactor check failed:
|
|
14562
14628
|
`));
|
|
14563
|
-
console.error(
|
|
14629
|
+
console.error(chalk152.red(` The following files exceed ${maxLines} lines:
|
|
14564
14630
|
`));
|
|
14565
14631
|
for (const violation of violations) {
|
|
14566
|
-
console.error(
|
|
14632
|
+
console.error(chalk152.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14567
14633
|
}
|
|
14568
14634
|
console.error(
|
|
14569
|
-
|
|
14635
|
+
chalk152.yellow(
|
|
14570
14636
|
`
|
|
14571
14637
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14572
14638
|
way to refactor it, ignore it with:
|
|
14573
14639
|
`
|
|
14574
14640
|
)
|
|
14575
14641
|
);
|
|
14576
|
-
console.error(
|
|
14642
|
+
console.error(chalk152.gray(` assist refactor ignore <file>
|
|
14577
14643
|
`));
|
|
14578
14644
|
if (process.env.CLAUDECODE) {
|
|
14579
|
-
console.error(
|
|
14645
|
+
console.error(chalk152.cyan(`
|
|
14580
14646
|
## Extracting Code to New Files
|
|
14581
14647
|
`));
|
|
14582
14648
|
console.error(
|
|
14583
|
-
|
|
14649
|
+
chalk152.cyan(
|
|
14584
14650
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14585
14651
|
`
|
|
14586
14652
|
)
|
|
14587
14653
|
);
|
|
14588
14654
|
console.error(
|
|
14589
|
-
|
|
14655
|
+
chalk152.cyan(
|
|
14590
14656
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14591
14657
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14592
14658
|
`
|
|
14593
14659
|
)
|
|
14594
14660
|
);
|
|
14595
14661
|
console.error(
|
|
14596
|
-
|
|
14662
|
+
chalk152.cyan(
|
|
14597
14663
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14598
14664
|
domains, move it to a common/shared folder.
|
|
14599
14665
|
`
|
|
@@ -14749,7 +14815,7 @@ async function check(pattern2, options2) {
|
|
|
14749
14815
|
|
|
14750
14816
|
// src/commands/refactor/extract/index.ts
|
|
14751
14817
|
import path35 from "path";
|
|
14752
|
-
import
|
|
14818
|
+
import chalk155 from "chalk";
|
|
14753
14819
|
|
|
14754
14820
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
14755
14821
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -15324,23 +15390,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
15324
15390
|
|
|
15325
15391
|
// src/commands/refactor/extract/displayPlan.ts
|
|
15326
15392
|
import path32 from "path";
|
|
15327
|
-
import
|
|
15393
|
+
import chalk153 from "chalk";
|
|
15328
15394
|
function section(title) {
|
|
15329
15395
|
return `
|
|
15330
|
-
${
|
|
15396
|
+
${chalk153.cyan(title)}`;
|
|
15331
15397
|
}
|
|
15332
15398
|
function displayImporters(plan2, cwd) {
|
|
15333
15399
|
if (plan2.importersToUpdate.length === 0) return;
|
|
15334
15400
|
console.log(section("Update importers:"));
|
|
15335
15401
|
for (const imp of plan2.importersToUpdate) {
|
|
15336
15402
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
15337
|
-
console.log(` ${
|
|
15403
|
+
console.log(` ${chalk153.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
15338
15404
|
}
|
|
15339
15405
|
}
|
|
15340
15406
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
15341
|
-
console.log(
|
|
15407
|
+
console.log(chalk153.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
15342
15408
|
`));
|
|
15343
|
-
console.log(` ${
|
|
15409
|
+
console.log(` ${chalk153.cyan("Functions to move:")}`);
|
|
15344
15410
|
for (const name of plan2.extractedNames) {
|
|
15345
15411
|
console.log(` ${name}`);
|
|
15346
15412
|
}
|
|
@@ -15374,7 +15440,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
15374
15440
|
|
|
15375
15441
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
15376
15442
|
import path34 from "path";
|
|
15377
|
-
import
|
|
15443
|
+
import chalk154 from "chalk";
|
|
15378
15444
|
import { Project as Project4 } from "ts-morph";
|
|
15379
15445
|
|
|
15380
15446
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -15434,7 +15500,7 @@ function loadProjectFile(file) {
|
|
|
15434
15500
|
});
|
|
15435
15501
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15436
15502
|
if (!sourceFile) {
|
|
15437
|
-
console.log(
|
|
15503
|
+
console.log(chalk154.red(`File not found in project: ${file}`));
|
|
15438
15504
|
process.exit(1);
|
|
15439
15505
|
}
|
|
15440
15506
|
return { project, sourceFile };
|
|
@@ -15457,19 +15523,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15457
15523
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15458
15524
|
if (options2.apply) {
|
|
15459
15525
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15460
|
-
console.log(
|
|
15526
|
+
console.log(chalk155.green("\nExtraction complete"));
|
|
15461
15527
|
} else {
|
|
15462
|
-
console.log(
|
|
15528
|
+
console.log(chalk155.dim("\nDry run. Use --apply to execute."));
|
|
15463
15529
|
}
|
|
15464
15530
|
}
|
|
15465
15531
|
|
|
15466
15532
|
// src/commands/refactor/ignore.ts
|
|
15467
15533
|
import fs23 from "fs";
|
|
15468
|
-
import
|
|
15534
|
+
import chalk156 from "chalk";
|
|
15469
15535
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15470
15536
|
function ignore(file) {
|
|
15471
15537
|
if (!fs23.existsSync(file)) {
|
|
15472
|
-
console.error(
|
|
15538
|
+
console.error(chalk156.red(`Error: File does not exist: ${file}`));
|
|
15473
15539
|
process.exit(1);
|
|
15474
15540
|
}
|
|
15475
15541
|
const content = fs23.readFileSync(file, "utf8");
|
|
@@ -15485,7 +15551,7 @@ function ignore(file) {
|
|
|
15485
15551
|
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15486
15552
|
}
|
|
15487
15553
|
console.log(
|
|
15488
|
-
|
|
15554
|
+
chalk156.green(
|
|
15489
15555
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15490
15556
|
)
|
|
15491
15557
|
);
|
|
@@ -15494,12 +15560,12 @@ function ignore(file) {
|
|
|
15494
15560
|
// src/commands/refactor/rename/index.ts
|
|
15495
15561
|
import fs26 from "fs";
|
|
15496
15562
|
import path40 from "path";
|
|
15497
|
-
import
|
|
15563
|
+
import chalk159 from "chalk";
|
|
15498
15564
|
|
|
15499
15565
|
// src/commands/refactor/rename/applyRename.ts
|
|
15500
15566
|
import fs25 from "fs";
|
|
15501
15567
|
import path37 from "path";
|
|
15502
|
-
import
|
|
15568
|
+
import chalk157 from "chalk";
|
|
15503
15569
|
|
|
15504
15570
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15505
15571
|
import path36 from "path";
|
|
@@ -15604,13 +15670,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
15604
15670
|
const updatedContents = applyRewrites(rewrites);
|
|
15605
15671
|
for (const [file, content] of updatedContents) {
|
|
15606
15672
|
fs25.writeFileSync(file, content, "utf8");
|
|
15607
|
-
console.log(
|
|
15673
|
+
console.log(chalk157.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15608
15674
|
}
|
|
15609
15675
|
const destDir = path37.dirname(destPath);
|
|
15610
15676
|
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15611
15677
|
fs25.renameSync(sourcePath, destPath);
|
|
15612
15678
|
console.log(
|
|
15613
|
-
|
|
15679
|
+
chalk157.white(
|
|
15614
15680
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15615
15681
|
)
|
|
15616
15682
|
);
|
|
@@ -15697,16 +15763,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15697
15763
|
|
|
15698
15764
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15699
15765
|
import path39 from "path";
|
|
15700
|
-
import
|
|
15766
|
+
import chalk158 from "chalk";
|
|
15701
15767
|
function printRenamePreview(rewrites, cwd) {
|
|
15702
15768
|
for (const rewrite of rewrites) {
|
|
15703
15769
|
console.log(
|
|
15704
|
-
|
|
15770
|
+
chalk158.dim(
|
|
15705
15771
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15706
15772
|
)
|
|
15707
15773
|
);
|
|
15708
15774
|
}
|
|
15709
|
-
console.log(
|
|
15775
|
+
console.log(chalk158.dim("Dry run. Use --apply to execute."));
|
|
15710
15776
|
}
|
|
15711
15777
|
|
|
15712
15778
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15717,20 +15783,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15717
15783
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15718
15784
|
const relDest = path40.relative(cwd, destPath);
|
|
15719
15785
|
if (!fs26.existsSync(sourcePath)) {
|
|
15720
|
-
console.log(
|
|
15786
|
+
console.log(chalk159.red(`File not found: ${source}`));
|
|
15721
15787
|
process.exit(1);
|
|
15722
15788
|
}
|
|
15723
15789
|
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15724
|
-
console.log(
|
|
15790
|
+
console.log(chalk159.red(`Destination already exists: ${destination}`));
|
|
15725
15791
|
process.exit(1);
|
|
15726
15792
|
}
|
|
15727
|
-
console.log(
|
|
15728
|
-
console.log(
|
|
15729
|
-
console.log(
|
|
15793
|
+
console.log(chalk159.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
15794
|
+
console.log(chalk159.dim("Loading project..."));
|
|
15795
|
+
console.log(chalk159.dim("Scanning imports across the project..."));
|
|
15730
15796
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15731
15797
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15732
15798
|
console.log(
|
|
15733
|
-
|
|
15799
|
+
chalk159.dim(
|
|
15734
15800
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15735
15801
|
)
|
|
15736
15802
|
);
|
|
@@ -15739,11 +15805,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15739
15805
|
return;
|
|
15740
15806
|
}
|
|
15741
15807
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
15742
|
-
console.log(
|
|
15808
|
+
console.log(chalk159.green("Done"));
|
|
15743
15809
|
}
|
|
15744
15810
|
|
|
15745
15811
|
// src/commands/refactor/renameSymbol/index.ts
|
|
15746
|
-
import
|
|
15812
|
+
import chalk160 from "chalk";
|
|
15747
15813
|
|
|
15748
15814
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
15749
15815
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -15789,33 +15855,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
15789
15855
|
const { project, sourceFile } = loadProjectFile(file);
|
|
15790
15856
|
const symbol = findSymbol(sourceFile, oldName);
|
|
15791
15857
|
if (!symbol) {
|
|
15792
|
-
console.log(
|
|
15858
|
+
console.log(chalk160.red(`Symbol "${oldName}" not found in ${file}`));
|
|
15793
15859
|
process.exit(1);
|
|
15794
15860
|
}
|
|
15795
15861
|
const grouped = groupReferences(symbol, cwd);
|
|
15796
15862
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
15797
15863
|
console.log(
|
|
15798
|
-
|
|
15864
|
+
chalk160.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
15799
15865
|
`)
|
|
15800
15866
|
);
|
|
15801
15867
|
for (const [refFile, lines] of grouped) {
|
|
15802
15868
|
console.log(
|
|
15803
|
-
` ${
|
|
15869
|
+
` ${chalk160.dim(refFile)}: lines ${chalk160.cyan(lines.join(", "))}`
|
|
15804
15870
|
);
|
|
15805
15871
|
}
|
|
15806
15872
|
if (options2.apply) {
|
|
15807
15873
|
symbol.rename(newName);
|
|
15808
15874
|
await project.save();
|
|
15809
|
-
console.log(
|
|
15875
|
+
console.log(chalk160.green(`
|
|
15810
15876
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
15811
15877
|
} else {
|
|
15812
|
-
console.log(
|
|
15878
|
+
console.log(chalk160.dim("\nDry run. Use --apply to execute."));
|
|
15813
15879
|
}
|
|
15814
15880
|
}
|
|
15815
15881
|
|
|
15816
15882
|
// src/commands/refactor/restructure/index.ts
|
|
15817
15883
|
import path48 from "path";
|
|
15818
|
-
import
|
|
15884
|
+
import chalk163 from "chalk";
|
|
15819
15885
|
|
|
15820
15886
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
15821
15887
|
import path42 from "path";
|
|
@@ -15894,50 +15960,50 @@ function clusterFiles(graph) {
|
|
|
15894
15960
|
|
|
15895
15961
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
15896
15962
|
import path44 from "path";
|
|
15897
|
-
import
|
|
15963
|
+
import chalk161 from "chalk";
|
|
15898
15964
|
function relPath(filePath) {
|
|
15899
15965
|
return path44.relative(process.cwd(), filePath);
|
|
15900
15966
|
}
|
|
15901
15967
|
function displayMoves(plan2) {
|
|
15902
15968
|
if (plan2.moves.length === 0) return;
|
|
15903
|
-
console.log(
|
|
15969
|
+
console.log(chalk161.bold("\nFile moves:"));
|
|
15904
15970
|
for (const move of plan2.moves) {
|
|
15905
15971
|
console.log(
|
|
15906
|
-
` ${
|
|
15972
|
+
` ${chalk161.red(relPath(move.from))} \u2192 ${chalk161.green(relPath(move.to))}`
|
|
15907
15973
|
);
|
|
15908
|
-
console.log(
|
|
15974
|
+
console.log(chalk161.dim(` ${move.reason}`));
|
|
15909
15975
|
}
|
|
15910
15976
|
}
|
|
15911
15977
|
function displayRewrites(rewrites) {
|
|
15912
15978
|
if (rewrites.length === 0) return;
|
|
15913
15979
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
15914
|
-
console.log(
|
|
15980
|
+
console.log(chalk161.bold(`
|
|
15915
15981
|
Import rewrites (${affectedFiles.size} files):`));
|
|
15916
15982
|
for (const file of affectedFiles) {
|
|
15917
|
-
console.log(` ${
|
|
15983
|
+
console.log(` ${chalk161.cyan(relPath(file))}:`);
|
|
15918
15984
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
15919
15985
|
(r) => r.file === file
|
|
15920
15986
|
)) {
|
|
15921
15987
|
console.log(
|
|
15922
|
-
` ${
|
|
15988
|
+
` ${chalk161.red(`"${oldSpecifier}"`)} \u2192 ${chalk161.green(`"${newSpecifier}"`)}`
|
|
15923
15989
|
);
|
|
15924
15990
|
}
|
|
15925
15991
|
}
|
|
15926
15992
|
}
|
|
15927
15993
|
function displayPlan2(plan2) {
|
|
15928
15994
|
if (plan2.warnings.length > 0) {
|
|
15929
|
-
console.log(
|
|
15930
|
-
for (const w of plan2.warnings) console.log(
|
|
15995
|
+
console.log(chalk161.yellow("\nWarnings:"));
|
|
15996
|
+
for (const w of plan2.warnings) console.log(chalk161.yellow(` ${w}`));
|
|
15931
15997
|
}
|
|
15932
15998
|
if (plan2.newDirectories.length > 0) {
|
|
15933
|
-
console.log(
|
|
15999
|
+
console.log(chalk161.bold("\nNew directories:"));
|
|
15934
16000
|
for (const dir of plan2.newDirectories)
|
|
15935
|
-
console.log(
|
|
16001
|
+
console.log(chalk161.green(` ${dir}/`));
|
|
15936
16002
|
}
|
|
15937
16003
|
displayMoves(plan2);
|
|
15938
16004
|
displayRewrites(plan2.rewrites);
|
|
15939
16005
|
console.log(
|
|
15940
|
-
|
|
16006
|
+
chalk161.dim(
|
|
15941
16007
|
`
|
|
15942
16008
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
15943
16009
|
)
|
|
@@ -15947,18 +16013,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
15947
16013
|
// src/commands/refactor/restructure/executePlan.ts
|
|
15948
16014
|
import fs27 from "fs";
|
|
15949
16015
|
import path45 from "path";
|
|
15950
|
-
import
|
|
16016
|
+
import chalk162 from "chalk";
|
|
15951
16017
|
function executePlan(plan2) {
|
|
15952
16018
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
15953
16019
|
for (const [file, content] of updatedContents) {
|
|
15954
16020
|
fs27.writeFileSync(file, content, "utf8");
|
|
15955
16021
|
console.log(
|
|
15956
|
-
|
|
16022
|
+
chalk162.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
15957
16023
|
);
|
|
15958
16024
|
}
|
|
15959
16025
|
for (const dir of plan2.newDirectories) {
|
|
15960
16026
|
fs27.mkdirSync(dir, { recursive: true });
|
|
15961
|
-
console.log(
|
|
16027
|
+
console.log(chalk162.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
15962
16028
|
}
|
|
15963
16029
|
for (const move of plan2.moves) {
|
|
15964
16030
|
const targetDir = path45.dirname(move.to);
|
|
@@ -15967,7 +16033,7 @@ function executePlan(plan2) {
|
|
|
15967
16033
|
}
|
|
15968
16034
|
fs27.renameSync(move.from, move.to);
|
|
15969
16035
|
console.log(
|
|
15970
|
-
|
|
16036
|
+
chalk162.white(
|
|
15971
16037
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
15972
16038
|
)
|
|
15973
16039
|
);
|
|
@@ -15982,7 +16048,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
15982
16048
|
if (entries.length === 0) {
|
|
15983
16049
|
fs27.rmdirSync(dir);
|
|
15984
16050
|
console.log(
|
|
15985
|
-
|
|
16051
|
+
chalk162.dim(
|
|
15986
16052
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
15987
16053
|
)
|
|
15988
16054
|
);
|
|
@@ -16115,22 +16181,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
16115
16181
|
const targetPattern = pattern2 ?? "src";
|
|
16116
16182
|
const files = findSourceFiles2(targetPattern);
|
|
16117
16183
|
if (files.length === 0) {
|
|
16118
|
-
console.log(
|
|
16184
|
+
console.log(chalk163.yellow("No files found matching pattern"));
|
|
16119
16185
|
return;
|
|
16120
16186
|
}
|
|
16121
16187
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
16122
16188
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
16123
16189
|
if (plan2.moves.length === 0) {
|
|
16124
|
-
console.log(
|
|
16190
|
+
console.log(chalk163.green("No restructuring needed"));
|
|
16125
16191
|
return;
|
|
16126
16192
|
}
|
|
16127
16193
|
displayPlan2(plan2);
|
|
16128
16194
|
if (options2.apply) {
|
|
16129
|
-
console.log(
|
|
16195
|
+
console.log(chalk163.bold("\nApplying changes..."));
|
|
16130
16196
|
executePlan(plan2);
|
|
16131
|
-
console.log(
|
|
16197
|
+
console.log(chalk163.green("\nRestructuring complete"));
|
|
16132
16198
|
} else {
|
|
16133
|
-
console.log(
|
|
16199
|
+
console.log(chalk163.dim("\nDry run. Use --apply to execute."));
|
|
16134
16200
|
}
|
|
16135
16201
|
}
|
|
16136
16202
|
|
|
@@ -16699,18 +16765,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16699
16765
|
}
|
|
16700
16766
|
|
|
16701
16767
|
// src/commands/review/warnOutOfDiff.ts
|
|
16702
|
-
import
|
|
16768
|
+
import chalk164 from "chalk";
|
|
16703
16769
|
function warnOutOfDiff(outOfDiff) {
|
|
16704
16770
|
if (outOfDiff.length === 0) return;
|
|
16705
16771
|
console.warn(
|
|
16706
|
-
|
|
16772
|
+
chalk164.yellow(
|
|
16707
16773
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16708
16774
|
)
|
|
16709
16775
|
);
|
|
16710
16776
|
for (const finding of outOfDiff) {
|
|
16711
16777
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16712
16778
|
console.warn(
|
|
16713
|
-
` ${
|
|
16779
|
+
` ${chalk164.yellow("\xB7")} ${finding.title} ${chalk164.dim(
|
|
16714
16780
|
`(${finding.file}:${range})`
|
|
16715
16781
|
)}`
|
|
16716
16782
|
);
|
|
@@ -16729,18 +16795,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16729
16795
|
}
|
|
16730
16796
|
|
|
16731
16797
|
// src/commands/review/warnUnlocated.ts
|
|
16732
|
-
import
|
|
16798
|
+
import chalk165 from "chalk";
|
|
16733
16799
|
function warnUnlocated(unlocated) {
|
|
16734
16800
|
if (unlocated.length === 0) return;
|
|
16735
16801
|
console.warn(
|
|
16736
|
-
|
|
16802
|
+
chalk165.yellow(
|
|
16737
16803
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
16738
16804
|
)
|
|
16739
16805
|
);
|
|
16740
16806
|
for (const finding of unlocated) {
|
|
16741
|
-
const where = finding.location ||
|
|
16807
|
+
const where = finding.location || chalk165.dim("missing");
|
|
16742
16808
|
console.warn(
|
|
16743
|
-
` ${
|
|
16809
|
+
` ${chalk165.yellow("\xB7")} ${finding.title} ${chalk165.dim(`(${where})`)}`
|
|
16744
16810
|
);
|
|
16745
16811
|
}
|
|
16746
16812
|
}
|
|
@@ -17911,7 +17977,7 @@ function registerReview(program2) {
|
|
|
17911
17977
|
}
|
|
17912
17978
|
|
|
17913
17979
|
// src/commands/seq/seqAuth.ts
|
|
17914
|
-
import
|
|
17980
|
+
import chalk167 from "chalk";
|
|
17915
17981
|
|
|
17916
17982
|
// src/commands/seq/loadConnections.ts
|
|
17917
17983
|
function loadConnections2() {
|
|
@@ -17940,10 +18006,10 @@ function setDefaultConnection(name) {
|
|
|
17940
18006
|
}
|
|
17941
18007
|
|
|
17942
18008
|
// src/shared/assertUniqueName.ts
|
|
17943
|
-
import
|
|
18009
|
+
import chalk166 from "chalk";
|
|
17944
18010
|
function assertUniqueName(existingNames, name) {
|
|
17945
18011
|
if (existingNames.includes(name)) {
|
|
17946
|
-
console.error(
|
|
18012
|
+
console.error(chalk166.red(`Connection "${name}" already exists.`));
|
|
17947
18013
|
process.exit(1);
|
|
17948
18014
|
}
|
|
17949
18015
|
}
|
|
@@ -17961,16 +18027,16 @@ async function promptConnection2(existingNames) {
|
|
|
17961
18027
|
var seqAuth = createConnectionAuth({
|
|
17962
18028
|
load: loadConnections2,
|
|
17963
18029
|
save: saveConnections2,
|
|
17964
|
-
format: (c) => `${
|
|
18030
|
+
format: (c) => `${chalk167.bold(c.name)} ${c.url}`,
|
|
17965
18031
|
promptNew: promptConnection2,
|
|
17966
18032
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
17967
18033
|
});
|
|
17968
18034
|
|
|
17969
18035
|
// src/commands/seq/seqQuery.ts
|
|
17970
|
-
import
|
|
18036
|
+
import chalk171 from "chalk";
|
|
17971
18037
|
|
|
17972
18038
|
// src/commands/seq/fetchSeq.ts
|
|
17973
|
-
import
|
|
18039
|
+
import chalk168 from "chalk";
|
|
17974
18040
|
async function fetchSeq(conn, path57, params) {
|
|
17975
18041
|
const url = `${conn.url}${path57}?${params}`;
|
|
17976
18042
|
const response = await fetch(url, {
|
|
@@ -17981,7 +18047,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
17981
18047
|
});
|
|
17982
18048
|
if (!response.ok) {
|
|
17983
18049
|
const body = await response.text();
|
|
17984
|
-
console.error(
|
|
18050
|
+
console.error(chalk168.red(`Seq returned ${response.status}: ${body}`));
|
|
17985
18051
|
process.exit(1);
|
|
17986
18052
|
}
|
|
17987
18053
|
return response;
|
|
@@ -18040,23 +18106,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
18040
18106
|
}
|
|
18041
18107
|
|
|
18042
18108
|
// src/commands/seq/formatEvent.ts
|
|
18043
|
-
import
|
|
18109
|
+
import chalk169 from "chalk";
|
|
18044
18110
|
function levelColor(level) {
|
|
18045
18111
|
switch (level) {
|
|
18046
18112
|
case "Fatal":
|
|
18047
|
-
return
|
|
18113
|
+
return chalk169.bgRed.white;
|
|
18048
18114
|
case "Error":
|
|
18049
|
-
return
|
|
18115
|
+
return chalk169.red;
|
|
18050
18116
|
case "Warning":
|
|
18051
|
-
return
|
|
18117
|
+
return chalk169.yellow;
|
|
18052
18118
|
case "Information":
|
|
18053
|
-
return
|
|
18119
|
+
return chalk169.cyan;
|
|
18054
18120
|
case "Debug":
|
|
18055
|
-
return
|
|
18121
|
+
return chalk169.gray;
|
|
18056
18122
|
case "Verbose":
|
|
18057
|
-
return
|
|
18123
|
+
return chalk169.dim;
|
|
18058
18124
|
default:
|
|
18059
|
-
return
|
|
18125
|
+
return chalk169.white;
|
|
18060
18126
|
}
|
|
18061
18127
|
}
|
|
18062
18128
|
function levelAbbrev(level) {
|
|
@@ -18097,12 +18163,12 @@ function formatTimestamp(iso) {
|
|
|
18097
18163
|
function formatEvent(event) {
|
|
18098
18164
|
const color = levelColor(event.Level);
|
|
18099
18165
|
const abbrev = levelAbbrev(event.Level);
|
|
18100
|
-
const ts8 =
|
|
18166
|
+
const ts8 = chalk169.dim(formatTimestamp(event.Timestamp));
|
|
18101
18167
|
const msg = renderMessage(event);
|
|
18102
18168
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
18103
18169
|
if (event.Exception) {
|
|
18104
18170
|
for (const line of event.Exception.split("\n")) {
|
|
18105
|
-
lines.push(
|
|
18171
|
+
lines.push(chalk169.red(` ${line}`));
|
|
18106
18172
|
}
|
|
18107
18173
|
}
|
|
18108
18174
|
return lines.join("\n");
|
|
@@ -18135,11 +18201,11 @@ function rejectTimestampFilter(filter) {
|
|
|
18135
18201
|
}
|
|
18136
18202
|
|
|
18137
18203
|
// src/shared/resolveNamedConnection.ts
|
|
18138
|
-
import
|
|
18204
|
+
import chalk170 from "chalk";
|
|
18139
18205
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
18140
18206
|
if (connections.length === 0) {
|
|
18141
18207
|
console.error(
|
|
18142
|
-
|
|
18208
|
+
chalk170.red(
|
|
18143
18209
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
18144
18210
|
)
|
|
18145
18211
|
);
|
|
@@ -18148,7 +18214,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
18148
18214
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
18149
18215
|
const connection = connections.find((c) => c.name === target);
|
|
18150
18216
|
if (!connection) {
|
|
18151
|
-
console.error(
|
|
18217
|
+
console.error(chalk170.red(`${kind} connection "${target}" not found.`));
|
|
18152
18218
|
process.exit(1);
|
|
18153
18219
|
}
|
|
18154
18220
|
return connection;
|
|
@@ -18177,7 +18243,7 @@ async function seqQuery(filter, options2) {
|
|
|
18177
18243
|
new URLSearchParams({ filter, count: String(count6) })
|
|
18178
18244
|
);
|
|
18179
18245
|
if (events.length === 0) {
|
|
18180
|
-
console.log(
|
|
18246
|
+
console.log(chalk171.yellow("No events found."));
|
|
18181
18247
|
return;
|
|
18182
18248
|
}
|
|
18183
18249
|
if (options2.json) {
|
|
@@ -18188,11 +18254,11 @@ async function seqQuery(filter, options2) {
|
|
|
18188
18254
|
for (const event of chronological) {
|
|
18189
18255
|
console.log(formatEvent(event));
|
|
18190
18256
|
}
|
|
18191
|
-
console.log(
|
|
18257
|
+
console.log(chalk171.dim(`
|
|
18192
18258
|
${events.length} events`));
|
|
18193
18259
|
if (events.length >= count6) {
|
|
18194
18260
|
console.log(
|
|
18195
|
-
|
|
18261
|
+
chalk171.yellow(
|
|
18196
18262
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
18197
18263
|
)
|
|
18198
18264
|
);
|
|
@@ -18200,10 +18266,10 @@ ${events.length} events`));
|
|
|
18200
18266
|
}
|
|
18201
18267
|
|
|
18202
18268
|
// src/shared/setNamedDefaultConnection.ts
|
|
18203
|
-
import
|
|
18269
|
+
import chalk172 from "chalk";
|
|
18204
18270
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
18205
18271
|
if (!connections.find((c) => c.name === name)) {
|
|
18206
|
-
console.error(
|
|
18272
|
+
console.error(chalk172.red(`Connection "${name}" not found.`));
|
|
18207
18273
|
process.exit(1);
|
|
18208
18274
|
}
|
|
18209
18275
|
setDefault(name);
|
|
@@ -18251,7 +18317,7 @@ function registerSignal(program2) {
|
|
|
18251
18317
|
}
|
|
18252
18318
|
|
|
18253
18319
|
// src/commands/sql/sqlAuth.ts
|
|
18254
|
-
import
|
|
18320
|
+
import chalk174 from "chalk";
|
|
18255
18321
|
|
|
18256
18322
|
// src/commands/sql/loadConnections.ts
|
|
18257
18323
|
function loadConnections3() {
|
|
@@ -18280,7 +18346,7 @@ function setDefaultConnection2(name) {
|
|
|
18280
18346
|
}
|
|
18281
18347
|
|
|
18282
18348
|
// src/commands/sql/promptConnection.ts
|
|
18283
|
-
import
|
|
18349
|
+
import chalk173 from "chalk";
|
|
18284
18350
|
async function promptConnection3(existingNames) {
|
|
18285
18351
|
const name = await promptInput("name", "Connection name:", "default");
|
|
18286
18352
|
assertUniqueName(existingNames, name);
|
|
@@ -18288,7 +18354,7 @@ async function promptConnection3(existingNames) {
|
|
|
18288
18354
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
18289
18355
|
const port = Number.parseInt(portStr, 10);
|
|
18290
18356
|
if (!Number.isFinite(port)) {
|
|
18291
|
-
console.error(
|
|
18357
|
+
console.error(chalk173.red(`Invalid port "${portStr}".`));
|
|
18292
18358
|
process.exit(1);
|
|
18293
18359
|
}
|
|
18294
18360
|
const user = await promptInput("user", "User:");
|
|
@@ -18301,13 +18367,13 @@ async function promptConnection3(existingNames) {
|
|
|
18301
18367
|
var sqlAuth = createConnectionAuth({
|
|
18302
18368
|
load: loadConnections3,
|
|
18303
18369
|
save: saveConnections3,
|
|
18304
|
-
format: (c) => `${
|
|
18370
|
+
format: (c) => `${chalk174.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
18305
18371
|
promptNew: promptConnection3,
|
|
18306
18372
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
18307
18373
|
});
|
|
18308
18374
|
|
|
18309
18375
|
// src/commands/sql/printTable.ts
|
|
18310
|
-
import
|
|
18376
|
+
import chalk175 from "chalk";
|
|
18311
18377
|
function formatCell(value) {
|
|
18312
18378
|
if (value === null || value === void 0) return "";
|
|
18313
18379
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -18316,7 +18382,7 @@ function formatCell(value) {
|
|
|
18316
18382
|
}
|
|
18317
18383
|
function printTable(rows) {
|
|
18318
18384
|
if (rows.length === 0) {
|
|
18319
|
-
console.log(
|
|
18385
|
+
console.log(chalk175.yellow("(no rows)"));
|
|
18320
18386
|
return;
|
|
18321
18387
|
}
|
|
18322
18388
|
const columns = Object.keys(rows[0]);
|
|
@@ -18324,13 +18390,13 @@ function printTable(rows) {
|
|
|
18324
18390
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
18325
18391
|
);
|
|
18326
18392
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
18327
|
-
console.log(
|
|
18328
|
-
console.log(
|
|
18393
|
+
console.log(chalk175.dim(header));
|
|
18394
|
+
console.log(chalk175.dim("-".repeat(header.length)));
|
|
18329
18395
|
for (const row of rows) {
|
|
18330
18396
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
18331
18397
|
console.log(line);
|
|
18332
18398
|
}
|
|
18333
|
-
console.log(
|
|
18399
|
+
console.log(chalk175.dim(`
|
|
18334
18400
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
18335
18401
|
}
|
|
18336
18402
|
|
|
@@ -18390,7 +18456,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
18390
18456
|
}
|
|
18391
18457
|
|
|
18392
18458
|
// src/commands/sql/sqlMutate.ts
|
|
18393
|
-
import
|
|
18459
|
+
import chalk176 from "chalk";
|
|
18394
18460
|
|
|
18395
18461
|
// src/commands/sql/isMutation.ts
|
|
18396
18462
|
var MUTATION_KEYWORDS = [
|
|
@@ -18424,7 +18490,7 @@ function isMutation(sql6) {
|
|
|
18424
18490
|
async function sqlMutate(query, connectionName) {
|
|
18425
18491
|
if (!isMutation(query)) {
|
|
18426
18492
|
console.error(
|
|
18427
|
-
|
|
18493
|
+
chalk176.red(
|
|
18428
18494
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18429
18495
|
)
|
|
18430
18496
|
);
|
|
@@ -18434,18 +18500,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18434
18500
|
const pool = await sqlConnect(conn);
|
|
18435
18501
|
try {
|
|
18436
18502
|
const result = await pool.request().query(query);
|
|
18437
|
-
console.log(
|
|
18503
|
+
console.log(chalk176.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18438
18504
|
} finally {
|
|
18439
18505
|
await pool.close();
|
|
18440
18506
|
}
|
|
18441
18507
|
}
|
|
18442
18508
|
|
|
18443
18509
|
// src/commands/sql/sqlQuery.ts
|
|
18444
|
-
import
|
|
18510
|
+
import chalk177 from "chalk";
|
|
18445
18511
|
async function sqlQuery(query, connectionName) {
|
|
18446
18512
|
if (isMutation(query)) {
|
|
18447
18513
|
console.error(
|
|
18448
|
-
|
|
18514
|
+
chalk177.red(
|
|
18449
18515
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18450
18516
|
)
|
|
18451
18517
|
);
|
|
@@ -18460,7 +18526,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18460
18526
|
printTable(rows);
|
|
18461
18527
|
} else {
|
|
18462
18528
|
console.log(
|
|
18463
|
-
|
|
18529
|
+
chalk177.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18464
18530
|
);
|
|
18465
18531
|
}
|
|
18466
18532
|
} finally {
|
|
@@ -19040,14 +19106,14 @@ import {
|
|
|
19040
19106
|
import { dirname as dirname24, join as join52 } from "path";
|
|
19041
19107
|
|
|
19042
19108
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
19043
|
-
import
|
|
19109
|
+
import chalk178 from "chalk";
|
|
19044
19110
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
19045
19111
|
function validateStagedContent(filename, content) {
|
|
19046
19112
|
const firstLine = content.split("\n")[0];
|
|
19047
19113
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
19048
19114
|
if (!match) {
|
|
19049
19115
|
console.error(
|
|
19050
|
-
|
|
19116
|
+
chalk178.red(
|
|
19051
19117
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
19052
19118
|
)
|
|
19053
19119
|
);
|
|
@@ -19056,7 +19122,7 @@ function validateStagedContent(filename, content) {
|
|
|
19056
19122
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
19057
19123
|
if (!contentAfterLink) {
|
|
19058
19124
|
console.error(
|
|
19059
|
-
|
|
19125
|
+
chalk178.red(
|
|
19060
19126
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
19061
19127
|
)
|
|
19062
19128
|
);
|
|
@@ -19460,7 +19526,7 @@ function registerVoice(program2) {
|
|
|
19460
19526
|
|
|
19461
19527
|
// src/commands/roam/auth.ts
|
|
19462
19528
|
import { randomBytes } from "crypto";
|
|
19463
|
-
import
|
|
19529
|
+
import chalk179 from "chalk";
|
|
19464
19530
|
|
|
19465
19531
|
// src/commands/roam/waitForCallback.ts
|
|
19466
19532
|
import { createServer as createServer3 } from "http";
|
|
@@ -19591,13 +19657,13 @@ async function auth() {
|
|
|
19591
19657
|
saveGlobalConfig(config);
|
|
19592
19658
|
const state = randomBytes(16).toString("hex");
|
|
19593
19659
|
console.log(
|
|
19594
|
-
|
|
19660
|
+
chalk179.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19595
19661
|
);
|
|
19596
|
-
console.log(
|
|
19597
|
-
console.log(
|
|
19598
|
-
console.log(
|
|
19662
|
+
console.log(chalk179.white("http://localhost:14523/callback\n"));
|
|
19663
|
+
console.log(chalk179.blue("Opening browser for authorization..."));
|
|
19664
|
+
console.log(chalk179.dim("Waiting for authorization callback..."));
|
|
19599
19665
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19600
|
-
console.log(
|
|
19666
|
+
console.log(chalk179.dim("Exchanging code for tokens..."));
|
|
19601
19667
|
const tokens = await exchangeToken({
|
|
19602
19668
|
code,
|
|
19603
19669
|
clientId,
|
|
@@ -19613,7 +19679,7 @@ async function auth() {
|
|
|
19613
19679
|
};
|
|
19614
19680
|
saveGlobalConfig(config);
|
|
19615
19681
|
console.log(
|
|
19616
|
-
|
|
19682
|
+
chalk179.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19617
19683
|
);
|
|
19618
19684
|
}
|
|
19619
19685
|
|
|
@@ -20065,7 +20131,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
20065
20131
|
import { existsSync as existsSync52, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20066
20132
|
import { tmpdir as tmpdir7 } from "os";
|
|
20067
20133
|
import { join as join63, resolve as resolve15 } from "path";
|
|
20068
|
-
import
|
|
20134
|
+
import chalk180 from "chalk";
|
|
20069
20135
|
|
|
20070
20136
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
20071
20137
|
var captureWindowPs1 = `
|
|
@@ -20216,13 +20282,13 @@ function screenshot(processName) {
|
|
|
20216
20282
|
const config = loadConfig();
|
|
20217
20283
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
20218
20284
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
20219
|
-
console.log(
|
|
20285
|
+
console.log(chalk180.gray(`Capturing window for process "${processName}" ...`));
|
|
20220
20286
|
try {
|
|
20221
20287
|
runPowerShellScript(processName, outputPath);
|
|
20222
|
-
console.log(
|
|
20288
|
+
console.log(chalk180.green(`Screenshot saved: ${outputPath}`));
|
|
20223
20289
|
} catch (error) {
|
|
20224
20290
|
const msg = error instanceof Error ? error.message : String(error);
|
|
20225
|
-
console.error(
|
|
20291
|
+
console.error(chalk180.red(`Failed to capture screenshot: ${msg}`));
|
|
20226
20292
|
process.exit(1);
|
|
20227
20293
|
}
|
|
20228
20294
|
}
|
|
@@ -22508,7 +22574,7 @@ function registerDaemon(program2) {
|
|
|
22508
22574
|
|
|
22509
22575
|
// src/commands/sessions/summarise/index.ts
|
|
22510
22576
|
import * as fs35 from "fs";
|
|
22511
|
-
import
|
|
22577
|
+
import chalk181 from "chalk";
|
|
22512
22578
|
|
|
22513
22579
|
// src/commands/sessions/summarise/shared.ts
|
|
22514
22580
|
import * as fs33 from "fs";
|
|
@@ -22662,22 +22728,22 @@ ${firstMessage}`);
|
|
|
22662
22728
|
async function summarise3(options2) {
|
|
22663
22729
|
const files = await discoverSessionFiles();
|
|
22664
22730
|
if (files.length === 0) {
|
|
22665
|
-
console.log(
|
|
22731
|
+
console.log(chalk181.yellow("No sessions found."));
|
|
22666
22732
|
return;
|
|
22667
22733
|
}
|
|
22668
22734
|
const toProcess = selectCandidates(files, options2);
|
|
22669
22735
|
if (toProcess.length === 0) {
|
|
22670
|
-
console.log(
|
|
22736
|
+
console.log(chalk181.green("All sessions already summarised."));
|
|
22671
22737
|
return;
|
|
22672
22738
|
}
|
|
22673
22739
|
console.log(
|
|
22674
|
-
|
|
22740
|
+
chalk181.cyan(
|
|
22675
22741
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22676
22742
|
)
|
|
22677
22743
|
);
|
|
22678
22744
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22679
22745
|
console.log(
|
|
22680
|
-
|
|
22746
|
+
chalk181.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk181.yellow(`, ${failed2} skipped`) : "")
|
|
22681
22747
|
);
|
|
22682
22748
|
}
|
|
22683
22749
|
function selectCandidates(files, options2) {
|
|
@@ -22697,16 +22763,16 @@ function processSessions(files) {
|
|
|
22697
22763
|
let failed2 = 0;
|
|
22698
22764
|
for (let i = 0; i < files.length; i++) {
|
|
22699
22765
|
const file = files[i];
|
|
22700
|
-
process.stdout.write(
|
|
22766
|
+
process.stdout.write(chalk181.dim(` [${i + 1}/${files.length}] `));
|
|
22701
22767
|
const summary = summariseSession(file);
|
|
22702
22768
|
if (summary) {
|
|
22703
22769
|
writeSummary(file, summary);
|
|
22704
22770
|
succeeded++;
|
|
22705
|
-
process.stdout.write(`${
|
|
22771
|
+
process.stdout.write(`${chalk181.green("\u2713")} ${summary}
|
|
22706
22772
|
`);
|
|
22707
22773
|
} else {
|
|
22708
22774
|
failed2++;
|
|
22709
|
-
process.stdout.write(` ${
|
|
22775
|
+
process.stdout.write(` ${chalk181.yellow("skip")}
|
|
22710
22776
|
`);
|
|
22711
22777
|
}
|
|
22712
22778
|
}
|
|
@@ -22724,10 +22790,10 @@ function registerSessions(program2) {
|
|
|
22724
22790
|
}
|
|
22725
22791
|
|
|
22726
22792
|
// src/commands/statusLine.ts
|
|
22727
|
-
import
|
|
22793
|
+
import chalk183 from "chalk";
|
|
22728
22794
|
|
|
22729
22795
|
// src/commands/buildLimitsSegment.ts
|
|
22730
|
-
import
|
|
22796
|
+
import chalk182 from "chalk";
|
|
22731
22797
|
|
|
22732
22798
|
// src/shared/rateLimitLevel.ts
|
|
22733
22799
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22758,9 +22824,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22758
22824
|
|
|
22759
22825
|
// src/commands/buildLimitsSegment.ts
|
|
22760
22826
|
var LEVEL_COLOR = {
|
|
22761
|
-
ok:
|
|
22762
|
-
warn:
|
|
22763
|
-
over:
|
|
22827
|
+
ok: chalk182.green,
|
|
22828
|
+
warn: chalk182.yellow,
|
|
22829
|
+
over: chalk182.red
|
|
22764
22830
|
};
|
|
22765
22831
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22766
22832
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22800,14 +22866,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
22800
22866
|
}
|
|
22801
22867
|
|
|
22802
22868
|
// src/commands/statusLine.ts
|
|
22803
|
-
|
|
22869
|
+
chalk183.level = 3;
|
|
22804
22870
|
function formatNumber(num) {
|
|
22805
22871
|
return num.toLocaleString("en-US");
|
|
22806
22872
|
}
|
|
22807
22873
|
function colorizePercent(pct) {
|
|
22808
22874
|
const label2 = `${Math.round(pct)}%`;
|
|
22809
|
-
if (pct > 80) return
|
|
22810
|
-
if (pct > 40) return
|
|
22875
|
+
if (pct > 80) return chalk183.red(label2);
|
|
22876
|
+
if (pct > 40) return chalk183.yellow(label2);
|
|
22811
22877
|
return label2;
|
|
22812
22878
|
}
|
|
22813
22879
|
async function statusLine() {
|
|
@@ -22831,7 +22897,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
22831
22897
|
// src/commands/sync/syncClaudeMd.ts
|
|
22832
22898
|
import * as fs36 from "fs";
|
|
22833
22899
|
import * as path53 from "path";
|
|
22834
|
-
import
|
|
22900
|
+
import chalk184 from "chalk";
|
|
22835
22901
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22836
22902
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22837
22903
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
@@ -22840,12 +22906,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22840
22906
|
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22841
22907
|
if (sourceContent !== targetContent) {
|
|
22842
22908
|
console.log(
|
|
22843
|
-
|
|
22909
|
+
chalk184.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22844
22910
|
);
|
|
22845
22911
|
console.log();
|
|
22846
22912
|
printDiff(targetContent, sourceContent);
|
|
22847
22913
|
const confirm = options2?.yes || await promptConfirm(
|
|
22848
|
-
|
|
22914
|
+
chalk184.red("Overwrite existing CLAUDE.md?"),
|
|
22849
22915
|
false
|
|
22850
22916
|
);
|
|
22851
22917
|
if (!confirm) {
|
|
@@ -22861,7 +22927,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22861
22927
|
// src/commands/sync/syncSettings.ts
|
|
22862
22928
|
import * as fs37 from "fs";
|
|
22863
22929
|
import * as path54 from "path";
|
|
22864
|
-
import
|
|
22930
|
+
import chalk185 from "chalk";
|
|
22865
22931
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22866
22932
|
const source = path54.join(claudeDir, "settings.json");
|
|
22867
22933
|
const target = path54.join(targetBase, "settings.json");
|
|
@@ -22877,14 +22943,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22877
22943
|
if (mergedContent !== normalizedTarget) {
|
|
22878
22944
|
if (!options2?.yes) {
|
|
22879
22945
|
console.log(
|
|
22880
|
-
|
|
22946
|
+
chalk185.yellow(
|
|
22881
22947
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22882
22948
|
)
|
|
22883
22949
|
);
|
|
22884
22950
|
console.log();
|
|
22885
22951
|
printDiff(targetContent, mergedContent);
|
|
22886
22952
|
const confirm = await promptConfirm(
|
|
22887
|
-
|
|
22953
|
+
chalk185.red("Overwrite existing settings.json?"),
|
|
22888
22954
|
false
|
|
22889
22955
|
);
|
|
22890
22956
|
if (!confirm) {
|