@staff0rd/assist 0.404.2 → 0.406.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 +3 -1
- package/claude/commands/bug.md +18 -0
- package/claude/commands/draft.md +18 -0
- package/claude/commands/github.md +130 -0
- package/claude/commands/refine.md +10 -0
- package/claude/settings.json +2 -0
- package/dist/commands/sessions/web/bundle.js +80 -80
- package/dist/index.js +860 -727
- 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.406.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -458,7 +458,8 @@ var items = pgTable2(
|
|
|
458
458
|
status: text2().notNull().default("todo"),
|
|
459
459
|
currentPhase: integer2("current_phase"),
|
|
460
460
|
starred: boolean().notNull().default(false),
|
|
461
|
-
jiraKey: text2("jira_key")
|
|
461
|
+
jiraKey: text2("jira_key"),
|
|
462
|
+
githubIssue: text2("github_issue")
|
|
462
463
|
},
|
|
463
464
|
(t) => [index("items_origin_idx").on(t.origin)]
|
|
464
465
|
);
|
|
@@ -1114,6 +1115,16 @@ var migration0006BackfillPhaseSessions = {
|
|
|
1114
1115
|
sql: sql7
|
|
1115
1116
|
};
|
|
1116
1117
|
|
|
1118
|
+
// src/shared/db/migrations/migration0007GithubIssue.ts
|
|
1119
|
+
var sql8 = `
|
|
1120
|
+
ALTER TABLE items ADD COLUMN IF NOT EXISTS github_issue TEXT;
|
|
1121
|
+
`;
|
|
1122
|
+
var migration0007GithubIssue = {
|
|
1123
|
+
id: 7,
|
|
1124
|
+
name: "github-issue",
|
|
1125
|
+
sql: sql8
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1117
1128
|
// src/shared/db/migrations/index.ts
|
|
1118
1129
|
var migrations = [
|
|
1119
1130
|
migration0001Baseline,
|
|
@@ -1121,7 +1132,8 @@ var migrations = [
|
|
|
1121
1132
|
migration0003PhaseCycleContext,
|
|
1122
1133
|
migration0004DropUsagePeaksContext,
|
|
1123
1134
|
migration0005PhaseSessions,
|
|
1124
|
-
migration0006BackfillPhaseSessions
|
|
1135
|
+
migration0006BackfillPhaseSessions,
|
|
1136
|
+
migration0007GithubIssue
|
|
1125
1137
|
];
|
|
1126
1138
|
var latestMigrationId = migrations.reduce(
|
|
1127
1139
|
(max, m) => Math.max(max, m.id),
|
|
@@ -1204,8 +1216,8 @@ async function assertMigrationsInSync(exec3) {
|
|
|
1204
1216
|
// src/shared/db/migrations/MigrationExecutor.ts
|
|
1205
1217
|
function pgExecutor(queryable) {
|
|
1206
1218
|
return {
|
|
1207
|
-
exec: (
|
|
1208
|
-
query: async (
|
|
1219
|
+
exec: (sql24) => queryable.query(sql24),
|
|
1220
|
+
query: async (sql24, params) => (await queryable.query(sql24, params)).rows
|
|
1209
1221
|
};
|
|
1210
1222
|
}
|
|
1211
1223
|
|
|
@@ -4737,8 +4749,8 @@ async function buildDump(tables, copyOut) {
|
|
|
4737
4749
|
// src/commands/backlog/dump/copyTableOut.ts
|
|
4738
4750
|
import { to as copyTo } from "pg-copy-streams";
|
|
4739
4751
|
async function copyTableOut(client, table) {
|
|
4740
|
-
const
|
|
4741
|
-
const stream = client.query(copyTo(
|
|
4752
|
+
const sql24 = `COPY ${table.name} (${table.columns.join(", ")}) TO STDOUT`;
|
|
4753
|
+
const stream = client.query(copyTo(sql24));
|
|
4742
4754
|
const chunks = [];
|
|
4743
4755
|
for await (const chunk of stream) {
|
|
4744
4756
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -5421,7 +5433,8 @@ function itemColumns(item, origin) {
|
|
|
5421
5433
|
status: item.status,
|
|
5422
5434
|
currentPhase: item.currentPhase ?? null,
|
|
5423
5435
|
starred: item.starred,
|
|
5424
|
-
jiraKey: item.jiraKey ?? null
|
|
5436
|
+
jiraKey: item.jiraKey ?? null,
|
|
5437
|
+
githubIssue: item.githubIssue ?? null
|
|
5425
5438
|
};
|
|
5426
5439
|
}
|
|
5427
5440
|
|
|
@@ -5719,6 +5732,7 @@ function assignOptionalColumns(item, row) {
|
|
|
5719
5732
|
if (row.description != null) item.description = row.description;
|
|
5720
5733
|
if (row.currentPhase != null) item.currentPhase = row.currentPhase;
|
|
5721
5734
|
if (row.jiraKey != null) item.jiraKey = row.jiraKey;
|
|
5735
|
+
if (row.githubIssue != null) item.githubIssue = row.githubIssue;
|
|
5722
5736
|
}
|
|
5723
5737
|
function baseItem(row) {
|
|
5724
5738
|
const item = {
|
|
@@ -5849,7 +5863,8 @@ var backlogItemSchema = z3.strictObject({
|
|
|
5849
5863
|
usageTotal: phaseUsageTotalSchema.optional(),
|
|
5850
5864
|
gitRefs: z3.array(gitRefSchema).optional(),
|
|
5851
5865
|
origin: z3.string().optional(),
|
|
5852
|
-
jiraKey: z3.string().optional()
|
|
5866
|
+
jiraKey: z3.string().optional(),
|
|
5867
|
+
githubIssue: z3.string().optional()
|
|
5853
5868
|
});
|
|
5854
5869
|
var backlogFileSchema = z3.array(backlogItemSchema);
|
|
5855
5870
|
|
|
@@ -6003,13 +6018,13 @@ async function loadItem(orm, id) {
|
|
|
6003
6018
|
}
|
|
6004
6019
|
|
|
6005
6020
|
// src/commands/backlog/saveAllItems.ts
|
|
6006
|
-
import { eq as eq7, sql as
|
|
6021
|
+
import { eq as eq7, sql as sql9 } from "drizzle-orm";
|
|
6007
6022
|
|
|
6008
6023
|
// src/commands/backlog/deleteItemRelations.ts
|
|
6009
6024
|
import { eq as eq6 } from "drizzle-orm";
|
|
6010
6025
|
|
|
6011
6026
|
// src/commands/backlog/searchItemIds.ts
|
|
6012
|
-
import { and as and3, asc as asc4, eq as eq8, ilike, or, sql as
|
|
6027
|
+
import { and as and3, asc as asc4, eq as eq8, ilike, or, sql as sql10 } from "drizzle-orm";
|
|
6013
6028
|
async function searchItemIds(orm, query, origin) {
|
|
6014
6029
|
const pattern2 = `%${query}%`;
|
|
6015
6030
|
const numberPattern = `%${query.replace(/^#/, "")}%`;
|
|
@@ -6023,7 +6038,7 @@ async function searchItemIds(orm, query, origin) {
|
|
|
6023
6038
|
ilike(items.jiraKey, pattern2),
|
|
6024
6039
|
ilike(comments.text, pattern2),
|
|
6025
6040
|
ilike(planPhases.name, pattern2),
|
|
6026
|
-
ilike(
|
|
6041
|
+
ilike(sql10`${items.id}::text`, numberPattern)
|
|
6027
6042
|
)
|
|
6028
6043
|
)
|
|
6029
6044
|
).orderBy(asc4(items.id));
|
|
@@ -6147,11 +6162,11 @@ async function findPhaseBySessionId(db, itemId2, claudeSessionId) {
|
|
|
6147
6162
|
}
|
|
6148
6163
|
|
|
6149
6164
|
// src/commands/backlog/appendComment.ts
|
|
6150
|
-
import { sql as
|
|
6165
|
+
import { sql as sql11 } from "drizzle-orm";
|
|
6151
6166
|
async function appendComment(orm, itemId2, text17, opts = {}) {
|
|
6152
6167
|
await orm.insert(comments).values({
|
|
6153
6168
|
itemId: itemId2,
|
|
6154
|
-
idx:
|
|
6169
|
+
idx: sql11`(SELECT COALESCE(MAX(${comments.idx}) + 1, 0) FROM ${comments} WHERE ${comments.itemId} = ${itemId2})`,
|
|
6155
6170
|
text: text17,
|
|
6156
6171
|
phase: opts.phase ?? null,
|
|
6157
6172
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -6604,7 +6619,7 @@ function launchPhaseSession(item, phaseNumber, phase, phaseLabel2, claudeSession
|
|
|
6604
6619
|
import os from "os";
|
|
6605
6620
|
|
|
6606
6621
|
// src/shared/db/recordPhaseSession.ts
|
|
6607
|
-
import { sql as
|
|
6622
|
+
import { sql as sql12 } from "drizzle-orm";
|
|
6608
6623
|
async function recordPhaseSession(db, itemId2, phaseIdx, claudeSessionId, hostname, osUser) {
|
|
6609
6624
|
await db.insert(phaseSessions).values({ itemId: itemId2, phaseIdx, claudeSessionId, hostname, osUser }).onConflictDoUpdate({
|
|
6610
6625
|
target: [
|
|
@@ -6613,7 +6628,7 @@ async function recordPhaseSession(db, itemId2, phaseIdx, claudeSessionId, hostna
|
|
|
6613
6628
|
phaseSessions.claudeSessionId
|
|
6614
6629
|
],
|
|
6615
6630
|
set: { hostname, osUser },
|
|
6616
|
-
setWhere:
|
|
6631
|
+
setWhere: sql12`${phaseSessions.hostname} = 'unknown'`
|
|
6617
6632
|
});
|
|
6618
6633
|
}
|
|
6619
6634
|
|
|
@@ -7354,6 +7369,18 @@ function renderMarkdownTerminal(text17) {
|
|
|
7354
7369
|
return marked.parse(text17).trimEnd();
|
|
7355
7370
|
}
|
|
7356
7371
|
|
|
7372
|
+
// src/commands/backlog/shortenGithubIssue.ts
|
|
7373
|
+
var SHORTHAND = /^([^/\s]+)\/([^/\s]+)#(\d+)$/;
|
|
7374
|
+
function shortenGithubIssue(githubIssue, origin) {
|
|
7375
|
+
const match = SHORTHAND.exec(githubIssue);
|
|
7376
|
+
if (!match || !origin) return githubIssue;
|
|
7377
|
+
const [, owner, repo, number] = match;
|
|
7378
|
+
if (`github.com/${owner}/${repo}`.toLowerCase() === origin.toLowerCase()) {
|
|
7379
|
+
return `#${number}`;
|
|
7380
|
+
}
|
|
7381
|
+
return githubIssue;
|
|
7382
|
+
}
|
|
7383
|
+
|
|
7357
7384
|
// src/commands/backlog/show/printActivity.ts
|
|
7358
7385
|
import chalk50 from "chalk";
|
|
7359
7386
|
|
|
@@ -7526,6 +7553,11 @@ function printHeader(item) {
|
|
|
7526
7553
|
if (item.jiraKey) {
|
|
7527
7554
|
console.log(`${chalk55.dim("Jira:")} ${item.jiraKey}`);
|
|
7528
7555
|
}
|
|
7556
|
+
if (item.githubIssue) {
|
|
7557
|
+
console.log(
|
|
7558
|
+
`${chalk55.dim("GitHub:")} ${shortenGithubIssue(item.githubIssue, item.origin)}`
|
|
7559
|
+
);
|
|
7560
|
+
}
|
|
7529
7561
|
console.log();
|
|
7530
7562
|
}
|
|
7531
7563
|
function printAcceptanceCriteria(criteria) {
|
|
@@ -7843,29 +7875,29 @@ function createFallbackHandler(routes3, htmlHandler2, extra) {
|
|
|
7843
7875
|
import { asc as asc5, eq as eq12 } from "drizzle-orm";
|
|
7844
7876
|
|
|
7845
7877
|
// src/commands/backlog/incompleteSubtaskCounts.ts
|
|
7846
|
-
import { ne, sql as
|
|
7878
|
+
import { ne, sql as sql13 } from "drizzle-orm";
|
|
7847
7879
|
function incompleteSubtaskCounts(orm) {
|
|
7848
7880
|
return orm.select({
|
|
7849
7881
|
itemId: itemSubtasks.itemId,
|
|
7850
|
-
count:
|
|
7882
|
+
count: sql13`count(*)::int`.as("incomplete_subtasks")
|
|
7851
7883
|
}).from(itemSubtasks).where(ne(itemSubtasks.status, "done")).groupBy(itemSubtasks.itemId).as("incomplete_counts");
|
|
7852
7884
|
}
|
|
7853
7885
|
|
|
7854
7886
|
// src/commands/backlog/phaseUsageTotals.ts
|
|
7855
|
-
import { sql as
|
|
7887
|
+
import { sql as sql14 } from "drizzle-orm";
|
|
7856
7888
|
function phaseUsageTotals(orm) {
|
|
7857
7889
|
return orm.select({
|
|
7858
7890
|
itemId: phaseUsage.itemId,
|
|
7859
|
-
tokensUp:
|
|
7891
|
+
tokensUp: sql14`sum(${phaseUsage.tokensUp})::bigint`.as(
|
|
7860
7892
|
"total_tokens_up"
|
|
7861
7893
|
),
|
|
7862
|
-
tokensDown:
|
|
7894
|
+
tokensDown: sql14`sum(${phaseUsage.tokensDown})::bigint`.as(
|
|
7863
7895
|
"total_tokens_down"
|
|
7864
7896
|
),
|
|
7865
|
-
activeMs:
|
|
7897
|
+
activeMs: sql14`sum(${phaseUsage.activeMs})::bigint`.as(
|
|
7866
7898
|
"total_active_ms"
|
|
7867
7899
|
),
|
|
7868
|
-
peakContextPct:
|
|
7900
|
+
peakContextPct: sql14`max(${phaseUsage.peakContextPct})`.as(
|
|
7869
7901
|
"max_peak_context_pct"
|
|
7870
7902
|
)
|
|
7871
7903
|
}).from(phaseUsage).groupBy(phaseUsage.itemId).as("usage_totals");
|
|
@@ -7881,6 +7913,7 @@ function rowToItemSummary(row) {
|
|
|
7881
7913
|
status: row.status,
|
|
7882
7914
|
starred: row.starred,
|
|
7883
7915
|
jiraKey: row.jiraKey ?? void 0,
|
|
7916
|
+
githubIssue: row.githubIssue ?? void 0,
|
|
7884
7917
|
incompleteSubtasks: row.incompleteSubtasks ?? 0,
|
|
7885
7918
|
usageTotal: row.tokensUp == null ? void 0 : {
|
|
7886
7919
|
tokensUp: Number(row.tokensUp),
|
|
@@ -7903,6 +7936,7 @@ async function loadItemSummaries(orm, origin) {
|
|
|
7903
7936
|
status: items.status,
|
|
7904
7937
|
starred: items.starred,
|
|
7905
7938
|
jiraKey: items.jiraKey,
|
|
7939
|
+
githubIssue: items.githubIssue,
|
|
7906
7940
|
incompleteSubtasks: incompleteCounts.count,
|
|
7907
7941
|
tokensUp: usageTotals.tokensUp,
|
|
7908
7942
|
tokensDown: usageTotals.tokensDown,
|
|
@@ -8674,12 +8708,12 @@ async function listNewsItems(_req, res) {
|
|
|
8674
8708
|
}
|
|
8675
8709
|
|
|
8676
8710
|
// src/shared/db/listUsagePeaks.ts
|
|
8677
|
-
import { and as and7, count, desc as desc2, eq as eq16, getTableColumns, sql as
|
|
8711
|
+
import { and as and7, count, desc as desc2, eq as eq16, getTableColumns, sql as sql15 } from "drizzle-orm";
|
|
8678
8712
|
async function listUsagePeaks(db, paging) {
|
|
8679
8713
|
const avgContext = db.select({
|
|
8680
8714
|
window: phaseCycleContext.window,
|
|
8681
8715
|
resetsAt: phaseCycleContext.resetsAt,
|
|
8682
|
-
avgContextPct:
|
|
8716
|
+
avgContextPct: sql15`cast(avg(${phaseCycleContext.peakContextPct}) as double precision)`.as(
|
|
8683
8717
|
"avg_context_pct"
|
|
8684
8718
|
),
|
|
8685
8719
|
phaseCount: count().as("phase_count")
|
|
@@ -9447,17 +9481,113 @@ function registerActivityCommands(cmd) {
|
|
|
9447
9481
|
).option("--title <title>", "Title metadata for the ref").option("--url <url>", "URL metadata (auto-filled for branch/commit)").option("--state <state>", "State metadata for the ref").action(addActivity);
|
|
9448
9482
|
}
|
|
9449
9483
|
|
|
9450
|
-
// src/commands/backlog/associate-
|
|
9484
|
+
// src/commands/backlog/associate-github/index.ts
|
|
9451
9485
|
import chalk63 from "chalk";
|
|
9486
|
+
import { eq as eq18 } from "drizzle-orm";
|
|
9487
|
+
|
|
9488
|
+
// src/commands/backlog/beginAssociation.ts
|
|
9489
|
+
import chalk62 from "chalk";
|
|
9452
9490
|
import { eq as eq17 } from "drizzle-orm";
|
|
9491
|
+
async function beginAssociation(id, options2, clearPatch, label2) {
|
|
9492
|
+
const found = await findOneItem(id);
|
|
9493
|
+
if (!found) {
|
|
9494
|
+
process.exitCode = 1;
|
|
9495
|
+
return null;
|
|
9496
|
+
}
|
|
9497
|
+
const { orm } = found;
|
|
9498
|
+
const itemId2 = found.item.id;
|
|
9499
|
+
if (options2.clear) {
|
|
9500
|
+
await orm.update(items).set(clearPatch).where(eq17(items.id, itemId2));
|
|
9501
|
+
console.log(
|
|
9502
|
+
chalk62.green(
|
|
9503
|
+
`Cleared ${label2} association on item ${formatItemId(itemId2)}.`
|
|
9504
|
+
)
|
|
9505
|
+
);
|
|
9506
|
+
return null;
|
|
9507
|
+
}
|
|
9508
|
+
return { orm, itemId: itemId2 };
|
|
9509
|
+
}
|
|
9453
9510
|
|
|
9454
|
-
// src/commands/
|
|
9511
|
+
// src/commands/backlog/associate-github/fetchGithubIssueTitle.ts
|
|
9455
9512
|
import { execSync as execSync30 } from "child_process";
|
|
9456
|
-
|
|
9513
|
+
function fetchGithubIssueTitle(issue) {
|
|
9514
|
+
const match = /^([^/]+)\/([^#]+)#(\d+)$/.exec(issue);
|
|
9515
|
+
if (!match) return void 0;
|
|
9516
|
+
const [, owner, repo, number] = match;
|
|
9517
|
+
try {
|
|
9518
|
+
const result = execSync30(
|
|
9519
|
+
`gh issue view ${number} -R ${owner}/${repo} --json title`,
|
|
9520
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
9521
|
+
);
|
|
9522
|
+
const parsed = JSON.parse(result);
|
|
9523
|
+
return parsed.title;
|
|
9524
|
+
} catch {
|
|
9525
|
+
return void 0;
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9528
|
+
|
|
9529
|
+
// src/commands/backlog/associate-github/normalizeGithubIssue.ts
|
|
9530
|
+
var URL_PATTERN = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+)\/issues\/(\d+)\/?$/;
|
|
9531
|
+
var SHORTHAND_PATTERN = /^([^/\s]+)\/([^/\s#]+)#(\d+)$/;
|
|
9532
|
+
function normalizeGithubIssue(input) {
|
|
9533
|
+
const trimmed = input.trim();
|
|
9534
|
+
const match = URL_PATTERN.exec(trimmed) ?? SHORTHAND_PATTERN.exec(trimmed);
|
|
9535
|
+
if (!match) return null;
|
|
9536
|
+
const [, owner, repo, number] = match;
|
|
9537
|
+
return `${owner}/${repo}#${number}`;
|
|
9538
|
+
}
|
|
9539
|
+
|
|
9540
|
+
// src/commands/backlog/associate-github/index.ts
|
|
9541
|
+
async function associateGithub(id, issue, options2) {
|
|
9542
|
+
const target = await beginAssociation(
|
|
9543
|
+
id,
|
|
9544
|
+
options2,
|
|
9545
|
+
{ githubIssue: null },
|
|
9546
|
+
"GitHub"
|
|
9547
|
+
);
|
|
9548
|
+
if (!target) return;
|
|
9549
|
+
const { orm, itemId: itemId2 } = target;
|
|
9550
|
+
if (!issue) {
|
|
9551
|
+
console.log(
|
|
9552
|
+
chalk63.red("Provide a GitHub issue, or use --clear to remove one.")
|
|
9553
|
+
);
|
|
9554
|
+
process.exitCode = 1;
|
|
9555
|
+
return;
|
|
9556
|
+
}
|
|
9557
|
+
const normalized = normalizeGithubIssue(issue);
|
|
9558
|
+
if (!normalized) {
|
|
9559
|
+
console.log(
|
|
9560
|
+
chalk63.red(
|
|
9561
|
+
`Malformed GitHub issue "${issue}". Expected owner/repo#number or a github.com issue URL.`
|
|
9562
|
+
)
|
|
9563
|
+
);
|
|
9564
|
+
process.exitCode = 1;
|
|
9565
|
+
return;
|
|
9566
|
+
}
|
|
9567
|
+
const title = fetchGithubIssueTitle(normalized);
|
|
9568
|
+
await orm.update(items).set({ githubIssue: normalized, jiraKey: null }).where(eq18(items.id, itemId2));
|
|
9569
|
+
console.log(
|
|
9570
|
+
chalk63.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
9571
|
+
title ? chalk63.dim(`(${title})`) : ""
|
|
9572
|
+
);
|
|
9573
|
+
}
|
|
9574
|
+
|
|
9575
|
+
// src/commands/backlog/registerAssociateGithubCommand.ts
|
|
9576
|
+
function registerAssociateGithubCommand(cmd) {
|
|
9577
|
+
cmd.command("associate-github <id> [issue]").description("Associate a GitHub issue with a backlog item").option("--clear", "Remove the GitHub association from the item").action(associateGithub);
|
|
9578
|
+
}
|
|
9579
|
+
|
|
9580
|
+
// src/commands/backlog/associate-jira/index.ts
|
|
9581
|
+
import chalk65 from "chalk";
|
|
9582
|
+
import { eq as eq19 } from "drizzle-orm";
|
|
9583
|
+
|
|
9584
|
+
// src/commands/jira/fetchIssue.ts
|
|
9585
|
+
import { execSync as execSync31 } from "child_process";
|
|
9586
|
+
import chalk64 from "chalk";
|
|
9457
9587
|
function fetchIssue(issueKey, fields) {
|
|
9458
9588
|
let result;
|
|
9459
9589
|
try {
|
|
9460
|
-
result =
|
|
9590
|
+
result = execSync31(
|
|
9461
9591
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
9462
9592
|
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
9463
9593
|
);
|
|
@@ -9466,56 +9596,58 @@ function fetchIssue(issueKey, fields) {
|
|
|
9466
9596
|
const stderr = error.stderr;
|
|
9467
9597
|
if (stderr.includes("unauthorized")) {
|
|
9468
9598
|
console.error(
|
|
9469
|
-
|
|
9599
|
+
chalk64.red("Jira authentication expired."),
|
|
9470
9600
|
"Run",
|
|
9471
|
-
|
|
9601
|
+
chalk64.cyan("assist jira auth"),
|
|
9472
9602
|
"to re-authenticate."
|
|
9473
9603
|
);
|
|
9474
9604
|
process.exit(1);
|
|
9475
9605
|
}
|
|
9476
9606
|
}
|
|
9477
|
-
console.error(
|
|
9607
|
+
console.error(chalk64.red(`Failed to fetch ${issueKey}.`));
|
|
9478
9608
|
process.exit(1);
|
|
9479
9609
|
}
|
|
9480
9610
|
return JSON.parse(result);
|
|
9481
9611
|
}
|
|
9482
9612
|
|
|
9613
|
+
// src/commands/backlog/associate-jira/normalizeJiraKey.ts
|
|
9614
|
+
var KEY_PATTERN = /^[A-Z]+-\d+$/;
|
|
9615
|
+
var URL_PATTERN2 = /^https?:\/\/[^/\s]+\/browse\/([A-Za-z]+-\d+)(?:[/?#].*)?$/;
|
|
9616
|
+
function normalizeJiraKey(input) {
|
|
9617
|
+
const trimmed = input.trim();
|
|
9618
|
+
if (KEY_PATTERN.test(trimmed)) return trimmed;
|
|
9619
|
+
const match = URL_PATTERN2.exec(trimmed);
|
|
9620
|
+
if (match) return match[1].toUpperCase();
|
|
9621
|
+
return null;
|
|
9622
|
+
}
|
|
9623
|
+
|
|
9483
9624
|
// src/commands/backlog/associate-jira/index.ts
|
|
9484
|
-
var JIRA_KEY_PATTERN = /^[A-Z]+-\d+$/;
|
|
9485
9625
|
async function associateJira(id, key, options2) {
|
|
9486
|
-
const
|
|
9487
|
-
if (!
|
|
9488
|
-
|
|
9489
|
-
return;
|
|
9490
|
-
}
|
|
9491
|
-
const { orm } = found;
|
|
9492
|
-
const itemId2 = found.item.id;
|
|
9493
|
-
if (options2.clear) {
|
|
9494
|
-
await orm.update(items).set({ jiraKey: null }).where(eq17(items.id, itemId2));
|
|
9495
|
-
console.log(
|
|
9496
|
-
chalk63.green(`Cleared Jira association on item ${formatItemId(itemId2)}.`)
|
|
9497
|
-
);
|
|
9498
|
-
return;
|
|
9499
|
-
}
|
|
9626
|
+
const target = await beginAssociation(id, options2, { jiraKey: null }, "Jira");
|
|
9627
|
+
if (!target) return;
|
|
9628
|
+
const { orm, itemId: itemId2 } = target;
|
|
9500
9629
|
if (!key) {
|
|
9501
|
-
console.log(
|
|
9630
|
+
console.log(chalk65.red("Provide a Jira key, or use --clear to remove one."));
|
|
9502
9631
|
process.exitCode = 1;
|
|
9503
9632
|
return;
|
|
9504
9633
|
}
|
|
9505
|
-
|
|
9634
|
+
const normalized = normalizeJiraKey(key);
|
|
9635
|
+
if (!normalized) {
|
|
9506
9636
|
console.log(
|
|
9507
|
-
|
|
9637
|
+
chalk65.red(
|
|
9638
|
+
`Malformed Jira key "${key}". Expected a key like PROJ-123 or a browse URL.`
|
|
9639
|
+
)
|
|
9508
9640
|
);
|
|
9509
9641
|
process.exitCode = 1;
|
|
9510
9642
|
return;
|
|
9511
9643
|
}
|
|
9512
|
-
const parsed = fetchIssue(
|
|
9644
|
+
const parsed = fetchIssue(normalized, "summary");
|
|
9513
9645
|
const fields = parsed?.fields;
|
|
9514
9646
|
const summary = fields?.summary;
|
|
9515
|
-
await orm.update(items).set({ jiraKey:
|
|
9647
|
+
await orm.update(items).set({ jiraKey: normalized, githubIssue: null }).where(eq19(items.id, itemId2));
|
|
9516
9648
|
console.log(
|
|
9517
|
-
|
|
9518
|
-
summary ?
|
|
9649
|
+
chalk65.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
9650
|
+
summary ? chalk65.dim(`(${summary})`) : ""
|
|
9519
9651
|
);
|
|
9520
9652
|
}
|
|
9521
9653
|
|
|
@@ -9525,29 +9657,29 @@ function registerAssociateJiraCommand(cmd) {
|
|
|
9525
9657
|
}
|
|
9526
9658
|
|
|
9527
9659
|
// src/commands/backlog/comment/index.ts
|
|
9528
|
-
import
|
|
9660
|
+
import chalk66 from "chalk";
|
|
9529
9661
|
async function comment(id, text17) {
|
|
9530
9662
|
const found = await findOneItem(id);
|
|
9531
9663
|
if (!found) process.exit(1);
|
|
9532
9664
|
await appendComment(found.orm, found.item.id, text17);
|
|
9533
9665
|
console.log(
|
|
9534
|
-
|
|
9666
|
+
chalk66.green(`Comment added to item ${formatItemId(found.item.id)}.`)
|
|
9535
9667
|
);
|
|
9536
9668
|
}
|
|
9537
9669
|
|
|
9538
9670
|
// src/commands/backlog/comments/index.ts
|
|
9539
|
-
import
|
|
9671
|
+
import chalk67 from "chalk";
|
|
9540
9672
|
async function comments2(id) {
|
|
9541
9673
|
const found = await findOneItem(id);
|
|
9542
9674
|
if (!found) process.exit(1);
|
|
9543
9675
|
const { item } = found;
|
|
9544
9676
|
const entries = item.comments ?? [];
|
|
9545
9677
|
if (entries.length === 0) {
|
|
9546
|
-
console.log(
|
|
9678
|
+
console.log(chalk67.dim(`No comments on item ${formatItemId(item.id)}.`));
|
|
9547
9679
|
return;
|
|
9548
9680
|
}
|
|
9549
9681
|
console.log(
|
|
9550
|
-
|
|
9682
|
+
chalk67.bold(`Comments for ${formatItemId(item.id)}: ${item.name}
|
|
9551
9683
|
`)
|
|
9552
9684
|
);
|
|
9553
9685
|
for (const entry of entries) {
|
|
@@ -9557,7 +9689,7 @@ async function comments2(id) {
|
|
|
9557
9689
|
}
|
|
9558
9690
|
|
|
9559
9691
|
// src/commands/backlog/delete-comment/index.ts
|
|
9560
|
-
import
|
|
9692
|
+
import chalk68 from "chalk";
|
|
9561
9693
|
async function deleteCommentCmd(id, commentId) {
|
|
9562
9694
|
const found = await findOneItem(id);
|
|
9563
9695
|
if (!found) process.exit(1);
|
|
@@ -9570,14 +9702,14 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
9570
9702
|
switch (outcome) {
|
|
9571
9703
|
case "deleted":
|
|
9572
9704
|
console.log(
|
|
9573
|
-
|
|
9705
|
+
chalk68.green(
|
|
9574
9706
|
`Comment #${commentId} deleted from item ${formatItemId(itemId2)}.`
|
|
9575
9707
|
)
|
|
9576
9708
|
);
|
|
9577
9709
|
break;
|
|
9578
9710
|
case "not-found":
|
|
9579
9711
|
console.log(
|
|
9580
|
-
|
|
9712
|
+
chalk68.red(
|
|
9581
9713
|
`Comment #${commentId} not found on item ${formatItemId(itemId2)}.`
|
|
9582
9714
|
)
|
|
9583
9715
|
);
|
|
@@ -9585,7 +9717,7 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
9585
9717
|
break;
|
|
9586
9718
|
case "is-summary":
|
|
9587
9719
|
console.log(
|
|
9588
|
-
|
|
9720
|
+
chalk68.red(
|
|
9589
9721
|
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
9590
9722
|
)
|
|
9591
9723
|
);
|
|
@@ -9610,7 +9742,7 @@ function registerExportCommand(cmd) {
|
|
|
9610
9742
|
|
|
9611
9743
|
// src/commands/backlog/import/index.ts
|
|
9612
9744
|
import { readFile } from "fs/promises";
|
|
9613
|
-
import
|
|
9745
|
+
import chalk70 from "chalk";
|
|
9614
9746
|
|
|
9615
9747
|
// src/commands/backlog/dump/countCopyRows.ts
|
|
9616
9748
|
function countCopyRows(data) {
|
|
@@ -9682,7 +9814,7 @@ function validateDump({ header, sections }) {
|
|
|
9682
9814
|
}
|
|
9683
9815
|
|
|
9684
9816
|
// src/commands/backlog/import/confirmReplace.ts
|
|
9685
|
-
import
|
|
9817
|
+
import chalk69 from "chalk";
|
|
9686
9818
|
async function countRows(client, table) {
|
|
9687
9819
|
const { rows } = await client.query(
|
|
9688
9820
|
`SELECT count(*)::int AS n FROM ${table}`
|
|
@@ -9693,7 +9825,7 @@ function printSummary(tables, current, incoming) {
|
|
|
9693
9825
|
const lines = tables.map(
|
|
9694
9826
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
9695
9827
|
);
|
|
9696
|
-
console.error(
|
|
9828
|
+
console.error(chalk69.bold("\nThis will REPLACE all backlog data:"));
|
|
9697
9829
|
console.error(`${lines.join("\n")}
|
|
9698
9830
|
`);
|
|
9699
9831
|
}
|
|
@@ -9723,8 +9855,8 @@ async function readStdinBuffer() {
|
|
|
9723
9855
|
import { finished } from "stream/promises";
|
|
9724
9856
|
import { from as copyFrom } from "pg-copy-streams";
|
|
9725
9857
|
async function copyTableIn(client, table, data) {
|
|
9726
|
-
const
|
|
9727
|
-
const stream = client.query(copyFrom(
|
|
9858
|
+
const sql24 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
|
|
9859
|
+
const stream = client.query(copyFrom(sql24));
|
|
9728
9860
|
stream.end(data);
|
|
9729
9861
|
await finished(stream);
|
|
9730
9862
|
}
|
|
@@ -9795,13 +9927,13 @@ async function importBacklog(file, options2 = {}) {
|
|
|
9795
9927
|
);
|
|
9796
9928
|
await withDbClient(async (client) => {
|
|
9797
9929
|
if (!options2.yes && !await confirmReplace(client, tables, incoming, !file)) {
|
|
9798
|
-
console.error(
|
|
9930
|
+
console.error(chalk70.yellow("Import cancelled; no changes made."));
|
|
9799
9931
|
return;
|
|
9800
9932
|
}
|
|
9801
9933
|
await restore(client, parsed);
|
|
9802
9934
|
const total = incoming.reduce((sum, n) => sum + n, 0);
|
|
9803
9935
|
console.error(
|
|
9804
|
-
|
|
9936
|
+
chalk70.green(
|
|
9805
9937
|
`Imported backlog: ${total} rows restored across ${tables.length} tables.`
|
|
9806
9938
|
)
|
|
9807
9939
|
);
|
|
@@ -9818,18 +9950,18 @@ function registerImportCommand(cmd) {
|
|
|
9818
9950
|
}
|
|
9819
9951
|
|
|
9820
9952
|
// src/commands/backlog/add/index.ts
|
|
9821
|
-
import
|
|
9953
|
+
import chalk72 from "chalk";
|
|
9822
9954
|
|
|
9823
9955
|
// src/commands/backlog/insertPhaseAt.ts
|
|
9824
|
-
import { eq as
|
|
9956
|
+
import { eq as eq21 } from "drizzle-orm";
|
|
9825
9957
|
|
|
9826
9958
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
9827
|
-
import { and as and8, desc as desc3, eq as
|
|
9959
|
+
import { and as and8, desc as desc3, eq as eq20, gte } from "drizzle-orm";
|
|
9828
9960
|
async function shiftPhasesUp(db, itemId2, fromIdx) {
|
|
9829
|
-
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and8(
|
|
9961
|
+
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and8(eq20(planPhases.itemId, itemId2), gte(planPhases.idx, fromIdx))).orderBy(desc3(planPhases.idx));
|
|
9830
9962
|
for (const p of toShift) {
|
|
9831
|
-
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and8(
|
|
9832
|
-
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and8(
|
|
9963
|
+
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and8(eq20(planTasks.itemId, itemId2), eq20(planTasks.phaseIdx, p.idx)));
|
|
9964
|
+
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and8(eq20(planPhases.itemId, itemId2), eq20(planPhases.idx, p.idx)));
|
|
9833
9965
|
}
|
|
9834
9966
|
}
|
|
9835
9967
|
|
|
@@ -9842,17 +9974,17 @@ async function insertPhaseAt(orm, itemId2, phaseIdx, name, tasks, manualChecks,
|
|
|
9842
9974
|
await tx.insert(planTasks).values(tasks.map((task, i) => ({ itemId: itemId2, phaseIdx, idx: i, task })));
|
|
9843
9975
|
}
|
|
9844
9976
|
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
9845
|
-
await tx.update(items).set({ currentPhase: phaseIdx + 1 }).where(
|
|
9977
|
+
await tx.update(items).set({ currentPhase: phaseIdx + 1 }).where(eq21(items.id, itemId2));
|
|
9846
9978
|
}
|
|
9847
9979
|
});
|
|
9848
9980
|
}
|
|
9849
9981
|
|
|
9850
9982
|
// src/commands/backlog/insertSubtask.ts
|
|
9851
|
-
import { sql as
|
|
9983
|
+
import { sql as sql16 } from "drizzle-orm";
|
|
9852
9984
|
async function insertSubtask(orm, itemId2, title, description) {
|
|
9853
9985
|
await orm.insert(itemSubtasks).values({
|
|
9854
9986
|
itemId: itemId2,
|
|
9855
|
-
idx:
|
|
9987
|
+
idx: sql16`(SELECT COALESCE(MAX(${itemSubtasks.idx}) + 1, 0) FROM ${itemSubtasks} WHERE ${itemSubtasks.itemId} = ${itemId2})`,
|
|
9856
9988
|
title,
|
|
9857
9989
|
description: description ?? null,
|
|
9858
9990
|
status: "todo"
|
|
@@ -9860,11 +9992,11 @@ async function insertSubtask(orm, itemId2, title, description) {
|
|
|
9860
9992
|
}
|
|
9861
9993
|
|
|
9862
9994
|
// src/commands/backlog/ensureRemoteOrigin.ts
|
|
9863
|
-
import
|
|
9995
|
+
import chalk71 from "chalk";
|
|
9864
9996
|
function ensureRemoteOrigin() {
|
|
9865
9997
|
if (getRemoteOriginUrl(getBacklogDir())) return true;
|
|
9866
9998
|
console.log(
|
|
9867
|
-
|
|
9999
|
+
chalk71.red(
|
|
9868
10000
|
"Backlog requires a git remote so items get a stable origin.\nAdd one with: git remote add origin <url>"
|
|
9869
10001
|
)
|
|
9870
10002
|
);
|
|
@@ -9968,23 +10100,23 @@ async function add(options2) {
|
|
|
9968
10100
|
for (const subtask of loadConfig().subtasks ?? []) {
|
|
9969
10101
|
await insertSubtask(orm, id, subtask.title, subtask.description);
|
|
9970
10102
|
}
|
|
9971
|
-
console.log(
|
|
10103
|
+
console.log(chalk72.green(`Added item ${formatItemId(id)}: ${name}`));
|
|
9972
10104
|
}
|
|
9973
10105
|
|
|
9974
10106
|
// src/commands/backlog/addPhase.ts
|
|
9975
|
-
import
|
|
10107
|
+
import chalk74 from "chalk";
|
|
9976
10108
|
|
|
9977
10109
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
9978
|
-
import
|
|
9979
|
-
import { count as count2, eq as
|
|
10110
|
+
import chalk73 from "chalk";
|
|
10111
|
+
import { count as count2, eq as eq22 } from "drizzle-orm";
|
|
9980
10112
|
async function resolveInsertPosition(orm, itemId2, position) {
|
|
9981
|
-
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(
|
|
10113
|
+
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq22(planPhases.itemId, itemId2));
|
|
9982
10114
|
const phaseCount = row?.cnt ?? 0;
|
|
9983
10115
|
if (position === void 0) return phaseCount;
|
|
9984
10116
|
const pos = Number.parseInt(position, 10);
|
|
9985
10117
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
9986
10118
|
console.log(
|
|
9987
|
-
|
|
10119
|
+
chalk73.red(
|
|
9988
10120
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
9989
10121
|
)
|
|
9990
10122
|
);
|
|
@@ -10006,7 +10138,7 @@ async function addPhase(id, name, options2) {
|
|
|
10006
10138
|
if (!found) return;
|
|
10007
10139
|
const tasks = options2.task ?? [];
|
|
10008
10140
|
if (tasks.length === 0) {
|
|
10009
|
-
console.log(
|
|
10141
|
+
console.log(chalk74.red("At least one --task is required."));
|
|
10010
10142
|
process.exitCode = 1;
|
|
10011
10143
|
return;
|
|
10012
10144
|
}
|
|
@@ -10025,14 +10157,14 @@ async function addPhase(id, name, options2) {
|
|
|
10025
10157
|
);
|
|
10026
10158
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
10027
10159
|
console.log(
|
|
10028
|
-
|
|
10160
|
+
chalk74.green(
|
|
10029
10161
|
`${verb} phase ${phaseIdx + 1} "${name}" to item ${formatItemId(itemId2)} with ${tasks.length} task(s).`
|
|
10030
10162
|
)
|
|
10031
10163
|
);
|
|
10032
10164
|
}
|
|
10033
10165
|
|
|
10034
10166
|
// src/commands/backlog/list/index.ts
|
|
10035
|
-
import
|
|
10167
|
+
import chalk75 from "chalk";
|
|
10036
10168
|
function filterItems(items2, options2) {
|
|
10037
10169
|
if (options2.status) return items2.filter((i) => i.status === options2.status);
|
|
10038
10170
|
if (!options2.all)
|
|
@@ -10046,19 +10178,19 @@ function repoPrefixer(items2, allRepos) {
|
|
|
10046
10178
|
);
|
|
10047
10179
|
const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
|
|
10048
10180
|
const width = Math.max(0, ...items2.map((i) => repoNameOf(i).length));
|
|
10049
|
-
return (item) => `${
|
|
10181
|
+
return (item) => `${chalk75.dim(repoNameOf(item).padEnd(width))} `;
|
|
10050
10182
|
}
|
|
10051
10183
|
async function list2(options2) {
|
|
10052
10184
|
const allItems = await loadBacklog(options2.allRepos);
|
|
10053
10185
|
const items2 = filterItems(allItems, options2);
|
|
10054
10186
|
if (items2.length === 0) {
|
|
10055
|
-
console.log(
|
|
10187
|
+
console.log(chalk75.dim("Backlog is empty."));
|
|
10056
10188
|
return;
|
|
10057
10189
|
}
|
|
10058
10190
|
const prefixOf = repoPrefixer(items2, !!options2.allRepos);
|
|
10059
10191
|
for (const item of items2) {
|
|
10060
10192
|
console.log(
|
|
10061
|
-
`${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
10193
|
+
`${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk75.dim(formatItemId(item.id))} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
10062
10194
|
);
|
|
10063
10195
|
if (options2.verbose) {
|
|
10064
10196
|
printVerboseDetails(item);
|
|
@@ -10086,7 +10218,7 @@ function registerItemCommands(cmd) {
|
|
|
10086
10218
|
}
|
|
10087
10219
|
|
|
10088
10220
|
// src/commands/backlog/link.ts
|
|
10089
|
-
import
|
|
10221
|
+
import chalk77 from "chalk";
|
|
10090
10222
|
|
|
10091
10223
|
// src/commands/backlog/hasCycle.ts
|
|
10092
10224
|
function hasCycle(adjacency, fromId, toId) {
|
|
@@ -10105,9 +10237,9 @@ function hasCycle(adjacency, fromId, toId) {
|
|
|
10105
10237
|
}
|
|
10106
10238
|
|
|
10107
10239
|
// src/commands/backlog/loadDependencyGraph.ts
|
|
10108
|
-
import { eq as
|
|
10240
|
+
import { eq as eq23 } from "drizzle-orm";
|
|
10109
10241
|
async function loadDependencyGraph(orm) {
|
|
10110
|
-
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(
|
|
10242
|
+
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq23(links.type, "depends-on"));
|
|
10111
10243
|
const graph = /* @__PURE__ */ new Map();
|
|
10112
10244
|
for (const { itemId: itemId2, targetId } of rows) {
|
|
10113
10245
|
const bucket = graph.get(itemId2);
|
|
@@ -10118,14 +10250,14 @@ async function loadDependencyGraph(orm) {
|
|
|
10118
10250
|
}
|
|
10119
10251
|
|
|
10120
10252
|
// src/commands/backlog/validateLinkTarget.ts
|
|
10121
|
-
import
|
|
10253
|
+
import chalk76 from "chalk";
|
|
10122
10254
|
function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
10123
10255
|
const duplicate = (fromItem.links ?? []).some(
|
|
10124
10256
|
(l) => l.targetId === toNum && l.type === linkType
|
|
10125
10257
|
);
|
|
10126
10258
|
if (duplicate) {
|
|
10127
10259
|
console.log(
|
|
10128
|
-
|
|
10260
|
+
chalk76.yellow(
|
|
10129
10261
|
`Link already exists: ${formatItemId(fromNum)} ${linkType} ${formatItemId(toNum)}`
|
|
10130
10262
|
)
|
|
10131
10263
|
);
|
|
@@ -10136,7 +10268,7 @@ function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
|
10136
10268
|
|
|
10137
10269
|
// src/commands/backlog/link.ts
|
|
10138
10270
|
function fail2(message) {
|
|
10139
|
-
console.log(
|
|
10271
|
+
console.log(chalk77.red(message));
|
|
10140
10272
|
return void 0;
|
|
10141
10273
|
}
|
|
10142
10274
|
function parseLinkType(type) {
|
|
@@ -10169,38 +10301,38 @@ async function link(fromId, toId, opts) {
|
|
|
10169
10301
|
if (!validateLinkTarget(fromItem, fromNum, toNum, linkType)) return;
|
|
10170
10302
|
if (await createsCycle(orm, linkType, fromNum, toNum)) return;
|
|
10171
10303
|
await orm.insert(links).values({ itemId: fromNum, type: linkType, targetId: toNum });
|
|
10172
|
-
console.log(
|
|
10304
|
+
console.log(chalk77.green(`Linked ${from} ${linkType} ${to} (${toItem.name})`));
|
|
10173
10305
|
}
|
|
10174
10306
|
|
|
10175
10307
|
// src/commands/backlog/unlink.ts
|
|
10176
|
-
import
|
|
10177
|
-
import { and as and9, eq as
|
|
10308
|
+
import chalk78 from "chalk";
|
|
10309
|
+
import { and as and9, eq as eq24 } from "drizzle-orm";
|
|
10178
10310
|
async function unlink(fromId, toId) {
|
|
10179
10311
|
const fromNum = parseItemId(fromId);
|
|
10180
10312
|
const toNum = parseItemId(toId);
|
|
10181
10313
|
const { orm } = await getReady();
|
|
10182
10314
|
const fromItem = await loadItem(orm, fromNum);
|
|
10183
10315
|
if (!fromItem) {
|
|
10184
|
-
console.log(
|
|
10316
|
+
console.log(chalk78.red(`Item ${formatItemId(fromNum)} not found.`));
|
|
10185
10317
|
return;
|
|
10186
10318
|
}
|
|
10187
10319
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
10188
10320
|
console.log(
|
|
10189
|
-
|
|
10321
|
+
chalk78.yellow(`No links found on item ${formatItemId(fromNum)}.`)
|
|
10190
10322
|
);
|
|
10191
10323
|
return;
|
|
10192
10324
|
}
|
|
10193
10325
|
if (!fromItem.links.some((l) => l.targetId === toNum)) {
|
|
10194
10326
|
console.log(
|
|
10195
|
-
|
|
10327
|
+
chalk78.yellow(
|
|
10196
10328
|
`No link from ${formatItemId(fromNum)} to ${formatItemId(toNum)} found.`
|
|
10197
10329
|
)
|
|
10198
10330
|
);
|
|
10199
10331
|
return;
|
|
10200
10332
|
}
|
|
10201
|
-
await orm.delete(links).where(and9(
|
|
10333
|
+
await orm.delete(links).where(and9(eq24(links.itemId, fromNum), eq24(links.targetId, toNum)));
|
|
10202
10334
|
console.log(
|
|
10203
|
-
|
|
10335
|
+
chalk78.green(
|
|
10204
10336
|
`Removed link from ${formatItemId(fromNum)} to ${formatItemId(toNum)}.`
|
|
10205
10337
|
)
|
|
10206
10338
|
);
|
|
@@ -10217,25 +10349,25 @@ function registerLinkCommands(cmd) {
|
|
|
10217
10349
|
}
|
|
10218
10350
|
|
|
10219
10351
|
// src/commands/backlog/move-repo/index.ts
|
|
10220
|
-
import
|
|
10221
|
-
import { eq as
|
|
10352
|
+
import chalk80 from "chalk";
|
|
10353
|
+
import { eq as eq26 } from "drizzle-orm";
|
|
10222
10354
|
|
|
10223
10355
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
10224
|
-
import
|
|
10356
|
+
import chalk79 from "chalk";
|
|
10225
10357
|
function pluralItems(n) {
|
|
10226
10358
|
return `${n} item${n === 1 ? "" : "s"}`;
|
|
10227
10359
|
}
|
|
10228
10360
|
async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
10229
10361
|
console.log(
|
|
10230
|
-
`${pluralItems(cnt)}: ${
|
|
10362
|
+
`${pluralItems(cnt)}: ${chalk79.cyan(oldOrigin)} \u2192 ${chalk79.cyan(newOrigin)}`
|
|
10231
10363
|
);
|
|
10232
10364
|
return promptConfirm(`Retag ${pluralItems(cnt)}?`);
|
|
10233
10365
|
}
|
|
10234
10366
|
|
|
10235
10367
|
// src/commands/backlog/move-repo/countByOrigin.ts
|
|
10236
|
-
import { count as count3, eq as
|
|
10368
|
+
import { count as count3, eq as eq25 } from "drizzle-orm";
|
|
10237
10369
|
async function countByOrigin(orm, origin) {
|
|
10238
|
-
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(
|
|
10370
|
+
const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(eq25(items.origin, origin));
|
|
10239
10371
|
return cnt;
|
|
10240
10372
|
}
|
|
10241
10373
|
|
|
@@ -10259,7 +10391,7 @@ Pass the full origin.`
|
|
|
10259
10391
|
|
|
10260
10392
|
// src/commands/backlog/move-repo/index.ts
|
|
10261
10393
|
function fail3(message) {
|
|
10262
|
-
console.log(
|
|
10394
|
+
console.log(chalk80.red(message));
|
|
10263
10395
|
process.exitCode = 1;
|
|
10264
10396
|
}
|
|
10265
10397
|
async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
@@ -10275,12 +10407,12 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
10275
10407
|
}
|
|
10276
10408
|
const cnt = await countByOrigin(orm, oldOrigin);
|
|
10277
10409
|
if (!options2.yes && !await confirmMove(cnt, oldOrigin, newOrigin)) {
|
|
10278
|
-
console.log(
|
|
10410
|
+
console.log(chalk80.yellow("Move cancelled; no changes made."));
|
|
10279
10411
|
return;
|
|
10280
10412
|
}
|
|
10281
|
-
await orm.update(items).set({ origin: newOrigin }).where(
|
|
10413
|
+
await orm.update(items).set({ origin: newOrigin }).where(eq26(items.origin, oldOrigin));
|
|
10282
10414
|
console.log(
|
|
10283
|
-
|
|
10415
|
+
chalk80.green(
|
|
10284
10416
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
10285
10417
|
)
|
|
10286
10418
|
);
|
|
@@ -10309,7 +10441,7 @@ function registerPlanCommands(cmd) {
|
|
|
10309
10441
|
}
|
|
10310
10442
|
|
|
10311
10443
|
// src/commands/backlog/refine.ts
|
|
10312
|
-
import
|
|
10444
|
+
import chalk83 from "chalk";
|
|
10313
10445
|
import enquirer7 from "enquirer";
|
|
10314
10446
|
|
|
10315
10447
|
// src/commands/backlog/launchMode.ts
|
|
@@ -10343,7 +10475,7 @@ function spawnHarness(harness, prompt, options2 = {}) {
|
|
|
10343
10475
|
}
|
|
10344
10476
|
|
|
10345
10477
|
// src/commands/backlog/handleLaunchSignal.ts
|
|
10346
|
-
import
|
|
10478
|
+
import chalk82 from "chalk";
|
|
10347
10479
|
|
|
10348
10480
|
// src/commands/backlog/surfaceCreatedItem.ts
|
|
10349
10481
|
async function surfaceCreatedItem(slashCommand, id) {
|
|
@@ -10366,32 +10498,32 @@ async function surfaceCreatedItem(slashCommand, id) {
|
|
|
10366
10498
|
}
|
|
10367
10499
|
|
|
10368
10500
|
// src/commands/backlog/tryRunById.ts
|
|
10369
|
-
import
|
|
10501
|
+
import chalk81 from "chalk";
|
|
10370
10502
|
async function tryRunById(id, options2) {
|
|
10371
10503
|
const numericId = parseItemId(id);
|
|
10372
10504
|
const label2 = formatItemId(numericId);
|
|
10373
10505
|
const { orm } = await getReady();
|
|
10374
10506
|
const item = await loadItem(orm, numericId);
|
|
10375
10507
|
if (!item) {
|
|
10376
|
-
console.log(
|
|
10508
|
+
console.log(chalk81.red(`Item ${label2} not found.`));
|
|
10377
10509
|
return false;
|
|
10378
10510
|
}
|
|
10379
10511
|
if (item.status === "done") {
|
|
10380
|
-
console.log(
|
|
10512
|
+
console.log(chalk81.red(`Item ${label2} is already done.`));
|
|
10381
10513
|
return false;
|
|
10382
10514
|
}
|
|
10383
10515
|
if (item.status === "wontdo") {
|
|
10384
|
-
console.log(
|
|
10516
|
+
console.log(chalk81.red(`Item ${label2} is marked won't do.`));
|
|
10385
10517
|
return false;
|
|
10386
10518
|
}
|
|
10387
10519
|
const hasDeps = (item.links ?? []).some((l) => l.type === "depends-on");
|
|
10388
10520
|
if (hasDeps && isBlocked(item, await loadItemSummaries(orm, getOrigin()))) {
|
|
10389
10521
|
console.log(
|
|
10390
|
-
|
|
10522
|
+
chalk81.red(`Item ${label2} is blocked by unresolved dependencies.`)
|
|
10391
10523
|
);
|
|
10392
10524
|
return false;
|
|
10393
10525
|
}
|
|
10394
|
-
console.log(
|
|
10526
|
+
console.log(chalk81.bold(`
|
|
10395
10527
|
Running backlog item ${label2}...
|
|
10396
10528
|
`));
|
|
10397
10529
|
await run2(id, options2);
|
|
@@ -10410,13 +10542,13 @@ async function handleLaunchSignal(slashCommand, once) {
|
|
|
10410
10542
|
if (typeof signal.id === "string" && signal.id) {
|
|
10411
10543
|
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
10412
10544
|
}
|
|
10413
|
-
console.log(
|
|
10545
|
+
console.log(chalk82.bold("\nChaining into assist next...\n"));
|
|
10414
10546
|
await next({ allowEdits: true, once });
|
|
10415
10547
|
}
|
|
10416
10548
|
} catch (error) {
|
|
10417
10549
|
const message = error instanceof Error ? error.message : String(error);
|
|
10418
10550
|
console.error(
|
|
10419
|
-
|
|
10551
|
+
chalk82.yellow(
|
|
10420
10552
|
`
|
|
10421
10553
|
Could not complete post-run step (${message}).
|
|
10422
10554
|
This is usually a transient database/network blip \u2014 the work is saved and the session is safe to resume.`
|
|
@@ -10463,13 +10595,13 @@ async function pickItemForRefine() {
|
|
|
10463
10595
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
10464
10596
|
);
|
|
10465
10597
|
if (active.length === 0) {
|
|
10466
|
-
console.log(
|
|
10598
|
+
console.log(chalk83.yellow("No active backlog items to refine."));
|
|
10467
10599
|
return void 0;
|
|
10468
10600
|
}
|
|
10469
10601
|
if (active.length === 1) {
|
|
10470
10602
|
const item = active[0];
|
|
10471
10603
|
console.log(
|
|
10472
|
-
|
|
10604
|
+
chalk83.bold(`Auto-selecting item ${formatItemId(item.id)}: ${item.name}`)
|
|
10473
10605
|
);
|
|
10474
10606
|
return formatItemId(item.id);
|
|
10475
10607
|
}
|
|
@@ -10517,7 +10649,7 @@ function registerRefineCommand(cmd) {
|
|
|
10517
10649
|
}
|
|
10518
10650
|
|
|
10519
10651
|
// src/commands/backlog/rewindPhase.ts
|
|
10520
|
-
import
|
|
10652
|
+
import chalk84 from "chalk";
|
|
10521
10653
|
async function rewindPhase(id, phase, opts) {
|
|
10522
10654
|
const phaseNumber = Number.parseInt(phase, 10);
|
|
10523
10655
|
const found = await findOneItem(id);
|
|
@@ -10525,12 +10657,12 @@ async function rewindPhase(id, phase, opts) {
|
|
|
10525
10657
|
const { orm, item } = found;
|
|
10526
10658
|
const result = await rewindItemToPhase(orm, item, phaseNumber, opts.reason);
|
|
10527
10659
|
if (!result.ok) {
|
|
10528
|
-
console.log(
|
|
10660
|
+
console.log(chalk84.red(result.error));
|
|
10529
10661
|
process.exitCode = 1;
|
|
10530
10662
|
return;
|
|
10531
10663
|
}
|
|
10532
10664
|
console.log(
|
|
10533
|
-
|
|
10665
|
+
chalk84.green(
|
|
10534
10666
|
`Rewound item ${formatItemId(item.id)} to phase ${phaseNumber} (${result.phaseName}).`
|
|
10535
10667
|
)
|
|
10536
10668
|
);
|
|
@@ -10558,22 +10690,22 @@ function registerRunCommand(cmd) {
|
|
|
10558
10690
|
}
|
|
10559
10691
|
|
|
10560
10692
|
// src/commands/backlog/search/index.ts
|
|
10561
|
-
import
|
|
10693
|
+
import chalk85 from "chalk";
|
|
10562
10694
|
async function search(query) {
|
|
10563
10695
|
const items2 = await searchBacklog(query);
|
|
10564
10696
|
if (items2.length === 0) {
|
|
10565
|
-
console.log(
|
|
10697
|
+
console.log(chalk85.dim(`No items matching "${query}".`));
|
|
10566
10698
|
return;
|
|
10567
10699
|
}
|
|
10568
10700
|
console.log(
|
|
10569
|
-
|
|
10701
|
+
chalk85.dim(
|
|
10570
10702
|
`${items2.length} item${items2.length === 1 ? "" : "s"} matching "${query}":
|
|
10571
10703
|
`
|
|
10572
10704
|
)
|
|
10573
10705
|
);
|
|
10574
10706
|
for (const item of items2) {
|
|
10575
10707
|
console.log(
|
|
10576
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
10708
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk85.dim(formatItemId(item.id))} ${item.name}`
|
|
10577
10709
|
);
|
|
10578
10710
|
}
|
|
10579
10711
|
}
|
|
@@ -10584,18 +10716,18 @@ function registerSearchCommand(cmd) {
|
|
|
10584
10716
|
}
|
|
10585
10717
|
|
|
10586
10718
|
// src/commands/backlog/delete/index.ts
|
|
10587
|
-
import
|
|
10719
|
+
import chalk86 from "chalk";
|
|
10588
10720
|
async function del(id) {
|
|
10589
10721
|
const name = await removeItem(id);
|
|
10590
10722
|
if (name) {
|
|
10591
10723
|
console.log(
|
|
10592
|
-
|
|
10724
|
+
chalk86.green(`Deleted item ${formatItemId(parseItemId(id))}: ${name}`)
|
|
10593
10725
|
);
|
|
10594
10726
|
}
|
|
10595
10727
|
}
|
|
10596
10728
|
|
|
10597
10729
|
// src/commands/backlog/done/index.ts
|
|
10598
|
-
import
|
|
10730
|
+
import chalk87 from "chalk";
|
|
10599
10731
|
async function done(id, summary) {
|
|
10600
10732
|
const found = await findOneItem(id);
|
|
10601
10733
|
if (!found) return;
|
|
@@ -10609,12 +10741,12 @@ async function done(id, summary) {
|
|
|
10609
10741
|
const pending = item.plan.slice(completedCount);
|
|
10610
10742
|
if (pending.length > 0) {
|
|
10611
10743
|
console.log(
|
|
10612
|
-
|
|
10744
|
+
chalk87.red(
|
|
10613
10745
|
`Cannot complete item ${formatItemId(item.id)}: ${pending.length} pending phase(s):`
|
|
10614
10746
|
)
|
|
10615
10747
|
);
|
|
10616
10748
|
for (const phase of pending) {
|
|
10617
|
-
console.log(
|
|
10749
|
+
console.log(chalk87.yellow(` - ${phase.name}`));
|
|
10618
10750
|
}
|
|
10619
10751
|
process.exitCode = 1;
|
|
10620
10752
|
return;
|
|
@@ -10626,12 +10758,12 @@ async function done(id, summary) {
|
|
|
10626
10758
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
10627
10759
|
}
|
|
10628
10760
|
console.log(
|
|
10629
|
-
|
|
10761
|
+
chalk87.green(`Completed item ${formatItemId(item.id)}: ${item.name}`)
|
|
10630
10762
|
);
|
|
10631
10763
|
}
|
|
10632
10764
|
|
|
10633
10765
|
// src/commands/backlog/set-status/index.ts
|
|
10634
|
-
import
|
|
10766
|
+
import chalk88 from "chalk";
|
|
10635
10767
|
var allowedStatuses = [
|
|
10636
10768
|
"todo",
|
|
10637
10769
|
"in-progress",
|
|
@@ -10641,7 +10773,7 @@ var allowedStatuses = [
|
|
|
10641
10773
|
async function setStatusCommand(id, status3) {
|
|
10642
10774
|
if (!allowedStatuses.includes(status3)) {
|
|
10643
10775
|
console.log(
|
|
10644
|
-
|
|
10776
|
+
chalk88.red(
|
|
10645
10777
|
`Invalid status "${status3}". Must be one of: ${allowedStatuses.join(", ")}.`
|
|
10646
10778
|
)
|
|
10647
10779
|
);
|
|
@@ -10651,7 +10783,7 @@ async function setStatusCommand(id, status3) {
|
|
|
10651
10783
|
const name = await setStatus(id, status3);
|
|
10652
10784
|
if (name) {
|
|
10653
10785
|
console.log(
|
|
10654
|
-
|
|
10786
|
+
chalk88.green(
|
|
10655
10787
|
`Set item ${formatItemId(parseItemId(id))} to ${status3}: ${name}`
|
|
10656
10788
|
)
|
|
10657
10789
|
);
|
|
@@ -10659,16 +10791,16 @@ async function setStatusCommand(id, status3) {
|
|
|
10659
10791
|
}
|
|
10660
10792
|
|
|
10661
10793
|
// src/commands/backlog/star/index.ts
|
|
10662
|
-
import
|
|
10794
|
+
import chalk90 from "chalk";
|
|
10663
10795
|
|
|
10664
10796
|
// src/commands/backlog/setStarred.ts
|
|
10665
|
-
import
|
|
10797
|
+
import chalk89 from "chalk";
|
|
10666
10798
|
async function setStarred(id, starred) {
|
|
10667
10799
|
const { orm } = await getReady();
|
|
10668
10800
|
const numId = parseItemId(id);
|
|
10669
10801
|
const name = await updateStarred(orm, numId, starred);
|
|
10670
10802
|
if (name === void 0)
|
|
10671
|
-
console.log(
|
|
10803
|
+
console.log(chalk89.red(`Item ${formatItemId(numId)} not found.`));
|
|
10672
10804
|
return name;
|
|
10673
10805
|
}
|
|
10674
10806
|
|
|
@@ -10677,52 +10809,52 @@ async function star(id) {
|
|
|
10677
10809
|
const name = await setStarred(id, true);
|
|
10678
10810
|
if (name) {
|
|
10679
10811
|
console.log(
|
|
10680
|
-
|
|
10812
|
+
chalk90.green(`Starred item ${formatItemId(parseItemId(id))}: ${name}`)
|
|
10681
10813
|
);
|
|
10682
10814
|
}
|
|
10683
10815
|
}
|
|
10684
10816
|
|
|
10685
10817
|
// src/commands/backlog/start/index.ts
|
|
10686
|
-
import
|
|
10818
|
+
import chalk91 from "chalk";
|
|
10687
10819
|
async function start(id) {
|
|
10688
10820
|
const name = await setStatus(id, "in-progress");
|
|
10689
10821
|
if (name) {
|
|
10690
10822
|
console.log(
|
|
10691
|
-
|
|
10823
|
+
chalk91.green(`Started item ${formatItemId(parseItemId(id))}: ${name}`)
|
|
10692
10824
|
);
|
|
10693
10825
|
}
|
|
10694
10826
|
}
|
|
10695
10827
|
|
|
10696
10828
|
// src/commands/backlog/stop/index.ts
|
|
10697
|
-
import
|
|
10698
|
-
import { and as and10, eq as
|
|
10829
|
+
import chalk92 from "chalk";
|
|
10830
|
+
import { and as and10, eq as eq27 } from "drizzle-orm";
|
|
10699
10831
|
async function stop() {
|
|
10700
10832
|
const { orm } = await getReady();
|
|
10701
|
-
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and10(
|
|
10833
|
+
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and10(eq27(items.status, "in-progress"), eq27(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
10702
10834
|
if (stopped.length === 0) {
|
|
10703
|
-
console.log(
|
|
10835
|
+
console.log(chalk92.yellow("No in-progress items to stop."));
|
|
10704
10836
|
return;
|
|
10705
10837
|
}
|
|
10706
10838
|
for (const item of stopped) {
|
|
10707
10839
|
console.log(
|
|
10708
|
-
|
|
10840
|
+
chalk92.yellow(`Stopped item ${formatItemId(item.id)}: ${item.name}`)
|
|
10709
10841
|
);
|
|
10710
10842
|
}
|
|
10711
10843
|
}
|
|
10712
10844
|
|
|
10713
10845
|
// src/commands/backlog/unstar/index.ts
|
|
10714
|
-
import
|
|
10846
|
+
import chalk93 from "chalk";
|
|
10715
10847
|
async function unstar(id) {
|
|
10716
10848
|
const name = await setStarred(id, false);
|
|
10717
10849
|
if (name) {
|
|
10718
10850
|
console.log(
|
|
10719
|
-
|
|
10851
|
+
chalk93.green(`Unstarred item ${formatItemId(parseItemId(id))}: ${name}`)
|
|
10720
10852
|
);
|
|
10721
10853
|
}
|
|
10722
10854
|
}
|
|
10723
10855
|
|
|
10724
10856
|
// src/commands/backlog/wontdo/index.ts
|
|
10725
|
-
import
|
|
10857
|
+
import chalk94 from "chalk";
|
|
10726
10858
|
async function wontdo(id, reason) {
|
|
10727
10859
|
const found = await findOneItem(id);
|
|
10728
10860
|
if (!found) return;
|
|
@@ -10733,7 +10865,7 @@ async function wontdo(id, reason) {
|
|
|
10733
10865
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
10734
10866
|
}
|
|
10735
10867
|
console.log(
|
|
10736
|
-
|
|
10868
|
+
chalk94.red(`Won't do item ${formatItemId(item.id)}: ${item.name}`)
|
|
10737
10869
|
);
|
|
10738
10870
|
}
|
|
10739
10871
|
|
|
@@ -10752,17 +10884,17 @@ function registerStatusCommands(cmd) {
|
|
|
10752
10884
|
}
|
|
10753
10885
|
|
|
10754
10886
|
// src/commands/backlog/addSubtask.ts
|
|
10755
|
-
import
|
|
10887
|
+
import chalk95 from "chalk";
|
|
10756
10888
|
async function addSubtask(id, options2) {
|
|
10757
10889
|
const title = options2.title?.trim();
|
|
10758
10890
|
if (!title) {
|
|
10759
|
-
console.log(
|
|
10891
|
+
console.log(chalk95.red("A sub-task title is required (--title)."));
|
|
10760
10892
|
process.exitCode = 1;
|
|
10761
10893
|
return;
|
|
10762
10894
|
}
|
|
10763
10895
|
if (title.length > 50) {
|
|
10764
10896
|
console.log(
|
|
10765
|
-
|
|
10897
|
+
chalk95.red(
|
|
10766
10898
|
"A sub-task title must be 50 characters or fewer. Use --desc for longer detail."
|
|
10767
10899
|
)
|
|
10768
10900
|
);
|
|
@@ -10778,21 +10910,21 @@ async function addSubtask(id, options2) {
|
|
|
10778
10910
|
const description = options2.desc?.replaceAll(String.raw`\n`, "\n");
|
|
10779
10911
|
await insertSubtask(orm, item.id, title, description);
|
|
10780
10912
|
console.log(
|
|
10781
|
-
|
|
10913
|
+
chalk95.green(`Added sub-task to item ${formatItemId(item.id)}: ${title}`)
|
|
10782
10914
|
);
|
|
10783
10915
|
}
|
|
10784
10916
|
|
|
10785
10917
|
// src/commands/backlog/editSubtask.ts
|
|
10786
|
-
import
|
|
10918
|
+
import chalk97 from "chalk";
|
|
10787
10919
|
|
|
10788
10920
|
// src/commands/backlog/resolveSubtaskIndex.ts
|
|
10789
|
-
import
|
|
10921
|
+
import chalk96 from "chalk";
|
|
10790
10922
|
function resolveSubtaskIndex(index3, item) {
|
|
10791
10923
|
const position = Number.parseInt(index3, 10);
|
|
10792
10924
|
const subtasks = item.subtasks ?? [];
|
|
10793
10925
|
if (Number.isNaN(position) || position < 1 || position > subtasks.length) {
|
|
10794
10926
|
console.log(
|
|
10795
|
-
|
|
10927
|
+
chalk96.red(
|
|
10796
10928
|
`Item ${formatItemId(item.id)} has no sub-task ${index3}${subtasks.length > 0 ? ` (1-${subtasks.length})` : ""}.`
|
|
10797
10929
|
)
|
|
10798
10930
|
);
|
|
@@ -10815,13 +10947,13 @@ async function findSubtask(id, index3) {
|
|
|
10815
10947
|
}
|
|
10816
10948
|
|
|
10817
10949
|
// src/commands/backlog/updateSubtask.ts
|
|
10818
|
-
import { and as and11, eq as
|
|
10950
|
+
import { and as and11, eq as eq28 } from "drizzle-orm";
|
|
10819
10951
|
async function updateSubtask(orm, itemId2, idx, fields) {
|
|
10820
10952
|
const set = {};
|
|
10821
10953
|
if (fields.title !== void 0) set.title = fields.title;
|
|
10822
10954
|
if (fields.description !== void 0) set.description = fields.description;
|
|
10823
10955
|
if (fields.status !== void 0) set.status = fields.status;
|
|
10824
|
-
const [row] = await orm.update(itemSubtasks).set(set).where(and11(
|
|
10956
|
+
const [row] = await orm.update(itemSubtasks).set(set).where(and11(eq28(itemSubtasks.itemId, itemId2), eq28(itemSubtasks.idx, idx))).returning({ title: itemSubtasks.title });
|
|
10825
10957
|
return row?.title;
|
|
10826
10958
|
}
|
|
10827
10959
|
|
|
@@ -10859,33 +10991,33 @@ async function editSubtask(id, index3, options2) {
|
|
|
10859
10991
|
if (!found) return;
|
|
10860
10992
|
const fields = buildUpdate(options2);
|
|
10861
10993
|
if (typeof fields === "string") {
|
|
10862
|
-
console.log(
|
|
10994
|
+
console.log(chalk97.red(fields));
|
|
10863
10995
|
process.exitCode = 1;
|
|
10864
10996
|
return;
|
|
10865
10997
|
}
|
|
10866
10998
|
const { orm, item, idx } = found;
|
|
10867
10999
|
const title = await updateSubtask(orm, item.id, idx, fields);
|
|
10868
11000
|
console.log(
|
|
10869
|
-
|
|
11001
|
+
chalk97.green(
|
|
10870
11002
|
`Updated sub-task ${idx + 1} of item ${formatItemId(item.id)}: ${title}`
|
|
10871
11003
|
)
|
|
10872
11004
|
);
|
|
10873
11005
|
}
|
|
10874
11006
|
|
|
10875
11007
|
// src/commands/backlog/removeSubtask.ts
|
|
10876
|
-
import
|
|
11008
|
+
import chalk98 from "chalk";
|
|
10877
11009
|
|
|
10878
11010
|
// src/commands/backlog/deleteSubtask.ts
|
|
10879
|
-
import { and as and12, asc as asc6, eq as
|
|
11011
|
+
import { and as and12, asc as asc6, eq as eq29 } from "drizzle-orm";
|
|
10880
11012
|
async function deleteSubtask(orm, itemId2, idx) {
|
|
10881
|
-
const [row] = await orm.delete(itemSubtasks).where(and12(
|
|
11013
|
+
const [row] = await orm.delete(itemSubtasks).where(and12(eq29(itemSubtasks.itemId, itemId2), eq29(itemSubtasks.idx, idx))).returning({ title: itemSubtasks.title });
|
|
10882
11014
|
if (!row) return void 0;
|
|
10883
|
-
const remaining = await orm.select({ idx: itemSubtasks.idx }).from(itemSubtasks).where(
|
|
11015
|
+
const remaining = await orm.select({ idx: itemSubtasks.idx }).from(itemSubtasks).where(eq29(itemSubtasks.itemId, itemId2)).orderBy(asc6(itemSubtasks.idx));
|
|
10884
11016
|
for (let i = 0; i < remaining.length; i++) {
|
|
10885
11017
|
const oldIdx = remaining[i].idx;
|
|
10886
11018
|
if (oldIdx === i) continue;
|
|
10887
11019
|
await orm.update(itemSubtasks).set({ idx: i }).where(
|
|
10888
|
-
and12(
|
|
11020
|
+
and12(eq29(itemSubtasks.itemId, itemId2), eq29(itemSubtasks.idx, oldIdx))
|
|
10889
11021
|
);
|
|
10890
11022
|
}
|
|
10891
11023
|
return row.title;
|
|
@@ -10898,18 +11030,18 @@ async function removeSubtask(id, index3) {
|
|
|
10898
11030
|
const { orm, item, idx } = found;
|
|
10899
11031
|
const title = await deleteSubtask(orm, item.id, idx);
|
|
10900
11032
|
console.log(
|
|
10901
|
-
|
|
11033
|
+
chalk98.green(
|
|
10902
11034
|
`Removed sub-task ${idx + 1} of item ${formatItemId(item.id)}: ${title}`
|
|
10903
11035
|
)
|
|
10904
11036
|
);
|
|
10905
11037
|
}
|
|
10906
11038
|
|
|
10907
11039
|
// src/commands/backlog/subtaskStatus.ts
|
|
10908
|
-
import
|
|
11040
|
+
import chalk99 from "chalk";
|
|
10909
11041
|
async function subtaskStatus(id, index3, status3) {
|
|
10910
11042
|
if (!validSubtaskStatuses.includes(status3)) {
|
|
10911
11043
|
console.log(
|
|
10912
|
-
|
|
11044
|
+
chalk99.red(
|
|
10913
11045
|
`Invalid status "${status3}". Use one of: ${validSubtaskStatuses.join(", ")}.`
|
|
10914
11046
|
)
|
|
10915
11047
|
);
|
|
@@ -10926,7 +11058,7 @@ async function subtaskStatus(id, index3, status3) {
|
|
|
10926
11058
|
status3
|
|
10927
11059
|
);
|
|
10928
11060
|
console.log(
|
|
10929
|
-
|
|
11061
|
+
chalk99.green(
|
|
10930
11062
|
`Set sub-task ${idx + 1} of item ${formatItemId(item.id)} to ${status3}: ${title}`
|
|
10931
11063
|
)
|
|
10932
11064
|
);
|
|
@@ -10953,21 +11085,21 @@ function registerSubtaskCommands(cmd) {
|
|
|
10953
11085
|
}
|
|
10954
11086
|
|
|
10955
11087
|
// src/commands/backlog/movePhase.ts
|
|
10956
|
-
import
|
|
10957
|
-
import { count as count5, eq as
|
|
11088
|
+
import chalk100 from "chalk";
|
|
11089
|
+
import { count as count5, eq as eq32 } from "drizzle-orm";
|
|
10958
11090
|
|
|
10959
11091
|
// src/commands/backlog/reorderPhaseRows.ts
|
|
10960
|
-
import { and as and14, asc as asc8, eq as
|
|
11092
|
+
import { and as and14, asc as asc8, eq as eq31 } from "drizzle-orm";
|
|
10961
11093
|
|
|
10962
11094
|
// src/commands/backlog/reindexPhases.ts
|
|
10963
|
-
import { and as and13, asc as asc7, count as count4, eq as
|
|
11095
|
+
import { and as and13, asc as asc7, count as count4, eq as eq30 } from "drizzle-orm";
|
|
10964
11096
|
async function reindexPhases(db, itemId2) {
|
|
10965
|
-
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
11097
|
+
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq30(planPhases.itemId, itemId2)).orderBy(asc7(planPhases.idx));
|
|
10966
11098
|
for (let i = 0; i < remaining.length; i++) {
|
|
10967
11099
|
const oldIdx = remaining[i].idx;
|
|
10968
11100
|
if (oldIdx === i) continue;
|
|
10969
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(and13(
|
|
10970
|
-
await db.update(planPhases).set({ idx: i }).where(and13(
|
|
11101
|
+
await db.update(planTasks).set({ phaseIdx: i }).where(and13(eq30(planTasks.itemId, itemId2), eq30(planTasks.phaseIdx, oldIdx)));
|
|
11102
|
+
await db.update(planPhases).set({ idx: i }).where(and13(eq30(planPhases.itemId, itemId2), eq30(planPhases.idx, oldIdx)));
|
|
10971
11103
|
}
|
|
10972
11104
|
}
|
|
10973
11105
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -10975,24 +11107,24 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
10975
11107
|
if (currentPhase === void 0) return;
|
|
10976
11108
|
const currentIdx = currentPhase - 1;
|
|
10977
11109
|
if (removedIdx < currentIdx) {
|
|
10978
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
11110
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq30(items.id, item.id));
|
|
10979
11111
|
return;
|
|
10980
11112
|
}
|
|
10981
11113
|
if (removedIdx !== currentIdx) return;
|
|
10982
|
-
const [row] = await db.select({ cnt: count4() }).from(planPhases).where(
|
|
11114
|
+
const [row] = await db.select({ cnt: count4() }).from(planPhases).where(eq30(planPhases.itemId, item.id));
|
|
10983
11115
|
const cnt = row?.cnt ?? 0;
|
|
10984
|
-
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(
|
|
11116
|
+
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq30(items.id, item.id));
|
|
10985
11117
|
}
|
|
10986
11118
|
|
|
10987
11119
|
// src/commands/backlog/reorderPhaseRows.ts
|
|
10988
11120
|
async function reorderPhaseRows(orm, itemId2, fromIdx, toIdx) {
|
|
10989
11121
|
await orm.transaction(async (tx) => {
|
|
10990
|
-
const [phaseRow] = await tx.select({ name: planPhases.name, manualChecks: planPhases.manualChecks }).from(planPhases).where(and14(
|
|
10991
|
-
const tasks = await tx.select({ idx: planTasks.idx, task: planTasks.task }).from(planTasks).where(and14(
|
|
11122
|
+
const [phaseRow] = await tx.select({ name: planPhases.name, manualChecks: planPhases.manualChecks }).from(planPhases).where(and14(eq31(planPhases.itemId, itemId2), eq31(planPhases.idx, fromIdx)));
|
|
11123
|
+
const tasks = await tx.select({ idx: planTasks.idx, task: planTasks.task }).from(planTasks).where(and14(eq31(planTasks.itemId, itemId2), eq31(planTasks.phaseIdx, fromIdx))).orderBy(asc8(planTasks.idx));
|
|
10992
11124
|
await tx.delete(planTasks).where(
|
|
10993
|
-
and14(
|
|
11125
|
+
and14(eq31(planTasks.itemId, itemId2), eq31(planTasks.phaseIdx, fromIdx))
|
|
10994
11126
|
);
|
|
10995
|
-
await tx.delete(planPhases).where(and14(
|
|
11127
|
+
await tx.delete(planPhases).where(and14(eq31(planPhases.itemId, itemId2), eq31(planPhases.idx, fromIdx)));
|
|
10996
11128
|
await reindexPhases(tx, itemId2);
|
|
10997
11129
|
await shiftPhasesUp(tx, itemId2, toIdx);
|
|
10998
11130
|
await tx.insert(planPhases).values({
|
|
@@ -11019,7 +11151,7 @@ function toIndex(value, phaseCount) {
|
|
|
11019
11151
|
const pos = Number.parseInt(value, 10);
|
|
11020
11152
|
if (Number.isNaN(pos) || pos < 1 || pos > phaseCount) {
|
|
11021
11153
|
console.log(
|
|
11022
|
-
|
|
11154
|
+
chalk100.red(
|
|
11023
11155
|
`Position "${value}" is out of range. Must be between 1 and ${phaseCount}.`
|
|
11024
11156
|
)
|
|
11025
11157
|
);
|
|
@@ -11033,7 +11165,7 @@ async function movePhase(id, from, to) {
|
|
|
11033
11165
|
if (!found) return;
|
|
11034
11166
|
const { orm, item } = found;
|
|
11035
11167
|
const itemId2 = item.id;
|
|
11036
|
-
const [row] = await orm.select({ cnt: count5() }).from(planPhases).where(
|
|
11168
|
+
const [row] = await orm.select({ cnt: count5() }).from(planPhases).where(eq32(planPhases.itemId, itemId2));
|
|
11037
11169
|
const phaseCount = row?.cnt ?? 0;
|
|
11038
11170
|
const fromIdx = toIndex(from, phaseCount);
|
|
11039
11171
|
if (fromIdx === void 0) return;
|
|
@@ -11042,29 +11174,29 @@ async function movePhase(id, from, to) {
|
|
|
11042
11174
|
if (fromIdx !== toIdx) {
|
|
11043
11175
|
await reorderPhaseRows(orm, itemId2, fromIdx, toIdx);
|
|
11044
11176
|
}
|
|
11045
|
-
console.log(
|
|
11177
|
+
console.log(chalk100.green(`Moved phase ${from} to position ${to}.`));
|
|
11046
11178
|
}
|
|
11047
11179
|
|
|
11048
11180
|
// src/commands/backlog/updatePhase.ts
|
|
11049
|
-
import
|
|
11181
|
+
import chalk102 from "chalk";
|
|
11050
11182
|
|
|
11051
11183
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
11052
|
-
import { and as and15, eq as
|
|
11184
|
+
import { and as and15, eq as eq33 } from "drizzle-orm";
|
|
11053
11185
|
async function applyPhaseUpdate(orm, itemId2, phaseIdx, fields) {
|
|
11054
11186
|
await orm.transaction(async (tx) => {
|
|
11055
11187
|
if (fields.name) {
|
|
11056
11188
|
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
11057
|
-
and15(
|
|
11189
|
+
and15(eq33(planPhases.itemId, itemId2), eq33(planPhases.idx, phaseIdx))
|
|
11058
11190
|
);
|
|
11059
11191
|
}
|
|
11060
11192
|
if (fields.manualCheck) {
|
|
11061
11193
|
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
11062
|
-
and15(
|
|
11194
|
+
and15(eq33(planPhases.itemId, itemId2), eq33(planPhases.idx, phaseIdx))
|
|
11063
11195
|
);
|
|
11064
11196
|
}
|
|
11065
11197
|
if (fields.task) {
|
|
11066
11198
|
await tx.delete(planTasks).where(
|
|
11067
|
-
and15(
|
|
11199
|
+
and15(eq33(planTasks.itemId, itemId2), eq33(planTasks.phaseIdx, phaseIdx))
|
|
11068
11200
|
);
|
|
11069
11201
|
if (fields.task.length) {
|
|
11070
11202
|
await tx.insert(planTasks).values(
|
|
@@ -11081,18 +11213,18 @@ async function applyPhaseUpdate(orm, itemId2, phaseIdx, fields) {
|
|
|
11081
11213
|
}
|
|
11082
11214
|
|
|
11083
11215
|
// src/commands/backlog/findPhase.ts
|
|
11084
|
-
import
|
|
11085
|
-
import { and as and16, count as count6, eq as
|
|
11216
|
+
import chalk101 from "chalk";
|
|
11217
|
+
import { and as and16, count as count6, eq as eq34 } from "drizzle-orm";
|
|
11086
11218
|
async function findPhase(id, phase) {
|
|
11087
11219
|
const found = await findOneItem(id);
|
|
11088
11220
|
if (!found) return void 0;
|
|
11089
11221
|
const { orm, item } = found;
|
|
11090
11222
|
const itemId2 = item.id;
|
|
11091
11223
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
11092
|
-
const [row] = await orm.select({ cnt: count6() }).from(planPhases).where(and16(
|
|
11224
|
+
const [row] = await orm.select({ cnt: count6() }).from(planPhases).where(and16(eq34(planPhases.itemId, itemId2), eq34(planPhases.idx, phaseIdx)));
|
|
11093
11225
|
if (!row || row.cnt === 0) {
|
|
11094
11226
|
console.log(
|
|
11095
|
-
|
|
11227
|
+
chalk101.red(
|
|
11096
11228
|
`Phase ${phaseIdx + 1} not found on item ${formatItemId(itemId2)}.`
|
|
11097
11229
|
)
|
|
11098
11230
|
);
|
|
@@ -11226,7 +11358,7 @@ async function updatePhase(id, phase, options2) {
|
|
|
11226
11358
|
const { item, orm, itemId: itemId2, phaseIdx } = found;
|
|
11227
11359
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
11228
11360
|
if (!resolved.ok) {
|
|
11229
|
-
console.log(
|
|
11361
|
+
console.log(chalk102.red(resolved.error));
|
|
11230
11362
|
process.exitCode = 1;
|
|
11231
11363
|
return;
|
|
11232
11364
|
}
|
|
@@ -11238,7 +11370,7 @@ async function updatePhase(id, phase, options2) {
|
|
|
11238
11370
|
manualCheck && "manual checks"
|
|
11239
11371
|
].filter(Boolean).join(", ");
|
|
11240
11372
|
console.log(
|
|
11241
|
-
|
|
11373
|
+
chalk102.green(
|
|
11242
11374
|
`Updated ${fields} on phase ${phaseIdx + 1} of item ${formatItemId(itemId2)}.`
|
|
11243
11375
|
)
|
|
11244
11376
|
);
|
|
@@ -11261,30 +11393,30 @@ function registerUpdatePhaseCommand(cmd) {
|
|
|
11261
11393
|
}
|
|
11262
11394
|
|
|
11263
11395
|
// src/commands/backlog/removePhase.ts
|
|
11264
|
-
import
|
|
11265
|
-
import { and as and17, eq as
|
|
11396
|
+
import chalk103 from "chalk";
|
|
11397
|
+
import { and as and17, eq as eq35 } from "drizzle-orm";
|
|
11266
11398
|
async function removePhase(id, phase) {
|
|
11267
11399
|
const found = await findPhase(id, phase);
|
|
11268
11400
|
if (!found) return;
|
|
11269
11401
|
const { item, orm, itemId: itemId2, phaseIdx } = found;
|
|
11270
11402
|
await orm.transaction(async (tx) => {
|
|
11271
11403
|
await tx.delete(planTasks).where(
|
|
11272
|
-
and17(
|
|
11404
|
+
and17(eq35(planTasks.itemId, itemId2), eq35(planTasks.phaseIdx, phaseIdx))
|
|
11273
11405
|
);
|
|
11274
|
-
await tx.delete(planPhases).where(and17(
|
|
11406
|
+
await tx.delete(planPhases).where(and17(eq35(planPhases.itemId, itemId2), eq35(planPhases.idx, phaseIdx)));
|
|
11275
11407
|
await reindexPhases(tx, itemId2);
|
|
11276
11408
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
11277
11409
|
});
|
|
11278
11410
|
console.log(
|
|
11279
|
-
|
|
11411
|
+
chalk103.green(
|
|
11280
11412
|
`Removed phase ${phaseIdx + 1} from item ${formatItemId(itemId2)}.`
|
|
11281
11413
|
)
|
|
11282
11414
|
);
|
|
11283
11415
|
}
|
|
11284
11416
|
|
|
11285
11417
|
// src/commands/backlog/update/index.ts
|
|
11286
|
-
import
|
|
11287
|
-
import { eq as
|
|
11418
|
+
import chalk105 from "chalk";
|
|
11419
|
+
import { eq as eq36 } from "drizzle-orm";
|
|
11288
11420
|
|
|
11289
11421
|
// src/commands/backlog/update/applyAcMutations.ts
|
|
11290
11422
|
function hasAcMutations(options2) {
|
|
@@ -11305,16 +11437,16 @@ function applyAcMutations(current, options2) {
|
|
|
11305
11437
|
}
|
|
11306
11438
|
|
|
11307
11439
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
11308
|
-
import
|
|
11440
|
+
import chalk104 from "chalk";
|
|
11309
11441
|
function buildUpdateValues(options2) {
|
|
11310
11442
|
const { name, desc: desc6, type, ac } = options2;
|
|
11311
11443
|
if (!name && !desc6 && !type && !ac) {
|
|
11312
|
-
console.log(
|
|
11444
|
+
console.log(chalk104.red("Nothing to update. Provide at least one flag."));
|
|
11313
11445
|
process.exitCode = 1;
|
|
11314
11446
|
return void 0;
|
|
11315
11447
|
}
|
|
11316
11448
|
if (type && type !== "story" && type !== "bug") {
|
|
11317
|
-
console.log(
|
|
11449
|
+
console.log(chalk104.red('Invalid type. Must be "story" or "bug".'));
|
|
11318
11450
|
process.exitCode = 1;
|
|
11319
11451
|
return void 0;
|
|
11320
11452
|
}
|
|
@@ -11347,14 +11479,14 @@ async function update(id, options2) {
|
|
|
11347
11479
|
if (hasAcMutations(options2)) {
|
|
11348
11480
|
if (options2.ac) {
|
|
11349
11481
|
console.log(
|
|
11350
|
-
|
|
11482
|
+
chalk105.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
11351
11483
|
);
|
|
11352
11484
|
process.exitCode = 1;
|
|
11353
11485
|
return;
|
|
11354
11486
|
}
|
|
11355
11487
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
11356
11488
|
if (!mutation.ok) {
|
|
11357
|
-
console.log(
|
|
11489
|
+
console.log(chalk105.red(mutation.error));
|
|
11358
11490
|
process.exitCode = 1;
|
|
11359
11491
|
return;
|
|
11360
11492
|
}
|
|
@@ -11364,9 +11496,9 @@ async function update(id, options2) {
|
|
|
11364
11496
|
if (!built) return;
|
|
11365
11497
|
const { orm } = found;
|
|
11366
11498
|
const itemId2 = found.item.id;
|
|
11367
|
-
await orm.update(items).set(built.set).where(
|
|
11499
|
+
await orm.update(items).set(built.set).where(eq36(items.id, itemId2));
|
|
11368
11500
|
console.log(
|
|
11369
|
-
|
|
11501
|
+
chalk105.green(`Updated ${built.fields} on item ${formatItemId(itemId2)}.`)
|
|
11370
11502
|
);
|
|
11371
11503
|
}
|
|
11372
11504
|
|
|
@@ -11420,6 +11552,7 @@ var registrars = [
|
|
|
11420
11552
|
registerImportCommand,
|
|
11421
11553
|
registerMoveRepoCommand,
|
|
11422
11554
|
registerAssociateJiraCommand,
|
|
11555
|
+
registerAssociateGithubCommand,
|
|
11423
11556
|
registerActivityCommands
|
|
11424
11557
|
];
|
|
11425
11558
|
function registerBacklog(program2) {
|
|
@@ -12169,11 +12302,11 @@ function assertCliExists(cli) {
|
|
|
12169
12302
|
}
|
|
12170
12303
|
|
|
12171
12304
|
// src/commands/permitCliReads/colorize.ts
|
|
12172
|
-
import
|
|
12305
|
+
import chalk106 from "chalk";
|
|
12173
12306
|
function colorize(plainOutput) {
|
|
12174
12307
|
return plainOutput.split("\n").map((line) => {
|
|
12175
|
-
if (line.startsWith(" R ")) return
|
|
12176
|
-
if (line.startsWith(" W ")) return
|
|
12308
|
+
if (line.startsWith(" R ")) return chalk106.green(line);
|
|
12309
|
+
if (line.startsWith(" W ")) return chalk106.red(line);
|
|
12177
12310
|
return line;
|
|
12178
12311
|
}).join("\n");
|
|
12179
12312
|
}
|
|
@@ -12471,7 +12604,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
12471
12604
|
}
|
|
12472
12605
|
|
|
12473
12606
|
// src/commands/deny/denyAdd.ts
|
|
12474
|
-
import
|
|
12607
|
+
import chalk107 from "chalk";
|
|
12475
12608
|
|
|
12476
12609
|
// src/commands/deny/loadDenyConfig.ts
|
|
12477
12610
|
function loadDenyConfig(global) {
|
|
@@ -12491,16 +12624,16 @@ function loadDenyConfig(global) {
|
|
|
12491
12624
|
function denyAdd(pattern2, message, options2) {
|
|
12492
12625
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
12493
12626
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
12494
|
-
console.log(
|
|
12627
|
+
console.log(chalk107.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
12495
12628
|
return;
|
|
12496
12629
|
}
|
|
12497
12630
|
deny.push({ pattern: pattern2, message });
|
|
12498
12631
|
saveDeny(deny);
|
|
12499
|
-
console.log(
|
|
12632
|
+
console.log(chalk107.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
12500
12633
|
}
|
|
12501
12634
|
|
|
12502
12635
|
// src/commands/deny/denyList.ts
|
|
12503
|
-
import
|
|
12636
|
+
import chalk108 from "chalk";
|
|
12504
12637
|
function denyList() {
|
|
12505
12638
|
const globalRaw = loadGlobalConfigRaw();
|
|
12506
12639
|
const projectRaw = loadProjectConfig();
|
|
@@ -12511,7 +12644,7 @@ function denyList() {
|
|
|
12511
12644
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
12512
12645
|
);
|
|
12513
12646
|
if (!merged || merged.length === 0) {
|
|
12514
|
-
console.log(
|
|
12647
|
+
console.log(chalk108.dim("No deny rules configured."));
|
|
12515
12648
|
return;
|
|
12516
12649
|
}
|
|
12517
12650
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -12519,23 +12652,23 @@ function denyList() {
|
|
|
12519
12652
|
for (const rule of merged) {
|
|
12520
12653
|
const inProject = projectPatterns.has(rule.pattern);
|
|
12521
12654
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
12522
|
-
const label2 = inProject && inGlobal ?
|
|
12523
|
-
console.log(`${
|
|
12655
|
+
const label2 = inProject && inGlobal ? chalk108.dim(" (project, overrides global)") : inGlobal ? chalk108.dim(" (global)") : "";
|
|
12656
|
+
console.log(`${chalk108.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
12524
12657
|
}
|
|
12525
12658
|
}
|
|
12526
12659
|
|
|
12527
12660
|
// src/commands/deny/denyRemove.ts
|
|
12528
|
-
import
|
|
12661
|
+
import chalk109 from "chalk";
|
|
12529
12662
|
function denyRemove(pattern2, options2) {
|
|
12530
12663
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
12531
12664
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
12532
12665
|
if (index3 === -1) {
|
|
12533
|
-
console.log(
|
|
12666
|
+
console.log(chalk109.yellow(`No deny rule found for: ${pattern2}`));
|
|
12534
12667
|
return;
|
|
12535
12668
|
}
|
|
12536
12669
|
deny.splice(index3, 1);
|
|
12537
12670
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
12538
|
-
console.log(
|
|
12671
|
+
console.log(chalk109.green(`Removed deny rule: ${pattern2}`));
|
|
12539
12672
|
}
|
|
12540
12673
|
|
|
12541
12674
|
// src/commands/registerDeny.ts
|
|
@@ -12579,7 +12712,7 @@ function registerCliHook(program2) {
|
|
|
12579
12712
|
|
|
12580
12713
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
12581
12714
|
import { existsSync as existsSync31, readFileSync as readFileSync27, unlinkSync as unlinkSync8, writeFileSync as writeFileSync24 } from "fs";
|
|
12582
|
-
import
|
|
12715
|
+
import chalk110 from "chalk";
|
|
12583
12716
|
|
|
12584
12717
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
12585
12718
|
import { homedir as homedir17 } from "os";
|
|
@@ -12632,12 +12765,12 @@ function codeCommentConfirm(pin) {
|
|
|
12632
12765
|
sweepRestrictedDir();
|
|
12633
12766
|
const state = readPinState(pin);
|
|
12634
12767
|
if (!state) {
|
|
12635
|
-
console.error(
|
|
12768
|
+
console.error(chalk110.red(`No pending comment for pin: ${pin}`));
|
|
12636
12769
|
process.exitCode = 1;
|
|
12637
12770
|
return;
|
|
12638
12771
|
}
|
|
12639
12772
|
if (!existsSync31(state.file)) {
|
|
12640
|
-
console.error(
|
|
12773
|
+
console.error(chalk110.red(`Target file no longer exists: ${state.file}`));
|
|
12641
12774
|
process.exitCode = 1;
|
|
12642
12775
|
return;
|
|
12643
12776
|
}
|
|
@@ -12646,7 +12779,7 @@ function codeCommentConfirm(pin) {
|
|
|
12646
12779
|
const index3 = state.line - 1;
|
|
12647
12780
|
if (index3 > lines.length) {
|
|
12648
12781
|
console.error(
|
|
12649
|
-
|
|
12782
|
+
chalk110.red(
|
|
12650
12783
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
12651
12784
|
)
|
|
12652
12785
|
);
|
|
@@ -12660,14 +12793,14 @@ function codeCommentConfirm(pin) {
|
|
|
12660
12793
|
writeFileSync24(state.file, lines.join("\n"));
|
|
12661
12794
|
unlinkSync8(getPinStatePath(pin));
|
|
12662
12795
|
console.log(
|
|
12663
|
-
|
|
12796
|
+
chalk110.green(
|
|
12664
12797
|
`Inserted "${marker} ${state.text}" at ${state.file}:${state.line}`
|
|
12665
12798
|
)
|
|
12666
12799
|
);
|
|
12667
12800
|
}
|
|
12668
12801
|
|
|
12669
12802
|
// src/commands/codeComment/codeCommentSet.ts
|
|
12670
|
-
import
|
|
12803
|
+
import chalk111 from "chalk";
|
|
12671
12804
|
|
|
12672
12805
|
// src/commands/codeComment/validateCommentText.ts
|
|
12673
12806
|
var MAX_COMMENT_LENGTH = 50;
|
|
@@ -12718,7 +12851,7 @@ function generatePin() {
|
|
|
12718
12851
|
function codeCommentSet(file, line, text17) {
|
|
12719
12852
|
const lineNumber = Number.parseInt(line, 10);
|
|
12720
12853
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
12721
|
-
console.error(
|
|
12854
|
+
console.error(chalk111.red(`Invalid line number: ${line}`));
|
|
12722
12855
|
process.exitCode = 1;
|
|
12723
12856
|
return;
|
|
12724
12857
|
}
|
|
@@ -12726,20 +12859,20 @@ function codeCommentSet(file, line, text17) {
|
|
|
12726
12859
|
const marker = hash ? "#" : "//";
|
|
12727
12860
|
const validation = validateCommentText(text17, hash);
|
|
12728
12861
|
if (!validation.ok) {
|
|
12729
|
-
console.error(
|
|
12730
|
-
console.error(
|
|
12862
|
+
console.error(chalk111.red(`Refused: ${validation.reason}`));
|
|
12863
|
+
console.error(chalk111.red("No pin issued."));
|
|
12731
12864
|
process.exitCode = 1;
|
|
12732
12865
|
return;
|
|
12733
12866
|
}
|
|
12734
12867
|
console.error(
|
|
12735
|
-
|
|
12868
|
+
chalk111.yellow.bold(
|
|
12736
12869
|
"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."
|
|
12737
12870
|
)
|
|
12738
12871
|
);
|
|
12739
12872
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
12740
12873
|
if (!delivered) {
|
|
12741
12874
|
console.error(
|
|
12742
|
-
|
|
12875
|
+
chalk111.red(
|
|
12743
12876
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
12744
12877
|
)
|
|
12745
12878
|
);
|
|
@@ -12749,7 +12882,7 @@ function codeCommentSet(file, line, text17) {
|
|
|
12749
12882
|
console.log(
|
|
12750
12883
|
`A confirmation pin was sent to your desktop notifications.
|
|
12751
12884
|
To insert "${marker} ${validation.text}" at ${file}:${lineNumber}, run:
|
|
12752
|
-
${
|
|
12885
|
+
${chalk111.cyan(" assist code-comment confirm <PIN>")}
|
|
12753
12886
|
using the pin from that notification.`
|
|
12754
12887
|
);
|
|
12755
12888
|
}
|
|
@@ -12828,15 +12961,15 @@ function registerCodexHook(program2) {
|
|
|
12828
12961
|
}
|
|
12829
12962
|
|
|
12830
12963
|
// src/commands/complexity/analyze.ts
|
|
12831
|
-
import
|
|
12964
|
+
import chalk120 from "chalk";
|
|
12832
12965
|
|
|
12833
12966
|
// src/commands/complexity/cyclomatic.ts
|
|
12834
|
-
import
|
|
12967
|
+
import chalk113 from "chalk";
|
|
12835
12968
|
|
|
12836
12969
|
// src/commands/complexity/shared/index.ts
|
|
12837
12970
|
import fs20 from "fs";
|
|
12838
12971
|
import path27 from "path";
|
|
12839
|
-
import
|
|
12972
|
+
import chalk112 from "chalk";
|
|
12840
12973
|
import ts5 from "typescript";
|
|
12841
12974
|
|
|
12842
12975
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -13087,7 +13220,7 @@ function createSourceFromFile(filePath) {
|
|
|
13087
13220
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
13088
13221
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
13089
13222
|
if (files.length === 0) {
|
|
13090
|
-
console.log(
|
|
13223
|
+
console.log(chalk112.yellow("No files found matching pattern"));
|
|
13091
13224
|
return void 0;
|
|
13092
13225
|
}
|
|
13093
13226
|
return callback(files);
|
|
@@ -13120,11 +13253,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
13120
13253
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
13121
13254
|
for (const { file, name, complexity } of results) {
|
|
13122
13255
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
13123
|
-
const color = exceedsThreshold ?
|
|
13124
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
13256
|
+
const color = exceedsThreshold ? chalk113.red : chalk113.white;
|
|
13257
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk113.cyan(complexity)}`);
|
|
13125
13258
|
}
|
|
13126
13259
|
console.log(
|
|
13127
|
-
|
|
13260
|
+
chalk113.dim(
|
|
13128
13261
|
`
|
|
13129
13262
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
13130
13263
|
)
|
|
@@ -13136,7 +13269,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
13136
13269
|
}
|
|
13137
13270
|
|
|
13138
13271
|
// src/commands/complexity/halstead.ts
|
|
13139
|
-
import
|
|
13272
|
+
import chalk114 from "chalk";
|
|
13140
13273
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
13141
13274
|
withSourceFiles(pattern2, (files) => {
|
|
13142
13275
|
const results = [];
|
|
@@ -13151,13 +13284,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
13151
13284
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
13152
13285
|
for (const { file, name, metrics } of results) {
|
|
13153
13286
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
13154
|
-
const color = exceedsThreshold ?
|
|
13287
|
+
const color = exceedsThreshold ? chalk114.red : chalk114.white;
|
|
13155
13288
|
console.log(
|
|
13156
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
13289
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk114.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk114.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk114.magenta(metrics.effort.toFixed(1))}`
|
|
13157
13290
|
);
|
|
13158
13291
|
}
|
|
13159
13292
|
console.log(
|
|
13160
|
-
|
|
13293
|
+
chalk114.dim(
|
|
13161
13294
|
`
|
|
13162
13295
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
13163
13296
|
)
|
|
@@ -13169,27 +13302,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
13169
13302
|
}
|
|
13170
13303
|
|
|
13171
13304
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
13172
|
-
import
|
|
13305
|
+
import chalk117 from "chalk";
|
|
13173
13306
|
|
|
13174
13307
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
13175
|
-
import
|
|
13308
|
+
import chalk115 from "chalk";
|
|
13176
13309
|
function formatResultLine(entry, failing) {
|
|
13177
13310
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
13178
|
-
const name = failing ?
|
|
13179
|
-
const suffix = override !== void 0 ?
|
|
13180
|
-
return `${name} \u2192 avg: ${
|
|
13311
|
+
const name = failing ? chalk115.red(file) : chalk115.white(file);
|
|
13312
|
+
const suffix = override !== void 0 ? chalk115.magenta(` (override: ${override})`) : "";
|
|
13313
|
+
return `${name} \u2192 avg: ${chalk115.cyan(avgMaintainability.toFixed(1))}, min: ${chalk115.yellow(minMaintainability.toFixed(1))}${suffix}`;
|
|
13181
13314
|
}
|
|
13182
13315
|
|
|
13183
13316
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
13184
|
-
import
|
|
13317
|
+
import chalk116 from "chalk";
|
|
13185
13318
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
13186
13319
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
13187
13320
|
console.error(
|
|
13188
|
-
|
|
13321
|
+
chalk116.red(
|
|
13189
13322
|
`
|
|
13190
13323
|
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.
|
|
13191
13324
|
|
|
13192
|
-
\u26A0\uFE0F ${
|
|
13325
|
+
\u26A0\uFE0F ${chalk116.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
|
|
13193
13326
|
|
|
13194
13327
|
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.`
|
|
13195
13328
|
)
|
|
@@ -13201,7 +13334,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
13201
13334
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
13202
13335
|
if (!gating) {
|
|
13203
13336
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
13204
|
-
console.log(
|
|
13337
|
+
console.log(chalk117.dim(`
|
|
13205
13338
|
Analyzed ${results.length} files`));
|
|
13206
13339
|
return;
|
|
13207
13340
|
}
|
|
@@ -13210,7 +13343,7 @@ Analyzed ${results.length} files`));
|
|
|
13210
13343
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
13211
13344
|
});
|
|
13212
13345
|
if (failing.length === 0) {
|
|
13213
|
-
console.log(
|
|
13346
|
+
console.log(chalk117.green("All files pass maintainability threshold"));
|
|
13214
13347
|
} else {
|
|
13215
13348
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
13216
13349
|
}
|
|
@@ -13219,7 +13352,7 @@ Analyzed ${results.length} files`));
|
|
|
13219
13352
|
);
|
|
13220
13353
|
for (const entry of passingOverrides)
|
|
13221
13354
|
console.log(formatResultLine(entry, false));
|
|
13222
|
-
console.log(
|
|
13355
|
+
console.log(chalk117.dim(`
|
|
13223
13356
|
Analyzed ${results.length} files`));
|
|
13224
13357
|
if (failing.length > 0) {
|
|
13225
13358
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -13228,10 +13361,10 @@ Analyzed ${results.length} files`));
|
|
|
13228
13361
|
}
|
|
13229
13362
|
|
|
13230
13363
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
13231
|
-
import
|
|
13364
|
+
import chalk118 from "chalk";
|
|
13232
13365
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
13233
13366
|
function printMaintainabilityFormula() {
|
|
13234
|
-
console.log(
|
|
13367
|
+
console.log(chalk118.dim(MI_FORMULA));
|
|
13235
13368
|
}
|
|
13236
13369
|
|
|
13237
13370
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -13307,7 +13440,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
13307
13440
|
|
|
13308
13441
|
// src/commands/complexity/sloc.ts
|
|
13309
13442
|
import fs22 from "fs";
|
|
13310
|
-
import
|
|
13443
|
+
import chalk119 from "chalk";
|
|
13311
13444
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
13312
13445
|
withSourceFiles(pattern2, (files) => {
|
|
13313
13446
|
const results = [];
|
|
@@ -13323,12 +13456,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
13323
13456
|
results.sort((a, b) => b.lines - a.lines);
|
|
13324
13457
|
for (const { file, lines } of results) {
|
|
13325
13458
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
13326
|
-
const color = exceedsThreshold ?
|
|
13327
|
-
console.log(`${color(file)} \u2192 ${
|
|
13459
|
+
const color = exceedsThreshold ? chalk119.red : chalk119.white;
|
|
13460
|
+
console.log(`${color(file)} \u2192 ${chalk119.cyan(lines)} lines`);
|
|
13328
13461
|
}
|
|
13329
13462
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
13330
13463
|
console.log(
|
|
13331
|
-
|
|
13464
|
+
chalk119.dim(`
|
|
13332
13465
|
Total: ${total} lines across ${files.length} files`)
|
|
13333
13466
|
);
|
|
13334
13467
|
if (hasViolation) {
|
|
@@ -13342,25 +13475,25 @@ async function analyze(pattern2) {
|
|
|
13342
13475
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
13343
13476
|
const files = findSourceFiles2(searchPattern);
|
|
13344
13477
|
if (files.length === 0) {
|
|
13345
|
-
console.log(
|
|
13478
|
+
console.log(chalk120.yellow("No files found matching pattern"));
|
|
13346
13479
|
return;
|
|
13347
13480
|
}
|
|
13348
13481
|
if (files.length === 1) {
|
|
13349
13482
|
const file = files[0];
|
|
13350
|
-
console.log(
|
|
13483
|
+
console.log(chalk120.bold.underline("SLOC"));
|
|
13351
13484
|
await sloc(file);
|
|
13352
13485
|
console.log();
|
|
13353
|
-
console.log(
|
|
13486
|
+
console.log(chalk120.bold.underline("Cyclomatic Complexity"));
|
|
13354
13487
|
await cyclomatic(file);
|
|
13355
13488
|
console.log();
|
|
13356
|
-
console.log(
|
|
13489
|
+
console.log(chalk120.bold.underline("Halstead Metrics"));
|
|
13357
13490
|
await halstead(file);
|
|
13358
13491
|
console.log();
|
|
13359
|
-
console.log(
|
|
13492
|
+
console.log(chalk120.bold.underline("Maintainability Index"));
|
|
13360
13493
|
await maintainability(file);
|
|
13361
13494
|
console.log();
|
|
13362
13495
|
console.log(
|
|
13363
|
-
|
|
13496
|
+
chalk120.dim(
|
|
13364
13497
|
"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."
|
|
13365
13498
|
)
|
|
13366
13499
|
);
|
|
@@ -13404,7 +13537,7 @@ function registerComplexity(program2) {
|
|
|
13404
13537
|
}
|
|
13405
13538
|
|
|
13406
13539
|
// src/commands/config/index.ts
|
|
13407
|
-
import
|
|
13540
|
+
import chalk121 from "chalk";
|
|
13408
13541
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
13409
13542
|
|
|
13410
13543
|
// src/commands/config/setNestedValue.ts
|
|
@@ -13467,7 +13600,7 @@ function formatIssuePath(issue, key) {
|
|
|
13467
13600
|
function printValidationErrors(issues, key) {
|
|
13468
13601
|
for (const issue of issues) {
|
|
13469
13602
|
console.error(
|
|
13470
|
-
|
|
13603
|
+
chalk121.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
13471
13604
|
);
|
|
13472
13605
|
}
|
|
13473
13606
|
}
|
|
@@ -13484,7 +13617,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
13484
13617
|
function assertNotGlobalOnly(key, global) {
|
|
13485
13618
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
13486
13619
|
console.error(
|
|
13487
|
-
|
|
13620
|
+
chalk121.red(
|
|
13488
13621
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
13489
13622
|
)
|
|
13490
13623
|
);
|
|
@@ -13507,7 +13640,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
13507
13640
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
13508
13641
|
const target = options2.global ? "global" : "project";
|
|
13509
13642
|
console.log(
|
|
13510
|
-
|
|
13643
|
+
chalk121.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
13511
13644
|
);
|
|
13512
13645
|
}
|
|
13513
13646
|
function configList() {
|
|
@@ -13516,7 +13649,7 @@ function configList() {
|
|
|
13516
13649
|
}
|
|
13517
13650
|
|
|
13518
13651
|
// src/commands/config/configGet.ts
|
|
13519
|
-
import
|
|
13652
|
+
import chalk122 from "chalk";
|
|
13520
13653
|
|
|
13521
13654
|
// src/commands/config/getNestedValue.ts
|
|
13522
13655
|
function isTraversable(value) {
|
|
@@ -13548,7 +13681,7 @@ function requireNestedValue(config, key) {
|
|
|
13548
13681
|
return value;
|
|
13549
13682
|
}
|
|
13550
13683
|
function exitKeyNotSet(key) {
|
|
13551
|
-
console.error(
|
|
13684
|
+
console.error(chalk122.red(`Key "${key}" is not set`));
|
|
13552
13685
|
process.exit(1);
|
|
13553
13686
|
}
|
|
13554
13687
|
|
|
@@ -13561,40 +13694,40 @@ function registerConfig(program2) {
|
|
|
13561
13694
|
}
|
|
13562
13695
|
|
|
13563
13696
|
// src/commands/db/reportMigrationStatus.ts
|
|
13564
|
-
import
|
|
13697
|
+
import chalk123 from "chalk";
|
|
13565
13698
|
function reportApplied(applied) {
|
|
13566
13699
|
if (applied.length === 0) {
|
|
13567
|
-
console.error(
|
|
13700
|
+
console.error(chalk123.green("Database is up to date; nothing to apply."));
|
|
13568
13701
|
return;
|
|
13569
13702
|
}
|
|
13570
13703
|
for (const migration of applied) {
|
|
13571
13704
|
console.error(
|
|
13572
|
-
|
|
13705
|
+
chalk123.green(`Applied migration ${migration.id} (${migration.name}).`)
|
|
13573
13706
|
);
|
|
13574
13707
|
}
|
|
13575
13708
|
}
|
|
13576
13709
|
function reportMigrationStatus(status3) {
|
|
13577
13710
|
if (status3.state === "in-sync") {
|
|
13578
13711
|
console.error(
|
|
13579
|
-
|
|
13712
|
+
chalk123.green(`In sync at migration ${status3.version} (latest).`)
|
|
13580
13713
|
);
|
|
13581
13714
|
return;
|
|
13582
13715
|
}
|
|
13583
13716
|
if (status3.state === "behind") {
|
|
13584
13717
|
console.error(
|
|
13585
|
-
|
|
13718
|
+
chalk123.yellow(
|
|
13586
13719
|
`Behind: applied ${status3.applied}, build expects ${status3.expected}.`
|
|
13587
13720
|
)
|
|
13588
13721
|
);
|
|
13589
13722
|
console.error(
|
|
13590
|
-
|
|
13723
|
+
chalk123.yellow(
|
|
13591
13724
|
`Pending: ${status3.pending.join(", ")}. Run \`assist db migrate\`.`
|
|
13592
13725
|
)
|
|
13593
13726
|
);
|
|
13594
13727
|
return;
|
|
13595
13728
|
}
|
|
13596
13729
|
console.error(
|
|
13597
|
-
|
|
13730
|
+
chalk123.red(
|
|
13598
13731
|
`Ahead: applied ${status3.applied}, build knows ${status3.expected}. Update assist.`
|
|
13599
13732
|
)
|
|
13600
13733
|
);
|
|
@@ -13629,7 +13762,7 @@ function registerDb(program2) {
|
|
|
13629
13762
|
|
|
13630
13763
|
// src/commands/deploy/redirect.ts
|
|
13631
13764
|
import { existsSync as existsSync32, readFileSync as readFileSync28, writeFileSync as writeFileSync26 } from "fs";
|
|
13632
|
-
import
|
|
13765
|
+
import chalk124 from "chalk";
|
|
13633
13766
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
13634
13767
|
if (!window.location.pathname.endsWith('/')) {
|
|
13635
13768
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -13638,23 +13771,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
13638
13771
|
function redirect() {
|
|
13639
13772
|
const indexPath = "index.html";
|
|
13640
13773
|
if (!existsSync32(indexPath)) {
|
|
13641
|
-
console.log(
|
|
13774
|
+
console.log(chalk124.yellow("No index.html found"));
|
|
13642
13775
|
return;
|
|
13643
13776
|
}
|
|
13644
13777
|
const content = readFileSync28(indexPath, "utf8");
|
|
13645
13778
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
13646
|
-
console.log(
|
|
13779
|
+
console.log(chalk124.dim("Trailing slash script already present"));
|
|
13647
13780
|
return;
|
|
13648
13781
|
}
|
|
13649
13782
|
const headCloseIndex = content.indexOf("</head>");
|
|
13650
13783
|
if (headCloseIndex === -1) {
|
|
13651
|
-
console.log(
|
|
13784
|
+
console.log(chalk124.red("Could not find </head> tag in index.html"));
|
|
13652
13785
|
return;
|
|
13653
13786
|
}
|
|
13654
13787
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
13655
13788
|
${content.slice(headCloseIndex)}`;
|
|
13656
13789
|
writeFileSync26(indexPath, newContent);
|
|
13657
|
-
console.log(
|
|
13790
|
+
console.log(chalk124.green("Added trailing slash redirect to index.html"));
|
|
13658
13791
|
}
|
|
13659
13792
|
|
|
13660
13793
|
// src/commands/registerDeploy.ts
|
|
@@ -13680,8 +13813,8 @@ function loadBlogSkipDays(repoName) {
|
|
|
13680
13813
|
}
|
|
13681
13814
|
|
|
13682
13815
|
// src/commands/devlog/shared.ts
|
|
13683
|
-
import { execSync as
|
|
13684
|
-
import
|
|
13816
|
+
import { execSync as execSync32 } from "child_process";
|
|
13817
|
+
import chalk125 from "chalk";
|
|
13685
13818
|
|
|
13686
13819
|
// src/shared/getRepoName.ts
|
|
13687
13820
|
import { existsSync as existsSync33, readFileSync as readFileSync29 } from "fs";
|
|
@@ -13772,7 +13905,7 @@ function loadAllDevlogLatestDates() {
|
|
|
13772
13905
|
// src/commands/devlog/shared.ts
|
|
13773
13906
|
function getCommitFiles(hash) {
|
|
13774
13907
|
try {
|
|
13775
|
-
const output =
|
|
13908
|
+
const output = execSync32(`git show --name-only --format="" ${hash}`, {
|
|
13776
13909
|
encoding: "utf8"
|
|
13777
13910
|
});
|
|
13778
13911
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -13790,13 +13923,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
13790
13923
|
}
|
|
13791
13924
|
function printCommitsWithFiles(commits2, ignore3, verbose) {
|
|
13792
13925
|
for (const commit2 of commits2) {
|
|
13793
|
-
console.log(` ${
|
|
13926
|
+
console.log(` ${chalk125.yellow(commit2.hash)} ${commit2.message}`);
|
|
13794
13927
|
if (verbose) {
|
|
13795
13928
|
const visibleFiles = commit2.files.filter(
|
|
13796
13929
|
(file) => !ignore3.some((p) => file.startsWith(p))
|
|
13797
13930
|
);
|
|
13798
13931
|
for (const file of visibleFiles) {
|
|
13799
|
-
console.log(` ${
|
|
13932
|
+
console.log(` ${chalk125.dim(file)}`);
|
|
13800
13933
|
}
|
|
13801
13934
|
}
|
|
13802
13935
|
}
|
|
@@ -13821,15 +13954,15 @@ function parseGitLogCommits(output, ignore3, afterDate) {
|
|
|
13821
13954
|
}
|
|
13822
13955
|
|
|
13823
13956
|
// src/commands/devlog/list/printDateHeader.ts
|
|
13824
|
-
import
|
|
13957
|
+
import chalk126 from "chalk";
|
|
13825
13958
|
function printDateHeader(date, isSkipped, entries) {
|
|
13826
13959
|
if (isSkipped) {
|
|
13827
|
-
console.log(`${
|
|
13960
|
+
console.log(`${chalk126.bold.blue(date)} ${chalk126.dim("skipped")}`);
|
|
13828
13961
|
} else if (entries && entries.length > 0) {
|
|
13829
|
-
const entryInfo = entries.map((e) => `${
|
|
13830
|
-
console.log(`${
|
|
13962
|
+
const entryInfo = entries.map((e) => `${chalk126.green(e.version)} ${e.title}`).join(" | ");
|
|
13963
|
+
console.log(`${chalk126.bold.blue(date)} ${entryInfo}`);
|
|
13831
13964
|
} else {
|
|
13832
|
-
console.log(`${
|
|
13965
|
+
console.log(`${chalk126.bold.blue(date)} ${chalk126.red("\u26A0 devlog missing")}`);
|
|
13833
13966
|
}
|
|
13834
13967
|
}
|
|
13835
13968
|
|
|
@@ -13868,11 +14001,11 @@ function list3(options2) {
|
|
|
13868
14001
|
}
|
|
13869
14002
|
|
|
13870
14003
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
13871
|
-
import { execFileSync as execFileSync3, execSync as
|
|
14004
|
+
import { execFileSync as execFileSync3, execSync as execSync33 } from "child_process";
|
|
13872
14005
|
import semver from "semver";
|
|
13873
14006
|
function getVersionAtCommit(hash) {
|
|
13874
14007
|
try {
|
|
13875
|
-
const content =
|
|
14008
|
+
const content = execSync33(`git show ${hash}:package.json`, {
|
|
13876
14009
|
encoding: "utf8"
|
|
13877
14010
|
});
|
|
13878
14011
|
const pkg = JSON.parse(content);
|
|
@@ -13933,24 +14066,24 @@ function bumpVersion(version2, type) {
|
|
|
13933
14066
|
|
|
13934
14067
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
13935
14068
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
13936
|
-
import
|
|
14069
|
+
import chalk128 from "chalk";
|
|
13937
14070
|
|
|
13938
14071
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
13939
|
-
import
|
|
14072
|
+
import chalk127 from "chalk";
|
|
13940
14073
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
13941
14074
|
if (conventional && firstHash) {
|
|
13942
14075
|
const version2 = getVersionAtCommit(firstHash);
|
|
13943
14076
|
if (version2) {
|
|
13944
|
-
console.log(`${
|
|
14077
|
+
console.log(`${chalk127.bold("version:")} ${stripToMinor(version2)}`);
|
|
13945
14078
|
} else {
|
|
13946
|
-
console.log(`${
|
|
14079
|
+
console.log(`${chalk127.bold("version:")} ${chalk127.red("unknown")}`);
|
|
13947
14080
|
}
|
|
13948
14081
|
} else if (patchVersion && minorVersion) {
|
|
13949
14082
|
console.log(
|
|
13950
|
-
`${
|
|
14083
|
+
`${chalk127.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
13951
14084
|
);
|
|
13952
14085
|
} else {
|
|
13953
|
-
console.log(`${
|
|
14086
|
+
console.log(`${chalk127.bold("version:")} v0.1 (initial)`);
|
|
13954
14087
|
}
|
|
13955
14088
|
}
|
|
13956
14089
|
|
|
@@ -13998,16 +14131,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
13998
14131
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
13999
14132
|
}
|
|
14000
14133
|
function logName(repoName) {
|
|
14001
|
-
console.log(`${
|
|
14134
|
+
console.log(`${chalk128.bold("name:")} ${repoName}`);
|
|
14002
14135
|
}
|
|
14003
14136
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
14004
14137
|
logName(ctx.repoName);
|
|
14005
14138
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
14006
|
-
console.log(
|
|
14139
|
+
console.log(chalk128.bold.blue(targetDate));
|
|
14007
14140
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
14008
14141
|
}
|
|
14009
14142
|
function logNoCommits(lastInfo) {
|
|
14010
|
-
console.log(
|
|
14143
|
+
console.log(chalk128.dim(noCommitsMessage(!!lastInfo)));
|
|
14011
14144
|
}
|
|
14012
14145
|
|
|
14013
14146
|
// src/commands/devlog/next/index.ts
|
|
@@ -14045,14 +14178,14 @@ function next2(options2) {
|
|
|
14045
14178
|
}
|
|
14046
14179
|
|
|
14047
14180
|
// src/commands/devlog/repos/index.ts
|
|
14048
|
-
import { execSync as
|
|
14181
|
+
import { execSync as execSync34 } from "child_process";
|
|
14049
14182
|
|
|
14050
14183
|
// src/commands/devlog/repos/printReposTable.ts
|
|
14051
|
-
import
|
|
14184
|
+
import chalk129 from "chalk";
|
|
14052
14185
|
function colorStatus(status3) {
|
|
14053
|
-
if (status3 === "missing") return
|
|
14054
|
-
if (status3 === "outdated") return
|
|
14055
|
-
return
|
|
14186
|
+
if (status3 === "missing") return chalk129.red(status3);
|
|
14187
|
+
if (status3 === "outdated") return chalk129.yellow(status3);
|
|
14188
|
+
return chalk129.green(status3);
|
|
14056
14189
|
}
|
|
14057
14190
|
function formatRow(row, nameWidth) {
|
|
14058
14191
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -14066,8 +14199,8 @@ function printReposTable(rows) {
|
|
|
14066
14199
|
"Last Devlog".padEnd(11),
|
|
14067
14200
|
"Status"
|
|
14068
14201
|
].join(" ");
|
|
14069
|
-
console.log(
|
|
14070
|
-
console.log(
|
|
14202
|
+
console.log(chalk129.dim(header));
|
|
14203
|
+
console.log(chalk129.dim("-".repeat(header.length)));
|
|
14071
14204
|
for (const row of rows) {
|
|
14072
14205
|
console.log(formatRow(row, nameWidth));
|
|
14073
14206
|
}
|
|
@@ -14080,7 +14213,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
14080
14213
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
14081
14214
|
}
|
|
14082
14215
|
function fetchRepos(days, all) {
|
|
14083
|
-
const json =
|
|
14216
|
+
const json = execSync34(
|
|
14084
14217
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
14085
14218
|
{ encoding: "utf8" }
|
|
14086
14219
|
);
|
|
@@ -14125,14 +14258,14 @@ function repos(options2) {
|
|
|
14125
14258
|
// src/commands/devlog/skip.ts
|
|
14126
14259
|
import { writeFileSync as writeFileSync27 } from "fs";
|
|
14127
14260
|
import { join as join36 } from "path";
|
|
14128
|
-
import
|
|
14261
|
+
import chalk130 from "chalk";
|
|
14129
14262
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
14130
14263
|
function getBlogConfigPath() {
|
|
14131
14264
|
return join36(BLOG_REPO_ROOT, "assist.yml");
|
|
14132
14265
|
}
|
|
14133
14266
|
function skip(date) {
|
|
14134
14267
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
14135
|
-
console.log(
|
|
14268
|
+
console.log(chalk130.red("Invalid date format. Use YYYY-MM-DD"));
|
|
14136
14269
|
process.exit(1);
|
|
14137
14270
|
}
|
|
14138
14271
|
const repoName = getRepoName();
|
|
@@ -14143,7 +14276,7 @@ function skip(date) {
|
|
|
14143
14276
|
const skipDays = skip2[repoName] ?? [];
|
|
14144
14277
|
if (skipDays.includes(date)) {
|
|
14145
14278
|
console.log(
|
|
14146
|
-
|
|
14279
|
+
chalk130.yellow(`${date} is already in skip list for ${repoName}`)
|
|
14147
14280
|
);
|
|
14148
14281
|
return;
|
|
14149
14282
|
}
|
|
@@ -14153,20 +14286,20 @@ function skip(date) {
|
|
|
14153
14286
|
devlog.skip = skip2;
|
|
14154
14287
|
config.devlog = devlog;
|
|
14155
14288
|
writeFileSync27(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
14156
|
-
console.log(
|
|
14289
|
+
console.log(chalk130.green(`Added ${date} to skip list for ${repoName}`));
|
|
14157
14290
|
}
|
|
14158
14291
|
|
|
14159
14292
|
// src/commands/devlog/version.ts
|
|
14160
|
-
import
|
|
14293
|
+
import chalk131 from "chalk";
|
|
14161
14294
|
function version() {
|
|
14162
14295
|
const config = loadConfig();
|
|
14163
14296
|
const name = getRepoName();
|
|
14164
14297
|
const lastInfo = getLastVersionInfo(name, config);
|
|
14165
14298
|
const lastVersion = lastInfo?.version ?? null;
|
|
14166
14299
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
14167
|
-
console.log(`${
|
|
14168
|
-
console.log(`${
|
|
14169
|
-
console.log(`${
|
|
14300
|
+
console.log(`${chalk131.bold("name:")} ${name}`);
|
|
14301
|
+
console.log(`${chalk131.bold("last:")} ${lastVersion ?? chalk131.dim("none")}`);
|
|
14302
|
+
console.log(`${chalk131.bold("next:")} ${nextVersion ?? chalk131.dim("none")}`);
|
|
14170
14303
|
}
|
|
14171
14304
|
|
|
14172
14305
|
// src/commands/devlog/devlogConfigHelp.ts
|
|
@@ -14210,7 +14343,7 @@ function registerDevlog(program2) {
|
|
|
14210
14343
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
14211
14344
|
import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync5 } from "fs";
|
|
14212
14345
|
import { join as join37 } from "path";
|
|
14213
|
-
import
|
|
14346
|
+
import chalk132 from "chalk";
|
|
14214
14347
|
|
|
14215
14348
|
// src/shared/findRepoRoot.ts
|
|
14216
14349
|
import { existsSync as existsSync34 } from "fs";
|
|
@@ -14273,14 +14406,14 @@ function checkBuildLocks(startDir) {
|
|
|
14273
14406
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
14274
14407
|
if (locked) {
|
|
14275
14408
|
console.error(
|
|
14276
|
-
|
|
14409
|
+
chalk132.red("Build output locked (is VS debugging?): ") + locked
|
|
14277
14410
|
);
|
|
14278
14411
|
process.exit(1);
|
|
14279
14412
|
}
|
|
14280
14413
|
}
|
|
14281
14414
|
async function checkBuildLocksCommand() {
|
|
14282
14415
|
checkBuildLocks();
|
|
14283
|
-
console.log(
|
|
14416
|
+
console.log(chalk132.green("No build locks detected"));
|
|
14284
14417
|
}
|
|
14285
14418
|
|
|
14286
14419
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -14379,30 +14512,30 @@ function escapeRegex(s) {
|
|
|
14379
14512
|
}
|
|
14380
14513
|
|
|
14381
14514
|
// src/commands/dotnet/printTree.ts
|
|
14382
|
-
import
|
|
14515
|
+
import chalk133 from "chalk";
|
|
14383
14516
|
function printNodes(nodes, prefix2) {
|
|
14384
14517
|
for (let i = 0; i < nodes.length; i++) {
|
|
14385
14518
|
const isLast = i === nodes.length - 1;
|
|
14386
14519
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
14387
14520
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
14388
14521
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
14389
|
-
const label2 = isMissing ?
|
|
14522
|
+
const label2 = isMissing ? chalk133.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
14390
14523
|
console.log(`${prefix2}${connector}${label2}`);
|
|
14391
14524
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
14392
14525
|
}
|
|
14393
14526
|
}
|
|
14394
14527
|
function printTree(tree, totalCount, solutions) {
|
|
14395
|
-
console.log(
|
|
14396
|
-
console.log(
|
|
14528
|
+
console.log(chalk133.bold("\nProject Dependency Tree"));
|
|
14529
|
+
console.log(chalk133.cyan(tree.relativePath));
|
|
14397
14530
|
printNodes(tree.children, "");
|
|
14398
|
-
console.log(
|
|
14531
|
+
console.log(chalk133.dim(`
|
|
14399
14532
|
${totalCount} projects total (including root)`));
|
|
14400
|
-
console.log(
|
|
14533
|
+
console.log(chalk133.bold("\nSolution Membership"));
|
|
14401
14534
|
if (solutions.length === 0) {
|
|
14402
|
-
console.log(
|
|
14535
|
+
console.log(chalk133.yellow(" Not found in any .sln"));
|
|
14403
14536
|
} else {
|
|
14404
14537
|
for (const sln of solutions) {
|
|
14405
|
-
console.log(` ${
|
|
14538
|
+
console.log(` ${chalk133.green(sln)}`);
|
|
14406
14539
|
}
|
|
14407
14540
|
}
|
|
14408
14541
|
console.log();
|
|
@@ -14431,16 +14564,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
14431
14564
|
// src/commands/dotnet/resolveCsproj.ts
|
|
14432
14565
|
import { existsSync as existsSync35 } from "fs";
|
|
14433
14566
|
import path31 from "path";
|
|
14434
|
-
import
|
|
14567
|
+
import chalk134 from "chalk";
|
|
14435
14568
|
function resolveCsproj(csprojPath) {
|
|
14436
14569
|
const resolved = path31.resolve(csprojPath);
|
|
14437
14570
|
if (!existsSync35(resolved)) {
|
|
14438
|
-
console.error(
|
|
14571
|
+
console.error(chalk134.red(`File not found: ${resolved}`));
|
|
14439
14572
|
process.exit(1);
|
|
14440
14573
|
}
|
|
14441
14574
|
const repoRoot = findRepoRoot(path31.dirname(resolved));
|
|
14442
14575
|
if (!repoRoot) {
|
|
14443
|
-
console.error(
|
|
14576
|
+
console.error(chalk134.red("Could not find git repository root"));
|
|
14444
14577
|
process.exit(1);
|
|
14445
14578
|
}
|
|
14446
14579
|
return { resolved, repoRoot };
|
|
@@ -14460,7 +14593,7 @@ async function deps(csprojPath, options2) {
|
|
|
14460
14593
|
}
|
|
14461
14594
|
|
|
14462
14595
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
14463
|
-
import { execSync as
|
|
14596
|
+
import { execSync as execSync35 } from "child_process";
|
|
14464
14597
|
var SCOPE_ALL = "all";
|
|
14465
14598
|
var SCOPE_BASE = "base:";
|
|
14466
14599
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -14484,18 +14617,18 @@ function getChangedCsFiles(scope) {
|
|
|
14484
14617
|
} else {
|
|
14485
14618
|
cmd = "git diff --name-only HEAD";
|
|
14486
14619
|
}
|
|
14487
|
-
const output =
|
|
14620
|
+
const output = execSync35(cmd, { encoding: "utf8" }).trim();
|
|
14488
14621
|
if (output === "") return [];
|
|
14489
14622
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
14490
14623
|
}
|
|
14491
14624
|
|
|
14492
14625
|
// src/commands/dotnet/inSln.ts
|
|
14493
|
-
import
|
|
14626
|
+
import chalk135 from "chalk";
|
|
14494
14627
|
async function inSln(csprojPath) {
|
|
14495
14628
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
14496
14629
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
14497
14630
|
if (solutions.length === 0) {
|
|
14498
|
-
console.log(
|
|
14631
|
+
console.log(chalk135.yellow("Not found in any .sln file"));
|
|
14499
14632
|
process.exit(1);
|
|
14500
14633
|
}
|
|
14501
14634
|
for (const sln of solutions) {
|
|
@@ -14504,7 +14637,7 @@ async function inSln(csprojPath) {
|
|
|
14504
14637
|
}
|
|
14505
14638
|
|
|
14506
14639
|
// src/commands/dotnet/inspect.ts
|
|
14507
|
-
import
|
|
14640
|
+
import chalk141 from "chalk";
|
|
14508
14641
|
|
|
14509
14642
|
// src/shared/formatElapsed.ts
|
|
14510
14643
|
function formatElapsed(ms) {
|
|
@@ -14516,12 +14649,12 @@ function formatElapsed(ms) {
|
|
|
14516
14649
|
}
|
|
14517
14650
|
|
|
14518
14651
|
// src/commands/dotnet/displayIssues.ts
|
|
14519
|
-
import
|
|
14652
|
+
import chalk136 from "chalk";
|
|
14520
14653
|
var SEVERITY_COLOR = {
|
|
14521
|
-
ERROR:
|
|
14522
|
-
WARNING:
|
|
14523
|
-
SUGGESTION:
|
|
14524
|
-
HINT:
|
|
14654
|
+
ERROR: chalk136.red,
|
|
14655
|
+
WARNING: chalk136.yellow,
|
|
14656
|
+
SUGGESTION: chalk136.cyan,
|
|
14657
|
+
HINT: chalk136.dim
|
|
14525
14658
|
};
|
|
14526
14659
|
function groupByFile(issues) {
|
|
14527
14660
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -14537,15 +14670,15 @@ function groupByFile(issues) {
|
|
|
14537
14670
|
}
|
|
14538
14671
|
function displayIssues(issues) {
|
|
14539
14672
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
14540
|
-
console.log(
|
|
14673
|
+
console.log(chalk136.bold(file));
|
|
14541
14674
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
14542
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
14675
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk136.white;
|
|
14543
14676
|
console.log(
|
|
14544
|
-
` ${
|
|
14677
|
+
` ${chalk136.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
14545
14678
|
);
|
|
14546
14679
|
}
|
|
14547
14680
|
}
|
|
14548
|
-
console.log(
|
|
14681
|
+
console.log(chalk136.dim(`
|
|
14549
14682
|
${issues.length} issue(s) found`));
|
|
14550
14683
|
}
|
|
14551
14684
|
|
|
@@ -14604,12 +14737,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
14604
14737
|
// src/commands/dotnet/resolveSolution.ts
|
|
14605
14738
|
import { existsSync as existsSync36 } from "fs";
|
|
14606
14739
|
import path32 from "path";
|
|
14607
|
-
import
|
|
14740
|
+
import chalk138 from "chalk";
|
|
14608
14741
|
|
|
14609
14742
|
// src/commands/dotnet/findSolution.ts
|
|
14610
14743
|
import { readdirSync as readdirSync7 } from "fs";
|
|
14611
14744
|
import { dirname as dirname22, join as join38 } from "path";
|
|
14612
|
-
import
|
|
14745
|
+
import chalk137 from "chalk";
|
|
14613
14746
|
function findSlnInDir(dir) {
|
|
14614
14747
|
try {
|
|
14615
14748
|
return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) => join38(dir, f));
|
|
@@ -14625,17 +14758,17 @@ function findSolution() {
|
|
|
14625
14758
|
const slnFiles = findSlnInDir(current);
|
|
14626
14759
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
14627
14760
|
if (slnFiles.length > 1) {
|
|
14628
|
-
console.error(
|
|
14761
|
+
console.error(chalk137.red(`Multiple .sln files found in ${current}:`));
|
|
14629
14762
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
14630
14763
|
console.error(
|
|
14631
|
-
|
|
14764
|
+
chalk137.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
14632
14765
|
);
|
|
14633
14766
|
process.exit(1);
|
|
14634
14767
|
}
|
|
14635
14768
|
if (current === ceiling) break;
|
|
14636
14769
|
current = dirname22(current);
|
|
14637
14770
|
}
|
|
14638
|
-
console.error(
|
|
14771
|
+
console.error(chalk137.red("No .sln file found between cwd and repo root"));
|
|
14639
14772
|
process.exit(1);
|
|
14640
14773
|
}
|
|
14641
14774
|
|
|
@@ -14644,7 +14777,7 @@ function resolveSolution(sln) {
|
|
|
14644
14777
|
if (sln) {
|
|
14645
14778
|
const resolved = path32.resolve(sln);
|
|
14646
14779
|
if (!existsSync36(resolved)) {
|
|
14647
|
-
console.error(
|
|
14780
|
+
console.error(chalk138.red(`Solution file not found: ${resolved}`));
|
|
14648
14781
|
process.exit(1);
|
|
14649
14782
|
}
|
|
14650
14783
|
return resolved;
|
|
@@ -14682,18 +14815,18 @@ function parseInspectReport(json) {
|
|
|
14682
14815
|
}
|
|
14683
14816
|
|
|
14684
14817
|
// src/commands/dotnet/runInspectCode.ts
|
|
14685
|
-
import { execSync as
|
|
14818
|
+
import { execSync as execSync36 } from "child_process";
|
|
14686
14819
|
import { existsSync as existsSync37, readFileSync as readFileSync33, unlinkSync as unlinkSync9 } from "fs";
|
|
14687
14820
|
import { tmpdir as tmpdir3 } from "os";
|
|
14688
14821
|
import path33 from "path";
|
|
14689
|
-
import
|
|
14822
|
+
import chalk139 from "chalk";
|
|
14690
14823
|
function assertJbInstalled() {
|
|
14691
14824
|
try {
|
|
14692
|
-
|
|
14825
|
+
execSync36("jb inspectcode --version", { stdio: "pipe" });
|
|
14693
14826
|
} catch {
|
|
14694
|
-
console.error(
|
|
14827
|
+
console.error(chalk139.red("jb is not installed. Install with:"));
|
|
14695
14828
|
console.error(
|
|
14696
|
-
|
|
14829
|
+
chalk139.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
14697
14830
|
);
|
|
14698
14831
|
process.exit(1);
|
|
14699
14832
|
}
|
|
@@ -14703,7 +14836,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
14703
14836
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
14704
14837
|
const sweaFlag = swea ? " --swea" : "";
|
|
14705
14838
|
try {
|
|
14706
|
-
|
|
14839
|
+
execSync36(
|
|
14707
14840
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
14708
14841
|
{ stdio: "pipe" }
|
|
14709
14842
|
);
|
|
@@ -14711,11 +14844,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
14711
14844
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
14712
14845
|
process.stderr.write(error.stderr);
|
|
14713
14846
|
}
|
|
14714
|
-
console.error(
|
|
14847
|
+
console.error(chalk139.red("jb inspectcode failed"));
|
|
14715
14848
|
process.exit(1);
|
|
14716
14849
|
}
|
|
14717
14850
|
if (!existsSync37(reportPath)) {
|
|
14718
|
-
console.error(
|
|
14851
|
+
console.error(chalk139.red("Report file not generated"));
|
|
14719
14852
|
process.exit(1);
|
|
14720
14853
|
}
|
|
14721
14854
|
const xml = readFileSync33(reportPath, "utf8");
|
|
@@ -14724,8 +14857,8 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
14724
14857
|
}
|
|
14725
14858
|
|
|
14726
14859
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
14727
|
-
import { execSync as
|
|
14728
|
-
import
|
|
14860
|
+
import { execSync as execSync37 } from "child_process";
|
|
14861
|
+
import chalk140 from "chalk";
|
|
14729
14862
|
function resolveMsbuildPath() {
|
|
14730
14863
|
const { run: run4 } = loadConfig();
|
|
14731
14864
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -14735,11 +14868,11 @@ function resolveMsbuildPath() {
|
|
|
14735
14868
|
function assertMsbuildInstalled() {
|
|
14736
14869
|
const msbuild = resolveMsbuildPath();
|
|
14737
14870
|
try {
|
|
14738
|
-
|
|
14871
|
+
execSync37(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
14739
14872
|
} catch {
|
|
14740
|
-
console.error(
|
|
14873
|
+
console.error(chalk140.red(`msbuild not found at: ${msbuild}`));
|
|
14741
14874
|
console.error(
|
|
14742
|
-
|
|
14875
|
+
chalk140.yellow(
|
|
14743
14876
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
14744
14877
|
)
|
|
14745
14878
|
);
|
|
@@ -14761,7 +14894,7 @@ function runRoslynInspect(slnPath) {
|
|
|
14761
14894
|
const msbuild = resolveMsbuildPath();
|
|
14762
14895
|
let output;
|
|
14763
14896
|
try {
|
|
14764
|
-
output =
|
|
14897
|
+
output = execSync37(
|
|
14765
14898
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
14766
14899
|
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
14767
14900
|
);
|
|
@@ -14786,17 +14919,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
14786
14919
|
// src/commands/dotnet/inspect.ts
|
|
14787
14920
|
function logScope(changedFiles) {
|
|
14788
14921
|
if (changedFiles === null) {
|
|
14789
|
-
console.log(
|
|
14922
|
+
console.log(chalk141.dim("Inspecting full solution..."));
|
|
14790
14923
|
} else {
|
|
14791
14924
|
console.log(
|
|
14792
|
-
|
|
14925
|
+
chalk141.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
14793
14926
|
);
|
|
14794
14927
|
}
|
|
14795
14928
|
}
|
|
14796
14929
|
function reportResults(issues, elapsed) {
|
|
14797
14930
|
if (issues.length > 0) displayIssues(issues);
|
|
14798
|
-
else console.log(
|
|
14799
|
-
console.log(
|
|
14931
|
+
else console.log(chalk141.green("No issues found"));
|
|
14932
|
+
console.log(chalk141.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
14800
14933
|
if (issues.length > 0) process.exit(1);
|
|
14801
14934
|
}
|
|
14802
14935
|
async function inspect(sln, options2) {
|
|
@@ -14807,7 +14940,7 @@ async function inspect(sln, options2) {
|
|
|
14807
14940
|
const scope = parseScope(options2.scope);
|
|
14808
14941
|
const changedFiles = getChangedCsFiles(scope);
|
|
14809
14942
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
14810
|
-
console.log(
|
|
14943
|
+
console.log(chalk141.green("No changed .cs files found"));
|
|
14811
14944
|
return;
|
|
14812
14945
|
}
|
|
14813
14946
|
logScope(changedFiles);
|
|
@@ -15155,25 +15288,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
15155
15288
|
}
|
|
15156
15289
|
|
|
15157
15290
|
// src/commands/github/printCountTable.ts
|
|
15158
|
-
import
|
|
15291
|
+
import chalk142 from "chalk";
|
|
15159
15292
|
function printCountTable(labelHeader, rows) {
|
|
15160
15293
|
const labelWidth = Math.max(
|
|
15161
15294
|
labelHeader.length,
|
|
15162
15295
|
...rows.map((row) => row.label.length)
|
|
15163
15296
|
);
|
|
15164
15297
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
15165
|
-
console.log(
|
|
15166
|
-
console.log(
|
|
15298
|
+
console.log(chalk142.dim(header));
|
|
15299
|
+
console.log(chalk142.dim("-".repeat(header.length)));
|
|
15167
15300
|
for (const row of rows) {
|
|
15168
15301
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
15169
15302
|
}
|
|
15170
15303
|
}
|
|
15171
15304
|
|
|
15172
15305
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
15173
|
-
import
|
|
15306
|
+
import chalk143 from "chalk";
|
|
15174
15307
|
function printRepoAuthorBreakdown(repos2) {
|
|
15175
15308
|
for (const repo of repos2) {
|
|
15176
|
-
console.log(
|
|
15309
|
+
console.log(chalk143.bold(repo.name));
|
|
15177
15310
|
const authorWidth = Math.max(
|
|
15178
15311
|
0,
|
|
15179
15312
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -15270,9 +15403,9 @@ function registerGithub(program2) {
|
|
|
15270
15403
|
}
|
|
15271
15404
|
|
|
15272
15405
|
// src/commands/handover/countPendingHandovers.ts
|
|
15273
|
-
import { and as and18, eq as
|
|
15406
|
+
import { and as and18, eq as eq37, isNull, sql as sql17 } from "drizzle-orm";
|
|
15274
15407
|
async function countPendingHandovers(orm, origin) {
|
|
15275
|
-
const [row] = await orm.select({ count:
|
|
15408
|
+
const [row] = await orm.select({ count: sql17`count(*)::int` }).from(handovers).where(and18(eq37(handovers.origin, origin), isNull(handovers.recalledAt)));
|
|
15276
15409
|
return row?.count ?? 0;
|
|
15277
15410
|
}
|
|
15278
15411
|
|
|
@@ -15412,13 +15545,13 @@ async function load2(options2 = {}) {
|
|
|
15412
15545
|
}
|
|
15413
15546
|
|
|
15414
15547
|
// src/commands/handover/listPendingHandovers.ts
|
|
15415
|
-
import { and as and19, desc as desc4, eq as
|
|
15548
|
+
import { and as and19, desc as desc4, eq as eq38, isNull as isNull2 } from "drizzle-orm";
|
|
15416
15549
|
async function listPendingHandovers(orm, origin) {
|
|
15417
15550
|
return orm.select({
|
|
15418
15551
|
id: handovers.id,
|
|
15419
15552
|
summary: handovers.summary,
|
|
15420
15553
|
createdAt: handovers.createdAt
|
|
15421
|
-
}).from(handovers).where(and19(
|
|
15554
|
+
}).from(handovers).where(and19(eq38(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc4(handovers.createdAt), desc4(handovers.id));
|
|
15422
15555
|
}
|
|
15423
15556
|
|
|
15424
15557
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -15431,17 +15564,17 @@ async function printPendingHandovers() {
|
|
|
15431
15564
|
}
|
|
15432
15565
|
|
|
15433
15566
|
// src/commands/handover/recallHandover.ts
|
|
15434
|
-
import { and as and20, desc as desc5, eq as
|
|
15567
|
+
import { and as and20, desc as desc5, eq as eq39, isNull as isNull3 } from "drizzle-orm";
|
|
15435
15568
|
async function recallHandover(orm, origin, id) {
|
|
15436
15569
|
const [row] = await orm.select().from(handovers).where(
|
|
15437
15570
|
and20(
|
|
15438
|
-
|
|
15571
|
+
eq39(handovers.origin, origin),
|
|
15439
15572
|
isNull3(handovers.recalledAt),
|
|
15440
|
-
...id === void 0 ? [] : [
|
|
15573
|
+
...id === void 0 ? [] : [eq39(handovers.id, id)]
|
|
15441
15574
|
)
|
|
15442
15575
|
).orderBy(desc5(handovers.createdAt), desc5(handovers.id)).limit(1);
|
|
15443
15576
|
if (!row) return void 0;
|
|
15444
|
-
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(
|
|
15577
|
+
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq39(handovers.id, row.id));
|
|
15445
15578
|
return row.content;
|
|
15446
15579
|
}
|
|
15447
15580
|
|
|
@@ -15491,7 +15624,7 @@ function registerHandover(program2) {
|
|
|
15491
15624
|
}
|
|
15492
15625
|
|
|
15493
15626
|
// src/commands/jira/acceptanceCriteria.ts
|
|
15494
|
-
import
|
|
15627
|
+
import chalk144 from "chalk";
|
|
15495
15628
|
|
|
15496
15629
|
// src/commands/jira/adfToText.ts
|
|
15497
15630
|
function renderInline(node) {
|
|
@@ -15558,7 +15691,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
15558
15691
|
const parsed = fetchIssue(issueKey, field);
|
|
15559
15692
|
const acValue = parsed?.fields?.[field];
|
|
15560
15693
|
if (!acValue) {
|
|
15561
|
-
console.log(
|
|
15694
|
+
console.log(chalk144.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
15562
15695
|
return;
|
|
15563
15696
|
}
|
|
15564
15697
|
if (typeof acValue === "string") {
|
|
@@ -15573,7 +15706,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
15573
15706
|
}
|
|
15574
15707
|
|
|
15575
15708
|
// src/commands/jira/jiraAuth.ts
|
|
15576
|
-
import { execSync as
|
|
15709
|
+
import { execSync as execSync38 } from "child_process";
|
|
15577
15710
|
|
|
15578
15711
|
// src/shared/promptInput.ts
|
|
15579
15712
|
import Enquirer from "enquirer";
|
|
@@ -15608,7 +15741,7 @@ async function jiraAuth() {
|
|
|
15608
15741
|
console.error("All fields are required.");
|
|
15609
15742
|
process.exit(1);
|
|
15610
15743
|
}
|
|
15611
|
-
|
|
15744
|
+
execSync38(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
15612
15745
|
encoding: "utf8",
|
|
15613
15746
|
input: token,
|
|
15614
15747
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -15624,14 +15757,14 @@ async function jiraAuth() {
|
|
|
15624
15757
|
}
|
|
15625
15758
|
|
|
15626
15759
|
// src/commands/jira/viewIssue.ts
|
|
15627
|
-
import
|
|
15760
|
+
import chalk145 from "chalk";
|
|
15628
15761
|
function viewIssue(issueKey) {
|
|
15629
15762
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
15630
15763
|
const fields = parsed?.fields;
|
|
15631
15764
|
const summary = fields?.summary;
|
|
15632
15765
|
const description = fields?.description;
|
|
15633
15766
|
if (summary) {
|
|
15634
|
-
console.log(
|
|
15767
|
+
console.log(chalk145.bold(summary));
|
|
15635
15768
|
}
|
|
15636
15769
|
if (description) {
|
|
15637
15770
|
if (summary) console.log();
|
|
@@ -15645,7 +15778,7 @@ function viewIssue(issueKey) {
|
|
|
15645
15778
|
}
|
|
15646
15779
|
if (!summary && !description) {
|
|
15647
15780
|
console.log(
|
|
15648
|
-
|
|
15781
|
+
chalk145.yellow(`No summary or description found on ${issueKey}.`)
|
|
15649
15782
|
);
|
|
15650
15783
|
}
|
|
15651
15784
|
}
|
|
@@ -15701,13 +15834,13 @@ function registerRefineLaunch(program2, resumeFlag) {
|
|
|
15701
15834
|
// src/commands/reviewPrComments.ts
|
|
15702
15835
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
15703
15836
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
15704
|
-
import
|
|
15837
|
+
import chalk146 from "chalk";
|
|
15705
15838
|
async function reviewPrComments(number) {
|
|
15706
15839
|
if (number) {
|
|
15707
15840
|
try {
|
|
15708
15841
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
15709
15842
|
} catch {
|
|
15710
|
-
console.error(
|
|
15843
|
+
console.error(chalk146.red(`gh pr checkout ${number} failed; aborting.`));
|
|
15711
15844
|
process.exit(1);
|
|
15712
15845
|
}
|
|
15713
15846
|
}
|
|
@@ -15780,15 +15913,15 @@ function registerList(program2) {
|
|
|
15780
15913
|
// src/commands/mermaid/index.ts
|
|
15781
15914
|
import { mkdirSync as mkdirSync15, readdirSync as readdirSync9 } from "fs";
|
|
15782
15915
|
import { resolve as resolve11 } from "path";
|
|
15783
|
-
import
|
|
15916
|
+
import chalk149 from "chalk";
|
|
15784
15917
|
|
|
15785
15918
|
// src/commands/mermaid/exportFile.ts
|
|
15786
15919
|
import { readFileSync as readFileSync35, writeFileSync as writeFileSync29 } from "fs";
|
|
15787
15920
|
import { basename as basename11, extname, resolve as resolve10 } from "path";
|
|
15788
|
-
import
|
|
15921
|
+
import chalk148 from "chalk";
|
|
15789
15922
|
|
|
15790
15923
|
// src/commands/mermaid/renderBlock.ts
|
|
15791
|
-
import
|
|
15924
|
+
import chalk147 from "chalk";
|
|
15792
15925
|
async function renderBlock(krokiUrl, source) {
|
|
15793
15926
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
15794
15927
|
method: "POST",
|
|
@@ -15797,7 +15930,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
15797
15930
|
});
|
|
15798
15931
|
if (!response.ok) {
|
|
15799
15932
|
console.error(
|
|
15800
|
-
|
|
15933
|
+
chalk147.red(
|
|
15801
15934
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
15802
15935
|
)
|
|
15803
15936
|
);
|
|
@@ -15815,19 +15948,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
15815
15948
|
if (onlyIndex !== void 0) {
|
|
15816
15949
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
15817
15950
|
console.error(
|
|
15818
|
-
|
|
15951
|
+
chalk148.red(
|
|
15819
15952
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
15820
15953
|
)
|
|
15821
15954
|
);
|
|
15822
15955
|
process.exit(1);
|
|
15823
15956
|
}
|
|
15824
15957
|
console.log(
|
|
15825
|
-
|
|
15958
|
+
chalk148.gray(
|
|
15826
15959
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
15827
15960
|
)
|
|
15828
15961
|
);
|
|
15829
15962
|
} else {
|
|
15830
|
-
console.log(
|
|
15963
|
+
console.log(chalk148.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
15831
15964
|
}
|
|
15832
15965
|
for (const [i, source] of blocks.entries()) {
|
|
15833
15966
|
const idx = i + 1;
|
|
@@ -15835,7 +15968,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
15835
15968
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
15836
15969
|
const svg = await renderBlock(krokiUrl, source);
|
|
15837
15970
|
writeFileSync29(outPath, svg, "utf8");
|
|
15838
|
-
console.log(
|
|
15971
|
+
console.log(chalk148.green(` \u2192 ${outPath}`));
|
|
15839
15972
|
}
|
|
15840
15973
|
}
|
|
15841
15974
|
function extractMermaidBlocks(markdown) {
|
|
@@ -15851,18 +15984,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
15851
15984
|
if (options2.index !== void 0) {
|
|
15852
15985
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
15853
15986
|
console.error(
|
|
15854
|
-
|
|
15987
|
+
chalk149.red(`--index must be a positive integer (got ${options2.index})`)
|
|
15855
15988
|
);
|
|
15856
15989
|
process.exit(1);
|
|
15857
15990
|
}
|
|
15858
15991
|
if (!file) {
|
|
15859
|
-
console.error(
|
|
15992
|
+
console.error(chalk149.red("--index requires a file argument"));
|
|
15860
15993
|
process.exit(1);
|
|
15861
15994
|
}
|
|
15862
15995
|
}
|
|
15863
15996
|
const files = file ? [file] : readdirSync9(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
15864
15997
|
if (files.length === 0) {
|
|
15865
|
-
console.log(
|
|
15998
|
+
console.log(chalk149.gray("No markdown files found in current directory."));
|
|
15866
15999
|
return;
|
|
15867
16000
|
}
|
|
15868
16001
|
for (const f of files) {
|
|
@@ -15895,7 +16028,7 @@ function registerMermaid(program2) {
|
|
|
15895
16028
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
15896
16029
|
import { createServer as createServer2 } from "http";
|
|
15897
16030
|
import { dirname as dirname24 } from "path";
|
|
15898
|
-
import
|
|
16031
|
+
import chalk151 from "chalk";
|
|
15899
16032
|
|
|
15900
16033
|
// src/commands/netcap/corsHeaders.ts
|
|
15901
16034
|
var corsHeaders = {
|
|
@@ -15974,7 +16107,7 @@ function createNetcapHandler(options2) {
|
|
|
15974
16107
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
15975
16108
|
import { networkInterfaces } from "os";
|
|
15976
16109
|
import { join as join44 } from "path";
|
|
15977
|
-
import
|
|
16110
|
+
import chalk150 from "chalk";
|
|
15978
16111
|
|
|
15979
16112
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
15980
16113
|
import { dirname as dirname23, join as join43 } from "path";
|
|
@@ -16018,7 +16151,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
16018
16151
|
const host = lanIPv4();
|
|
16019
16152
|
if (!host) {
|
|
16020
16153
|
console.log(
|
|
16021
|
-
|
|
16154
|
+
chalk150.yellow("could not determine the WSL IP for the extension")
|
|
16022
16155
|
);
|
|
16023
16156
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
16024
16157
|
return source;
|
|
@@ -16029,7 +16162,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
16029
16162
|
return WSL_WINDOWS_PATH;
|
|
16030
16163
|
} catch {
|
|
16031
16164
|
console.log(
|
|
16032
|
-
|
|
16165
|
+
chalk150.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
16033
16166
|
);
|
|
16034
16167
|
return source;
|
|
16035
16168
|
}
|
|
@@ -16062,30 +16195,30 @@ async function netcap(options2) {
|
|
|
16062
16195
|
let count7 = 0;
|
|
16063
16196
|
const handler = createNetcapHandler({
|
|
16064
16197
|
outPath,
|
|
16065
|
-
onPing: () => console.log(
|
|
16198
|
+
onPing: () => console.log(chalk151.dim("ping from extension")),
|
|
16066
16199
|
onCapture: (entry) => {
|
|
16067
16200
|
count7 += 1;
|
|
16068
16201
|
console.log(
|
|
16069
|
-
|
|
16070
|
-
|
|
16202
|
+
chalk151.green(`captured #${count7}`),
|
|
16203
|
+
chalk151.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
16071
16204
|
);
|
|
16072
16205
|
}
|
|
16073
16206
|
});
|
|
16074
16207
|
const server = createServer2(handler);
|
|
16075
16208
|
server.listen(port, () => {
|
|
16076
16209
|
console.log(
|
|
16077
|
-
|
|
16210
|
+
chalk151.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
16078
16211
|
);
|
|
16079
|
-
console.log(
|
|
16212
|
+
console.log(chalk151.dim(`appending captures to ${outPath}`));
|
|
16080
16213
|
if (filter)
|
|
16081
|
-
console.log(
|
|
16082
|
-
console.log(
|
|
16083
|
-
console.log(
|
|
16214
|
+
console.log(chalk151.dim(`forwarding only URLs matching "${filter}"`));
|
|
16215
|
+
console.log(chalk151.dim(`load the unpacked extension from ${extensionPath}`));
|
|
16216
|
+
console.log(chalk151.dim("press Ctrl-C to stop"));
|
|
16084
16217
|
});
|
|
16085
16218
|
process.on("SIGINT", () => {
|
|
16086
16219
|
server.close();
|
|
16087
16220
|
console.log(
|
|
16088
|
-
|
|
16221
|
+
chalk151.bold(
|
|
16089
16222
|
`
|
|
16090
16223
|
netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
16091
16224
|
)
|
|
@@ -16097,7 +16230,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
|
|
|
16097
16230
|
// src/commands/netcap/netcapExtract.ts
|
|
16098
16231
|
import { writeFileSync as writeFileSync30 } from "fs";
|
|
16099
16232
|
import { join as join47 } from "path";
|
|
16100
|
-
import
|
|
16233
|
+
import chalk152 from "chalk";
|
|
16101
16234
|
|
|
16102
16235
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
16103
16236
|
import { readFileSync as readFileSync36 } from "fs";
|
|
@@ -16545,8 +16678,8 @@ function netcapExtract(file) {
|
|
|
16545
16678
|
writeFileSync30(outFile, `${JSON.stringify(posts, null, 2)}
|
|
16546
16679
|
`);
|
|
16547
16680
|
console.log(
|
|
16548
|
-
|
|
16549
|
-
|
|
16681
|
+
chalk152.green(`extracted ${posts.length} posts`),
|
|
16682
|
+
chalk152.dim(`-> ${outFile}`)
|
|
16550
16683
|
);
|
|
16551
16684
|
}
|
|
16552
16685
|
|
|
@@ -16567,7 +16700,7 @@ function registerNetcap(program2) {
|
|
|
16567
16700
|
}
|
|
16568
16701
|
|
|
16569
16702
|
// src/commands/news/add/index.ts
|
|
16570
|
-
import
|
|
16703
|
+
import chalk153 from "chalk";
|
|
16571
16704
|
import enquirer8 from "enquirer";
|
|
16572
16705
|
async function add2(url) {
|
|
16573
16706
|
if (!url) {
|
|
@@ -16589,10 +16722,10 @@ async function add2(url) {
|
|
|
16589
16722
|
const { orm } = await getReady();
|
|
16590
16723
|
const added = await addFeed(orm, url);
|
|
16591
16724
|
if (!added) {
|
|
16592
|
-
console.log(
|
|
16725
|
+
console.log(chalk153.yellow("Feed already exists"));
|
|
16593
16726
|
return;
|
|
16594
16727
|
}
|
|
16595
|
-
console.log(
|
|
16728
|
+
console.log(chalk153.green(`Added feed: ${url}`));
|
|
16596
16729
|
}
|
|
16597
16730
|
|
|
16598
16731
|
// src/commands/registerNews.ts
|
|
@@ -16639,7 +16772,7 @@ function registerPiHook(program2) {
|
|
|
16639
16772
|
}
|
|
16640
16773
|
|
|
16641
16774
|
// src/commands/prompts/printPromptsTable.ts
|
|
16642
|
-
import
|
|
16775
|
+
import chalk154 from "chalk";
|
|
16643
16776
|
function truncate(str, max) {
|
|
16644
16777
|
if (str.length <= max) return str;
|
|
16645
16778
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -16657,14 +16790,14 @@ function printPromptsTable(rows) {
|
|
|
16657
16790
|
"Command".padEnd(commandWidth),
|
|
16658
16791
|
"Repos"
|
|
16659
16792
|
].join(" ");
|
|
16660
|
-
console.log(
|
|
16661
|
-
console.log(
|
|
16793
|
+
console.log(chalk154.dim(header));
|
|
16794
|
+
console.log(chalk154.dim("-".repeat(header.length)));
|
|
16662
16795
|
for (const row of rows) {
|
|
16663
16796
|
const count7 = String(row.count).padStart(countWidth);
|
|
16664
16797
|
const tool = row.tool.padEnd(toolWidth);
|
|
16665
16798
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
16666
16799
|
console.log(
|
|
16667
|
-
`${
|
|
16800
|
+
`${chalk154.yellow(count7)} ${tool} ${command} ${chalk154.dim(row.repos)}`
|
|
16668
16801
|
);
|
|
16669
16802
|
}
|
|
16670
16803
|
}
|
|
@@ -16693,7 +16826,7 @@ function registerPrompts(program2) {
|
|
|
16693
16826
|
}
|
|
16694
16827
|
|
|
16695
16828
|
// src/commands/prs/shared.ts
|
|
16696
|
-
import { execSync as
|
|
16829
|
+
import { execSync as execSync39 } from "child_process";
|
|
16697
16830
|
function isGhNotInstalled(error) {
|
|
16698
16831
|
if (error instanceof Error) {
|
|
16699
16832
|
const msg = error.message.toLowerCase();
|
|
@@ -16711,12 +16844,12 @@ function getRepoInfo() {
|
|
|
16711
16844
|
const preferred = getPreferredRemoteRepo();
|
|
16712
16845
|
if (preferred) return preferred;
|
|
16713
16846
|
const repoInfo = JSON.parse(
|
|
16714
|
-
|
|
16847
|
+
execSync39("gh repo view --json owner,name", { encoding: "utf8" })
|
|
16715
16848
|
);
|
|
16716
16849
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
16717
16850
|
}
|
|
16718
16851
|
function getCurrentBranch2() {
|
|
16719
|
-
return
|
|
16852
|
+
return execSync39("git rev-parse --abbrev-ref HEAD", {
|
|
16720
16853
|
encoding: "utf8"
|
|
16721
16854
|
}).trim();
|
|
16722
16855
|
}
|
|
@@ -16724,7 +16857,7 @@ function viewCurrentPr(fields) {
|
|
|
16724
16857
|
const { org, repo } = getRepoInfo();
|
|
16725
16858
|
const branch2 = getCurrentBranch2();
|
|
16726
16859
|
return JSON.parse(
|
|
16727
|
-
|
|
16860
|
+
execSync39(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
|
|
16728
16861
|
encoding: "utf8"
|
|
16729
16862
|
})
|
|
16730
16863
|
);
|
|
@@ -17026,10 +17159,10 @@ function edit(options2) {
|
|
|
17026
17159
|
}
|
|
17027
17160
|
|
|
17028
17161
|
// src/commands/prs/fixed.ts
|
|
17029
|
-
import { execSync as
|
|
17162
|
+
import { execSync as execSync42 } from "child_process";
|
|
17030
17163
|
|
|
17031
17164
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
17032
|
-
import { execSync as
|
|
17165
|
+
import { execSync as execSync41 } from "child_process";
|
|
17033
17166
|
import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync31 } from "fs";
|
|
17034
17167
|
import { tmpdir as tmpdir5 } from "os";
|
|
17035
17168
|
import { join as join49 } from "path";
|
|
@@ -17058,9 +17191,9 @@ function deleteCommentsCache(prNumber) {
|
|
|
17058
17191
|
}
|
|
17059
17192
|
|
|
17060
17193
|
// src/commands/prs/replyToComment.ts
|
|
17061
|
-
import { execSync as
|
|
17194
|
+
import { execSync as execSync40 } from "child_process";
|
|
17062
17195
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
17063
|
-
|
|
17196
|
+
execSync40(
|
|
17064
17197
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, String.raw`\"`)}" -F in_reply_to=${commentId}`,
|
|
17065
17198
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
17066
17199
|
);
|
|
@@ -17072,7 +17205,7 @@ function resolveThread(threadId) {
|
|
|
17072
17205
|
const queryFile = join49(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
17073
17206
|
writeFileSync31(queryFile, mutation);
|
|
17074
17207
|
try {
|
|
17075
|
-
|
|
17208
|
+
execSync41(
|
|
17076
17209
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
17077
17210
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
17078
17211
|
);
|
|
@@ -17124,7 +17257,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
17124
17257
|
// src/commands/prs/fixed.ts
|
|
17125
17258
|
function verifySha(sha) {
|
|
17126
17259
|
try {
|
|
17127
|
-
return
|
|
17260
|
+
return execSync42(`git rev-parse --verify ${sha}`, {
|
|
17128
17261
|
encoding: "utf8"
|
|
17129
17262
|
}).trim();
|
|
17130
17263
|
} catch {
|
|
@@ -17138,7 +17271,7 @@ function fixed(commentId, sha) {
|
|
|
17138
17271
|
const { org, repo } = getRepoInfo();
|
|
17139
17272
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
17140
17273
|
const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
17141
|
-
|
|
17274
|
+
execSync42("git push", { stdio: "inherit" });
|
|
17142
17275
|
resolveCommentWithReply(commentId, message);
|
|
17143
17276
|
} catch (error) {
|
|
17144
17277
|
if (isGhNotInstalled(error)) {
|
|
@@ -17156,7 +17289,7 @@ import { join as join51 } from "path";
|
|
|
17156
17289
|
import { stringify } from "yaml";
|
|
17157
17290
|
|
|
17158
17291
|
// src/commands/prs/fetchThreadIds.ts
|
|
17159
|
-
import { execSync as
|
|
17292
|
+
import { execSync as execSync43 } from "child_process";
|
|
17160
17293
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync32 } from "fs";
|
|
17161
17294
|
import { tmpdir as tmpdir6 } from "os";
|
|
17162
17295
|
import { join as join50 } from "path";
|
|
@@ -17165,7 +17298,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
17165
17298
|
const queryFile = join50(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
17166
17299
|
writeFileSync32(queryFile, THREAD_QUERY);
|
|
17167
17300
|
try {
|
|
17168
|
-
const result =
|
|
17301
|
+
const result = execSync43(
|
|
17169
17302
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
17170
17303
|
{ encoding: "utf8" }
|
|
17171
17304
|
);
|
|
@@ -17187,9 +17320,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
17187
17320
|
}
|
|
17188
17321
|
|
|
17189
17322
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
17190
|
-
import { execSync as
|
|
17323
|
+
import { execSync as execSync44 } from "child_process";
|
|
17191
17324
|
function fetchJson(endpoint) {
|
|
17192
|
-
const result =
|
|
17325
|
+
const result = execSync44(`gh api --paginate ${endpoint}`, {
|
|
17193
17326
|
encoding: "utf8"
|
|
17194
17327
|
});
|
|
17195
17328
|
if (!result.trim()) return [];
|
|
@@ -17231,20 +17364,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
17231
17364
|
}
|
|
17232
17365
|
|
|
17233
17366
|
// src/commands/prs/listComments/printComments.ts
|
|
17234
|
-
import
|
|
17367
|
+
import chalk155 from "chalk";
|
|
17235
17368
|
function formatForHuman(comment3) {
|
|
17236
17369
|
if (comment3.type === "review") {
|
|
17237
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
17370
|
+
const stateColor = comment3.state === "APPROVED" ? chalk155.green : comment3.state === "CHANGES_REQUESTED" ? chalk155.red : chalk155.yellow;
|
|
17238
17371
|
return [
|
|
17239
|
-
`${
|
|
17372
|
+
`${chalk155.cyan("Review")} by ${chalk155.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
17240
17373
|
comment3.body,
|
|
17241
17374
|
""
|
|
17242
17375
|
].join("\n");
|
|
17243
17376
|
}
|
|
17244
17377
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
17245
17378
|
return [
|
|
17246
|
-
`${
|
|
17247
|
-
|
|
17379
|
+
`${chalk155.cyan("Line comment")} by ${chalk155.bold(comment3.user)} on ${chalk155.dim(`${comment3.path}${location}`)}`,
|
|
17380
|
+
chalk155.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
17248
17381
|
comment3.body,
|
|
17249
17382
|
""
|
|
17250
17383
|
].join("\n");
|
|
@@ -17328,19 +17461,19 @@ async function listComments() {
|
|
|
17328
17461
|
}
|
|
17329
17462
|
|
|
17330
17463
|
// src/commands/prs/prs/index.ts
|
|
17331
|
-
import { execSync as
|
|
17464
|
+
import { execSync as execSync45 } from "child_process";
|
|
17332
17465
|
|
|
17333
17466
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
17334
17467
|
import enquirer9 from "enquirer";
|
|
17335
17468
|
|
|
17336
17469
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
17337
|
-
import
|
|
17470
|
+
import chalk156 from "chalk";
|
|
17338
17471
|
var STATUS_MAP = {
|
|
17339
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
17340
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
17472
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk156.magenta("merged"), date: pr.mergedAt } : null,
|
|
17473
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk156.red("closed"), date: pr.closedAt } : null
|
|
17341
17474
|
};
|
|
17342
17475
|
function defaultStatus(pr) {
|
|
17343
|
-
return { label:
|
|
17476
|
+
return { label: chalk156.green("opened"), date: pr.createdAt };
|
|
17344
17477
|
}
|
|
17345
17478
|
function getStatus2(pr) {
|
|
17346
17479
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -17349,11 +17482,11 @@ function formatDate(dateStr) {
|
|
|
17349
17482
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
17350
17483
|
}
|
|
17351
17484
|
function formatPrHeader(pr, status3) {
|
|
17352
|
-
return `${
|
|
17485
|
+
return `${chalk156.cyan(`#${pr.number}`)} ${pr.title} ${chalk156.dim(`(${pr.author.login},`)} ${status3.label} ${chalk156.dim(`${formatDate(status3.date)})`)}`;
|
|
17353
17486
|
}
|
|
17354
17487
|
function logPrDetails(pr) {
|
|
17355
17488
|
console.log(
|
|
17356
|
-
|
|
17489
|
+
chalk156.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
17357
17490
|
);
|
|
17358
17491
|
console.log();
|
|
17359
17492
|
}
|
|
@@ -17435,7 +17568,7 @@ async function prs(options2) {
|
|
|
17435
17568
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
17436
17569
|
try {
|
|
17437
17570
|
const { org, repo } = getRepoInfo();
|
|
17438
|
-
const result =
|
|
17571
|
+
const result = execSync45(
|
|
17439
17572
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
|
|
17440
17573
|
{ encoding: "utf8" }
|
|
17441
17574
|
);
|
|
@@ -17490,16 +17623,16 @@ function buildCreateArgs(title, body, options2) {
|
|
|
17490
17623
|
}
|
|
17491
17624
|
|
|
17492
17625
|
// src/commands/prs/readSessionPrRef.ts
|
|
17493
|
-
import { execSync as
|
|
17626
|
+
import { execSync as execSync46 } from "child_process";
|
|
17494
17627
|
function readSessionPrRef() {
|
|
17495
17628
|
try {
|
|
17496
|
-
const branch2 =
|
|
17629
|
+
const branch2 = execSync46("git rev-parse --abbrev-ref HEAD", {
|
|
17497
17630
|
encoding: "utf8",
|
|
17498
17631
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17499
17632
|
}).trim();
|
|
17500
17633
|
if (!branch2 || branch2 === "HEAD") return null;
|
|
17501
17634
|
const pr = JSON.parse(
|
|
17502
|
-
|
|
17635
|
+
execSync46(`gh pr view ${branch2} --json number,title,url,state`, {
|
|
17503
17636
|
encoding: "utf8",
|
|
17504
17637
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17505
17638
|
})
|
|
@@ -17577,7 +17710,7 @@ function reply(commentId, body) {
|
|
|
17577
17710
|
}
|
|
17578
17711
|
|
|
17579
17712
|
// src/commands/prs/wontfix.ts
|
|
17580
|
-
import { execSync as
|
|
17713
|
+
import { execSync as execSync47 } from "child_process";
|
|
17581
17714
|
function validateReason(reason) {
|
|
17582
17715
|
const lowerReason = reason.toLowerCase();
|
|
17583
17716
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -17594,7 +17727,7 @@ function validateShaReferences(reason) {
|
|
|
17594
17727
|
const invalidShas = [];
|
|
17595
17728
|
for (const sha of shas) {
|
|
17596
17729
|
try {
|
|
17597
|
-
|
|
17730
|
+
execSync47(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
17598
17731
|
} catch {
|
|
17599
17732
|
invalidShas.push(sha);
|
|
17600
17733
|
}
|
|
@@ -17702,10 +17835,10 @@ function registerPrs(program2) {
|
|
|
17702
17835
|
}
|
|
17703
17836
|
|
|
17704
17837
|
// src/commands/ravendb/ravendbAuth.ts
|
|
17705
|
-
import
|
|
17838
|
+
import chalk162 from "chalk";
|
|
17706
17839
|
|
|
17707
17840
|
// src/shared/createConnectionAuth.ts
|
|
17708
|
-
import
|
|
17841
|
+
import chalk157 from "chalk";
|
|
17709
17842
|
function listConnections(connections, format) {
|
|
17710
17843
|
if (connections.length === 0) {
|
|
17711
17844
|
console.log("No connections configured.");
|
|
@@ -17718,7 +17851,7 @@ function listConnections(connections, format) {
|
|
|
17718
17851
|
function removeConnection(connections, name, save) {
|
|
17719
17852
|
const filtered = connections.filter((c) => c.name !== name);
|
|
17720
17853
|
if (filtered.length === connections.length) {
|
|
17721
|
-
console.error(
|
|
17854
|
+
console.error(chalk157.red(`Connection "${name}" not found.`));
|
|
17722
17855
|
process.exit(1);
|
|
17723
17856
|
}
|
|
17724
17857
|
save(filtered);
|
|
@@ -17764,17 +17897,17 @@ function saveConnections(connections) {
|
|
|
17764
17897
|
}
|
|
17765
17898
|
|
|
17766
17899
|
// src/commands/ravendb/promptConnection.ts
|
|
17767
|
-
import
|
|
17900
|
+
import chalk160 from "chalk";
|
|
17768
17901
|
|
|
17769
17902
|
// src/commands/ravendb/selectOpSecret.ts
|
|
17770
|
-
import
|
|
17903
|
+
import chalk159 from "chalk";
|
|
17771
17904
|
import Enquirer2 from "enquirer";
|
|
17772
17905
|
|
|
17773
17906
|
// src/commands/ravendb/searchItems.ts
|
|
17774
|
-
import { execSync as
|
|
17775
|
-
import
|
|
17907
|
+
import { execSync as execSync48 } from "child_process";
|
|
17908
|
+
import chalk158 from "chalk";
|
|
17776
17909
|
function opExec(args) {
|
|
17777
|
-
return
|
|
17910
|
+
return execSync48(`op ${args}`, {
|
|
17778
17911
|
encoding: "utf8",
|
|
17779
17912
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17780
17913
|
}).trim();
|
|
@@ -17785,7 +17918,7 @@ function searchItems(search2) {
|
|
|
17785
17918
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
17786
17919
|
} catch {
|
|
17787
17920
|
console.error(
|
|
17788
|
-
|
|
17921
|
+
chalk158.red(
|
|
17789
17922
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
17790
17923
|
)
|
|
17791
17924
|
);
|
|
@@ -17799,7 +17932,7 @@ function getItemFields(itemId2) {
|
|
|
17799
17932
|
const item = JSON.parse(opExec(`item get "${itemId2}" --format=json`));
|
|
17800
17933
|
return item.fields.filter((f) => f.reference && f.label);
|
|
17801
17934
|
} catch {
|
|
17802
|
-
console.error(
|
|
17935
|
+
console.error(chalk158.red("Failed to get item details from 1Password."));
|
|
17803
17936
|
process.exit(1);
|
|
17804
17937
|
}
|
|
17805
17938
|
}
|
|
@@ -17818,7 +17951,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
17818
17951
|
}).run();
|
|
17819
17952
|
const items2 = searchItems(search2);
|
|
17820
17953
|
if (items2.length === 0) {
|
|
17821
|
-
console.error(
|
|
17954
|
+
console.error(chalk159.red(`No items found matching "${search2}".`));
|
|
17822
17955
|
process.exit(1);
|
|
17823
17956
|
}
|
|
17824
17957
|
const itemId2 = await selectOne(
|
|
@@ -17827,7 +17960,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
17827
17960
|
);
|
|
17828
17961
|
const fields = getItemFields(itemId2);
|
|
17829
17962
|
if (fields.length === 0) {
|
|
17830
|
-
console.error(
|
|
17963
|
+
console.error(chalk159.red("No fields with references found on this item."));
|
|
17831
17964
|
process.exit(1);
|
|
17832
17965
|
}
|
|
17833
17966
|
const ref = await selectOne(
|
|
@@ -17841,7 +17974,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
17841
17974
|
async function promptConnection(existingNames) {
|
|
17842
17975
|
const name = await promptInput("name", "Connection name:");
|
|
17843
17976
|
if (existingNames.includes(name)) {
|
|
17844
|
-
console.error(
|
|
17977
|
+
console.error(chalk160.red(`Connection "${name}" already exists.`));
|
|
17845
17978
|
process.exit(1);
|
|
17846
17979
|
}
|
|
17847
17980
|
const url = await promptInput(
|
|
@@ -17850,22 +17983,22 @@ async function promptConnection(existingNames) {
|
|
|
17850
17983
|
);
|
|
17851
17984
|
const database = await promptInput("database", "Database name:");
|
|
17852
17985
|
if (!name || !url || !database) {
|
|
17853
|
-
console.error(
|
|
17986
|
+
console.error(chalk160.red("All fields are required."));
|
|
17854
17987
|
process.exit(1);
|
|
17855
17988
|
}
|
|
17856
17989
|
const apiKeyRef = await selectOpSecret();
|
|
17857
|
-
console.log(
|
|
17990
|
+
console.log(chalk160.dim(`Using: ${apiKeyRef}`));
|
|
17858
17991
|
return { name, url, database, apiKeyRef };
|
|
17859
17992
|
}
|
|
17860
17993
|
|
|
17861
17994
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
17862
|
-
import
|
|
17995
|
+
import chalk161 from "chalk";
|
|
17863
17996
|
function ravendbSetConnection(name) {
|
|
17864
17997
|
const raw = loadGlobalConfigRaw();
|
|
17865
17998
|
const ravendb = raw.ravendb ?? {};
|
|
17866
17999
|
const connections = ravendb.connections ?? [];
|
|
17867
18000
|
if (!connections.some((c) => c.name === name)) {
|
|
17868
|
-
console.error(
|
|
18001
|
+
console.error(chalk161.red(`Connection "${name}" not found.`));
|
|
17869
18002
|
console.error(
|
|
17870
18003
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
17871
18004
|
);
|
|
@@ -17881,16 +18014,16 @@ function ravendbSetConnection(name) {
|
|
|
17881
18014
|
var ravendbAuth = createConnectionAuth({
|
|
17882
18015
|
load: loadConnections,
|
|
17883
18016
|
save: saveConnections,
|
|
17884
|
-
format: (c) => `${
|
|
18017
|
+
format: (c) => `${chalk162.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
17885
18018
|
promptNew: promptConnection,
|
|
17886
18019
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
17887
18020
|
});
|
|
17888
18021
|
|
|
17889
18022
|
// src/commands/ravendb/ravendbCollections.ts
|
|
17890
|
-
import
|
|
18023
|
+
import chalk166 from "chalk";
|
|
17891
18024
|
|
|
17892
18025
|
// src/commands/ravendb/ravenFetch.ts
|
|
17893
|
-
import
|
|
18026
|
+
import chalk164 from "chalk";
|
|
17894
18027
|
|
|
17895
18028
|
// src/commands/ravendb/getAccessToken.ts
|
|
17896
18029
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -17926,21 +18059,21 @@ ${errorText}`
|
|
|
17926
18059
|
}
|
|
17927
18060
|
|
|
17928
18061
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
17929
|
-
import { execSync as
|
|
17930
|
-
import
|
|
18062
|
+
import { execSync as execSync49 } from "child_process";
|
|
18063
|
+
import chalk163 from "chalk";
|
|
17931
18064
|
function resolveOpSecret(reference) {
|
|
17932
18065
|
if (!reference.startsWith("op://")) {
|
|
17933
|
-
console.error(
|
|
18066
|
+
console.error(chalk163.red(`Invalid secret reference: must start with op://`));
|
|
17934
18067
|
process.exit(1);
|
|
17935
18068
|
}
|
|
17936
18069
|
try {
|
|
17937
|
-
return
|
|
18070
|
+
return execSync49(`op read "${reference}"`, {
|
|
17938
18071
|
encoding: "utf8",
|
|
17939
18072
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17940
18073
|
}).trim();
|
|
17941
18074
|
} catch {
|
|
17942
18075
|
console.error(
|
|
17943
|
-
|
|
18076
|
+
chalk163.red(
|
|
17944
18077
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
17945
18078
|
)
|
|
17946
18079
|
);
|
|
@@ -17967,7 +18100,7 @@ async function ravenFetch(connection, path67) {
|
|
|
17967
18100
|
if (!response.ok) {
|
|
17968
18101
|
const body = await response.text();
|
|
17969
18102
|
console.error(
|
|
17970
|
-
|
|
18103
|
+
chalk164.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
17971
18104
|
);
|
|
17972
18105
|
console.error(body.substring(0, 500));
|
|
17973
18106
|
process.exit(1);
|
|
@@ -17976,7 +18109,7 @@ async function ravenFetch(connection, path67) {
|
|
|
17976
18109
|
}
|
|
17977
18110
|
|
|
17978
18111
|
// src/commands/ravendb/resolveConnection.ts
|
|
17979
|
-
import
|
|
18112
|
+
import chalk165 from "chalk";
|
|
17980
18113
|
function loadRavendb() {
|
|
17981
18114
|
const raw = loadGlobalConfigRaw();
|
|
17982
18115
|
const ravendb = raw.ravendb;
|
|
@@ -17990,7 +18123,7 @@ function resolveConnection(name) {
|
|
|
17990
18123
|
const connectionName = name ?? defaultConnection;
|
|
17991
18124
|
if (!connectionName) {
|
|
17992
18125
|
console.error(
|
|
17993
|
-
|
|
18126
|
+
chalk165.red(
|
|
17994
18127
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
17995
18128
|
)
|
|
17996
18129
|
);
|
|
@@ -17998,7 +18131,7 @@ function resolveConnection(name) {
|
|
|
17998
18131
|
}
|
|
17999
18132
|
const connection = connections.find((c) => c.name === connectionName);
|
|
18000
18133
|
if (!connection) {
|
|
18001
|
-
console.error(
|
|
18134
|
+
console.error(chalk165.red(`Connection "${connectionName}" not found.`));
|
|
18002
18135
|
console.error(
|
|
18003
18136
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
18004
18137
|
);
|
|
@@ -18029,7 +18162,7 @@ async function ravendbCollections(connectionName) {
|
|
|
18029
18162
|
return;
|
|
18030
18163
|
}
|
|
18031
18164
|
for (const c of collections) {
|
|
18032
|
-
console.log(`${
|
|
18165
|
+
console.log(`${chalk166.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
18033
18166
|
}
|
|
18034
18167
|
}
|
|
18035
18168
|
|
|
@@ -18048,10 +18181,10 @@ var ravendbConfigHelp = [
|
|
|
18048
18181
|
];
|
|
18049
18182
|
|
|
18050
18183
|
// src/commands/ravendb/ravendbQuery.ts
|
|
18051
|
-
import
|
|
18184
|
+
import chalk168 from "chalk";
|
|
18052
18185
|
|
|
18053
18186
|
// src/commands/ravendb/fetchAllPages.ts
|
|
18054
|
-
import
|
|
18187
|
+
import chalk167 from "chalk";
|
|
18055
18188
|
|
|
18056
18189
|
// src/commands/ravendb/buildQueryPath.ts
|
|
18057
18190
|
function buildQueryPath(opts) {
|
|
@@ -18089,7 +18222,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
18089
18222
|
allResults.push(...results);
|
|
18090
18223
|
start3 += results.length;
|
|
18091
18224
|
process.stderr.write(
|
|
18092
|
-
`\r${
|
|
18225
|
+
`\r${chalk167.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
18093
18226
|
);
|
|
18094
18227
|
if (start3 >= totalResults) break;
|
|
18095
18228
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -18104,7 +18237,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
18104
18237
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
18105
18238
|
const resolved = resolveArgs(connectionName, collection);
|
|
18106
18239
|
if (!resolved.collection && !options2.query) {
|
|
18107
|
-
console.error(
|
|
18240
|
+
console.error(chalk168.red("Provide a collection name or --query filter."));
|
|
18108
18241
|
process.exit(1);
|
|
18109
18242
|
}
|
|
18110
18243
|
const { collection: col } = resolved;
|
|
@@ -18143,7 +18276,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
18143
18276
|
import * as path34 from "path";
|
|
18144
18277
|
|
|
18145
18278
|
// src/commands/refactor/logViolations.ts
|
|
18146
|
-
import
|
|
18279
|
+
import chalk169 from "chalk";
|
|
18147
18280
|
var DEFAULT_MAX_LINES = 100;
|
|
18148
18281
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
18149
18282
|
if (violations.length === 0) {
|
|
@@ -18152,43 +18285,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
18152
18285
|
}
|
|
18153
18286
|
return;
|
|
18154
18287
|
}
|
|
18155
|
-
console.error(
|
|
18288
|
+
console.error(chalk169.red(`
|
|
18156
18289
|
Refactor check failed:
|
|
18157
18290
|
`));
|
|
18158
|
-
console.error(
|
|
18291
|
+
console.error(chalk169.red(` The following files exceed ${maxLines} lines:
|
|
18159
18292
|
`));
|
|
18160
18293
|
for (const violation of violations) {
|
|
18161
|
-
console.error(
|
|
18294
|
+
console.error(chalk169.red(` ${violation.file} (${violation.lines} lines)`));
|
|
18162
18295
|
}
|
|
18163
18296
|
console.error(
|
|
18164
|
-
|
|
18297
|
+
chalk169.yellow(
|
|
18165
18298
|
`
|
|
18166
18299
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
18167
18300
|
way to refactor it, ignore it with:
|
|
18168
18301
|
`
|
|
18169
18302
|
)
|
|
18170
18303
|
);
|
|
18171
|
-
console.error(
|
|
18304
|
+
console.error(chalk169.gray(` assist refactor ignore <file>
|
|
18172
18305
|
`));
|
|
18173
18306
|
if (process.env.CLAUDECODE) {
|
|
18174
|
-
console.error(
|
|
18307
|
+
console.error(chalk169.cyan(`
|
|
18175
18308
|
## Extracting Code to New Files
|
|
18176
18309
|
`));
|
|
18177
18310
|
console.error(
|
|
18178
|
-
|
|
18311
|
+
chalk169.cyan(
|
|
18179
18312
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
18180
18313
|
`
|
|
18181
18314
|
)
|
|
18182
18315
|
);
|
|
18183
18316
|
console.error(
|
|
18184
|
-
|
|
18317
|
+
chalk169.cyan(
|
|
18185
18318
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
18186
18319
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
18187
18320
|
`
|
|
18188
18321
|
)
|
|
18189
18322
|
);
|
|
18190
18323
|
console.error(
|
|
18191
|
-
|
|
18324
|
+
chalk169.cyan(
|
|
18192
18325
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
18193
18326
|
domains, move it to a common/shared folder.
|
|
18194
18327
|
`
|
|
@@ -18198,7 +18331,7 @@ Refactor check failed:
|
|
|
18198
18331
|
}
|
|
18199
18332
|
|
|
18200
18333
|
// src/commands/refactor/check/getViolations/index.ts
|
|
18201
|
-
import { execSync as
|
|
18334
|
+
import { execSync as execSync50 } from "child_process";
|
|
18202
18335
|
import fs25 from "fs";
|
|
18203
18336
|
import { minimatch as minimatch6 } from "minimatch";
|
|
18204
18337
|
|
|
@@ -18248,7 +18381,7 @@ function getGitFiles(options2) {
|
|
|
18248
18381
|
}
|
|
18249
18382
|
const files = /* @__PURE__ */ new Set();
|
|
18250
18383
|
if (options2.staged || options2.modified) {
|
|
18251
|
-
const staged =
|
|
18384
|
+
const staged = execSync50("git diff --cached --name-only", {
|
|
18252
18385
|
encoding: "utf8"
|
|
18253
18386
|
});
|
|
18254
18387
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -18256,7 +18389,7 @@ function getGitFiles(options2) {
|
|
|
18256
18389
|
}
|
|
18257
18390
|
}
|
|
18258
18391
|
if (options2.unstaged || options2.modified) {
|
|
18259
|
-
const unstaged =
|
|
18392
|
+
const unstaged = execSync50("git diff --name-only", { encoding: "utf8" });
|
|
18260
18393
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
18261
18394
|
files.add(file);
|
|
18262
18395
|
}
|
|
@@ -18344,7 +18477,7 @@ async function check(pattern2, options2) {
|
|
|
18344
18477
|
|
|
18345
18478
|
// src/commands/refactor/extract/index.ts
|
|
18346
18479
|
import path41 from "path";
|
|
18347
|
-
import
|
|
18480
|
+
import chalk172 from "chalk";
|
|
18348
18481
|
|
|
18349
18482
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
18350
18483
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -18943,23 +19076,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
18943
19076
|
|
|
18944
19077
|
// src/commands/refactor/extract/displayPlan.ts
|
|
18945
19078
|
import path38 from "path";
|
|
18946
|
-
import
|
|
19079
|
+
import chalk170 from "chalk";
|
|
18947
19080
|
function section2(title) {
|
|
18948
19081
|
return `
|
|
18949
|
-
${
|
|
19082
|
+
${chalk170.cyan(title)}`;
|
|
18950
19083
|
}
|
|
18951
19084
|
function displayImporters(plan2, cwd) {
|
|
18952
19085
|
if (plan2.importersToUpdate.length === 0) return;
|
|
18953
19086
|
console.log(section2("Update importers:"));
|
|
18954
19087
|
for (const imp of plan2.importersToUpdate) {
|
|
18955
19088
|
const rel = path38.relative(cwd, imp.file.getFilePath());
|
|
18956
|
-
console.log(` ${
|
|
19089
|
+
console.log(` ${chalk170.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
18957
19090
|
}
|
|
18958
19091
|
}
|
|
18959
19092
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
18960
|
-
console.log(
|
|
19093
|
+
console.log(chalk170.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
18961
19094
|
`));
|
|
18962
|
-
console.log(` ${
|
|
19095
|
+
console.log(` ${chalk170.cyan("Functions to move:")}`);
|
|
18963
19096
|
for (const name of plan2.extractedNames) {
|
|
18964
19097
|
console.log(` ${name}`);
|
|
18965
19098
|
}
|
|
@@ -18993,7 +19126,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
18993
19126
|
|
|
18994
19127
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
18995
19128
|
import path40 from "path";
|
|
18996
|
-
import
|
|
19129
|
+
import chalk171 from "chalk";
|
|
18997
19130
|
import { Project as Project4 } from "ts-morph";
|
|
18998
19131
|
|
|
18999
19132
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -19053,7 +19186,7 @@ function loadProjectFile(file) {
|
|
|
19053
19186
|
});
|
|
19054
19187
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
19055
19188
|
if (!sourceFile) {
|
|
19056
|
-
console.log(
|
|
19189
|
+
console.log(chalk171.red(`File not found in project: ${file}`));
|
|
19057
19190
|
process.exit(1);
|
|
19058
19191
|
}
|
|
19059
19192
|
return { project, sourceFile };
|
|
@@ -19076,19 +19209,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
19076
19209
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
19077
19210
|
if (options2.apply) {
|
|
19078
19211
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
19079
|
-
console.log(
|
|
19212
|
+
console.log(chalk172.green("\nExtraction complete"));
|
|
19080
19213
|
} else {
|
|
19081
|
-
console.log(
|
|
19214
|
+
console.log(chalk172.dim("\nDry run. Use --apply to execute."));
|
|
19082
19215
|
}
|
|
19083
19216
|
}
|
|
19084
19217
|
|
|
19085
19218
|
// src/commands/refactor/ignore.ts
|
|
19086
19219
|
import fs27 from "fs";
|
|
19087
|
-
import
|
|
19220
|
+
import chalk173 from "chalk";
|
|
19088
19221
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
19089
19222
|
function ignore2(file) {
|
|
19090
19223
|
if (!fs27.existsSync(file)) {
|
|
19091
|
-
console.error(
|
|
19224
|
+
console.error(chalk173.red(`Error: File does not exist: ${file}`));
|
|
19092
19225
|
process.exit(1);
|
|
19093
19226
|
}
|
|
19094
19227
|
const content = fs27.readFileSync(file, "utf8");
|
|
@@ -19104,7 +19237,7 @@ function ignore2(file) {
|
|
|
19104
19237
|
fs27.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
19105
19238
|
}
|
|
19106
19239
|
console.log(
|
|
19107
|
-
|
|
19240
|
+
chalk173.green(
|
|
19108
19241
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
19109
19242
|
)
|
|
19110
19243
|
);
|
|
@@ -19113,12 +19246,12 @@ function ignore2(file) {
|
|
|
19113
19246
|
// src/commands/refactor/rename/index.ts
|
|
19114
19247
|
import fs30 from "fs";
|
|
19115
19248
|
import path46 from "path";
|
|
19116
|
-
import
|
|
19249
|
+
import chalk176 from "chalk";
|
|
19117
19250
|
|
|
19118
19251
|
// src/commands/refactor/rename/applyRename.ts
|
|
19119
19252
|
import fs29 from "fs";
|
|
19120
19253
|
import path43 from "path";
|
|
19121
|
-
import
|
|
19254
|
+
import chalk174 from "chalk";
|
|
19122
19255
|
|
|
19123
19256
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
19124
19257
|
import path42 from "path";
|
|
@@ -19223,13 +19356,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
19223
19356
|
const updatedContents = applyRewrites(rewrites);
|
|
19224
19357
|
for (const [file, content] of updatedContents) {
|
|
19225
19358
|
fs29.writeFileSync(file, content, "utf8");
|
|
19226
|
-
console.log(
|
|
19359
|
+
console.log(chalk174.cyan(` Updated imports in ${path43.relative(cwd, file)}`));
|
|
19227
19360
|
}
|
|
19228
19361
|
const destDir = path43.dirname(destPath);
|
|
19229
19362
|
if (!fs29.existsSync(destDir)) fs29.mkdirSync(destDir, { recursive: true });
|
|
19230
19363
|
fs29.renameSync(sourcePath, destPath);
|
|
19231
19364
|
console.log(
|
|
19232
|
-
|
|
19365
|
+
chalk174.white(
|
|
19233
19366
|
` Moved ${path43.relative(cwd, sourcePath)} \u2192 ${path43.relative(cwd, destPath)}`
|
|
19234
19367
|
)
|
|
19235
19368
|
);
|
|
@@ -19316,16 +19449,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
19316
19449
|
|
|
19317
19450
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
19318
19451
|
import path45 from "path";
|
|
19319
|
-
import
|
|
19452
|
+
import chalk175 from "chalk";
|
|
19320
19453
|
function printRenamePreview(rewrites, cwd) {
|
|
19321
19454
|
for (const rewrite of rewrites) {
|
|
19322
19455
|
console.log(
|
|
19323
|
-
|
|
19456
|
+
chalk175.dim(
|
|
19324
19457
|
` ${path45.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
19325
19458
|
)
|
|
19326
19459
|
);
|
|
19327
19460
|
}
|
|
19328
|
-
console.log(
|
|
19461
|
+
console.log(chalk175.dim("Dry run. Use --apply to execute."));
|
|
19329
19462
|
}
|
|
19330
19463
|
|
|
19331
19464
|
// src/commands/refactor/rename/index.ts
|
|
@@ -19336,20 +19469,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
19336
19469
|
const relSource = path46.relative(cwd, sourcePath);
|
|
19337
19470
|
const relDest = path46.relative(cwd, destPath);
|
|
19338
19471
|
if (!fs30.existsSync(sourcePath)) {
|
|
19339
|
-
console.log(
|
|
19472
|
+
console.log(chalk176.red(`File not found: ${source}`));
|
|
19340
19473
|
process.exit(1);
|
|
19341
19474
|
}
|
|
19342
19475
|
if (destPath !== sourcePath && fs30.existsSync(destPath)) {
|
|
19343
|
-
console.log(
|
|
19476
|
+
console.log(chalk176.red(`Destination already exists: ${destination}`));
|
|
19344
19477
|
process.exit(1);
|
|
19345
19478
|
}
|
|
19346
|
-
console.log(
|
|
19347
|
-
console.log(
|
|
19348
|
-
console.log(
|
|
19479
|
+
console.log(chalk176.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
19480
|
+
console.log(chalk176.dim("Loading project..."));
|
|
19481
|
+
console.log(chalk176.dim("Scanning imports across the project..."));
|
|
19349
19482
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
19350
19483
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
19351
19484
|
console.log(
|
|
19352
|
-
|
|
19485
|
+
chalk176.dim(
|
|
19353
19486
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
19354
19487
|
)
|
|
19355
19488
|
);
|
|
@@ -19358,11 +19491,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
19358
19491
|
return;
|
|
19359
19492
|
}
|
|
19360
19493
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
19361
|
-
console.log(
|
|
19494
|
+
console.log(chalk176.green("Done"));
|
|
19362
19495
|
}
|
|
19363
19496
|
|
|
19364
19497
|
// src/commands/refactor/renameSymbol/index.ts
|
|
19365
|
-
import
|
|
19498
|
+
import chalk177 from "chalk";
|
|
19366
19499
|
|
|
19367
19500
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
19368
19501
|
import { SyntaxKind as SyntaxKind15 } from "ts-morph";
|
|
@@ -19408,33 +19541,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
19408
19541
|
const { project, sourceFile } = loadProjectFile(file);
|
|
19409
19542
|
const symbol = findSymbol(sourceFile, oldName);
|
|
19410
19543
|
if (!symbol) {
|
|
19411
|
-
console.log(
|
|
19544
|
+
console.log(chalk177.red(`Symbol "${oldName}" not found in ${file}`));
|
|
19412
19545
|
process.exit(1);
|
|
19413
19546
|
}
|
|
19414
19547
|
const grouped = groupReferences(symbol, cwd);
|
|
19415
19548
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
19416
19549
|
console.log(
|
|
19417
|
-
|
|
19550
|
+
chalk177.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
19418
19551
|
`)
|
|
19419
19552
|
);
|
|
19420
19553
|
for (const [refFile, lines] of grouped) {
|
|
19421
19554
|
console.log(
|
|
19422
|
-
` ${
|
|
19555
|
+
` ${chalk177.dim(refFile)}: lines ${chalk177.cyan(lines.join(", "))}`
|
|
19423
19556
|
);
|
|
19424
19557
|
}
|
|
19425
19558
|
if (options2.apply) {
|
|
19426
19559
|
symbol.rename(newName);
|
|
19427
19560
|
await project.save();
|
|
19428
|
-
console.log(
|
|
19561
|
+
console.log(chalk177.green(`
|
|
19429
19562
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
19430
19563
|
} else {
|
|
19431
|
-
console.log(
|
|
19564
|
+
console.log(chalk177.dim("\nDry run. Use --apply to execute."));
|
|
19432
19565
|
}
|
|
19433
19566
|
}
|
|
19434
19567
|
|
|
19435
19568
|
// src/commands/refactor/restructure/index.ts
|
|
19436
19569
|
import path54 from "path";
|
|
19437
|
-
import
|
|
19570
|
+
import chalk180 from "chalk";
|
|
19438
19571
|
|
|
19439
19572
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
19440
19573
|
import path48 from "path";
|
|
@@ -19513,50 +19646,50 @@ function clusterFiles(graph) {
|
|
|
19513
19646
|
|
|
19514
19647
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
19515
19648
|
import path50 from "path";
|
|
19516
|
-
import
|
|
19649
|
+
import chalk178 from "chalk";
|
|
19517
19650
|
function relPath(filePath) {
|
|
19518
19651
|
return path50.relative(process.cwd(), filePath);
|
|
19519
19652
|
}
|
|
19520
19653
|
function displayMoves(plan2) {
|
|
19521
19654
|
if (plan2.moves.length === 0) return;
|
|
19522
|
-
console.log(
|
|
19655
|
+
console.log(chalk178.bold("\nFile moves:"));
|
|
19523
19656
|
for (const move2 of plan2.moves) {
|
|
19524
19657
|
console.log(
|
|
19525
|
-
` ${
|
|
19658
|
+
` ${chalk178.red(relPath(move2.from))} \u2192 ${chalk178.green(relPath(move2.to))}`
|
|
19526
19659
|
);
|
|
19527
|
-
console.log(
|
|
19660
|
+
console.log(chalk178.dim(` ${move2.reason}`));
|
|
19528
19661
|
}
|
|
19529
19662
|
}
|
|
19530
19663
|
function displayRewrites(rewrites) {
|
|
19531
19664
|
if (rewrites.length === 0) return;
|
|
19532
19665
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
19533
|
-
console.log(
|
|
19666
|
+
console.log(chalk178.bold(`
|
|
19534
19667
|
Import rewrites (${affectedFiles.size} files):`));
|
|
19535
19668
|
for (const file of affectedFiles) {
|
|
19536
|
-
console.log(` ${
|
|
19669
|
+
console.log(` ${chalk178.cyan(relPath(file))}:`);
|
|
19537
19670
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
19538
19671
|
(r) => r.file === file
|
|
19539
19672
|
)) {
|
|
19540
19673
|
console.log(
|
|
19541
|
-
` ${
|
|
19674
|
+
` ${chalk178.red(`"${oldSpecifier}"`)} \u2192 ${chalk178.green(`"${newSpecifier}"`)}`
|
|
19542
19675
|
);
|
|
19543
19676
|
}
|
|
19544
19677
|
}
|
|
19545
19678
|
}
|
|
19546
19679
|
function displayPlan2(plan2) {
|
|
19547
19680
|
if (plan2.warnings.length > 0) {
|
|
19548
|
-
console.log(
|
|
19549
|
-
for (const w of plan2.warnings) console.log(
|
|
19681
|
+
console.log(chalk178.yellow("\nWarnings:"));
|
|
19682
|
+
for (const w of plan2.warnings) console.log(chalk178.yellow(` ${w}`));
|
|
19550
19683
|
}
|
|
19551
19684
|
if (plan2.newDirectories.length > 0) {
|
|
19552
|
-
console.log(
|
|
19685
|
+
console.log(chalk178.bold("\nNew directories:"));
|
|
19553
19686
|
for (const dir of plan2.newDirectories)
|
|
19554
|
-
console.log(
|
|
19687
|
+
console.log(chalk178.green(` ${dir}/`));
|
|
19555
19688
|
}
|
|
19556
19689
|
displayMoves(plan2);
|
|
19557
19690
|
displayRewrites(plan2.rewrites);
|
|
19558
19691
|
console.log(
|
|
19559
|
-
|
|
19692
|
+
chalk178.dim(
|
|
19560
19693
|
`
|
|
19561
19694
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
19562
19695
|
)
|
|
@@ -19566,18 +19699,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
19566
19699
|
// src/commands/refactor/restructure/executePlan.ts
|
|
19567
19700
|
import fs31 from "fs";
|
|
19568
19701
|
import path51 from "path";
|
|
19569
|
-
import
|
|
19702
|
+
import chalk179 from "chalk";
|
|
19570
19703
|
function executePlan(plan2) {
|
|
19571
19704
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
19572
19705
|
for (const [file, content] of updatedContents) {
|
|
19573
19706
|
fs31.writeFileSync(file, content, "utf8");
|
|
19574
19707
|
console.log(
|
|
19575
|
-
|
|
19708
|
+
chalk179.cyan(` Rewrote imports in ${path51.relative(process.cwd(), file)}`)
|
|
19576
19709
|
);
|
|
19577
19710
|
}
|
|
19578
19711
|
for (const dir of plan2.newDirectories) {
|
|
19579
19712
|
fs31.mkdirSync(dir, { recursive: true });
|
|
19580
|
-
console.log(
|
|
19713
|
+
console.log(chalk179.green(` Created ${path51.relative(process.cwd(), dir)}/`));
|
|
19581
19714
|
}
|
|
19582
19715
|
for (const move2 of plan2.moves) {
|
|
19583
19716
|
const targetDir = path51.dirname(move2.to);
|
|
@@ -19586,7 +19719,7 @@ function executePlan(plan2) {
|
|
|
19586
19719
|
}
|
|
19587
19720
|
fs31.renameSync(move2.from, move2.to);
|
|
19588
19721
|
console.log(
|
|
19589
|
-
|
|
19722
|
+
chalk179.white(
|
|
19590
19723
|
` Moved ${path51.relative(process.cwd(), move2.from)} \u2192 ${path51.relative(process.cwd(), move2.to)}`
|
|
19591
19724
|
)
|
|
19592
19725
|
);
|
|
@@ -19601,7 +19734,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
19601
19734
|
if (entries.length === 0) {
|
|
19602
19735
|
fs31.rmdirSync(dir);
|
|
19603
19736
|
console.log(
|
|
19604
|
-
|
|
19737
|
+
chalk179.dim(
|
|
19605
19738
|
` Removed empty directory ${path51.relative(process.cwd(), dir)}`
|
|
19606
19739
|
)
|
|
19607
19740
|
);
|
|
@@ -19734,22 +19867,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
19734
19867
|
const targetPattern = pattern2 ?? "src";
|
|
19735
19868
|
const files = findSourceFiles2(targetPattern);
|
|
19736
19869
|
if (files.length === 0) {
|
|
19737
|
-
console.log(
|
|
19870
|
+
console.log(chalk180.yellow("No files found matching pattern"));
|
|
19738
19871
|
return;
|
|
19739
19872
|
}
|
|
19740
19873
|
const tsConfigPath = path54.resolve("tsconfig.json");
|
|
19741
19874
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
19742
19875
|
if (plan2.moves.length === 0) {
|
|
19743
|
-
console.log(
|
|
19876
|
+
console.log(chalk180.green("No restructuring needed"));
|
|
19744
19877
|
return;
|
|
19745
19878
|
}
|
|
19746
19879
|
displayPlan2(plan2);
|
|
19747
19880
|
if (options2.apply) {
|
|
19748
|
-
console.log(
|
|
19881
|
+
console.log(chalk180.bold("\nApplying changes..."));
|
|
19749
19882
|
executePlan(plan2);
|
|
19750
|
-
console.log(
|
|
19883
|
+
console.log(chalk180.green("\nRestructuring complete"));
|
|
19751
19884
|
} else {
|
|
19752
|
-
console.log(
|
|
19885
|
+
console.log(chalk180.dim("\nDry run. Use --apply to execute."));
|
|
19753
19886
|
}
|
|
19754
19887
|
}
|
|
19755
19888
|
|
|
@@ -19934,9 +20067,9 @@ function buildReviewPaths(repoRoot, key) {
|
|
|
19934
20067
|
}
|
|
19935
20068
|
|
|
19936
20069
|
// src/commands/review/fetchExistingComments.ts
|
|
19937
|
-
import { execSync as
|
|
20070
|
+
import { execSync as execSync51 } from "child_process";
|
|
19938
20071
|
function fetchRawComments(org, repo, prNumber) {
|
|
19939
|
-
const out =
|
|
20072
|
+
const out = execSync51(
|
|
19940
20073
|
`gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
19941
20074
|
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
|
|
19942
20075
|
);
|
|
@@ -19967,14 +20100,14 @@ function fetchExistingComments() {
|
|
|
19967
20100
|
}
|
|
19968
20101
|
|
|
19969
20102
|
// src/commands/review/gatherContext.ts
|
|
19970
|
-
import { execSync as
|
|
20103
|
+
import { execSync as execSync54 } from "child_process";
|
|
19971
20104
|
|
|
19972
20105
|
// src/commands/review/fetchPrDiff.ts
|
|
19973
|
-
import { execSync as
|
|
20106
|
+
import { execSync as execSync52 } from "child_process";
|
|
19974
20107
|
function fetchPrDiff(prNumber, baseSha, headSha) {
|
|
19975
20108
|
const { org, repo } = getRepoInfo();
|
|
19976
20109
|
try {
|
|
19977
|
-
return
|
|
20110
|
+
return execSync52(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
19978
20111
|
encoding: "utf8",
|
|
19979
20112
|
maxBuffer: 256 * 1024 * 1024,
|
|
19980
20113
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -19989,19 +20122,19 @@ function isDiffTooLarge(error) {
|
|
|
19989
20122
|
}
|
|
19990
20123
|
function fetchDiffViaGit(baseSha, headSha) {
|
|
19991
20124
|
try {
|
|
19992
|
-
|
|
20125
|
+
execSync52(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
|
|
19993
20126
|
} catch {
|
|
19994
20127
|
}
|
|
19995
|
-
return
|
|
20128
|
+
return execSync52(`git diff ${baseSha}...${headSha}`, {
|
|
19996
20129
|
encoding: "utf8",
|
|
19997
20130
|
maxBuffer: 256 * 1024 * 1024
|
|
19998
20131
|
});
|
|
19999
20132
|
}
|
|
20000
20133
|
|
|
20001
20134
|
// src/commands/review/fetchPrDiffInfo.ts
|
|
20002
|
-
import { execSync as
|
|
20135
|
+
import { execSync as execSync53 } from "child_process";
|
|
20003
20136
|
function getCurrentBranch3() {
|
|
20004
|
-
return
|
|
20137
|
+
return execSync53("git rev-parse --abbrev-ref HEAD", {
|
|
20005
20138
|
encoding: "utf8"
|
|
20006
20139
|
}).trim();
|
|
20007
20140
|
}
|
|
@@ -20009,7 +20142,7 @@ function fetchPrDiffInfo() {
|
|
|
20009
20142
|
const { org, repo } = getRepoInfo();
|
|
20010
20143
|
const branch2 = getCurrentBranch3();
|
|
20011
20144
|
const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
|
|
20012
|
-
const raw =
|
|
20145
|
+
const raw = execSync53(
|
|
20013
20146
|
`gh pr list --state open --head ${branch2} --json ${fields} -R ${org}/${repo}`,
|
|
20014
20147
|
{
|
|
20015
20148
|
encoding: "utf8",
|
|
@@ -20034,7 +20167,7 @@ function fetchPrDiffInfo() {
|
|
|
20034
20167
|
}
|
|
20035
20168
|
function fetchPrChangedFiles(prNumber) {
|
|
20036
20169
|
const { org, repo } = getRepoInfo();
|
|
20037
|
-
const out =
|
|
20170
|
+
const out = execSync53(
|
|
20038
20171
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
|
|
20039
20172
|
{
|
|
20040
20173
|
encoding: "utf8",
|
|
@@ -20046,11 +20179,11 @@ function fetchPrChangedFiles(prNumber) {
|
|
|
20046
20179
|
|
|
20047
20180
|
// src/commands/review/gatherContext.ts
|
|
20048
20181
|
function gatherContext() {
|
|
20049
|
-
const branch2 =
|
|
20182
|
+
const branch2 = execSync54("git rev-parse --abbrev-ref HEAD", {
|
|
20050
20183
|
encoding: "utf8"
|
|
20051
20184
|
}).trim();
|
|
20052
|
-
const sha =
|
|
20053
|
-
const shortSha =
|
|
20185
|
+
const sha = execSync54("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
20186
|
+
const shortSha = execSync54("git rev-parse --short=7 HEAD", {
|
|
20054
20187
|
encoding: "utf8"
|
|
20055
20188
|
}).trim();
|
|
20056
20189
|
const prInfo = fetchPrDiffInfo();
|
|
@@ -20332,18 +20465,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
20332
20465
|
}
|
|
20333
20466
|
|
|
20334
20467
|
// src/commands/review/warnOutOfDiff.ts
|
|
20335
|
-
import
|
|
20468
|
+
import chalk181 from "chalk";
|
|
20336
20469
|
function warnOutOfDiff(outOfDiff) {
|
|
20337
20470
|
if (outOfDiff.length === 0) return;
|
|
20338
20471
|
console.warn(
|
|
20339
|
-
|
|
20472
|
+
chalk181.yellow(
|
|
20340
20473
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
20341
20474
|
)
|
|
20342
20475
|
);
|
|
20343
20476
|
for (const finding of outOfDiff) {
|
|
20344
20477
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
20345
20478
|
console.warn(
|
|
20346
|
-
` ${
|
|
20479
|
+
` ${chalk181.yellow("\xB7")} ${finding.title} ${chalk181.dim(
|
|
20347
20480
|
`(${finding.file}:${range})`
|
|
20348
20481
|
)}`
|
|
20349
20482
|
);
|
|
@@ -20362,18 +20495,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
20362
20495
|
}
|
|
20363
20496
|
|
|
20364
20497
|
// src/commands/review/warnUnlocated.ts
|
|
20365
|
-
import
|
|
20498
|
+
import chalk182 from "chalk";
|
|
20366
20499
|
function warnUnlocated(unlocated) {
|
|
20367
20500
|
if (unlocated.length === 0) return;
|
|
20368
20501
|
console.warn(
|
|
20369
|
-
|
|
20502
|
+
chalk182.yellow(
|
|
20370
20503
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
20371
20504
|
)
|
|
20372
20505
|
);
|
|
20373
20506
|
for (const finding of unlocated) {
|
|
20374
|
-
const where = finding.location ||
|
|
20507
|
+
const where = finding.location || chalk182.dim("missing");
|
|
20375
20508
|
console.warn(
|
|
20376
|
-
` ${
|
|
20509
|
+
` ${chalk182.yellow("\xB7")} ${finding.title} ${chalk182.dim(`(${where})`)}`
|
|
20377
20510
|
);
|
|
20378
20511
|
}
|
|
20379
20512
|
}
|
|
@@ -21545,7 +21678,7 @@ function registerReview(program2) {
|
|
|
21545
21678
|
}
|
|
21546
21679
|
|
|
21547
21680
|
// src/commands/seq/seqAuth.ts
|
|
21548
|
-
import
|
|
21681
|
+
import chalk184 from "chalk";
|
|
21549
21682
|
|
|
21550
21683
|
// src/commands/seq/loadConnections.ts
|
|
21551
21684
|
function loadConnections2() {
|
|
@@ -21574,10 +21707,10 @@ function setDefaultConnection(name) {
|
|
|
21574
21707
|
}
|
|
21575
21708
|
|
|
21576
21709
|
// src/shared/assertUniqueName.ts
|
|
21577
|
-
import
|
|
21710
|
+
import chalk183 from "chalk";
|
|
21578
21711
|
function assertUniqueName(existingNames, name) {
|
|
21579
21712
|
if (existingNames.includes(name)) {
|
|
21580
|
-
console.error(
|
|
21713
|
+
console.error(chalk183.red(`Connection "${name}" already exists.`));
|
|
21581
21714
|
process.exit(1);
|
|
21582
21715
|
}
|
|
21583
21716
|
}
|
|
@@ -21595,7 +21728,7 @@ async function promptConnection2(existingNames) {
|
|
|
21595
21728
|
var seqAuth = createConnectionAuth({
|
|
21596
21729
|
load: loadConnections2,
|
|
21597
21730
|
save: saveConnections2,
|
|
21598
|
-
format: (c) => `${
|
|
21731
|
+
format: (c) => `${chalk184.bold(c.name)} ${c.url}`,
|
|
21599
21732
|
promptNew: promptConnection2,
|
|
21600
21733
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
21601
21734
|
});
|
|
@@ -21615,10 +21748,10 @@ var seqConfigHelp = [
|
|
|
21615
21748
|
];
|
|
21616
21749
|
|
|
21617
21750
|
// src/commands/seq/seqQuery.ts
|
|
21618
|
-
import
|
|
21751
|
+
import chalk188 from "chalk";
|
|
21619
21752
|
|
|
21620
21753
|
// src/commands/seq/fetchSeq.ts
|
|
21621
|
-
import
|
|
21754
|
+
import chalk185 from "chalk";
|
|
21622
21755
|
async function fetchSeq(conn, path67, params) {
|
|
21623
21756
|
const url = `${conn.url}${path67}?${params}`;
|
|
21624
21757
|
const response = await fetch(url, {
|
|
@@ -21629,7 +21762,7 @@ async function fetchSeq(conn, path67, params) {
|
|
|
21629
21762
|
});
|
|
21630
21763
|
if (!response.ok) {
|
|
21631
21764
|
const body = await response.text();
|
|
21632
|
-
console.error(
|
|
21765
|
+
console.error(chalk185.red(`Seq returned ${response.status}: ${body}`));
|
|
21633
21766
|
process.exit(1);
|
|
21634
21767
|
}
|
|
21635
21768
|
return response;
|
|
@@ -21643,8 +21776,8 @@ function filterToSql(filter) {
|
|
|
21643
21776
|
// src/commands/seq/fetchSeqData.ts
|
|
21644
21777
|
function buildDataParams(filter, count7, from, to) {
|
|
21645
21778
|
const sqlFilter = filterToSql(filter);
|
|
21646
|
-
const
|
|
21647
|
-
const params = new URLSearchParams({ q:
|
|
21779
|
+
const sql24 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count7}`;
|
|
21780
|
+
const params = new URLSearchParams({ q: sql24 });
|
|
21648
21781
|
if (from) params.set("rangeStartUtc", from);
|
|
21649
21782
|
if (to) params.set("rangeEndUtc", to);
|
|
21650
21783
|
return params;
|
|
@@ -21688,23 +21821,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
21688
21821
|
}
|
|
21689
21822
|
|
|
21690
21823
|
// src/commands/seq/formatEvent.ts
|
|
21691
|
-
import
|
|
21824
|
+
import chalk186 from "chalk";
|
|
21692
21825
|
function levelColor(level) {
|
|
21693
21826
|
switch (level) {
|
|
21694
21827
|
case "Fatal":
|
|
21695
|
-
return
|
|
21828
|
+
return chalk186.bgRed.white;
|
|
21696
21829
|
case "Error":
|
|
21697
|
-
return
|
|
21830
|
+
return chalk186.red;
|
|
21698
21831
|
case "Warning":
|
|
21699
|
-
return
|
|
21832
|
+
return chalk186.yellow;
|
|
21700
21833
|
case "Information":
|
|
21701
|
-
return
|
|
21834
|
+
return chalk186.cyan;
|
|
21702
21835
|
case "Debug":
|
|
21703
|
-
return
|
|
21836
|
+
return chalk186.gray;
|
|
21704
21837
|
case "Verbose":
|
|
21705
|
-
return
|
|
21838
|
+
return chalk186.dim;
|
|
21706
21839
|
default:
|
|
21707
|
-
return
|
|
21840
|
+
return chalk186.white;
|
|
21708
21841
|
}
|
|
21709
21842
|
}
|
|
21710
21843
|
function levelAbbrev(level) {
|
|
@@ -21745,12 +21878,12 @@ function formatTimestamp(iso) {
|
|
|
21745
21878
|
function formatEvent(event) {
|
|
21746
21879
|
const color = levelColor(event.Level);
|
|
21747
21880
|
const abbrev = levelAbbrev(event.Level);
|
|
21748
|
-
const ts8 =
|
|
21881
|
+
const ts8 = chalk186.dim(formatTimestamp(event.Timestamp));
|
|
21749
21882
|
const msg = renderMessage(event);
|
|
21750
21883
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
21751
21884
|
if (event.Exception) {
|
|
21752
21885
|
for (const line of event.Exception.split("\n")) {
|
|
21753
|
-
lines.push(
|
|
21886
|
+
lines.push(chalk186.red(` ${line}`));
|
|
21754
21887
|
}
|
|
21755
21888
|
}
|
|
21756
21889
|
return lines.join("\n");
|
|
@@ -21783,11 +21916,11 @@ function rejectTimestampFilter(filter) {
|
|
|
21783
21916
|
}
|
|
21784
21917
|
|
|
21785
21918
|
// src/shared/resolveNamedConnection.ts
|
|
21786
|
-
import
|
|
21919
|
+
import chalk187 from "chalk";
|
|
21787
21920
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
21788
21921
|
if (connections.length === 0) {
|
|
21789
21922
|
console.error(
|
|
21790
|
-
|
|
21923
|
+
chalk187.red(
|
|
21791
21924
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
21792
21925
|
)
|
|
21793
21926
|
);
|
|
@@ -21796,7 +21929,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
21796
21929
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
21797
21930
|
const connection = connections.find((c) => c.name === target);
|
|
21798
21931
|
if (!connection) {
|
|
21799
|
-
console.error(
|
|
21932
|
+
console.error(chalk187.red(`${kind} connection "${target}" not found.`));
|
|
21800
21933
|
process.exit(1);
|
|
21801
21934
|
}
|
|
21802
21935
|
return connection;
|
|
@@ -21825,7 +21958,7 @@ async function seqQuery(filter, options2) {
|
|
|
21825
21958
|
new URLSearchParams({ filter, count: String(count7) })
|
|
21826
21959
|
);
|
|
21827
21960
|
if (events.length === 0) {
|
|
21828
|
-
console.log(
|
|
21961
|
+
console.log(chalk188.yellow("No events found."));
|
|
21829
21962
|
return;
|
|
21830
21963
|
}
|
|
21831
21964
|
if (options2.json) {
|
|
@@ -21836,11 +21969,11 @@ async function seqQuery(filter, options2) {
|
|
|
21836
21969
|
for (const event of chronological) {
|
|
21837
21970
|
console.log(formatEvent(event));
|
|
21838
21971
|
}
|
|
21839
|
-
console.log(
|
|
21972
|
+
console.log(chalk188.dim(`
|
|
21840
21973
|
${events.length} events`));
|
|
21841
21974
|
if (events.length >= count7) {
|
|
21842
21975
|
console.log(
|
|
21843
|
-
|
|
21976
|
+
chalk188.yellow(
|
|
21844
21977
|
`Results limited to ${count7}. Use --count to retrieve more.`
|
|
21845
21978
|
)
|
|
21846
21979
|
);
|
|
@@ -21848,10 +21981,10 @@ ${events.length} events`));
|
|
|
21848
21981
|
}
|
|
21849
21982
|
|
|
21850
21983
|
// src/shared/setNamedDefaultConnection.ts
|
|
21851
|
-
import
|
|
21984
|
+
import chalk189 from "chalk";
|
|
21852
21985
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
21853
21986
|
if (!connections.find((c) => c.name === name)) {
|
|
21854
|
-
console.error(
|
|
21987
|
+
console.error(chalk189.red(`Connection "${name}" not found.`));
|
|
21855
21988
|
process.exit(1);
|
|
21856
21989
|
}
|
|
21857
21990
|
setDefault(name);
|
|
@@ -21900,36 +22033,36 @@ function registerSignal(program2) {
|
|
|
21900
22033
|
}
|
|
21901
22034
|
|
|
21902
22035
|
// src/commands/sql/sqlAuth.ts
|
|
21903
|
-
import
|
|
22036
|
+
import chalk191 from "chalk";
|
|
21904
22037
|
|
|
21905
22038
|
// src/commands/sql/loadConnections.ts
|
|
21906
22039
|
function loadConnections3() {
|
|
21907
22040
|
const raw = loadGlobalConfigRaw();
|
|
21908
|
-
const
|
|
21909
|
-
return
|
|
22041
|
+
const sql24 = raw.sql;
|
|
22042
|
+
return sql24?.connections ?? [];
|
|
21910
22043
|
}
|
|
21911
22044
|
function saveConnections3(connections) {
|
|
21912
22045
|
const raw = loadGlobalConfigRaw();
|
|
21913
|
-
const
|
|
21914
|
-
|
|
21915
|
-
raw.sql =
|
|
22046
|
+
const sql24 = raw.sql ?? {};
|
|
22047
|
+
sql24.connections = connections;
|
|
22048
|
+
raw.sql = sql24;
|
|
21916
22049
|
saveGlobalConfig(raw);
|
|
21917
22050
|
}
|
|
21918
22051
|
function getDefaultConnection2() {
|
|
21919
22052
|
const raw = loadGlobalConfigRaw();
|
|
21920
|
-
const
|
|
21921
|
-
return
|
|
22053
|
+
const sql24 = raw.sql;
|
|
22054
|
+
return sql24?.defaultConnection;
|
|
21922
22055
|
}
|
|
21923
22056
|
function setDefaultConnection2(name) {
|
|
21924
22057
|
const raw = loadGlobalConfigRaw();
|
|
21925
|
-
const
|
|
21926
|
-
|
|
21927
|
-
raw.sql =
|
|
22058
|
+
const sql24 = raw.sql ?? {};
|
|
22059
|
+
sql24.defaultConnection = name;
|
|
22060
|
+
raw.sql = sql24;
|
|
21928
22061
|
saveGlobalConfig(raw);
|
|
21929
22062
|
}
|
|
21930
22063
|
|
|
21931
22064
|
// src/commands/sql/promptConnection.ts
|
|
21932
|
-
import
|
|
22065
|
+
import chalk190 from "chalk";
|
|
21933
22066
|
async function promptConnection3(existingNames) {
|
|
21934
22067
|
const name = await promptInput("name", "Connection name:", "default");
|
|
21935
22068
|
assertUniqueName(existingNames, name);
|
|
@@ -21937,7 +22070,7 @@ async function promptConnection3(existingNames) {
|
|
|
21937
22070
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
21938
22071
|
const port = Number.parseInt(portStr, 10);
|
|
21939
22072
|
if (!Number.isFinite(port)) {
|
|
21940
|
-
console.error(
|
|
22073
|
+
console.error(chalk190.red(`Invalid port "${portStr}".`));
|
|
21941
22074
|
process.exit(1);
|
|
21942
22075
|
}
|
|
21943
22076
|
const user = await promptInput("user", "User:");
|
|
@@ -21950,13 +22083,13 @@ async function promptConnection3(existingNames) {
|
|
|
21950
22083
|
var sqlAuth = createConnectionAuth({
|
|
21951
22084
|
load: loadConnections3,
|
|
21952
22085
|
save: saveConnections3,
|
|
21953
|
-
format: (c) => `${
|
|
22086
|
+
format: (c) => `${chalk191.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
21954
22087
|
promptNew: promptConnection3,
|
|
21955
22088
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
21956
22089
|
});
|
|
21957
22090
|
|
|
21958
22091
|
// src/commands/sql/printTable.ts
|
|
21959
|
-
import
|
|
22092
|
+
import chalk192 from "chalk";
|
|
21960
22093
|
function formatCell(value) {
|
|
21961
22094
|
if (value === null || value === void 0) return "";
|
|
21962
22095
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -21965,7 +22098,7 @@ function formatCell(value) {
|
|
|
21965
22098
|
}
|
|
21966
22099
|
function printTable(rows) {
|
|
21967
22100
|
if (rows.length === 0) {
|
|
21968
|
-
console.log(
|
|
22101
|
+
console.log(chalk192.yellow("(no rows)"));
|
|
21969
22102
|
return;
|
|
21970
22103
|
}
|
|
21971
22104
|
const columns = Object.keys(rows[0]);
|
|
@@ -21973,13 +22106,13 @@ function printTable(rows) {
|
|
|
21973
22106
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
21974
22107
|
);
|
|
21975
22108
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
21976
|
-
console.log(
|
|
21977
|
-
console.log(
|
|
22109
|
+
console.log(chalk192.dim(header));
|
|
22110
|
+
console.log(chalk192.dim("-".repeat(header.length)));
|
|
21978
22111
|
for (const row of rows) {
|
|
21979
22112
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
21980
22113
|
console.log(line);
|
|
21981
22114
|
}
|
|
21982
|
-
console.log(
|
|
22115
|
+
console.log(chalk192.dim(`
|
|
21983
22116
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
21984
22117
|
}
|
|
21985
22118
|
|
|
@@ -21995,9 +22128,9 @@ function resolveConnection3(name) {
|
|
|
21995
22128
|
}
|
|
21996
22129
|
|
|
21997
22130
|
// src/commands/sql/sqlConnect.ts
|
|
21998
|
-
import
|
|
22131
|
+
import sql18 from "mssql";
|
|
21999
22132
|
async function sqlConnect(conn) {
|
|
22000
|
-
return await
|
|
22133
|
+
return await sql18.connect({
|
|
22001
22134
|
server: conn.server,
|
|
22002
22135
|
port: conn.port,
|
|
22003
22136
|
user: conn.user,
|
|
@@ -22053,7 +22186,7 @@ var sqlConfigHelp = [
|
|
|
22053
22186
|
];
|
|
22054
22187
|
|
|
22055
22188
|
// src/commands/sql/sqlMutate.ts
|
|
22056
|
-
import
|
|
22189
|
+
import chalk193 from "chalk";
|
|
22057
22190
|
|
|
22058
22191
|
// src/commands/sql/isMutation.ts
|
|
22059
22192
|
var MUTATION_KEYWORDS = [
|
|
@@ -22074,11 +22207,11 @@ var MUTATION_PATTERN = new RegExp(
|
|
|
22074
22207
|
`\\b(${MUTATION_KEYWORDS.join("|")})\\b`,
|
|
22075
22208
|
"i"
|
|
22076
22209
|
);
|
|
22077
|
-
function stripComments(
|
|
22078
|
-
return
|
|
22210
|
+
function stripComments(sql24) {
|
|
22211
|
+
return sql24.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
|
|
22079
22212
|
}
|
|
22080
|
-
function isMutation(
|
|
22081
|
-
const stripped = stripComments(
|
|
22213
|
+
function isMutation(sql24) {
|
|
22214
|
+
const stripped = stripComments(sql24);
|
|
22082
22215
|
if (MUTATION_PATTERN.test(stripped)) return true;
|
|
22083
22216
|
return /\bSELECT\b[\s\S]+\bINTO\s+\w/i.test(stripped);
|
|
22084
22217
|
}
|
|
@@ -22087,7 +22220,7 @@ function isMutation(sql23) {
|
|
|
22087
22220
|
async function sqlMutate(query, connectionName) {
|
|
22088
22221
|
if (!isMutation(query)) {
|
|
22089
22222
|
console.error(
|
|
22090
|
-
|
|
22223
|
+
chalk193.red(
|
|
22091
22224
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
22092
22225
|
)
|
|
22093
22226
|
);
|
|
@@ -22097,18 +22230,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
22097
22230
|
const pool = await sqlConnect(conn);
|
|
22098
22231
|
try {
|
|
22099
22232
|
const result = await pool.request().query(query);
|
|
22100
|
-
console.log(
|
|
22233
|
+
console.log(chalk193.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
22101
22234
|
} finally {
|
|
22102
22235
|
await pool.close();
|
|
22103
22236
|
}
|
|
22104
22237
|
}
|
|
22105
22238
|
|
|
22106
22239
|
// src/commands/sql/sqlQuery.ts
|
|
22107
|
-
import
|
|
22240
|
+
import chalk194 from "chalk";
|
|
22108
22241
|
async function sqlQuery(query, connectionName) {
|
|
22109
22242
|
if (isMutation(query)) {
|
|
22110
22243
|
console.error(
|
|
22111
|
-
|
|
22244
|
+
chalk194.red(
|
|
22112
22245
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
22113
22246
|
)
|
|
22114
22247
|
);
|
|
@@ -22123,7 +22256,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
22123
22256
|
printTable(rows);
|
|
22124
22257
|
} else {
|
|
22125
22258
|
console.log(
|
|
22126
|
-
|
|
22259
|
+
chalk194.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
22127
22260
|
);
|
|
22128
22261
|
}
|
|
22129
22262
|
} finally {
|
|
@@ -22700,7 +22833,7 @@ import { mkdirSync as mkdirSync20 } from "fs";
|
|
|
22700
22833
|
import { join as join58 } from "path";
|
|
22701
22834
|
|
|
22702
22835
|
// src/commands/voice/checkLockFile.ts
|
|
22703
|
-
import { execSync as
|
|
22836
|
+
import { execSync as execSync55 } from "child_process";
|
|
22704
22837
|
import { existsSync as existsSync47, mkdirSync as mkdirSync19, readFileSync as readFileSync42, writeFileSync as writeFileSync37 } from "fs";
|
|
22705
22838
|
import { join as join57 } from "path";
|
|
22706
22839
|
function isProcessAlive2(pid) {
|
|
@@ -22729,7 +22862,7 @@ function bootstrapVenv() {
|
|
|
22729
22862
|
if (existsSync47(getVenvPython())) return;
|
|
22730
22863
|
console.log("Setting up Python environment...");
|
|
22731
22864
|
const pythonDir = getPythonDir();
|
|
22732
|
-
|
|
22865
|
+
execSync55(
|
|
22733
22866
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
22734
22867
|
{
|
|
22735
22868
|
stdio: "inherit",
|
|
@@ -22938,7 +23071,7 @@ function registerVoice(program2) {
|
|
|
22938
23071
|
|
|
22939
23072
|
// src/commands/roam/auth.ts
|
|
22940
23073
|
import { randomBytes } from "crypto";
|
|
22941
|
-
import
|
|
23074
|
+
import chalk195 from "chalk";
|
|
22942
23075
|
|
|
22943
23076
|
// src/commands/roam/waitForCallback.ts
|
|
22944
23077
|
import { createServer as createServer3 } from "http";
|
|
@@ -23069,13 +23202,13 @@ async function auth() {
|
|
|
23069
23202
|
saveGlobalConfig(config);
|
|
23070
23203
|
const state = randomBytes(16).toString("hex");
|
|
23071
23204
|
console.log(
|
|
23072
|
-
|
|
23205
|
+
chalk195.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
23073
23206
|
);
|
|
23074
|
-
console.log(
|
|
23075
|
-
console.log(
|
|
23076
|
-
console.log(
|
|
23207
|
+
console.log(chalk195.white("http://localhost:14523/callback\n"));
|
|
23208
|
+
console.log(chalk195.blue("Opening browser for authorization..."));
|
|
23209
|
+
console.log(chalk195.dim("Waiting for authorization callback..."));
|
|
23077
23210
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
23078
|
-
console.log(
|
|
23211
|
+
console.log(chalk195.dim("Exchanging code for tokens..."));
|
|
23079
23212
|
const tokens = await exchangeToken({
|
|
23080
23213
|
code,
|
|
23081
23214
|
clientId,
|
|
@@ -23091,7 +23224,7 @@ async function auth() {
|
|
|
23091
23224
|
};
|
|
23092
23225
|
saveGlobalConfig(config);
|
|
23093
23226
|
console.log(
|
|
23094
|
-
|
|
23227
|
+
chalk195.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
23095
23228
|
);
|
|
23096
23229
|
}
|
|
23097
23230
|
|
|
@@ -23325,11 +23458,11 @@ function resolveParams(params, cliArgs) {
|
|
|
23325
23458
|
}
|
|
23326
23459
|
|
|
23327
23460
|
// src/commands/run/runPreCommands.ts
|
|
23328
|
-
import { execSync as
|
|
23461
|
+
import { execSync as execSync56 } from "child_process";
|
|
23329
23462
|
function runPreCommands(pre, cwd) {
|
|
23330
23463
|
for (const cmd of pre) {
|
|
23331
23464
|
try {
|
|
23332
|
-
|
|
23465
|
+
execSync56(cmd, { stdio: "inherit", cwd });
|
|
23333
23466
|
} catch (error) {
|
|
23334
23467
|
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
23335
23468
|
process.exit(code);
|
|
@@ -23630,11 +23763,11 @@ function registerRun(program2) {
|
|
|
23630
23763
|
}
|
|
23631
23764
|
|
|
23632
23765
|
// src/commands/screenshot/index.ts
|
|
23633
|
-
import { execSync as
|
|
23766
|
+
import { execSync as execSync57 } from "child_process";
|
|
23634
23767
|
import { existsSync as existsSync52, mkdirSync as mkdirSync23, unlinkSync as unlinkSync19, writeFileSync as writeFileSync40 } from "fs";
|
|
23635
23768
|
import { tmpdir as tmpdir7 } from "os";
|
|
23636
23769
|
import { join as join64, resolve as resolve15 } from "path";
|
|
23637
|
-
import
|
|
23770
|
+
import chalk196 from "chalk";
|
|
23638
23771
|
|
|
23639
23772
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
23640
23773
|
var captureWindowPs1 = `
|
|
@@ -23773,7 +23906,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
23773
23906
|
const scriptPath = join64(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
23774
23907
|
writeFileSync40(scriptPath, captureWindowPs1, "utf8");
|
|
23775
23908
|
try {
|
|
23776
|
-
|
|
23909
|
+
execSync57(
|
|
23777
23910
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
23778
23911
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
|
|
23779
23912
|
);
|
|
@@ -23785,13 +23918,13 @@ function screenshot(processName) {
|
|
|
23785
23918
|
const config = loadConfig();
|
|
23786
23919
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
23787
23920
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
23788
|
-
console.log(
|
|
23921
|
+
console.log(chalk196.gray(`Capturing window for process "${processName}" ...`));
|
|
23789
23922
|
try {
|
|
23790
23923
|
runPowerShellScript(processName, outputPath);
|
|
23791
|
-
console.log(
|
|
23924
|
+
console.log(chalk196.green(`Screenshot saved: ${outputPath}`));
|
|
23792
23925
|
} catch (error) {
|
|
23793
23926
|
const msg = error instanceof Error ? error.message : String(error);
|
|
23794
|
-
console.error(
|
|
23927
|
+
console.error(chalk196.red(`Failed to capture screenshot: ${msg}`));
|
|
23795
23928
|
process.exit(1);
|
|
23796
23929
|
}
|
|
23797
23930
|
}
|
|
@@ -24431,13 +24564,13 @@ function drainSessions(sessions, onDrained) {
|
|
|
24431
24564
|
}
|
|
24432
24565
|
|
|
24433
24566
|
// src/shared/db/recordPhaseActiveMs.ts
|
|
24434
|
-
import { sql as
|
|
24567
|
+
import { sql as sql19 } from "drizzle-orm";
|
|
24435
24568
|
async function recordPhaseActiveMs(db, itemId2, phaseIdx, activeMs) {
|
|
24436
24569
|
if (activeMs <= 0) return;
|
|
24437
24570
|
await db.insert(phaseUsage).values({ itemId: itemId2, phaseIdx, activeMs }).onConflictDoUpdate({
|
|
24438
24571
|
target: [phaseUsage.itemId, phaseUsage.phaseIdx],
|
|
24439
24572
|
set: {
|
|
24440
|
-
activeMs:
|
|
24573
|
+
activeMs: sql19`${phaseUsage.activeMs} + excluded.active_ms`
|
|
24441
24574
|
}
|
|
24442
24575
|
});
|
|
24443
24576
|
}
|
|
@@ -24629,7 +24762,7 @@ function makeStatusChangeHandler(dismiss, notify2, reuseForRun) {
|
|
|
24629
24762
|
}
|
|
24630
24763
|
|
|
24631
24764
|
// src/shared/db/recordPhaseCycleContext.ts
|
|
24632
|
-
import { sql as
|
|
24765
|
+
import { sql as sql20 } from "drizzle-orm";
|
|
24633
24766
|
async function recordPhaseCycleContext(db, itemId2, phaseIdx, window, resetsAt, pct) {
|
|
24634
24767
|
if (pct <= 0) return;
|
|
24635
24768
|
await db.insert(phaseCycleContext).values({ itemId: itemId2, phaseIdx, window, resetsAt, peakContextPct: pct }).onConflictDoUpdate({
|
|
@@ -24640,24 +24773,24 @@ async function recordPhaseCycleContext(db, itemId2, phaseIdx, window, resetsAt,
|
|
|
24640
24773
|
phaseCycleContext.resetsAt
|
|
24641
24774
|
],
|
|
24642
24775
|
set: {
|
|
24643
|
-
peakContextPct:
|
|
24776
|
+
peakContextPct: sql20`GREATEST(${phaseCycleContext.peakContextPct}, ${pct})`
|
|
24644
24777
|
}
|
|
24645
24778
|
});
|
|
24646
24779
|
}
|
|
24647
24780
|
|
|
24648
24781
|
// src/shared/db/recordPhasePeakContext.ts
|
|
24649
|
-
import { sql as
|
|
24782
|
+
import { sql as sql21 } from "drizzle-orm";
|
|
24650
24783
|
async function recordPhasePeakContext(db, itemId2, phaseIdx, pct) {
|
|
24651
24784
|
await db.insert(phaseUsage).values({ itemId: itemId2, phaseIdx, peakContextPct: pct }).onConflictDoUpdate({
|
|
24652
24785
|
target: [phaseUsage.itemId, phaseUsage.phaseIdx],
|
|
24653
24786
|
set: {
|
|
24654
|
-
peakContextPct:
|
|
24787
|
+
peakContextPct: sql21`GREATEST(${phaseUsage.peakContextPct}, ${pct})`
|
|
24655
24788
|
}
|
|
24656
24789
|
});
|
|
24657
24790
|
}
|
|
24658
24791
|
|
|
24659
24792
|
// src/shared/db/recordPhaseTranscriptUsage.ts
|
|
24660
|
-
import { sql as
|
|
24793
|
+
import { sql as sql22 } from "drizzle-orm";
|
|
24661
24794
|
async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
|
|
24662
24795
|
const byId = /* @__PURE__ */ new Map();
|
|
24663
24796
|
for (const r of responses) byId.set(r.messageId, r);
|
|
@@ -24677,8 +24810,8 @@ async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
|
|
|
24677
24810
|
await tx.insert(phaseUsage).values({ itemId: itemId2, phaseIdx, tokensUp, tokensDown }).onConflictDoUpdate({
|
|
24678
24811
|
target: [phaseUsage.itemId, phaseUsage.phaseIdx],
|
|
24679
24812
|
set: {
|
|
24680
|
-
tokensUp:
|
|
24681
|
-
tokensDown:
|
|
24813
|
+
tokensUp: sql22`${phaseUsage.tokensUp} + ${tokensUp}`,
|
|
24814
|
+
tokensDown: sql22`${phaseUsage.tokensDown} + ${tokensDown}`
|
|
24682
24815
|
}
|
|
24683
24816
|
});
|
|
24684
24817
|
return { tokensUp, tokensDown };
|
|
@@ -24686,17 +24819,17 @@ async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
|
|
|
24686
24819
|
}
|
|
24687
24820
|
|
|
24688
24821
|
// src/shared/db/recordWindowTokens.ts
|
|
24689
|
-
import { and as and21, eq as
|
|
24822
|
+
import { and as and21, eq as eq40, sql as sql23 } from "drizzle-orm";
|
|
24690
24823
|
async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
24691
24824
|
if (tokensUp <= 0 && tokensDown <= 0) return;
|
|
24692
24825
|
await db.update(usagePeaks).set({
|
|
24693
|
-
tokensUp:
|
|
24694
|
-
tokensDown:
|
|
24826
|
+
tokensUp: sql23`${usagePeaks.tokensUp} + ${tokensUp}`,
|
|
24827
|
+
tokensDown: sql23`${usagePeaks.tokensDown} + ${tokensDown}`
|
|
24695
24828
|
}).where(
|
|
24696
24829
|
and21(
|
|
24697
|
-
|
|
24698
|
-
|
|
24699
|
-
|
|
24830
|
+
eq40(usagePeaks.window, window),
|
|
24831
|
+
eq40(usagePeaks.resetsAt, resetsAt),
|
|
24832
|
+
eq40(usagePeaks.segment, 0)
|
|
24700
24833
|
)
|
|
24701
24834
|
);
|
|
24702
24835
|
}
|
|
@@ -24820,10 +24953,10 @@ function applyReviewPause(session, activity2) {
|
|
|
24820
24953
|
}
|
|
24821
24954
|
|
|
24822
24955
|
// src/shared/db/getPhaseActiveMs.ts
|
|
24823
|
-
import { and as and22, eq as
|
|
24956
|
+
import { and as and22, eq as eq41 } from "drizzle-orm";
|
|
24824
24957
|
async function getPhaseActiveMs(db, itemId2, phaseIdx) {
|
|
24825
24958
|
const [row] = await db.select({ activeMs: phaseUsage.activeMs }).from(phaseUsage).where(
|
|
24826
|
-
and22(
|
|
24959
|
+
and22(eq41(phaseUsage.itemId, itemId2), eq41(phaseUsage.phaseIdx, phaseIdx))
|
|
24827
24960
|
);
|
|
24828
24961
|
return row?.activeMs ?? 0;
|
|
24829
24962
|
}
|
|
@@ -26597,7 +26730,7 @@ function registerDaemon(program2) {
|
|
|
26597
26730
|
|
|
26598
26731
|
// src/commands/sessions/summarise/index.ts
|
|
26599
26732
|
import * as fs38 from "fs";
|
|
26600
|
-
import
|
|
26733
|
+
import chalk197 from "chalk";
|
|
26601
26734
|
|
|
26602
26735
|
// src/commands/sessions/summarise/shared.ts
|
|
26603
26736
|
import * as fs37 from "fs";
|
|
@@ -26671,22 +26804,22 @@ ${firstMessage}`);
|
|
|
26671
26804
|
async function summarise2(options2) {
|
|
26672
26805
|
const files = await discoverSessionFiles();
|
|
26673
26806
|
if (files.length === 0) {
|
|
26674
|
-
console.log(
|
|
26807
|
+
console.log(chalk197.yellow("No sessions found."));
|
|
26675
26808
|
return;
|
|
26676
26809
|
}
|
|
26677
26810
|
const toProcess = selectCandidates(files, options2);
|
|
26678
26811
|
if (toProcess.length === 0) {
|
|
26679
|
-
console.log(
|
|
26812
|
+
console.log(chalk197.green("All sessions already summarised."));
|
|
26680
26813
|
return;
|
|
26681
26814
|
}
|
|
26682
26815
|
console.log(
|
|
26683
|
-
|
|
26816
|
+
chalk197.cyan(
|
|
26684
26817
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
26685
26818
|
)
|
|
26686
26819
|
);
|
|
26687
26820
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
26688
26821
|
console.log(
|
|
26689
|
-
|
|
26822
|
+
chalk197.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk197.yellow(`, ${failed2} skipped`) : "")
|
|
26690
26823
|
);
|
|
26691
26824
|
}
|
|
26692
26825
|
function selectCandidates(files, options2) {
|
|
@@ -26706,16 +26839,16 @@ function processSessions(files) {
|
|
|
26706
26839
|
let failed2 = 0;
|
|
26707
26840
|
for (let i = 0; i < files.length; i++) {
|
|
26708
26841
|
const file = files[i];
|
|
26709
|
-
process.stdout.write(
|
|
26842
|
+
process.stdout.write(chalk197.dim(` [${i + 1}/${files.length}] `));
|
|
26710
26843
|
const summary = summariseSession(file);
|
|
26711
26844
|
if (summary) {
|
|
26712
26845
|
writeSummary(file, summary);
|
|
26713
26846
|
succeeded++;
|
|
26714
|
-
process.stdout.write(`${
|
|
26847
|
+
process.stdout.write(`${chalk197.green("\u2713")} ${summary}
|
|
26715
26848
|
`);
|
|
26716
26849
|
} else {
|
|
26717
26850
|
failed2++;
|
|
26718
|
-
process.stdout.write(` ${
|
|
26851
|
+
process.stdout.write(` ${chalk197.yellow("skip")}
|
|
26719
26852
|
`);
|
|
26720
26853
|
}
|
|
26721
26854
|
}
|
|
@@ -26759,7 +26892,7 @@ function registerSessions(program2) {
|
|
|
26759
26892
|
}
|
|
26760
26893
|
|
|
26761
26894
|
// src/commands/statusLine.ts
|
|
26762
|
-
import
|
|
26895
|
+
import chalk199 from "chalk";
|
|
26763
26896
|
|
|
26764
26897
|
// src/shared/contextLevel.ts
|
|
26765
26898
|
function contextLevel(pct) {
|
|
@@ -26769,7 +26902,7 @@ function contextLevel(pct) {
|
|
|
26769
26902
|
}
|
|
26770
26903
|
|
|
26771
26904
|
// src/commands/buildLimitsSegment.ts
|
|
26772
|
-
import
|
|
26905
|
+
import chalk198 from "chalk";
|
|
26773
26906
|
|
|
26774
26907
|
// src/shared/rateLimitLevel.ts
|
|
26775
26908
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -26800,9 +26933,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
26800
26933
|
|
|
26801
26934
|
// src/commands/buildLimitsSegment.ts
|
|
26802
26935
|
var LEVEL_COLOR = {
|
|
26803
|
-
ok:
|
|
26804
|
-
warn:
|
|
26805
|
-
over:
|
|
26936
|
+
ok: chalk198.green,
|
|
26937
|
+
warn: chalk198.yellow,
|
|
26938
|
+
over: chalk198.red
|
|
26806
26939
|
};
|
|
26807
26940
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
26808
26941
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -26898,7 +27031,7 @@ async function relayUsage(claudeSessionId, transcriptPath, usedPct) {
|
|
|
26898
27031
|
}
|
|
26899
27032
|
|
|
26900
27033
|
// src/commands/statusLine.ts
|
|
26901
|
-
|
|
27034
|
+
chalk199.level = 3;
|
|
26902
27035
|
function formatNumber(num) {
|
|
26903
27036
|
return num.toLocaleString("en-US");
|
|
26904
27037
|
}
|
|
@@ -26906,9 +27039,9 @@ function colorizePercent(pct) {
|
|
|
26906
27039
|
const label2 = `${Math.round(pct)}%`;
|
|
26907
27040
|
switch (contextLevel(pct)) {
|
|
26908
27041
|
case "red":
|
|
26909
|
-
return
|
|
27042
|
+
return chalk199.red(label2);
|
|
26910
27043
|
case "yellow":
|
|
26911
|
-
return
|
|
27044
|
+
return chalk199.yellow(label2);
|
|
26912
27045
|
default:
|
|
26913
27046
|
return label2;
|
|
26914
27047
|
}
|
|
@@ -26921,7 +27054,7 @@ async function statusLine() {
|
|
|
26921
27054
|
const usedPct = data.context_window.used_percentage ?? 0;
|
|
26922
27055
|
const dir = data.workspace?.current_dir ?? data.cwd;
|
|
26923
27056
|
const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
|
|
26924
|
-
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${
|
|
27057
|
+
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk199.cyan(branch2)} | ` : "";
|
|
26925
27058
|
console.log(
|
|
26926
27059
|
`${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
|
|
26927
27060
|
);
|
|
@@ -26942,7 +27075,7 @@ import { fileURLToPath as fileURLToPath9 } from "url";
|
|
|
26942
27075
|
// src/commands/sync/syncClaudeMd.ts
|
|
26943
27076
|
import * as fs39 from "fs";
|
|
26944
27077
|
import * as path57 from "path";
|
|
26945
|
-
import
|
|
27078
|
+
import chalk200 from "chalk";
|
|
26946
27079
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
26947
27080
|
const source = path57.join(claudeDir, "CLAUDE.md");
|
|
26948
27081
|
const target = path57.join(targetBase, "CLAUDE.md");
|
|
@@ -26951,12 +27084,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
26951
27084
|
const targetContent = fs39.readFileSync(target, "utf8");
|
|
26952
27085
|
if (sourceContent !== targetContent) {
|
|
26953
27086
|
console.log(
|
|
26954
|
-
|
|
27087
|
+
chalk200.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
26955
27088
|
);
|
|
26956
27089
|
console.log();
|
|
26957
27090
|
printDiff(targetContent, sourceContent);
|
|
26958
27091
|
const confirm = options2?.yes || await promptConfirm(
|
|
26959
|
-
|
|
27092
|
+
chalk200.red("Overwrite existing CLAUDE.md?"),
|
|
26960
27093
|
false
|
|
26961
27094
|
);
|
|
26962
27095
|
if (!confirm) {
|
|
@@ -27150,7 +27283,7 @@ function syncPi(claudeDir) {
|
|
|
27150
27283
|
// src/commands/sync/syncSettings.ts
|
|
27151
27284
|
import * as fs44 from "fs";
|
|
27152
27285
|
import * as path64 from "path";
|
|
27153
|
-
import
|
|
27286
|
+
import chalk201 from "chalk";
|
|
27154
27287
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
27155
27288
|
const source = path64.join(claudeDir, "settings.json");
|
|
27156
27289
|
const target = path64.join(targetBase, "settings.json");
|
|
@@ -27169,14 +27302,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
27169
27302
|
if (mergedContent !== normalizedTarget) {
|
|
27170
27303
|
if (!options2?.yes) {
|
|
27171
27304
|
console.log(
|
|
27172
|
-
|
|
27305
|
+
chalk201.yellow(
|
|
27173
27306
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
27174
27307
|
)
|
|
27175
27308
|
);
|
|
27176
27309
|
console.log();
|
|
27177
27310
|
printDiff(targetContent, mergedContent);
|
|
27178
27311
|
const confirm = await promptConfirm(
|
|
27179
|
-
|
|
27312
|
+
chalk201.red("Overwrite existing settings.json?"),
|
|
27180
27313
|
false
|
|
27181
27314
|
);
|
|
27182
27315
|
if (!confirm) {
|
|
@@ -27218,7 +27351,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
27218
27351
|
}
|
|
27219
27352
|
|
|
27220
27353
|
// src/commands/update.ts
|
|
27221
|
-
import { execSync as
|
|
27354
|
+
import { execSync as execSync58 } from "child_process";
|
|
27222
27355
|
import * as path66 from "path";
|
|
27223
27356
|
|
|
27224
27357
|
// src/commands/restartDaemonAfterUpdate.ts
|
|
@@ -27242,7 +27375,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
27242
27375
|
if (resolved.split(path66.sep).includes("node_modules")) {
|
|
27243
27376
|
return true;
|
|
27244
27377
|
}
|
|
27245
|
-
const globalPrefix =
|
|
27378
|
+
const globalPrefix = execSync58("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
27246
27379
|
return resolved.toLowerCase().startsWith(path66.resolve(globalPrefix).toLowerCase());
|
|
27247
27380
|
} catch {
|
|
27248
27381
|
return false;
|
|
@@ -27253,18 +27386,18 @@ async function update2() {
|
|
|
27253
27386
|
console.log(`Assist is installed at: ${installDir}`);
|
|
27254
27387
|
if (isGitRepo(installDir)) {
|
|
27255
27388
|
console.log("Detected git repo installation, pulling latest...");
|
|
27256
|
-
|
|
27389
|
+
execSync58("git pull", { cwd: installDir, stdio: "inherit" });
|
|
27257
27390
|
console.log("Installing dependencies...");
|
|
27258
|
-
|
|
27391
|
+
execSync58("npm i", { cwd: installDir, stdio: "inherit" });
|
|
27259
27392
|
console.log("Building...");
|
|
27260
|
-
|
|
27393
|
+
execSync58("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
27261
27394
|
console.log("Syncing commands...");
|
|
27262
|
-
|
|
27395
|
+
execSync58("assist sync", { stdio: "inherit" });
|
|
27263
27396
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
27264
27397
|
console.log("Detected global npm installation, updating...");
|
|
27265
|
-
|
|
27398
|
+
execSync58("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
27266
27399
|
console.log("Syncing commands...");
|
|
27267
|
-
|
|
27400
|
+
execSync58("assist sync", { stdio: "inherit" });
|
|
27268
27401
|
} else {
|
|
27269
27402
|
console.error(
|
|
27270
27403
|
"Could not determine installation method. Expected a git repo or global npm install."
|
|
@@ -27275,10 +27408,10 @@ async function update2() {
|
|
|
27275
27408
|
}
|
|
27276
27409
|
|
|
27277
27410
|
// src/reportCliError.ts
|
|
27278
|
-
import
|
|
27411
|
+
import chalk202 from "chalk";
|
|
27279
27412
|
function reportCliError(error) {
|
|
27280
27413
|
if (error instanceof InvalidItemIdError) {
|
|
27281
|
-
console.error(
|
|
27414
|
+
console.error(chalk202.red(error.message));
|
|
27282
27415
|
} else {
|
|
27283
27416
|
console.error(error);
|
|
27284
27417
|
}
|