@staff0rd/assist 0.342.1 → 0.343.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 +1 -0
- package/dist/commands/sessions/web/bundle.js +81 -81
- package/dist/index.js +853 -661
- 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.343.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1812,8 +1812,8 @@ var MACHINE_DIRECTIVES = [
|
|
|
1812
1812
|
"@vitest-environment",
|
|
1813
1813
|
MAINTAINABILITY_OVERRIDE_MARKER
|
|
1814
1814
|
];
|
|
1815
|
-
function isCommentExempt(
|
|
1816
|
-
const lower =
|
|
1815
|
+
function isCommentExempt(text7) {
|
|
1816
|
+
const lower = text7.toLowerCase();
|
|
1817
1817
|
return MACHINE_DIRECTIVES.some((d) => lower.includes(d));
|
|
1818
1818
|
}
|
|
1819
1819
|
|
|
@@ -1854,8 +1854,8 @@ function parseDiffAddedLines(diff2) {
|
|
|
1854
1854
|
|
|
1855
1855
|
// src/commands/verify/blockComments/findComments.ts
|
|
1856
1856
|
var SOURCE_EXTENSIONS = [".ts", ".tsx", ".cts", ".mts", ".js", ".jsx"];
|
|
1857
|
-
function toSingleLine(
|
|
1858
|
-
return
|
|
1857
|
+
function toSingleLine(text7) {
|
|
1858
|
+
return text7.replace(/\s+/g, " ").trim();
|
|
1859
1859
|
}
|
|
1860
1860
|
function shouldScan(file, ignoreGlobs) {
|
|
1861
1861
|
if (!SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext))) return false;
|
|
@@ -1876,11 +1876,11 @@ function findComments(options2) {
|
|
|
1876
1876
|
for (const [file, lines] of addedLines) {
|
|
1877
1877
|
if (!shouldScan(file, options2.ignoreGlobs)) continue;
|
|
1878
1878
|
const sourceFile = project.addSourceFileAtPath(file);
|
|
1879
|
-
for (const { pos, text:
|
|
1879
|
+
for (const { pos, text: text7 } of collectComments(sourceFile)) {
|
|
1880
1880
|
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
1881
1881
|
if (!lines.has(line)) continue;
|
|
1882
|
-
if (isCommentExempt(
|
|
1883
|
-
findings.push({ file, line, text: toSingleLine(
|
|
1882
|
+
if (isCommentExempt(text7)) continue;
|
|
1883
|
+
findings.push({ file, line, text: toSingleLine(text7) });
|
|
1884
1884
|
}
|
|
1885
1885
|
}
|
|
1886
1886
|
findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
@@ -1896,8 +1896,8 @@ function blockComments() {
|
|
|
1896
1896
|
process.exit(0);
|
|
1897
1897
|
}
|
|
1898
1898
|
console.log("Comments on changed lines:\n");
|
|
1899
|
-
for (const { file, line, text:
|
|
1900
|
-
console.log(`${file}:${line} \u2192 ${
|
|
1899
|
+
for (const { file, line, text: text7 } of findings) {
|
|
1900
|
+
console.log(`${file}:${line} \u2192 ${text7}`);
|
|
1901
1901
|
}
|
|
1902
1902
|
console.log(`
|
|
1903
1903
|
Total: ${findings.length} comment(s)`);
|
|
@@ -2855,13 +2855,11 @@ import { Pool } from "pg";
|
|
|
2855
2855
|
|
|
2856
2856
|
// src/shared/db/schema.ts
|
|
2857
2857
|
import {
|
|
2858
|
-
boolean as boolean2,
|
|
2859
2858
|
foreignKey,
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
text as text4
|
|
2859
|
+
integer as integer6,
|
|
2860
|
+
pgTable as pgTable6,
|
|
2861
|
+
primaryKey as primaryKey3,
|
|
2862
|
+
text as text5
|
|
2865
2863
|
} from "drizzle-orm/pg-core";
|
|
2866
2864
|
|
|
2867
2865
|
// src/shared/db/backups.ts
|
|
@@ -2889,98 +2887,117 @@ var handovers = pgTable2(
|
|
|
2889
2887
|
(t) => [index("handovers_origin_idx").on(t.origin)]
|
|
2890
2888
|
);
|
|
2891
2889
|
|
|
2890
|
+
// src/shared/db/items.ts
|
|
2891
|
+
import { boolean, index as index2, integer as integer3, pgTable as pgTable3, text as text3 } from "drizzle-orm/pg-core";
|
|
2892
|
+
var items = pgTable3(
|
|
2893
|
+
"items",
|
|
2894
|
+
{
|
|
2895
|
+
id: integer3().generatedByDefaultAsIdentity().primaryKey(),
|
|
2896
|
+
origin: text3().notNull(),
|
|
2897
|
+
type: text3().notNull().default("story"),
|
|
2898
|
+
name: text3().notNull(),
|
|
2899
|
+
description: text3(),
|
|
2900
|
+
acceptanceCriteria: text3("acceptance_criteria").notNull().default("[]"),
|
|
2901
|
+
status: text3().notNull().default("todo"),
|
|
2902
|
+
currentPhase: integer3("current_phase"),
|
|
2903
|
+
starred: boolean().notNull().default(false),
|
|
2904
|
+
jiraKey: text3("jira_key")
|
|
2905
|
+
},
|
|
2906
|
+
(t) => [index2("items_origin_idx").on(t.origin)]
|
|
2907
|
+
);
|
|
2908
|
+
|
|
2909
|
+
// src/shared/db/phaseUsage.ts
|
|
2910
|
+
import { bigint as bigint2, integer as integer4, pgTable as pgTable4, primaryKey } from "drizzle-orm/pg-core";
|
|
2911
|
+
var phaseUsage = pgTable4(
|
|
2912
|
+
"phase_usage",
|
|
2913
|
+
{
|
|
2914
|
+
itemId: integer4("item_id").notNull(),
|
|
2915
|
+
phaseIdx: integer4("phase_idx").notNull(),
|
|
2916
|
+
tokensUp: bigint2("tokens_up", { mode: "number" }).notNull().default(0),
|
|
2917
|
+
tokensDown: bigint2("tokens_down", { mode: "number" }).notNull().default(0),
|
|
2918
|
+
activeMs: bigint2("active_ms", { mode: "number" }).notNull().default(0),
|
|
2919
|
+
lastTotalIn: bigint2("last_total_in", { mode: "number" }),
|
|
2920
|
+
lastTotalOut: bigint2("last_total_out", { mode: "number" })
|
|
2921
|
+
},
|
|
2922
|
+
(t) => [primaryKey({ columns: [t.itemId, t.phaseIdx] })]
|
|
2923
|
+
);
|
|
2924
|
+
|
|
2892
2925
|
// src/shared/db/usagePeaks.ts
|
|
2893
2926
|
import {
|
|
2894
|
-
bigint as
|
|
2895
|
-
boolean,
|
|
2927
|
+
bigint as bigint3,
|
|
2928
|
+
boolean as boolean2,
|
|
2896
2929
|
doublePrecision,
|
|
2897
|
-
integer as
|
|
2898
|
-
pgTable as
|
|
2899
|
-
primaryKey,
|
|
2900
|
-
text as
|
|
2930
|
+
integer as integer5,
|
|
2931
|
+
pgTable as pgTable5,
|
|
2932
|
+
primaryKey as primaryKey2,
|
|
2933
|
+
text as text4,
|
|
2901
2934
|
timestamp as timestamp3
|
|
2902
2935
|
} from "drizzle-orm/pg-core";
|
|
2903
|
-
var usagePeaks =
|
|
2936
|
+
var usagePeaks = pgTable5(
|
|
2904
2937
|
"usage_peaks",
|
|
2905
2938
|
{
|
|
2906
|
-
window:
|
|
2907
|
-
resetsAt:
|
|
2908
|
-
segment:
|
|
2939
|
+
window: text4().$type().notNull(),
|
|
2940
|
+
resetsAt: bigint3("resets_at", { mode: "number" }).notNull(),
|
|
2941
|
+
segment: integer5().notNull().default(0),
|
|
2909
2942
|
usedPercentage: doublePrecision("used_percentage").notNull(),
|
|
2910
|
-
resetDetected:
|
|
2943
|
+
resetDetected: boolean2("reset_detected").notNull().default(false),
|
|
2911
2944
|
createdAt: timestamp3("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
2912
2945
|
},
|
|
2913
|
-
(t) => [
|
|
2946
|
+
(t) => [primaryKey2({ columns: [t.window, t.resetsAt, t.segment] })]
|
|
2914
2947
|
);
|
|
2915
2948
|
|
|
2916
2949
|
// src/shared/db/schema.ts
|
|
2917
|
-
var
|
|
2918
|
-
|
|
2919
|
-
{
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
acceptanceCriteria: text4("acceptance_criteria").notNull().default("[]"),
|
|
2926
|
-
status: text4().notNull().default("todo"),
|
|
2927
|
-
currentPhase: integer4("current_phase"),
|
|
2928
|
-
starred: boolean2().notNull().default(false),
|
|
2929
|
-
jiraKey: text4("jira_key")
|
|
2930
|
-
},
|
|
2931
|
-
(t) => [index2("items_origin_idx").on(t.origin)]
|
|
2932
|
-
);
|
|
2933
|
-
var comments = pgTable4("comments", {
|
|
2934
|
-
id: integer4().generatedByDefaultAsIdentity().primaryKey(),
|
|
2935
|
-
itemId: integer4("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2936
|
-
idx: integer4().notNull(),
|
|
2937
|
-
text: text4().notNull(),
|
|
2938
|
-
phase: integer4(),
|
|
2939
|
-
timestamp: text4().notNull(),
|
|
2940
|
-
type: text4().notNull().default("comment")
|
|
2950
|
+
var comments = pgTable6("comments", {
|
|
2951
|
+
id: integer6().generatedByDefaultAsIdentity().primaryKey(),
|
|
2952
|
+
itemId: integer6("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2953
|
+
idx: integer6().notNull(),
|
|
2954
|
+
text: text5().notNull(),
|
|
2955
|
+
phase: integer6(),
|
|
2956
|
+
timestamp: text5().notNull(),
|
|
2957
|
+
type: text5().notNull().default("comment")
|
|
2941
2958
|
});
|
|
2942
|
-
var links =
|
|
2959
|
+
var links = pgTable6(
|
|
2943
2960
|
"links",
|
|
2944
2961
|
{
|
|
2945
|
-
itemId:
|
|
2946
|
-
type:
|
|
2947
|
-
targetId:
|
|
2962
|
+
itemId: integer6("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2963
|
+
type: text5().notNull(),
|
|
2964
|
+
targetId: integer6("target_id").notNull()
|
|
2948
2965
|
},
|
|
2949
|
-
(t) => [
|
|
2966
|
+
(t) => [primaryKey3({ columns: [t.itemId, t.type, t.targetId] })]
|
|
2950
2967
|
);
|
|
2951
|
-
var planPhases =
|
|
2968
|
+
var planPhases = pgTable6(
|
|
2952
2969
|
"plan_phases",
|
|
2953
2970
|
{
|
|
2954
|
-
itemId:
|
|
2955
|
-
idx:
|
|
2956
|
-
name:
|
|
2957
|
-
manualChecks:
|
|
2971
|
+
itemId: integer6("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2972
|
+
idx: integer6().notNull(),
|
|
2973
|
+
name: text5().notNull(),
|
|
2974
|
+
manualChecks: text5("manual_checks")
|
|
2958
2975
|
},
|
|
2959
|
-
(t) => [
|
|
2976
|
+
(t) => [primaryKey3({ columns: [t.itemId, t.idx] })]
|
|
2960
2977
|
);
|
|
2961
|
-
var planTasks =
|
|
2978
|
+
var planTasks = pgTable6(
|
|
2962
2979
|
"plan_tasks",
|
|
2963
2980
|
{
|
|
2964
|
-
itemId:
|
|
2965
|
-
phaseIdx:
|
|
2966
|
-
idx:
|
|
2967
|
-
task:
|
|
2981
|
+
itemId: integer6("item_id").notNull(),
|
|
2982
|
+
phaseIdx: integer6("phase_idx").notNull(),
|
|
2983
|
+
idx: integer6().notNull(),
|
|
2984
|
+
task: text5().notNull()
|
|
2968
2985
|
},
|
|
2969
2986
|
(t) => [
|
|
2970
|
-
|
|
2987
|
+
primaryKey3({ columns: [t.itemId, t.phaseIdx, t.idx] }),
|
|
2971
2988
|
foreignKey({
|
|
2972
2989
|
columns: [t.itemId, t.phaseIdx],
|
|
2973
2990
|
foreignColumns: [planPhases.itemId, planPhases.idx]
|
|
2974
2991
|
}).onDelete("cascade")
|
|
2975
2992
|
]
|
|
2976
2993
|
);
|
|
2977
|
-
var metadata =
|
|
2978
|
-
key:
|
|
2979
|
-
value:
|
|
2994
|
+
var metadata = pgTable6("metadata", {
|
|
2995
|
+
key: text5().primaryKey(),
|
|
2996
|
+
value: text5().notNull()
|
|
2980
2997
|
});
|
|
2981
|
-
var feeds =
|
|
2982
|
-
id:
|
|
2983
|
-
url:
|
|
2998
|
+
var feeds = pgTable6("feeds", {
|
|
2999
|
+
id: integer6().generatedByDefaultAsIdentity().primaryKey(),
|
|
3000
|
+
url: text5().notNull().unique()
|
|
2984
3001
|
});
|
|
2985
3002
|
var schema = {
|
|
2986
3003
|
items,
|
|
@@ -2992,7 +3009,8 @@ var schema = {
|
|
|
2992
3009
|
feeds,
|
|
2993
3010
|
handovers,
|
|
2994
3011
|
usagePeaks,
|
|
2995
|
-
backups
|
|
3012
|
+
backups,
|
|
3013
|
+
phaseUsage
|
|
2996
3014
|
};
|
|
2997
3015
|
|
|
2998
3016
|
// src/commands/backlog/addFeed.ts
|
|
@@ -3252,6 +3270,17 @@ var SCHEMA = `
|
|
|
3252
3270
|
|
|
3253
3271
|
-- Backfill for databases created before backup duration was tracked.
|
|
3254
3272
|
ALTER TABLE backups ADD COLUMN IF NOT EXISTS duration_ms INTEGER;
|
|
3273
|
+
|
|
3274
|
+
CREATE TABLE IF NOT EXISTS phase_usage (
|
|
3275
|
+
item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
3276
|
+
phase_idx INTEGER NOT NULL,
|
|
3277
|
+
tokens_up BIGINT NOT NULL DEFAULT 0,
|
|
3278
|
+
tokens_down BIGINT NOT NULL DEFAULT 0,
|
|
3279
|
+
active_ms BIGINT NOT NULL DEFAULT 0,
|
|
3280
|
+
last_total_in BIGINT,
|
|
3281
|
+
last_total_out BIGINT,
|
|
3282
|
+
PRIMARY KEY (item_id, phase_idx)
|
|
3283
|
+
);
|
|
3255
3284
|
`;
|
|
3256
3285
|
async function ensureSchema(exec3) {
|
|
3257
3286
|
await exec3(SCHEMA);
|
|
@@ -3305,7 +3334,7 @@ function createPool() {
|
|
|
3305
3334
|
return pool;
|
|
3306
3335
|
}
|
|
3307
3336
|
async function initSchema(pool) {
|
|
3308
|
-
await ensureSchema((
|
|
3337
|
+
await ensureSchema((sql8) => pool.query(sql8));
|
|
3309
3338
|
const orm = makeOrmFromPool(pool);
|
|
3310
3339
|
await seedNewsFeeds(orm);
|
|
3311
3340
|
await runUsagePeakCleanup(orm);
|
|
@@ -3570,8 +3599,8 @@ async function buildDump(tables, copyOut) {
|
|
|
3570
3599
|
// src/commands/backlog/dump/copyTableOut.ts
|
|
3571
3600
|
import { to as copyTo } from "pg-copy-streams";
|
|
3572
3601
|
async function copyTableOut(client, table) {
|
|
3573
|
-
const
|
|
3574
|
-
const stream = client.query(copyTo(
|
|
3602
|
+
const sql8 = `COPY ${table.name} (${table.columns.join(", ")}) TO STDOUT`;
|
|
3603
|
+
const stream = client.query(copyTo(sql8));
|
|
3575
3604
|
const chunks = [];
|
|
3576
3605
|
for await (const chunk of stream) {
|
|
3577
3606
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -4121,8 +4150,21 @@ async function importItemsRemapped(orm, items2, origin) {
|
|
|
4121
4150
|
// src/commands/backlog/loadAllItems.ts
|
|
4122
4151
|
import { asc as asc3, eq as eq3 } from "drizzle-orm";
|
|
4123
4152
|
|
|
4124
|
-
// src/commands/backlog/
|
|
4153
|
+
// src/commands/backlog/relationQueries.ts
|
|
4125
4154
|
import { asc as asc2, inArray } from "drizzle-orm";
|
|
4155
|
+
var relationQueries = {
|
|
4156
|
+
comments: (orm, ids) => orm.select().from(comments).where(inArray(comments.itemId, ids)).orderBy(asc2(comments.itemId), asc2(comments.idx)),
|
|
4157
|
+
links: (orm, ids) => orm.select().from(links).where(inArray(links.itemId, ids)).orderBy(asc2(links.itemId)),
|
|
4158
|
+
phases: (orm, ids) => orm.select().from(planPhases).where(inArray(planPhases.itemId, ids)).orderBy(asc2(planPhases.itemId), asc2(planPhases.idx)),
|
|
4159
|
+
tasks: (orm, ids) => orm.select().from(planTasks).where(inArray(planTasks.itemId, ids)).orderBy(
|
|
4160
|
+
asc2(planTasks.itemId),
|
|
4161
|
+
asc2(planTasks.phaseIdx),
|
|
4162
|
+
asc2(planTasks.idx)
|
|
4163
|
+
),
|
|
4164
|
+
usage: (orm, ids) => orm.select().from(phaseUsage).where(inArray(phaseUsage.itemId, ids)).orderBy(asc2(phaseUsage.itemId), asc2(phaseUsage.phaseIdx))
|
|
4165
|
+
};
|
|
4166
|
+
|
|
4167
|
+
// src/commands/backlog/loadRelations.ts
|
|
4126
4168
|
function groupByItem(rows) {
|
|
4127
4169
|
const map = /* @__PURE__ */ new Map();
|
|
4128
4170
|
for (const row of rows) {
|
|
@@ -4132,43 +4174,28 @@ function groupByItem(rows) {
|
|
|
4132
4174
|
}
|
|
4133
4175
|
return map;
|
|
4134
4176
|
}
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
)
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
selectLinks(orm, ids),
|
|
4147
|
-
selectPhases(orm, ids),
|
|
4148
|
-
includeTasks ? selectTasks(orm, ids) : []
|
|
4177
|
+
async function loadRelations(orm, ids, {
|
|
4178
|
+
includeComments = true,
|
|
4179
|
+
includeTasks = true,
|
|
4180
|
+
includeUsage = false
|
|
4181
|
+
} = {}) {
|
|
4182
|
+
const [commentRows, linkRows, phaseRows, taskRows, usageRows] = await Promise.all([
|
|
4183
|
+
includeComments ? relationQueries.comments(orm, ids) : [],
|
|
4184
|
+
relationQueries.links(orm, ids),
|
|
4185
|
+
relationQueries.phases(orm, ids),
|
|
4186
|
+
includeTasks ? relationQueries.tasks(orm, ids) : [],
|
|
4187
|
+
includeUsage ? relationQueries.usage(orm, ids) : []
|
|
4149
4188
|
]);
|
|
4150
4189
|
return {
|
|
4151
4190
|
comments: groupByItem(commentRows),
|
|
4152
4191
|
links: groupByItem(linkRows),
|
|
4153
4192
|
phases: groupByItem(phaseRows),
|
|
4154
|
-
tasks: groupByItem(taskRows)
|
|
4193
|
+
tasks: groupByItem(taskRows),
|
|
4194
|
+
usage: groupByItem(usageRows)
|
|
4155
4195
|
};
|
|
4156
4196
|
}
|
|
4157
4197
|
|
|
4158
|
-
// src/commands/backlog/
|
|
4159
|
-
function rowToComment(c) {
|
|
4160
|
-
const comment3 = {
|
|
4161
|
-
id: c.id,
|
|
4162
|
-
text: c.text,
|
|
4163
|
-
timestamp: c.timestamp,
|
|
4164
|
-
type: c.type
|
|
4165
|
-
};
|
|
4166
|
-
if (c.phase != null) comment3.phase = c.phase;
|
|
4167
|
-
return comment3;
|
|
4168
|
-
}
|
|
4169
|
-
function rowToLink(l) {
|
|
4170
|
-
return { type: l.type, targetId: l.targetId };
|
|
4171
|
-
}
|
|
4198
|
+
// src/commands/backlog/buildPlan.ts
|
|
4172
4199
|
function groupTasksByPhase(taskRows) {
|
|
4173
4200
|
const byPhase = /* @__PURE__ */ new Map();
|
|
4174
4201
|
for (const t of taskRows) {
|
|
@@ -4190,6 +4217,21 @@ function buildPlan(phaseRows, taskRows) {
|
|
|
4190
4217
|
const byPhase = groupTasksByPhase(taskRows);
|
|
4191
4218
|
return phaseRows.map((p) => rowToPhase(p, byPhase));
|
|
4192
4219
|
}
|
|
4220
|
+
|
|
4221
|
+
// src/commands/backlog/rowToItem.ts
|
|
4222
|
+
function rowToComment(c) {
|
|
4223
|
+
const comment3 = {
|
|
4224
|
+
id: c.id,
|
|
4225
|
+
text: c.text,
|
|
4226
|
+
timestamp: c.timestamp,
|
|
4227
|
+
type: c.type
|
|
4228
|
+
};
|
|
4229
|
+
if (c.phase != null) comment3.phase = c.phase;
|
|
4230
|
+
return comment3;
|
|
4231
|
+
}
|
|
4232
|
+
function rowToLink(l) {
|
|
4233
|
+
return { type: l.type, targetId: l.targetId };
|
|
4234
|
+
}
|
|
4193
4235
|
function assignOptionalColumns(item, row) {
|
|
4194
4236
|
if (row.description != null) item.description = row.description;
|
|
4195
4237
|
if (row.currentPhase != null) item.currentPhase = row.currentPhase;
|
|
@@ -4220,11 +4262,24 @@ function attachPlan(item, rel, id2) {
|
|
|
4220
4262
|
const phases = rel.phases.get(id2) ?? [];
|
|
4221
4263
|
if (phases.length > 0) item.plan = buildPlan(phases, rel.tasks.get(id2) ?? []);
|
|
4222
4264
|
}
|
|
4265
|
+
function rowToUsage(u) {
|
|
4266
|
+
return {
|
|
4267
|
+
phaseIdx: u.phaseIdx,
|
|
4268
|
+
tokensUp: u.tokensUp,
|
|
4269
|
+
tokensDown: u.tokensDown,
|
|
4270
|
+
activeMs: u.activeMs
|
|
4271
|
+
};
|
|
4272
|
+
}
|
|
4273
|
+
function attachUsage(item, rel, id2) {
|
|
4274
|
+
const usage = (rel.usage.get(id2) ?? []).map(rowToUsage);
|
|
4275
|
+
if (usage.length > 0) item.phaseUsage = usage;
|
|
4276
|
+
}
|
|
4223
4277
|
function rowToItem(row, rel) {
|
|
4224
4278
|
const item = baseItem(row);
|
|
4225
4279
|
attachComments(item, rel, row.id);
|
|
4226
4280
|
attachLinks(item, rel, row.id);
|
|
4227
4281
|
attachPlan(item, rel, row.id);
|
|
4282
|
+
attachUsage(item, rel, row.id);
|
|
4228
4283
|
return item;
|
|
4229
4284
|
}
|
|
4230
4285
|
|
|
@@ -4255,6 +4310,12 @@ var planPhaseSchema = z3.strictObject({
|
|
|
4255
4310
|
tasks: z3.array(planTaskSchema),
|
|
4256
4311
|
manualChecks: z3.array(z3.string()).optional()
|
|
4257
4312
|
});
|
|
4313
|
+
var phaseUsageSchema = z3.strictObject({
|
|
4314
|
+
phaseIdx: z3.number(),
|
|
4315
|
+
tokensUp: z3.number(),
|
|
4316
|
+
tokensDown: z3.number(),
|
|
4317
|
+
activeMs: z3.number()
|
|
4318
|
+
});
|
|
4258
4319
|
var backlogCommentTypeSchema = z3.enum(["comment", "summary"]);
|
|
4259
4320
|
var backlogCommentSchema = z3.strictObject({
|
|
4260
4321
|
id: z3.number().optional(),
|
|
@@ -4280,6 +4341,7 @@ var backlogItemSchema = z3.strictObject({
|
|
|
4280
4341
|
status: backlogStatusSchema,
|
|
4281
4342
|
comments: z3.array(backlogCommentSchema).optional(),
|
|
4282
4343
|
links: z3.array(backlogLinkSchema).optional(),
|
|
4344
|
+
phaseUsage: z3.array(phaseUsageSchema).optional(),
|
|
4283
4345
|
origin: z3.string().optional(),
|
|
4284
4346
|
jiraKey: z3.string().optional()
|
|
4285
4347
|
});
|
|
@@ -4424,7 +4486,7 @@ import { eq as eq5 } from "drizzle-orm";
|
|
|
4424
4486
|
async function loadItem(orm, id2) {
|
|
4425
4487
|
const [row] = await orm.select().from(items).where(eq5(items.id, id2));
|
|
4426
4488
|
if (!row) return void 0;
|
|
4427
|
-
const rel = await loadRelations(orm, [id2]);
|
|
4489
|
+
const rel = await loadRelations(orm, [id2], { includeUsage: true });
|
|
4428
4490
|
return rowToItem(row, rel);
|
|
4429
4491
|
}
|
|
4430
4492
|
|
|
@@ -5167,11 +5229,11 @@ import chalk44 from "chalk";
|
|
|
5167
5229
|
|
|
5168
5230
|
// src/commands/backlog/appendComment.ts
|
|
5169
5231
|
import { sql as sql3 } from "drizzle-orm";
|
|
5170
|
-
async function appendComment(orm, itemId,
|
|
5232
|
+
async function appendComment(orm, itemId, text7, opts = {}) {
|
|
5171
5233
|
await orm.insert(comments).values({
|
|
5172
5234
|
itemId,
|
|
5173
5235
|
idx: sql3`(SELECT COALESCE(MAX(${comments.idx}) + 1, 0) FROM ${comments} WHERE ${comments.itemId} = ${itemId})`,
|
|
5174
|
-
text:
|
|
5236
|
+
text: text7,
|
|
5175
5237
|
phase: opts.phase ?? null,
|
|
5176
5238
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5177
5239
|
type: opts.type ?? "comment"
|
|
@@ -5945,6 +6007,8 @@ function getHtml() {
|
|
|
5945
6007
|
::-webkit-scrollbar-thumb { background: #555; border-radius: 3px; }
|
|
5946
6008
|
::-webkit-scrollbar-thumb:hover { background: #777; }
|
|
5947
6009
|
.markdown p { margin-bottom: 0.5em; }
|
|
6010
|
+
.markdown ul, .markdown ol { margin: 0 0 0.5em; padding-left: 1.5em; }
|
|
6011
|
+
.markdown li { margin-bottom: 0.25em; }
|
|
5948
6012
|
.markdown pre { background: rgba(0,0,0,0.1); padding: 12px; border-radius: 6px; overflow-x: auto; }
|
|
5949
6013
|
.markdown code { background: rgba(0,0,0,0.1); padding: 2px 4px; border-radius: 3px; font-size: 0.9em; }
|
|
5950
6014
|
.markdown pre code { background: none; padding: 0; }
|
|
@@ -6198,9 +6262,9 @@ function excerpt(xml, ...tags) {
|
|
|
6198
6262
|
for (const tag of tags) {
|
|
6199
6263
|
const raw = extractText(xml, tag);
|
|
6200
6264
|
if (!raw) continue;
|
|
6201
|
-
const
|
|
6202
|
-
if (
|
|
6203
|
-
return `${
|
|
6265
|
+
const text7 = stripHtml(raw);
|
|
6266
|
+
if (text7.length <= MAX_EXCERPT) return text7;
|
|
6267
|
+
return `${text7.slice(0, MAX_EXCERPT)}\u2026`;
|
|
6204
6268
|
}
|
|
6205
6269
|
return "";
|
|
6206
6270
|
}
|
|
@@ -7003,10 +7067,10 @@ function registerAssociateJiraCommand(cmd) {
|
|
|
7003
7067
|
|
|
7004
7068
|
// src/commands/backlog/comment/index.ts
|
|
7005
7069
|
import chalk58 from "chalk";
|
|
7006
|
-
async function comment(id2,
|
|
7070
|
+
async function comment(id2, text7) {
|
|
7007
7071
|
const found = await findOneItem(id2);
|
|
7008
7072
|
if (!found) process.exit(1);
|
|
7009
|
-
await appendComment(found.orm, found.item.id,
|
|
7073
|
+
await appendComment(found.orm, found.item.id, text7);
|
|
7010
7074
|
console.log(chalk58.green(`Comment added to item #${id2}.`));
|
|
7011
7075
|
}
|
|
7012
7076
|
|
|
@@ -7100,9 +7164,9 @@ function readLine(dump, start3) {
|
|
|
7100
7164
|
return { text: dump.subarray(start3, eol).toString("utf8"), next: eol + 1 };
|
|
7101
7165
|
}
|
|
7102
7166
|
function parseHeader(dump) {
|
|
7103
|
-
const { text:
|
|
7167
|
+
const { text: text7, next: next3 } = readLine(dump, 0);
|
|
7104
7168
|
try {
|
|
7105
|
-
return { header: JSON.parse(
|
|
7169
|
+
return { header: JSON.parse(text7), bodyStart: next3 };
|
|
7106
7170
|
} catch {
|
|
7107
7171
|
return invalid("header is not valid JSON.");
|
|
7108
7172
|
}
|
|
@@ -7111,9 +7175,9 @@ function parseSections(dump, bodyStart) {
|
|
|
7111
7175
|
const sections = /* @__PURE__ */ new Map();
|
|
7112
7176
|
let cursor = bodyStart;
|
|
7113
7177
|
while (cursor < dump.length) {
|
|
7114
|
-
const { text:
|
|
7115
|
-
const match =
|
|
7116
|
-
if (!match) invalid(`malformed table marker "${
|
|
7178
|
+
const { text: text7, next: next3 } = readLine(dump, cursor);
|
|
7179
|
+
const match = text7.match(/^@table (\S+) (\d+)$/);
|
|
7180
|
+
if (!match) invalid(`malformed table marker "${text7}".`);
|
|
7117
7181
|
const [, name, bytes] = match;
|
|
7118
7182
|
const end = next3 + Number(bytes);
|
|
7119
7183
|
if (end > dump.length) invalid(`section "${name}" overruns the dump.`);
|
|
@@ -7189,8 +7253,8 @@ async function readStdinBuffer() {
|
|
|
7189
7253
|
import { finished } from "stream/promises";
|
|
7190
7254
|
import { from as copyFrom } from "pg-copy-streams";
|
|
7191
7255
|
async function copyTableIn(client, table, data) {
|
|
7192
|
-
const
|
|
7193
|
-
const stream = client.query(copyFrom(
|
|
7256
|
+
const sql8 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
|
|
7257
|
+
const stream = client.query(copyFrom(sql8));
|
|
7194
7258
|
stream.end(data);
|
|
7195
7259
|
await finished(stream);
|
|
7196
7260
|
}
|
|
@@ -7235,8 +7299,8 @@ async function replaceData(client, parsed) {
|
|
|
7235
7299
|
await copyTableIn(client, table, data);
|
|
7236
7300
|
}
|
|
7237
7301
|
for (const col of await introspectIdentityColumns(client)) {
|
|
7238
|
-
const { text:
|
|
7239
|
-
await client.query(
|
|
7302
|
+
const { text: text7, values } = resyncIdentitySql(col);
|
|
7303
|
+
await client.query(text7, values);
|
|
7240
7304
|
}
|
|
7241
7305
|
}
|
|
7242
7306
|
async function restore(client, parsed) {
|
|
@@ -8047,15 +8111,39 @@ async function done(id2, summary) {
|
|
|
8047
8111
|
console.log(chalk78.green(`Completed item #${id2}: ${item.name}`));
|
|
8048
8112
|
}
|
|
8049
8113
|
|
|
8114
|
+
// src/commands/backlog/set-status/index.ts
|
|
8115
|
+
import chalk79 from "chalk";
|
|
8116
|
+
var allowedStatuses = [
|
|
8117
|
+
"todo",
|
|
8118
|
+
"in-progress",
|
|
8119
|
+
"done",
|
|
8120
|
+
"wontdo"
|
|
8121
|
+
];
|
|
8122
|
+
async function setStatusCommand(id2, status2) {
|
|
8123
|
+
if (!allowedStatuses.includes(status2)) {
|
|
8124
|
+
console.log(
|
|
8125
|
+
chalk79.red(
|
|
8126
|
+
`Invalid status "${status2}". Must be one of: ${allowedStatuses.join(", ")}.`
|
|
8127
|
+
)
|
|
8128
|
+
);
|
|
8129
|
+
process.exitCode = 1;
|
|
8130
|
+
return;
|
|
8131
|
+
}
|
|
8132
|
+
const name = await setStatus(id2, status2);
|
|
8133
|
+
if (name) {
|
|
8134
|
+
console.log(chalk79.green(`Set item #${id2} to ${status2}: ${name}`));
|
|
8135
|
+
}
|
|
8136
|
+
}
|
|
8137
|
+
|
|
8050
8138
|
// src/commands/backlog/star/index.ts
|
|
8051
|
-
import
|
|
8139
|
+
import chalk81 from "chalk";
|
|
8052
8140
|
|
|
8053
8141
|
// src/commands/backlog/setStarred.ts
|
|
8054
|
-
import
|
|
8142
|
+
import chalk80 from "chalk";
|
|
8055
8143
|
async function setStarred(id2, starred) {
|
|
8056
8144
|
const { orm } = await getReady();
|
|
8057
8145
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
8058
|
-
if (name === void 0) console.log(
|
|
8146
|
+
if (name === void 0) console.log(chalk80.red(`Item #${id2} not found.`));
|
|
8059
8147
|
return name;
|
|
8060
8148
|
}
|
|
8061
8149
|
|
|
@@ -8063,45 +8151,45 @@ async function setStarred(id2, starred) {
|
|
|
8063
8151
|
async function star(id2) {
|
|
8064
8152
|
const name = await setStarred(id2, true);
|
|
8065
8153
|
if (name) {
|
|
8066
|
-
console.log(
|
|
8154
|
+
console.log(chalk81.green(`Starred item #${id2}: ${name}`));
|
|
8067
8155
|
}
|
|
8068
8156
|
}
|
|
8069
8157
|
|
|
8070
8158
|
// src/commands/backlog/start/index.ts
|
|
8071
|
-
import
|
|
8159
|
+
import chalk82 from "chalk";
|
|
8072
8160
|
async function start(id2) {
|
|
8073
8161
|
const name = await setStatus(id2, "in-progress");
|
|
8074
8162
|
if (name) {
|
|
8075
|
-
console.log(
|
|
8163
|
+
console.log(chalk82.green(`Started item #${id2}: ${name}`));
|
|
8076
8164
|
}
|
|
8077
8165
|
}
|
|
8078
8166
|
|
|
8079
8167
|
// src/commands/backlog/stop/index.ts
|
|
8080
|
-
import
|
|
8168
|
+
import chalk83 from "chalk";
|
|
8081
8169
|
import { and as and7, eq as eq25 } from "drizzle-orm";
|
|
8082
8170
|
async function stop() {
|
|
8083
8171
|
const { orm } = await getReady();
|
|
8084
8172
|
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and7(eq25(items.status, "in-progress"), eq25(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
8085
8173
|
if (stopped.length === 0) {
|
|
8086
|
-
console.log(
|
|
8174
|
+
console.log(chalk83.yellow("No in-progress items to stop."));
|
|
8087
8175
|
return;
|
|
8088
8176
|
}
|
|
8089
8177
|
for (const item of stopped) {
|
|
8090
|
-
console.log(
|
|
8178
|
+
console.log(chalk83.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
8091
8179
|
}
|
|
8092
8180
|
}
|
|
8093
8181
|
|
|
8094
8182
|
// src/commands/backlog/unstar/index.ts
|
|
8095
|
-
import
|
|
8183
|
+
import chalk84 from "chalk";
|
|
8096
8184
|
async function unstar(id2) {
|
|
8097
8185
|
const name = await setStarred(id2, false);
|
|
8098
8186
|
if (name) {
|
|
8099
|
-
console.log(
|
|
8187
|
+
console.log(chalk84.green(`Unstarred item #${id2}: ${name}`));
|
|
8100
8188
|
}
|
|
8101
8189
|
}
|
|
8102
8190
|
|
|
8103
8191
|
// src/commands/backlog/wontdo/index.ts
|
|
8104
|
-
import
|
|
8192
|
+
import chalk85 from "chalk";
|
|
8105
8193
|
async function wontdo(id2, reason) {
|
|
8106
8194
|
const found = await findOneItem(id2);
|
|
8107
8195
|
if (!found) return;
|
|
@@ -8111,7 +8199,7 @@ async function wontdo(id2, reason) {
|
|
|
8111
8199
|
const phase = item.currentPhase ?? 1;
|
|
8112
8200
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
8113
8201
|
}
|
|
8114
|
-
console.log(
|
|
8202
|
+
console.log(chalk85.red(`Won't do item #${id2}: ${item.name}`));
|
|
8115
8203
|
}
|
|
8116
8204
|
|
|
8117
8205
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -8120,17 +8208,20 @@ function registerStatusCommands(cmd) {
|
|
|
8120
8208
|
cmd.command("stop").description("Revert all in-progress backlog items to todo").action(stop);
|
|
8121
8209
|
cmd.command("done <id> [summary]").description("Set a backlog item to done").action(done);
|
|
8122
8210
|
cmd.command("wontdo <id> [reason]").description("Set a backlog item to won't do").action(wontdo);
|
|
8211
|
+
cmd.command("set-status <id> <status>").description(
|
|
8212
|
+
"Set a backlog item to a specific status (todo, in-progress, done, wontdo)"
|
|
8213
|
+
).action(setStatusCommand);
|
|
8123
8214
|
cmd.command("star <id>").description("Star a backlog item to pin it in the web view").action(star);
|
|
8124
8215
|
cmd.command("unstar <id>").description("Remove the star from a backlog item").action(unstar);
|
|
8125
8216
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
8126
8217
|
}
|
|
8127
8218
|
|
|
8128
8219
|
// src/commands/backlog/removePhase.ts
|
|
8129
|
-
import
|
|
8220
|
+
import chalk87 from "chalk";
|
|
8130
8221
|
import { and as and10, eq as eq28 } from "drizzle-orm";
|
|
8131
8222
|
|
|
8132
8223
|
// src/commands/backlog/findPhase.ts
|
|
8133
|
-
import
|
|
8224
|
+
import chalk86 from "chalk";
|
|
8134
8225
|
import { and as and8, count as count5, eq as eq26 } from "drizzle-orm";
|
|
8135
8226
|
async function findPhase(id2, phase) {
|
|
8136
8227
|
const found = await findOneItem(id2);
|
|
@@ -8141,7 +8232,7 @@ async function findPhase(id2, phase) {
|
|
|
8141
8232
|
const [row] = await orm.select({ cnt: count5() }).from(planPhases).where(and8(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
|
|
8142
8233
|
if (!row || row.cnt === 0) {
|
|
8143
8234
|
console.log(
|
|
8144
|
-
|
|
8235
|
+
chalk86.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
8145
8236
|
);
|
|
8146
8237
|
process.exitCode = 1;
|
|
8147
8238
|
return void 0;
|
|
@@ -8188,12 +8279,12 @@ async function removePhase(id2, phase) {
|
|
|
8188
8279
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
8189
8280
|
});
|
|
8190
8281
|
console.log(
|
|
8191
|
-
|
|
8282
|
+
chalk87.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
8192
8283
|
);
|
|
8193
8284
|
}
|
|
8194
8285
|
|
|
8195
8286
|
// src/commands/backlog/update/index.ts
|
|
8196
|
-
import
|
|
8287
|
+
import chalk89 from "chalk";
|
|
8197
8288
|
import { eq as eq29 } from "drizzle-orm";
|
|
8198
8289
|
|
|
8199
8290
|
// src/commands/backlog/update/parseListIndex.ts
|
|
@@ -8269,16 +8360,16 @@ function applyAcMutations(current, options2) {
|
|
|
8269
8360
|
}
|
|
8270
8361
|
|
|
8271
8362
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
8272
|
-
import
|
|
8363
|
+
import chalk88 from "chalk";
|
|
8273
8364
|
function buildUpdateValues(options2) {
|
|
8274
8365
|
const { name, desc: desc6, type, ac } = options2;
|
|
8275
8366
|
if (!name && !desc6 && !type && !ac) {
|
|
8276
|
-
console.log(
|
|
8367
|
+
console.log(chalk88.red("Nothing to update. Provide at least one flag."));
|
|
8277
8368
|
process.exitCode = 1;
|
|
8278
8369
|
return void 0;
|
|
8279
8370
|
}
|
|
8280
8371
|
if (type && type !== "story" && type !== "bug") {
|
|
8281
|
-
console.log(
|
|
8372
|
+
console.log(chalk88.red('Invalid type. Must be "story" or "bug".'));
|
|
8282
8373
|
process.exitCode = 1;
|
|
8283
8374
|
return void 0;
|
|
8284
8375
|
}
|
|
@@ -8311,14 +8402,14 @@ async function update(id2, options2) {
|
|
|
8311
8402
|
if (hasAcMutations(options2)) {
|
|
8312
8403
|
if (options2.ac) {
|
|
8313
8404
|
console.log(
|
|
8314
|
-
|
|
8405
|
+
chalk89.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8315
8406
|
);
|
|
8316
8407
|
process.exitCode = 1;
|
|
8317
8408
|
return;
|
|
8318
8409
|
}
|
|
8319
8410
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8320
8411
|
if (!mutation.ok) {
|
|
8321
|
-
console.log(
|
|
8412
|
+
console.log(chalk89.red(mutation.error));
|
|
8322
8413
|
process.exitCode = 1;
|
|
8323
8414
|
return;
|
|
8324
8415
|
}
|
|
@@ -8329,11 +8420,11 @@ async function update(id2, options2) {
|
|
|
8329
8420
|
const { orm } = found;
|
|
8330
8421
|
const itemId = found.item.id;
|
|
8331
8422
|
await orm.update(items).set(built.set).where(eq29(items.id, itemId));
|
|
8332
|
-
console.log(
|
|
8423
|
+
console.log(chalk89.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
8333
8424
|
}
|
|
8334
8425
|
|
|
8335
8426
|
// src/commands/backlog/updatePhase.ts
|
|
8336
|
-
import
|
|
8427
|
+
import chalk90 from "chalk";
|
|
8337
8428
|
|
|
8338
8429
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8339
8430
|
import { and as and11, eq as eq30 } from "drizzle-orm";
|
|
@@ -8437,7 +8528,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8437
8528
|
const { item, orm, itemId, phaseIdx } = found;
|
|
8438
8529
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
8439
8530
|
if (!resolved.ok) {
|
|
8440
|
-
console.log(
|
|
8531
|
+
console.log(chalk90.red(resolved.error));
|
|
8441
8532
|
process.exitCode = 1;
|
|
8442
8533
|
return;
|
|
8443
8534
|
}
|
|
@@ -8449,7 +8540,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8449
8540
|
manualCheck && "manual checks"
|
|
8450
8541
|
].filter(Boolean).join(", ");
|
|
8451
8542
|
console.log(
|
|
8452
|
-
|
|
8543
|
+
chalk90.green(
|
|
8453
8544
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8454
8545
|
)
|
|
8455
8546
|
);
|
|
@@ -8664,8 +8755,8 @@ var RAW_BUILTIN_DENIES = BUILTIN_DENIES.map((rule) => ({
|
|
|
8664
8755
|
...rule,
|
|
8665
8756
|
regex: rawDenyRegex(rule.pattern)
|
|
8666
8757
|
}));
|
|
8667
|
-
function matchBuiltinDeny(
|
|
8668
|
-
return RAW_BUILTIN_DENIES.find((rule) => rule.regex.test(
|
|
8758
|
+
function matchBuiltinDeny(text7) {
|
|
8759
|
+
return RAW_BUILTIN_DENIES.find((rule) => rule.regex.test(text7));
|
|
8669
8760
|
}
|
|
8670
8761
|
function toDecision(rule) {
|
|
8671
8762
|
if (!rule) return void 0;
|
|
@@ -9182,11 +9273,11 @@ function assertCliExists(cli) {
|
|
|
9182
9273
|
}
|
|
9183
9274
|
|
|
9184
9275
|
// src/commands/permitCliReads/colorize.ts
|
|
9185
|
-
import
|
|
9276
|
+
import chalk91 from "chalk";
|
|
9186
9277
|
function colorize(plainOutput) {
|
|
9187
9278
|
return plainOutput.split("\n").map((line) => {
|
|
9188
|
-
if (line.startsWith(" R ")) return
|
|
9189
|
-
if (line.startsWith(" W ")) return
|
|
9279
|
+
if (line.startsWith(" R ")) return chalk91.green(line);
|
|
9280
|
+
if (line.startsWith(" W ")) return chalk91.red(line);
|
|
9190
9281
|
return line;
|
|
9191
9282
|
}).join("\n");
|
|
9192
9283
|
}
|
|
@@ -9405,8 +9496,8 @@ function formatHuman(cli, commands) {
|
|
|
9405
9496
|
`];
|
|
9406
9497
|
for (const cmd of sorted) {
|
|
9407
9498
|
const full = `${cli} ${cmd.path.join(" ")}`;
|
|
9408
|
-
const
|
|
9409
|
-
lines.push(`${prefix(classifyVerb(cmd.path))}${
|
|
9499
|
+
const text7 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
|
|
9500
|
+
lines.push(`${prefix(classifyVerb(cmd.path))}${text7}`);
|
|
9410
9501
|
}
|
|
9411
9502
|
return lines.join("\n");
|
|
9412
9503
|
}
|
|
@@ -9484,7 +9575,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
9484
9575
|
}
|
|
9485
9576
|
|
|
9486
9577
|
// src/commands/deny/denyAdd.ts
|
|
9487
|
-
import
|
|
9578
|
+
import chalk92 from "chalk";
|
|
9488
9579
|
|
|
9489
9580
|
// src/commands/deny/loadDenyConfig.ts
|
|
9490
9581
|
function loadDenyConfig(global) {
|
|
@@ -9504,16 +9595,16 @@ function loadDenyConfig(global) {
|
|
|
9504
9595
|
function denyAdd(pattern2, message, options2) {
|
|
9505
9596
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9506
9597
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
9507
|
-
console.log(
|
|
9598
|
+
console.log(chalk92.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
9508
9599
|
return;
|
|
9509
9600
|
}
|
|
9510
9601
|
deny.push({ pattern: pattern2, message });
|
|
9511
9602
|
saveDeny(deny);
|
|
9512
|
-
console.log(
|
|
9603
|
+
console.log(chalk92.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
9513
9604
|
}
|
|
9514
9605
|
|
|
9515
9606
|
// src/commands/deny/denyList.ts
|
|
9516
|
-
import
|
|
9607
|
+
import chalk93 from "chalk";
|
|
9517
9608
|
function denyList() {
|
|
9518
9609
|
const globalRaw = loadGlobalConfigRaw();
|
|
9519
9610
|
const projectRaw = loadProjectConfig();
|
|
@@ -9524,7 +9615,7 @@ function denyList() {
|
|
|
9524
9615
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
9525
9616
|
);
|
|
9526
9617
|
if (!merged || merged.length === 0) {
|
|
9527
|
-
console.log(
|
|
9618
|
+
console.log(chalk93.dim("No deny rules configured."));
|
|
9528
9619
|
return;
|
|
9529
9620
|
}
|
|
9530
9621
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -9532,23 +9623,23 @@ function denyList() {
|
|
|
9532
9623
|
for (const rule of merged) {
|
|
9533
9624
|
const inProject = projectPatterns.has(rule.pattern);
|
|
9534
9625
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
9535
|
-
const label2 = inProject && inGlobal ?
|
|
9536
|
-
console.log(`${
|
|
9626
|
+
const label2 = inProject && inGlobal ? chalk93.dim(" (project, overrides global)") : inGlobal ? chalk93.dim(" (global)") : "";
|
|
9627
|
+
console.log(`${chalk93.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
9537
9628
|
}
|
|
9538
9629
|
}
|
|
9539
9630
|
|
|
9540
9631
|
// src/commands/deny/denyRemove.ts
|
|
9541
|
-
import
|
|
9632
|
+
import chalk94 from "chalk";
|
|
9542
9633
|
function denyRemove(pattern2, options2) {
|
|
9543
9634
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9544
9635
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
9545
9636
|
if (index3 === -1) {
|
|
9546
|
-
console.log(
|
|
9637
|
+
console.log(chalk94.yellow(`No deny rule found for: ${pattern2}`));
|
|
9547
9638
|
return;
|
|
9548
9639
|
}
|
|
9549
9640
|
deny.splice(index3, 1);
|
|
9550
9641
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
9551
|
-
console.log(
|
|
9642
|
+
console.log(chalk94.green(`Removed deny rule: ${pattern2}`));
|
|
9552
9643
|
}
|
|
9553
9644
|
|
|
9554
9645
|
// src/commands/registerDeny.ts
|
|
@@ -9578,7 +9669,7 @@ function registerCliHook(program2) {
|
|
|
9578
9669
|
|
|
9579
9670
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9580
9671
|
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9581
|
-
import
|
|
9672
|
+
import chalk95 from "chalk";
|
|
9582
9673
|
|
|
9583
9674
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
9584
9675
|
import { homedir as homedir13 } from "os";
|
|
@@ -9628,12 +9719,12 @@ function codeCommentConfirm(pin) {
|
|
|
9628
9719
|
sweepRestrictedDir();
|
|
9629
9720
|
const state = readPinState(pin);
|
|
9630
9721
|
if (!state) {
|
|
9631
|
-
console.error(
|
|
9722
|
+
console.error(chalk95.red(`No pending comment for pin: ${pin}`));
|
|
9632
9723
|
process.exitCode = 1;
|
|
9633
9724
|
return;
|
|
9634
9725
|
}
|
|
9635
9726
|
if (!existsSync28(state.file)) {
|
|
9636
|
-
console.error(
|
|
9727
|
+
console.error(chalk95.red(`Target file no longer exists: ${state.file}`));
|
|
9637
9728
|
process.exitCode = 1;
|
|
9638
9729
|
return;
|
|
9639
9730
|
}
|
|
@@ -9642,7 +9733,7 @@ function codeCommentConfirm(pin) {
|
|
|
9642
9733
|
const index3 = state.line - 1;
|
|
9643
9734
|
if (index3 > lines.length) {
|
|
9644
9735
|
console.error(
|
|
9645
|
-
|
|
9736
|
+
chalk95.red(
|
|
9646
9737
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
9647
9738
|
)
|
|
9648
9739
|
);
|
|
@@ -9655,48 +9746,48 @@ function codeCommentConfirm(pin) {
|
|
|
9655
9746
|
writeFileSync22(state.file, lines.join("\n"));
|
|
9656
9747
|
unlinkSync8(getPinStatePath(pin));
|
|
9657
9748
|
console.log(
|
|
9658
|
-
|
|
9749
|
+
chalk95.green(`Inserted "// ${state.text}" at ${state.file}:${state.line}`)
|
|
9659
9750
|
);
|
|
9660
9751
|
}
|
|
9661
9752
|
|
|
9662
9753
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9663
|
-
import
|
|
9754
|
+
import chalk96 from "chalk";
|
|
9664
9755
|
|
|
9665
9756
|
// src/commands/codeComment/validateCommentText.ts
|
|
9666
9757
|
var MAX_COMMENT_LENGTH = 50;
|
|
9667
9758
|
function validateCommentText(raw) {
|
|
9668
|
-
const
|
|
9669
|
-
if (/[\r\n]/.test(
|
|
9759
|
+
const text7 = raw.replace(/^\/\/\s?/, "");
|
|
9760
|
+
if (/[\r\n]/.test(text7)) {
|
|
9670
9761
|
return {
|
|
9671
9762
|
ok: false,
|
|
9672
9763
|
reason: "Comment must be a single line \u2014 multi-line comments are not allowed."
|
|
9673
9764
|
};
|
|
9674
9765
|
}
|
|
9675
|
-
if (
|
|
9766
|
+
if (text7.includes("/*") || text7.includes("*/")) {
|
|
9676
9767
|
return {
|
|
9677
9768
|
ok: false,
|
|
9678
9769
|
reason: "Block comments (/* */) are not allowed \u2014 only single-line // comments."
|
|
9679
9770
|
};
|
|
9680
9771
|
}
|
|
9681
|
-
if (
|
|
9772
|
+
if (text7.length > MAX_COMMENT_LENGTH) {
|
|
9682
9773
|
return {
|
|
9683
9774
|
ok: false,
|
|
9684
|
-
reason: `Comment text is ${
|
|
9775
|
+
reason: `Comment text is ${text7.length} chars; the cap is ${MAX_COMMENT_LENGTH}. Make it shorter or, better, make the code self-documenting.`
|
|
9685
9776
|
};
|
|
9686
9777
|
}
|
|
9687
|
-
return { ok: true, text:
|
|
9778
|
+
return { ok: true, text: text7 };
|
|
9688
9779
|
}
|
|
9689
9780
|
|
|
9690
9781
|
// src/commands/codeComment/issuePin.ts
|
|
9691
9782
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync23 } from "fs";
|
|
9692
9783
|
import { randomInt } from "crypto";
|
|
9693
|
-
function issuePin(file, lineNumber,
|
|
9784
|
+
function issuePin(file, lineNumber, text7) {
|
|
9694
9785
|
const pin = generatePin();
|
|
9695
9786
|
mkdirSync12(getRestrictedDir(), { recursive: true });
|
|
9696
9787
|
sweepRestrictedDir();
|
|
9697
9788
|
writeFileSync23(
|
|
9698
9789
|
getPinStatePath(pin),
|
|
9699
|
-
JSON.stringify({ pin, file, line: lineNumber, text:
|
|
9790
|
+
JSON.stringify({ pin, file, line: lineNumber, text: text7 })
|
|
9700
9791
|
);
|
|
9701
9792
|
return showNotification({
|
|
9702
9793
|
title: "assist code-comment pin",
|
|
@@ -9708,29 +9799,29 @@ function generatePin() {
|
|
|
9708
9799
|
}
|
|
9709
9800
|
|
|
9710
9801
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9711
|
-
function codeCommentSet(file, line,
|
|
9802
|
+
function codeCommentSet(file, line, text7) {
|
|
9712
9803
|
const lineNumber = Number.parseInt(line, 10);
|
|
9713
9804
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
9714
|
-
console.error(
|
|
9805
|
+
console.error(chalk96.red(`Invalid line number: ${line}`));
|
|
9715
9806
|
process.exitCode = 1;
|
|
9716
9807
|
return;
|
|
9717
9808
|
}
|
|
9718
|
-
const validation = validateCommentText(
|
|
9809
|
+
const validation = validateCommentText(text7);
|
|
9719
9810
|
if (!validation.ok) {
|
|
9720
|
-
console.error(
|
|
9721
|
-
console.error(
|
|
9811
|
+
console.error(chalk96.red(`Refused: ${validation.reason}`));
|
|
9812
|
+
console.error(chalk96.red("No pin issued."));
|
|
9722
9813
|
process.exitCode = 1;
|
|
9723
9814
|
return;
|
|
9724
9815
|
}
|
|
9725
9816
|
console.error(
|
|
9726
|
-
|
|
9817
|
+
chalk96.yellow.bold(
|
|
9727
9818
|
"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."
|
|
9728
9819
|
)
|
|
9729
9820
|
);
|
|
9730
9821
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
9731
9822
|
if (!delivered) {
|
|
9732
9823
|
console.error(
|
|
9733
|
-
|
|
9824
|
+
chalk96.red(
|
|
9734
9825
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
9735
9826
|
)
|
|
9736
9827
|
);
|
|
@@ -9740,7 +9831,7 @@ function codeCommentSet(file, line, text6) {
|
|
|
9740
9831
|
console.log(
|
|
9741
9832
|
`A confirmation pin was sent to your desktop notifications.
|
|
9742
9833
|
To insert "// ${validation.text}" at ${file}:${lineNumber}, run:
|
|
9743
|
-
${
|
|
9834
|
+
${chalk96.cyan(" assist code-comment confirm <PIN>")}
|
|
9744
9835
|
using the pin from that notification.`
|
|
9745
9836
|
);
|
|
9746
9837
|
}
|
|
@@ -9760,15 +9851,15 @@ function registerCodeComment(parent) {
|
|
|
9760
9851
|
}
|
|
9761
9852
|
|
|
9762
9853
|
// src/commands/complexity/analyze.ts
|
|
9763
|
-
import
|
|
9854
|
+
import chalk105 from "chalk";
|
|
9764
9855
|
|
|
9765
9856
|
// src/commands/complexity/cyclomatic.ts
|
|
9766
|
-
import
|
|
9857
|
+
import chalk98 from "chalk";
|
|
9767
9858
|
|
|
9768
9859
|
// src/commands/complexity/shared/index.ts
|
|
9769
9860
|
import fs16 from "fs";
|
|
9770
9861
|
import path21 from "path";
|
|
9771
|
-
import
|
|
9862
|
+
import chalk97 from "chalk";
|
|
9772
9863
|
import ts5 from "typescript";
|
|
9773
9864
|
|
|
9774
9865
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -10019,7 +10110,7 @@ function createSourceFromFile(filePath) {
|
|
|
10019
10110
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
10020
10111
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
10021
10112
|
if (files.length === 0) {
|
|
10022
|
-
console.log(
|
|
10113
|
+
console.log(chalk97.yellow("No files found matching pattern"));
|
|
10023
10114
|
return void 0;
|
|
10024
10115
|
}
|
|
10025
10116
|
return callback(files);
|
|
@@ -10052,11 +10143,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10052
10143
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
10053
10144
|
for (const { file, name, complexity } of results) {
|
|
10054
10145
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
10055
|
-
const color = exceedsThreshold ?
|
|
10056
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
10146
|
+
const color = exceedsThreshold ? chalk98.red : chalk98.white;
|
|
10147
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk98.cyan(complexity)}`);
|
|
10057
10148
|
}
|
|
10058
10149
|
console.log(
|
|
10059
|
-
|
|
10150
|
+
chalk98.dim(
|
|
10060
10151
|
`
|
|
10061
10152
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10062
10153
|
)
|
|
@@ -10068,7 +10159,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10068
10159
|
}
|
|
10069
10160
|
|
|
10070
10161
|
// src/commands/complexity/halstead.ts
|
|
10071
|
-
import
|
|
10162
|
+
import chalk99 from "chalk";
|
|
10072
10163
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
10073
10164
|
withSourceFiles(pattern2, (files) => {
|
|
10074
10165
|
const results = [];
|
|
@@ -10083,13 +10174,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10083
10174
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
10084
10175
|
for (const { file, name, metrics } of results) {
|
|
10085
10176
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
10086
|
-
const color = exceedsThreshold ?
|
|
10177
|
+
const color = exceedsThreshold ? chalk99.red : chalk99.white;
|
|
10087
10178
|
console.log(
|
|
10088
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
10179
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk99.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk99.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk99.magenta(metrics.effort.toFixed(1))}`
|
|
10089
10180
|
);
|
|
10090
10181
|
}
|
|
10091
10182
|
console.log(
|
|
10092
|
-
|
|
10183
|
+
chalk99.dim(
|
|
10093
10184
|
`
|
|
10094
10185
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10095
10186
|
)
|
|
@@ -10101,27 +10192,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10101
10192
|
}
|
|
10102
10193
|
|
|
10103
10194
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
10104
|
-
import
|
|
10195
|
+
import chalk102 from "chalk";
|
|
10105
10196
|
|
|
10106
10197
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
10107
|
-
import
|
|
10198
|
+
import chalk100 from "chalk";
|
|
10108
10199
|
function formatResultLine(entry, failing) {
|
|
10109
10200
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
10110
|
-
const name = failing ?
|
|
10111
|
-
const suffix = override !== void 0 ?
|
|
10112
|
-
return `${name} \u2192 avg: ${
|
|
10201
|
+
const name = failing ? chalk100.red(file) : chalk100.white(file);
|
|
10202
|
+
const suffix = override !== void 0 ? chalk100.magenta(` (override: ${override})`) : "";
|
|
10203
|
+
return `${name} \u2192 avg: ${chalk100.cyan(avgMaintainability.toFixed(1))}, min: ${chalk100.yellow(minMaintainability.toFixed(1))}${suffix}`;
|
|
10113
10204
|
}
|
|
10114
10205
|
|
|
10115
10206
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
10116
|
-
import
|
|
10207
|
+
import chalk101 from "chalk";
|
|
10117
10208
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
10118
10209
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
10119
10210
|
console.error(
|
|
10120
|
-
|
|
10211
|
+
chalk101.red(
|
|
10121
10212
|
`
|
|
10122
10213
|
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.
|
|
10123
10214
|
|
|
10124
|
-
\u26A0\uFE0F ${
|
|
10215
|
+
\u26A0\uFE0F ${chalk101.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
|
|
10125
10216
|
|
|
10126
10217
|
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.`
|
|
10127
10218
|
)
|
|
@@ -10133,7 +10224,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
10133
10224
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
10134
10225
|
if (!gating) {
|
|
10135
10226
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
10136
|
-
console.log(
|
|
10227
|
+
console.log(chalk102.dim(`
|
|
10137
10228
|
Analyzed ${results.length} files`));
|
|
10138
10229
|
return;
|
|
10139
10230
|
}
|
|
@@ -10142,7 +10233,7 @@ Analyzed ${results.length} files`));
|
|
|
10142
10233
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
10143
10234
|
});
|
|
10144
10235
|
if (failing.length === 0) {
|
|
10145
|
-
console.log(
|
|
10236
|
+
console.log(chalk102.green("All files pass maintainability threshold"));
|
|
10146
10237
|
} else {
|
|
10147
10238
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
10148
10239
|
}
|
|
@@ -10151,7 +10242,7 @@ Analyzed ${results.length} files`));
|
|
|
10151
10242
|
);
|
|
10152
10243
|
for (const entry of passingOverrides)
|
|
10153
10244
|
console.log(formatResultLine(entry, false));
|
|
10154
|
-
console.log(
|
|
10245
|
+
console.log(chalk102.dim(`
|
|
10155
10246
|
Analyzed ${results.length} files`));
|
|
10156
10247
|
if (failing.length > 0) {
|
|
10157
10248
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -10160,10 +10251,10 @@ Analyzed ${results.length} files`));
|
|
|
10160
10251
|
}
|
|
10161
10252
|
|
|
10162
10253
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
10163
|
-
import
|
|
10254
|
+
import chalk103 from "chalk";
|
|
10164
10255
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
10165
10256
|
function printMaintainabilityFormula() {
|
|
10166
|
-
console.log(
|
|
10257
|
+
console.log(chalk103.dim(MI_FORMULA));
|
|
10167
10258
|
}
|
|
10168
10259
|
|
|
10169
10260
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -10239,7 +10330,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10239
10330
|
|
|
10240
10331
|
// src/commands/complexity/sloc.ts
|
|
10241
10332
|
import fs18 from "fs";
|
|
10242
|
-
import
|
|
10333
|
+
import chalk104 from "chalk";
|
|
10243
10334
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
10244
10335
|
withSourceFiles(pattern2, (files) => {
|
|
10245
10336
|
const results = [];
|
|
@@ -10255,12 +10346,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10255
10346
|
results.sort((a, b) => b.lines - a.lines);
|
|
10256
10347
|
for (const { file, lines } of results) {
|
|
10257
10348
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
10258
|
-
const color = exceedsThreshold ?
|
|
10259
|
-
console.log(`${color(file)} \u2192 ${
|
|
10349
|
+
const color = exceedsThreshold ? chalk104.red : chalk104.white;
|
|
10350
|
+
console.log(`${color(file)} \u2192 ${chalk104.cyan(lines)} lines`);
|
|
10260
10351
|
}
|
|
10261
10352
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
10262
10353
|
console.log(
|
|
10263
|
-
|
|
10354
|
+
chalk104.dim(`
|
|
10264
10355
|
Total: ${total} lines across ${files.length} files`)
|
|
10265
10356
|
);
|
|
10266
10357
|
if (hasViolation) {
|
|
@@ -10274,25 +10365,25 @@ async function analyze(pattern2) {
|
|
|
10274
10365
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
10275
10366
|
const files = findSourceFiles2(searchPattern);
|
|
10276
10367
|
if (files.length === 0) {
|
|
10277
|
-
console.log(
|
|
10368
|
+
console.log(chalk105.yellow("No files found matching pattern"));
|
|
10278
10369
|
return;
|
|
10279
10370
|
}
|
|
10280
10371
|
if (files.length === 1) {
|
|
10281
10372
|
const file = files[0];
|
|
10282
|
-
console.log(
|
|
10373
|
+
console.log(chalk105.bold.underline("SLOC"));
|
|
10283
10374
|
await sloc(file);
|
|
10284
10375
|
console.log();
|
|
10285
|
-
console.log(
|
|
10376
|
+
console.log(chalk105.bold.underline("Cyclomatic Complexity"));
|
|
10286
10377
|
await cyclomatic(file);
|
|
10287
10378
|
console.log();
|
|
10288
|
-
console.log(
|
|
10379
|
+
console.log(chalk105.bold.underline("Halstead Metrics"));
|
|
10289
10380
|
await halstead(file);
|
|
10290
10381
|
console.log();
|
|
10291
|
-
console.log(
|
|
10382
|
+
console.log(chalk105.bold.underline("Maintainability Index"));
|
|
10292
10383
|
await maintainability(file);
|
|
10293
10384
|
console.log();
|
|
10294
10385
|
console.log(
|
|
10295
|
-
|
|
10386
|
+
chalk105.dim(
|
|
10296
10387
|
"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."
|
|
10297
10388
|
)
|
|
10298
10389
|
);
|
|
@@ -10326,7 +10417,7 @@ function registerComplexity(program2) {
|
|
|
10326
10417
|
}
|
|
10327
10418
|
|
|
10328
10419
|
// src/commands/config/index.ts
|
|
10329
|
-
import
|
|
10420
|
+
import chalk106 from "chalk";
|
|
10330
10421
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
10331
10422
|
|
|
10332
10423
|
// src/commands/config/setNestedValue.ts
|
|
@@ -10389,7 +10480,7 @@ function formatIssuePath(issue, key) {
|
|
|
10389
10480
|
function printValidationErrors(issues, key) {
|
|
10390
10481
|
for (const issue of issues) {
|
|
10391
10482
|
console.error(
|
|
10392
|
-
|
|
10483
|
+
chalk106.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
10393
10484
|
);
|
|
10394
10485
|
}
|
|
10395
10486
|
}
|
|
@@ -10406,7 +10497,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
10406
10497
|
function assertNotGlobalOnly(key, global) {
|
|
10407
10498
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
10408
10499
|
console.error(
|
|
10409
|
-
|
|
10500
|
+
chalk106.red(
|
|
10410
10501
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
10411
10502
|
)
|
|
10412
10503
|
);
|
|
@@ -10429,7 +10520,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
10429
10520
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
10430
10521
|
const target = options2.global ? "global" : "project";
|
|
10431
10522
|
console.log(
|
|
10432
|
-
|
|
10523
|
+
chalk106.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
10433
10524
|
);
|
|
10434
10525
|
}
|
|
10435
10526
|
function configList() {
|
|
@@ -10438,7 +10529,7 @@ function configList() {
|
|
|
10438
10529
|
}
|
|
10439
10530
|
|
|
10440
10531
|
// src/commands/config/configGet.ts
|
|
10441
|
-
import
|
|
10532
|
+
import chalk107 from "chalk";
|
|
10442
10533
|
|
|
10443
10534
|
// src/commands/config/getNestedValue.ts
|
|
10444
10535
|
function isTraversable(value) {
|
|
@@ -10470,7 +10561,7 @@ function requireNestedValue(config, key) {
|
|
|
10470
10561
|
return value;
|
|
10471
10562
|
}
|
|
10472
10563
|
function exitKeyNotSet(key) {
|
|
10473
|
-
console.error(
|
|
10564
|
+
console.error(chalk107.red(`Key "${key}" is not set`));
|
|
10474
10565
|
process.exit(1);
|
|
10475
10566
|
}
|
|
10476
10567
|
|
|
@@ -10484,7 +10575,7 @@ function registerConfig(program2) {
|
|
|
10484
10575
|
|
|
10485
10576
|
// src/commands/deploy/redirect.ts
|
|
10486
10577
|
import { existsSync as existsSync29, readFileSync as readFileSync24, writeFileSync as writeFileSync24 } from "fs";
|
|
10487
|
-
import
|
|
10578
|
+
import chalk108 from "chalk";
|
|
10488
10579
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10489
10580
|
if (!window.location.pathname.endsWith('/')) {
|
|
10490
10581
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10493,23 +10584,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10493
10584
|
function redirect() {
|
|
10494
10585
|
const indexPath = "index.html";
|
|
10495
10586
|
if (!existsSync29(indexPath)) {
|
|
10496
|
-
console.log(
|
|
10587
|
+
console.log(chalk108.yellow("No index.html found"));
|
|
10497
10588
|
return;
|
|
10498
10589
|
}
|
|
10499
10590
|
const content = readFileSync24(indexPath, "utf8");
|
|
10500
10591
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10501
|
-
console.log(
|
|
10592
|
+
console.log(chalk108.dim("Trailing slash script already present"));
|
|
10502
10593
|
return;
|
|
10503
10594
|
}
|
|
10504
10595
|
const headCloseIndex = content.indexOf("</head>");
|
|
10505
10596
|
if (headCloseIndex === -1) {
|
|
10506
|
-
console.log(
|
|
10597
|
+
console.log(chalk108.red("Could not find </head> tag in index.html"));
|
|
10507
10598
|
return;
|
|
10508
10599
|
}
|
|
10509
10600
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10510
10601
|
${content.slice(headCloseIndex)}`;
|
|
10511
10602
|
writeFileSync24(indexPath, newContent);
|
|
10512
|
-
console.log(
|
|
10603
|
+
console.log(chalk108.green("Added trailing slash redirect to index.html"));
|
|
10513
10604
|
}
|
|
10514
10605
|
|
|
10515
10606
|
// src/commands/registerDeploy.ts
|
|
@@ -10536,7 +10627,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
10536
10627
|
|
|
10537
10628
|
// src/commands/devlog/shared.ts
|
|
10538
10629
|
import { execSync as execSync24 } from "child_process";
|
|
10539
|
-
import
|
|
10630
|
+
import chalk109 from "chalk";
|
|
10540
10631
|
|
|
10541
10632
|
// src/shared/getRepoName.ts
|
|
10542
10633
|
import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
|
|
@@ -10645,13 +10736,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10645
10736
|
}
|
|
10646
10737
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10647
10738
|
for (const commit2 of commits2) {
|
|
10648
|
-
console.log(` ${
|
|
10739
|
+
console.log(` ${chalk109.yellow(commit2.hash)} ${commit2.message}`);
|
|
10649
10740
|
if (verbose) {
|
|
10650
10741
|
const visibleFiles = commit2.files.filter(
|
|
10651
10742
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10652
10743
|
);
|
|
10653
10744
|
for (const file of visibleFiles) {
|
|
10654
|
-
console.log(` ${
|
|
10745
|
+
console.log(` ${chalk109.dim(file)}`);
|
|
10655
10746
|
}
|
|
10656
10747
|
}
|
|
10657
10748
|
}
|
|
@@ -10676,15 +10767,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10676
10767
|
}
|
|
10677
10768
|
|
|
10678
10769
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10679
|
-
import
|
|
10770
|
+
import chalk110 from "chalk";
|
|
10680
10771
|
function printDateHeader(date, isSkipped, entries) {
|
|
10681
10772
|
if (isSkipped) {
|
|
10682
|
-
console.log(`${
|
|
10773
|
+
console.log(`${chalk110.bold.blue(date)} ${chalk110.dim("skipped")}`);
|
|
10683
10774
|
} else if (entries && entries.length > 0) {
|
|
10684
|
-
const entryInfo = entries.map((e) => `${
|
|
10685
|
-
console.log(`${
|
|
10775
|
+
const entryInfo = entries.map((e) => `${chalk110.green(e.version)} ${e.title}`).join(" | ");
|
|
10776
|
+
console.log(`${chalk110.bold.blue(date)} ${entryInfo}`);
|
|
10686
10777
|
} else {
|
|
10687
|
-
console.log(`${
|
|
10778
|
+
console.log(`${chalk110.bold.blue(date)} ${chalk110.red("\u26A0 devlog missing")}`);
|
|
10688
10779
|
}
|
|
10689
10780
|
}
|
|
10690
10781
|
|
|
@@ -10788,24 +10879,24 @@ function bumpVersion(version2, type) {
|
|
|
10788
10879
|
|
|
10789
10880
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10790
10881
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10791
|
-
import
|
|
10882
|
+
import chalk112 from "chalk";
|
|
10792
10883
|
|
|
10793
10884
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10794
|
-
import
|
|
10885
|
+
import chalk111 from "chalk";
|
|
10795
10886
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10796
10887
|
if (conventional && firstHash) {
|
|
10797
10888
|
const version2 = getVersionAtCommit(firstHash);
|
|
10798
10889
|
if (version2) {
|
|
10799
|
-
console.log(`${
|
|
10890
|
+
console.log(`${chalk111.bold("version:")} ${stripToMinor(version2)}`);
|
|
10800
10891
|
} else {
|
|
10801
|
-
console.log(`${
|
|
10892
|
+
console.log(`${chalk111.bold("version:")} ${chalk111.red("unknown")}`);
|
|
10802
10893
|
}
|
|
10803
10894
|
} else if (patchVersion && minorVersion) {
|
|
10804
10895
|
console.log(
|
|
10805
|
-
`${
|
|
10896
|
+
`${chalk111.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10806
10897
|
);
|
|
10807
10898
|
} else {
|
|
10808
|
-
console.log(`${
|
|
10899
|
+
console.log(`${chalk111.bold("version:")} v0.1 (initial)`);
|
|
10809
10900
|
}
|
|
10810
10901
|
}
|
|
10811
10902
|
|
|
@@ -10853,16 +10944,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10853
10944
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10854
10945
|
}
|
|
10855
10946
|
function logName(repoName) {
|
|
10856
|
-
console.log(`${
|
|
10947
|
+
console.log(`${chalk112.bold("name:")} ${repoName}`);
|
|
10857
10948
|
}
|
|
10858
10949
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10859
10950
|
logName(ctx.repoName);
|
|
10860
10951
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10861
|
-
console.log(
|
|
10952
|
+
console.log(chalk112.bold.blue(targetDate));
|
|
10862
10953
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10863
10954
|
}
|
|
10864
10955
|
function logNoCommits(lastInfo) {
|
|
10865
|
-
console.log(
|
|
10956
|
+
console.log(chalk112.dim(noCommitsMessage(!!lastInfo)));
|
|
10866
10957
|
}
|
|
10867
10958
|
|
|
10868
10959
|
// src/commands/devlog/next/index.ts
|
|
@@ -10903,11 +10994,11 @@ function next2(options2) {
|
|
|
10903
10994
|
import { execSync as execSync26 } from "child_process";
|
|
10904
10995
|
|
|
10905
10996
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10906
|
-
import
|
|
10997
|
+
import chalk113 from "chalk";
|
|
10907
10998
|
function colorStatus(status2) {
|
|
10908
|
-
if (status2 === "missing") return
|
|
10909
|
-
if (status2 === "outdated") return
|
|
10910
|
-
return
|
|
10999
|
+
if (status2 === "missing") return chalk113.red(status2);
|
|
11000
|
+
if (status2 === "outdated") return chalk113.yellow(status2);
|
|
11001
|
+
return chalk113.green(status2);
|
|
10911
11002
|
}
|
|
10912
11003
|
function formatRow(row, nameWidth) {
|
|
10913
11004
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10921,8 +11012,8 @@ function printReposTable(rows) {
|
|
|
10921
11012
|
"Last Devlog".padEnd(11),
|
|
10922
11013
|
"Status"
|
|
10923
11014
|
].join(" ");
|
|
10924
|
-
console.log(
|
|
10925
|
-
console.log(
|
|
11015
|
+
console.log(chalk113.dim(header));
|
|
11016
|
+
console.log(chalk113.dim("-".repeat(header.length)));
|
|
10926
11017
|
for (const row of rows) {
|
|
10927
11018
|
console.log(formatRow(row, nameWidth));
|
|
10928
11019
|
}
|
|
@@ -10980,14 +11071,14 @@ function repos(options2) {
|
|
|
10980
11071
|
// src/commands/devlog/skip.ts
|
|
10981
11072
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
10982
11073
|
import { join as join32 } from "path";
|
|
10983
|
-
import
|
|
11074
|
+
import chalk114 from "chalk";
|
|
10984
11075
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10985
11076
|
function getBlogConfigPath() {
|
|
10986
11077
|
return join32(BLOG_REPO_ROOT, "assist.yml");
|
|
10987
11078
|
}
|
|
10988
11079
|
function skip(date) {
|
|
10989
11080
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10990
|
-
console.log(
|
|
11081
|
+
console.log(chalk114.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10991
11082
|
process.exit(1);
|
|
10992
11083
|
}
|
|
10993
11084
|
const repoName = getRepoName();
|
|
@@ -10998,7 +11089,7 @@ function skip(date) {
|
|
|
10998
11089
|
const skipDays = skip2[repoName] ?? [];
|
|
10999
11090
|
if (skipDays.includes(date)) {
|
|
11000
11091
|
console.log(
|
|
11001
|
-
|
|
11092
|
+
chalk114.yellow(`${date} is already in skip list for ${repoName}`)
|
|
11002
11093
|
);
|
|
11003
11094
|
return;
|
|
11004
11095
|
}
|
|
@@ -11008,20 +11099,20 @@ function skip(date) {
|
|
|
11008
11099
|
devlog.skip = skip2;
|
|
11009
11100
|
config.devlog = devlog;
|
|
11010
11101
|
writeFileSync25(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
11011
|
-
console.log(
|
|
11102
|
+
console.log(chalk114.green(`Added ${date} to skip list for ${repoName}`));
|
|
11012
11103
|
}
|
|
11013
11104
|
|
|
11014
11105
|
// src/commands/devlog/version.ts
|
|
11015
|
-
import
|
|
11106
|
+
import chalk115 from "chalk";
|
|
11016
11107
|
function version() {
|
|
11017
11108
|
const config = loadConfig();
|
|
11018
11109
|
const name = getRepoName();
|
|
11019
11110
|
const lastInfo = getLastVersionInfo(name, config);
|
|
11020
11111
|
const lastVersion = lastInfo?.version ?? null;
|
|
11021
11112
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
11022
|
-
console.log(`${
|
|
11023
|
-
console.log(`${
|
|
11024
|
-
console.log(`${
|
|
11113
|
+
console.log(`${chalk115.bold("name:")} ${name}`);
|
|
11114
|
+
console.log(`${chalk115.bold("last:")} ${lastVersion ?? chalk115.dim("none")}`);
|
|
11115
|
+
console.log(`${chalk115.bold("next:")} ${nextVersion ?? chalk115.dim("none")}`);
|
|
11025
11116
|
}
|
|
11026
11117
|
|
|
11027
11118
|
// src/commands/registerDevlog.ts
|
|
@@ -11045,7 +11136,7 @@ function registerDevlog(program2) {
|
|
|
11045
11136
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
11046
11137
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync4 } from "fs";
|
|
11047
11138
|
import { join as join33 } from "path";
|
|
11048
|
-
import
|
|
11139
|
+
import chalk116 from "chalk";
|
|
11049
11140
|
|
|
11050
11141
|
// src/shared/findRepoRoot.ts
|
|
11051
11142
|
import { existsSync as existsSync31 } from "fs";
|
|
@@ -11108,14 +11199,14 @@ function checkBuildLocks(startDir) {
|
|
|
11108
11199
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
11109
11200
|
if (locked) {
|
|
11110
11201
|
console.error(
|
|
11111
|
-
|
|
11202
|
+
chalk116.red("Build output locked (is VS debugging?): ") + locked
|
|
11112
11203
|
);
|
|
11113
11204
|
process.exit(1);
|
|
11114
11205
|
}
|
|
11115
11206
|
}
|
|
11116
11207
|
async function checkBuildLocksCommand() {
|
|
11117
11208
|
checkBuildLocks();
|
|
11118
|
-
console.log(
|
|
11209
|
+
console.log(chalk116.green("No build locks detected"));
|
|
11119
11210
|
}
|
|
11120
11211
|
|
|
11121
11212
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -11214,30 +11305,30 @@ function escapeRegex(s) {
|
|
|
11214
11305
|
}
|
|
11215
11306
|
|
|
11216
11307
|
// src/commands/dotnet/printTree.ts
|
|
11217
|
-
import
|
|
11308
|
+
import chalk117 from "chalk";
|
|
11218
11309
|
function printNodes(nodes, prefix2) {
|
|
11219
11310
|
for (let i = 0; i < nodes.length; i++) {
|
|
11220
11311
|
const isLast = i === nodes.length - 1;
|
|
11221
11312
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
11222
11313
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
11223
11314
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
11224
|
-
const label2 = isMissing ?
|
|
11315
|
+
const label2 = isMissing ? chalk117.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
11225
11316
|
console.log(`${prefix2}${connector}${label2}`);
|
|
11226
11317
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
11227
11318
|
}
|
|
11228
11319
|
}
|
|
11229
11320
|
function printTree(tree, totalCount, solutions) {
|
|
11230
|
-
console.log(
|
|
11231
|
-
console.log(
|
|
11321
|
+
console.log(chalk117.bold("\nProject Dependency Tree"));
|
|
11322
|
+
console.log(chalk117.cyan(tree.relativePath));
|
|
11232
11323
|
printNodes(tree.children, "");
|
|
11233
|
-
console.log(
|
|
11324
|
+
console.log(chalk117.dim(`
|
|
11234
11325
|
${totalCount} projects total (including root)`));
|
|
11235
|
-
console.log(
|
|
11326
|
+
console.log(chalk117.bold("\nSolution Membership"));
|
|
11236
11327
|
if (solutions.length === 0) {
|
|
11237
|
-
console.log(
|
|
11328
|
+
console.log(chalk117.yellow(" Not found in any .sln"));
|
|
11238
11329
|
} else {
|
|
11239
11330
|
for (const sln of solutions) {
|
|
11240
|
-
console.log(` ${
|
|
11331
|
+
console.log(` ${chalk117.green(sln)}`);
|
|
11241
11332
|
}
|
|
11242
11333
|
}
|
|
11243
11334
|
console.log();
|
|
@@ -11266,16 +11357,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
11266
11357
|
// src/commands/dotnet/resolveCsproj.ts
|
|
11267
11358
|
import { existsSync as existsSync32 } from "fs";
|
|
11268
11359
|
import path25 from "path";
|
|
11269
|
-
import
|
|
11360
|
+
import chalk118 from "chalk";
|
|
11270
11361
|
function resolveCsproj(csprojPath) {
|
|
11271
11362
|
const resolved = path25.resolve(csprojPath);
|
|
11272
11363
|
if (!existsSync32(resolved)) {
|
|
11273
|
-
console.error(
|
|
11364
|
+
console.error(chalk118.red(`File not found: ${resolved}`));
|
|
11274
11365
|
process.exit(1);
|
|
11275
11366
|
}
|
|
11276
11367
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
11277
11368
|
if (!repoRoot) {
|
|
11278
|
-
console.error(
|
|
11369
|
+
console.error(chalk118.red("Could not find git repository root"));
|
|
11279
11370
|
process.exit(1);
|
|
11280
11371
|
}
|
|
11281
11372
|
return { resolved, repoRoot };
|
|
@@ -11325,12 +11416,12 @@ function getChangedCsFiles(scope) {
|
|
|
11325
11416
|
}
|
|
11326
11417
|
|
|
11327
11418
|
// src/commands/dotnet/inSln.ts
|
|
11328
|
-
import
|
|
11419
|
+
import chalk119 from "chalk";
|
|
11329
11420
|
async function inSln(csprojPath) {
|
|
11330
11421
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
11331
11422
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
11332
11423
|
if (solutions.length === 0) {
|
|
11333
|
-
console.log(
|
|
11424
|
+
console.log(chalk119.yellow("Not found in any .sln file"));
|
|
11334
11425
|
process.exit(1);
|
|
11335
11426
|
}
|
|
11336
11427
|
for (const sln of solutions) {
|
|
@@ -11339,7 +11430,7 @@ async function inSln(csprojPath) {
|
|
|
11339
11430
|
}
|
|
11340
11431
|
|
|
11341
11432
|
// src/commands/dotnet/inspect.ts
|
|
11342
|
-
import
|
|
11433
|
+
import chalk125 from "chalk";
|
|
11343
11434
|
|
|
11344
11435
|
// src/shared/formatElapsed.ts
|
|
11345
11436
|
function formatElapsed(ms) {
|
|
@@ -11351,12 +11442,12 @@ function formatElapsed(ms) {
|
|
|
11351
11442
|
}
|
|
11352
11443
|
|
|
11353
11444
|
// src/commands/dotnet/displayIssues.ts
|
|
11354
|
-
import
|
|
11445
|
+
import chalk120 from "chalk";
|
|
11355
11446
|
var SEVERITY_COLOR = {
|
|
11356
|
-
ERROR:
|
|
11357
|
-
WARNING:
|
|
11358
|
-
SUGGESTION:
|
|
11359
|
-
HINT:
|
|
11447
|
+
ERROR: chalk120.red,
|
|
11448
|
+
WARNING: chalk120.yellow,
|
|
11449
|
+
SUGGESTION: chalk120.cyan,
|
|
11450
|
+
HINT: chalk120.dim
|
|
11360
11451
|
};
|
|
11361
11452
|
function groupByFile(issues) {
|
|
11362
11453
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -11372,15 +11463,15 @@ function groupByFile(issues) {
|
|
|
11372
11463
|
}
|
|
11373
11464
|
function displayIssues(issues) {
|
|
11374
11465
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
11375
|
-
console.log(
|
|
11466
|
+
console.log(chalk120.bold(file));
|
|
11376
11467
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
11377
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
11468
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk120.white;
|
|
11378
11469
|
console.log(
|
|
11379
|
-
` ${
|
|
11470
|
+
` ${chalk120.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
11380
11471
|
);
|
|
11381
11472
|
}
|
|
11382
11473
|
}
|
|
11383
|
-
console.log(
|
|
11474
|
+
console.log(chalk120.dim(`
|
|
11384
11475
|
${issues.length} issue(s) found`));
|
|
11385
11476
|
}
|
|
11386
11477
|
|
|
@@ -11439,12 +11530,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11439
11530
|
// src/commands/dotnet/resolveSolution.ts
|
|
11440
11531
|
import { existsSync as existsSync33 } from "fs";
|
|
11441
11532
|
import path26 from "path";
|
|
11442
|
-
import
|
|
11533
|
+
import chalk122 from "chalk";
|
|
11443
11534
|
|
|
11444
11535
|
// src/commands/dotnet/findSolution.ts
|
|
11445
11536
|
import { readdirSync as readdirSync6 } from "fs";
|
|
11446
11537
|
import { dirname as dirname20, join as join34 } from "path";
|
|
11447
|
-
import
|
|
11538
|
+
import chalk121 from "chalk";
|
|
11448
11539
|
function findSlnInDir(dir) {
|
|
11449
11540
|
try {
|
|
11450
11541
|
return readdirSync6(dir).filter((f) => f.endsWith(".sln")).map((f) => join34(dir, f));
|
|
@@ -11460,17 +11551,17 @@ function findSolution() {
|
|
|
11460
11551
|
const slnFiles = findSlnInDir(current);
|
|
11461
11552
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
11462
11553
|
if (slnFiles.length > 1) {
|
|
11463
|
-
console.error(
|
|
11554
|
+
console.error(chalk121.red(`Multiple .sln files found in ${current}:`));
|
|
11464
11555
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
11465
11556
|
console.error(
|
|
11466
|
-
|
|
11557
|
+
chalk121.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
11467
11558
|
);
|
|
11468
11559
|
process.exit(1);
|
|
11469
11560
|
}
|
|
11470
11561
|
if (current === ceiling) break;
|
|
11471
11562
|
current = dirname20(current);
|
|
11472
11563
|
}
|
|
11473
|
-
console.error(
|
|
11564
|
+
console.error(chalk121.red("No .sln file found between cwd and repo root"));
|
|
11474
11565
|
process.exit(1);
|
|
11475
11566
|
}
|
|
11476
11567
|
|
|
@@ -11479,7 +11570,7 @@ function resolveSolution(sln) {
|
|
|
11479
11570
|
if (sln) {
|
|
11480
11571
|
const resolved = path26.resolve(sln);
|
|
11481
11572
|
if (!existsSync33(resolved)) {
|
|
11482
|
-
console.error(
|
|
11573
|
+
console.error(chalk122.red(`Solution file not found: ${resolved}`));
|
|
11483
11574
|
process.exit(1);
|
|
11484
11575
|
}
|
|
11485
11576
|
return resolved;
|
|
@@ -11521,14 +11612,14 @@ import { execSync as execSync28 } from "child_process";
|
|
|
11521
11612
|
import { existsSync as existsSync34, readFileSync as readFileSync29, unlinkSync as unlinkSync9 } from "fs";
|
|
11522
11613
|
import { tmpdir as tmpdir3 } from "os";
|
|
11523
11614
|
import path27 from "path";
|
|
11524
|
-
import
|
|
11615
|
+
import chalk123 from "chalk";
|
|
11525
11616
|
function assertJbInstalled() {
|
|
11526
11617
|
try {
|
|
11527
11618
|
execSync28("jb inspectcode --version", { stdio: "pipe" });
|
|
11528
11619
|
} catch {
|
|
11529
|
-
console.error(
|
|
11620
|
+
console.error(chalk123.red("jb is not installed. Install with:"));
|
|
11530
11621
|
console.error(
|
|
11531
|
-
|
|
11622
|
+
chalk123.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11532
11623
|
);
|
|
11533
11624
|
process.exit(1);
|
|
11534
11625
|
}
|
|
@@ -11546,11 +11637,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11546
11637
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11547
11638
|
process.stderr.write(error.stderr);
|
|
11548
11639
|
}
|
|
11549
|
-
console.error(
|
|
11640
|
+
console.error(chalk123.red("jb inspectcode failed"));
|
|
11550
11641
|
process.exit(1);
|
|
11551
11642
|
}
|
|
11552
11643
|
if (!existsSync34(reportPath)) {
|
|
11553
|
-
console.error(
|
|
11644
|
+
console.error(chalk123.red("Report file not generated"));
|
|
11554
11645
|
process.exit(1);
|
|
11555
11646
|
}
|
|
11556
11647
|
const xml = readFileSync29(reportPath, "utf8");
|
|
@@ -11560,7 +11651,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11560
11651
|
|
|
11561
11652
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11562
11653
|
import { execSync as execSync29 } from "child_process";
|
|
11563
|
-
import
|
|
11654
|
+
import chalk124 from "chalk";
|
|
11564
11655
|
function resolveMsbuildPath() {
|
|
11565
11656
|
const { run: run4 } = loadConfig();
|
|
11566
11657
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11572,9 +11663,9 @@ function assertMsbuildInstalled() {
|
|
|
11572
11663
|
try {
|
|
11573
11664
|
execSync29(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11574
11665
|
} catch {
|
|
11575
|
-
console.error(
|
|
11666
|
+
console.error(chalk124.red(`msbuild not found at: ${msbuild}`));
|
|
11576
11667
|
console.error(
|
|
11577
|
-
|
|
11668
|
+
chalk124.yellow(
|
|
11578
11669
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11579
11670
|
)
|
|
11580
11671
|
);
|
|
@@ -11621,17 +11712,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11621
11712
|
// src/commands/dotnet/inspect.ts
|
|
11622
11713
|
function logScope(changedFiles) {
|
|
11623
11714
|
if (changedFiles === null) {
|
|
11624
|
-
console.log(
|
|
11715
|
+
console.log(chalk125.dim("Inspecting full solution..."));
|
|
11625
11716
|
} else {
|
|
11626
11717
|
console.log(
|
|
11627
|
-
|
|
11718
|
+
chalk125.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11628
11719
|
);
|
|
11629
11720
|
}
|
|
11630
11721
|
}
|
|
11631
11722
|
function reportResults(issues, elapsed) {
|
|
11632
11723
|
if (issues.length > 0) displayIssues(issues);
|
|
11633
|
-
else console.log(
|
|
11634
|
-
console.log(
|
|
11724
|
+
else console.log(chalk125.green("No issues found"));
|
|
11725
|
+
console.log(chalk125.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11635
11726
|
if (issues.length > 0) process.exit(1);
|
|
11636
11727
|
}
|
|
11637
11728
|
async function inspect(sln, options2) {
|
|
@@ -11642,7 +11733,7 @@ async function inspect(sln, options2) {
|
|
|
11642
11733
|
const scope = parseScope(options2.scope);
|
|
11643
11734
|
const changedFiles = getChangedCsFiles(scope);
|
|
11644
11735
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11645
|
-
console.log(
|
|
11736
|
+
console.log(chalk125.green("No changed .cs files found"));
|
|
11646
11737
|
return;
|
|
11647
11738
|
}
|
|
11648
11739
|
logScope(changedFiles);
|
|
@@ -11685,12 +11776,12 @@ function isSourceFile(filePath) {
|
|
|
11685
11776
|
if (!filePath) return false;
|
|
11686
11777
|
return SOURCE_EXTENSIONS2.some((ext) => filePath.endsWith(ext));
|
|
11687
11778
|
}
|
|
11688
|
-
function blankNonNewline(
|
|
11689
|
-
return
|
|
11779
|
+
function blankNonNewline(text7) {
|
|
11780
|
+
return text7.replace(/[^\n]/g, " ");
|
|
11690
11781
|
}
|
|
11691
|
-
function extractComments(
|
|
11782
|
+
function extractComments(text7) {
|
|
11692
11783
|
const comments3 = [];
|
|
11693
|
-
let work =
|
|
11784
|
+
let work = text7.replace(
|
|
11694
11785
|
/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`/g,
|
|
11695
11786
|
blankNonNewline
|
|
11696
11787
|
);
|
|
@@ -11945,25 +12036,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11945
12036
|
}
|
|
11946
12037
|
|
|
11947
12038
|
// src/commands/github/printCountTable.ts
|
|
11948
|
-
import
|
|
12039
|
+
import chalk126 from "chalk";
|
|
11949
12040
|
function printCountTable(labelHeader, rows) {
|
|
11950
12041
|
const labelWidth = Math.max(
|
|
11951
12042
|
labelHeader.length,
|
|
11952
12043
|
...rows.map((row) => row.label.length)
|
|
11953
12044
|
);
|
|
11954
12045
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11955
|
-
console.log(
|
|
11956
|
-
console.log(
|
|
12046
|
+
console.log(chalk126.dim(header));
|
|
12047
|
+
console.log(chalk126.dim("-".repeat(header.length)));
|
|
11957
12048
|
for (const row of rows) {
|
|
11958
12049
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11959
12050
|
}
|
|
11960
12051
|
}
|
|
11961
12052
|
|
|
11962
12053
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11963
|
-
import
|
|
12054
|
+
import chalk127 from "chalk";
|
|
11964
12055
|
function printRepoAuthorBreakdown(repos2) {
|
|
11965
12056
|
for (const repo of repos2) {
|
|
11966
|
-
console.log(
|
|
12057
|
+
console.log(chalk127.bold(repo.name));
|
|
11967
12058
|
const authorWidth = Math.max(
|
|
11968
12059
|
0,
|
|
11969
12060
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -12281,13 +12372,13 @@ function registerHandover(program2) {
|
|
|
12281
12372
|
}
|
|
12282
12373
|
|
|
12283
12374
|
// src/commands/jira/acceptanceCriteria.ts
|
|
12284
|
-
import
|
|
12375
|
+
import chalk128 from "chalk";
|
|
12285
12376
|
|
|
12286
12377
|
// src/commands/jira/adfToText.ts
|
|
12287
12378
|
function renderInline(node) {
|
|
12288
|
-
const
|
|
12289
|
-
if (node.marks?.some((m) => m.type === "code")) return `\`${
|
|
12290
|
-
return
|
|
12379
|
+
const text7 = node.text ?? "";
|
|
12380
|
+
if (node.marks?.some((m) => m.type === "code")) return `\`${text7}\``;
|
|
12381
|
+
return text7;
|
|
12291
12382
|
}
|
|
12292
12383
|
function renderChildren(node, indent2) {
|
|
12293
12384
|
return renderNodes(node.content ?? [], indent2);
|
|
@@ -12329,8 +12420,8 @@ function isListNode(node) {
|
|
|
12329
12420
|
function renderListChild(child, indent2, pad, marker, isFirst) {
|
|
12330
12421
|
if (isListNode(child)) return renderNodes([child], indent2 + 1);
|
|
12331
12422
|
if (child.type !== "paragraph") return renderNode(child, indent2);
|
|
12332
|
-
const
|
|
12333
|
-
return isFirst ? `${pad}${marker} ${
|
|
12423
|
+
const text7 = renderChildren(child, indent2);
|
|
12424
|
+
return isFirst ? `${pad}${marker} ${text7}` : `${pad} ${text7}`;
|
|
12334
12425
|
}
|
|
12335
12426
|
function renderListItem(node, indent2, marker) {
|
|
12336
12427
|
const pad = " ".repeat(indent2);
|
|
@@ -12348,7 +12439,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
12348
12439
|
const parsed = fetchIssue(issueKey, field);
|
|
12349
12440
|
const acValue = parsed?.fields?.[field];
|
|
12350
12441
|
if (!acValue) {
|
|
12351
|
-
console.log(
|
|
12442
|
+
console.log(chalk128.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
12352
12443
|
return;
|
|
12353
12444
|
}
|
|
12354
12445
|
if (typeof acValue === "string") {
|
|
@@ -12443,14 +12534,14 @@ async function jiraAuth() {
|
|
|
12443
12534
|
}
|
|
12444
12535
|
|
|
12445
12536
|
// src/commands/jira/viewIssue.ts
|
|
12446
|
-
import
|
|
12537
|
+
import chalk129 from "chalk";
|
|
12447
12538
|
function viewIssue(issueKey) {
|
|
12448
12539
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
12449
12540
|
const fields = parsed?.fields;
|
|
12450
12541
|
const summary = fields?.summary;
|
|
12451
12542
|
const description = fields?.description;
|
|
12452
12543
|
if (summary) {
|
|
12453
|
-
console.log(
|
|
12544
|
+
console.log(chalk129.bold(summary));
|
|
12454
12545
|
}
|
|
12455
12546
|
if (description) {
|
|
12456
12547
|
if (summary) console.log();
|
|
@@ -12464,7 +12555,7 @@ function viewIssue(issueKey) {
|
|
|
12464
12555
|
}
|
|
12465
12556
|
if (!summary && !description) {
|
|
12466
12557
|
console.log(
|
|
12467
|
-
|
|
12558
|
+
chalk129.yellow(`No summary or description found on ${issueKey}.`)
|
|
12468
12559
|
);
|
|
12469
12560
|
}
|
|
12470
12561
|
}
|
|
@@ -12480,13 +12571,13 @@ function registerJira(program2) {
|
|
|
12480
12571
|
// src/commands/reviewComments.ts
|
|
12481
12572
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
12482
12573
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
12483
|
-
import
|
|
12574
|
+
import chalk130 from "chalk";
|
|
12484
12575
|
async function reviewComments(number) {
|
|
12485
12576
|
if (number) {
|
|
12486
12577
|
try {
|
|
12487
12578
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
12488
12579
|
} catch {
|
|
12489
|
-
console.error(
|
|
12580
|
+
console.error(chalk130.red(`gh pr checkout ${number} failed; aborting.`));
|
|
12490
12581
|
process.exit(1);
|
|
12491
12582
|
}
|
|
12492
12583
|
}
|
|
@@ -12511,9 +12602,9 @@ function registerDescriptionLaunch(program2, name, slashCommand, description, al
|
|
|
12511
12602
|
"[description]",
|
|
12512
12603
|
`Text to forward to the /${slashCommand} slash command`
|
|
12513
12604
|
).description(description).option("--once", "Exit when the initial task completes").option("--resume-session <id>", RESUME_SESSION_FLAG).action(
|
|
12514
|
-
(
|
|
12605
|
+
(text7, opts) => launchMode(slashCommand, {
|
|
12515
12606
|
once: opts.once,
|
|
12516
|
-
description:
|
|
12607
|
+
description: text7,
|
|
12517
12608
|
resumeSessionId: opts.resumeSession
|
|
12518
12609
|
})
|
|
12519
12610
|
);
|
|
@@ -12560,15 +12651,15 @@ function registerList(program2) {
|
|
|
12560
12651
|
// src/commands/mermaid/index.ts
|
|
12561
12652
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync8 } from "fs";
|
|
12562
12653
|
import { resolve as resolve11 } from "path";
|
|
12563
|
-
import
|
|
12654
|
+
import chalk133 from "chalk";
|
|
12564
12655
|
|
|
12565
12656
|
// src/commands/mermaid/exportFile.ts
|
|
12566
12657
|
import { readFileSync as readFileSync32, writeFileSync as writeFileSync28 } from "fs";
|
|
12567
12658
|
import { basename as basename8, extname, resolve as resolve10 } from "path";
|
|
12568
|
-
import
|
|
12659
|
+
import chalk132 from "chalk";
|
|
12569
12660
|
|
|
12570
12661
|
// src/commands/mermaid/renderBlock.ts
|
|
12571
|
-
import
|
|
12662
|
+
import chalk131 from "chalk";
|
|
12572
12663
|
async function renderBlock(krokiUrl, source) {
|
|
12573
12664
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
12574
12665
|
method: "POST",
|
|
@@ -12577,7 +12668,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12577
12668
|
});
|
|
12578
12669
|
if (!response.ok) {
|
|
12579
12670
|
console.error(
|
|
12580
|
-
|
|
12671
|
+
chalk131.red(
|
|
12581
12672
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
12582
12673
|
)
|
|
12583
12674
|
);
|
|
@@ -12595,19 +12686,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12595
12686
|
if (onlyIndex !== void 0) {
|
|
12596
12687
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
12597
12688
|
console.error(
|
|
12598
|
-
|
|
12689
|
+
chalk132.red(
|
|
12599
12690
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
12600
12691
|
)
|
|
12601
12692
|
);
|
|
12602
12693
|
process.exit(1);
|
|
12603
12694
|
}
|
|
12604
12695
|
console.log(
|
|
12605
|
-
|
|
12696
|
+
chalk132.gray(
|
|
12606
12697
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
12607
12698
|
)
|
|
12608
12699
|
);
|
|
12609
12700
|
} else {
|
|
12610
|
-
console.log(
|
|
12701
|
+
console.log(chalk132.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
12611
12702
|
}
|
|
12612
12703
|
for (const [i, source] of blocks.entries()) {
|
|
12613
12704
|
const idx = i + 1;
|
|
@@ -12615,7 +12706,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12615
12706
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
12616
12707
|
const svg = await renderBlock(krokiUrl, source);
|
|
12617
12708
|
writeFileSync28(outPath, svg, "utf8");
|
|
12618
|
-
console.log(
|
|
12709
|
+
console.log(chalk132.green(` \u2192 ${outPath}`));
|
|
12619
12710
|
}
|
|
12620
12711
|
}
|
|
12621
12712
|
function extractMermaidBlocks(markdown) {
|
|
@@ -12631,18 +12722,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
12631
12722
|
if (options2.index !== void 0) {
|
|
12632
12723
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
12633
12724
|
console.error(
|
|
12634
|
-
|
|
12725
|
+
chalk133.red(`--index must be a positive integer (got ${options2.index})`)
|
|
12635
12726
|
);
|
|
12636
12727
|
process.exit(1);
|
|
12637
12728
|
}
|
|
12638
12729
|
if (!file) {
|
|
12639
|
-
console.error(
|
|
12730
|
+
console.error(chalk133.red("--index requires a file argument"));
|
|
12640
12731
|
process.exit(1);
|
|
12641
12732
|
}
|
|
12642
12733
|
}
|
|
12643
12734
|
const files = file ? [file] : readdirSync8(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
12644
12735
|
if (files.length === 0) {
|
|
12645
|
-
console.log(
|
|
12736
|
+
console.log(chalk133.gray("No markdown files found in current directory."));
|
|
12646
12737
|
return;
|
|
12647
12738
|
}
|
|
12648
12739
|
for (const f of files) {
|
|
@@ -12668,7 +12759,7 @@ function registerMermaid(program2) {
|
|
|
12668
12759
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12669
12760
|
import { createServer as createServer2 } from "http";
|
|
12670
12761
|
import { dirname as dirname22 } from "path";
|
|
12671
|
-
import
|
|
12762
|
+
import chalk135 from "chalk";
|
|
12672
12763
|
|
|
12673
12764
|
// src/commands/netcap/corsHeaders.ts
|
|
12674
12765
|
var corsHeaders = {
|
|
@@ -12747,7 +12838,7 @@ function createNetcapHandler(options2) {
|
|
|
12747
12838
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12748
12839
|
import { networkInterfaces } from "os";
|
|
12749
12840
|
import { join as join41 } from "path";
|
|
12750
|
-
import
|
|
12841
|
+
import chalk134 from "chalk";
|
|
12751
12842
|
|
|
12752
12843
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12753
12844
|
import { dirname as dirname21, join as join40 } from "path";
|
|
@@ -12791,7 +12882,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12791
12882
|
const host = lanIPv4();
|
|
12792
12883
|
if (!host) {
|
|
12793
12884
|
console.log(
|
|
12794
|
-
|
|
12885
|
+
chalk134.yellow("could not determine the WSL IP for the extension")
|
|
12795
12886
|
);
|
|
12796
12887
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12797
12888
|
return source;
|
|
@@ -12802,7 +12893,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12802
12893
|
return WSL_WINDOWS_PATH;
|
|
12803
12894
|
} catch {
|
|
12804
12895
|
console.log(
|
|
12805
|
-
|
|
12896
|
+
chalk134.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12806
12897
|
);
|
|
12807
12898
|
return source;
|
|
12808
12899
|
}
|
|
@@ -12835,30 +12926,30 @@ async function netcap(options2) {
|
|
|
12835
12926
|
let count7 = 0;
|
|
12836
12927
|
const handler = createNetcapHandler({
|
|
12837
12928
|
outPath,
|
|
12838
|
-
onPing: () => console.log(
|
|
12929
|
+
onPing: () => console.log(chalk135.dim("ping from extension")),
|
|
12839
12930
|
onCapture: (entry) => {
|
|
12840
12931
|
count7 += 1;
|
|
12841
12932
|
console.log(
|
|
12842
|
-
|
|
12843
|
-
|
|
12933
|
+
chalk135.green(`captured #${count7}`),
|
|
12934
|
+
chalk135.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12844
12935
|
);
|
|
12845
12936
|
}
|
|
12846
12937
|
});
|
|
12847
12938
|
const server = createServer2(handler);
|
|
12848
12939
|
server.listen(port, () => {
|
|
12849
12940
|
console.log(
|
|
12850
|
-
|
|
12941
|
+
chalk135.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12851
12942
|
);
|
|
12852
|
-
console.log(
|
|
12943
|
+
console.log(chalk135.dim(`appending captures to ${outPath}`));
|
|
12853
12944
|
if (filter)
|
|
12854
|
-
console.log(
|
|
12855
|
-
console.log(
|
|
12856
|
-
console.log(
|
|
12945
|
+
console.log(chalk135.dim(`forwarding only URLs matching "${filter}"`));
|
|
12946
|
+
console.log(chalk135.dim(`load the unpacked extension from ${extensionPath}`));
|
|
12947
|
+
console.log(chalk135.dim("press Ctrl-C to stop"));
|
|
12857
12948
|
});
|
|
12858
12949
|
process.on("SIGINT", () => {
|
|
12859
12950
|
server.close();
|
|
12860
12951
|
console.log(
|
|
12861
|
-
|
|
12952
|
+
chalk135.bold(
|
|
12862
12953
|
`
|
|
12863
12954
|
netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12864
12955
|
)
|
|
@@ -12870,7 +12961,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
|
|
|
12870
12961
|
// src/commands/netcap/netcapExtract.ts
|
|
12871
12962
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
12872
12963
|
import { join as join44 } from "path";
|
|
12873
|
-
import
|
|
12964
|
+
import chalk136 from "chalk";
|
|
12874
12965
|
|
|
12875
12966
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12876
12967
|
import { readFileSync as readFileSync33 } from "fs";
|
|
@@ -13008,8 +13099,8 @@ function dedupeLinks(links2) {
|
|
|
13008
13099
|
}
|
|
13009
13100
|
|
|
13010
13101
|
// src/commands/netcap/linkifyMentions.ts
|
|
13011
|
-
function linkifyMentions(
|
|
13012
|
-
let out =
|
|
13102
|
+
function linkifyMentions(text7, mentions) {
|
|
13103
|
+
let out = text7;
|
|
13013
13104
|
for (const m of mentions) {
|
|
13014
13105
|
if (m.name && out.includes(m.name)) {
|
|
13015
13106
|
out = out.replace(m.name, `[${m.name}](${m.url})`);
|
|
@@ -13036,13 +13127,13 @@ function resolveAuthor(mentionMap, author) {
|
|
|
13036
13127
|
return mentionMap.get(author) ?? { slug: author, url: profileUrl(author) };
|
|
13037
13128
|
}
|
|
13038
13129
|
function buildPost(raw, mentionMap, author) {
|
|
13039
|
-
const
|
|
13040
|
-
if (!
|
|
13130
|
+
const text7 = joinText(raw.text);
|
|
13131
|
+
if (!text7) return void 0;
|
|
13041
13132
|
const mentions = resolveMentions(raw, mentionMap, author);
|
|
13042
13133
|
const relatedPosts = [...new Set(raw.related)];
|
|
13043
13134
|
return {
|
|
13044
|
-
text:
|
|
13045
|
-
markdown: linkifyMentions(
|
|
13135
|
+
text: text7,
|
|
13136
|
+
markdown: linkifyMentions(text7, mentions),
|
|
13046
13137
|
mentions,
|
|
13047
13138
|
hashtags: [...new Set(raw.hashtags)],
|
|
13048
13139
|
links: dedupeLinks(raw.links),
|
|
@@ -13183,8 +13274,8 @@ function activityUrnOf(update3) {
|
|
|
13183
13274
|
return typeof urn === "string" ? urn : void 0;
|
|
13184
13275
|
}
|
|
13185
13276
|
function buildVoyagerPost(update3, profiles) {
|
|
13186
|
-
const
|
|
13187
|
-
if (!
|
|
13277
|
+
const text7 = commentaryText(update3);
|
|
13278
|
+
if (!text7) return void 0;
|
|
13188
13279
|
const author = resolveVoyagerAuthor(update3);
|
|
13189
13280
|
const { mentions, hashtags, links: links2 } = collectVoyagerAttributes(
|
|
13190
13281
|
update3,
|
|
@@ -13193,8 +13284,8 @@ function buildVoyagerPost(update3, profiles) {
|
|
|
13193
13284
|
);
|
|
13194
13285
|
const activityUrn = activityUrnOf(update3);
|
|
13195
13286
|
return {
|
|
13196
|
-
text:
|
|
13197
|
-
markdown: linkifyMentions(
|
|
13287
|
+
text: text7,
|
|
13288
|
+
markdown: linkifyMentions(text7, mentions),
|
|
13198
13289
|
mentions,
|
|
13199
13290
|
hashtags,
|
|
13200
13291
|
links: links2,
|
|
@@ -13318,8 +13409,8 @@ function netcapExtract(file) {
|
|
|
13318
13409
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13319
13410
|
`);
|
|
13320
13411
|
console.log(
|
|
13321
|
-
|
|
13322
|
-
|
|
13412
|
+
chalk136.green(`extracted ${posts.length} posts`),
|
|
13413
|
+
chalk136.dim(`-> ${outFile}`)
|
|
13323
13414
|
);
|
|
13324
13415
|
}
|
|
13325
13416
|
|
|
@@ -13340,7 +13431,7 @@ function registerNetcap(program2) {
|
|
|
13340
13431
|
}
|
|
13341
13432
|
|
|
13342
13433
|
// src/commands/news/add/index.ts
|
|
13343
|
-
import
|
|
13434
|
+
import chalk137 from "chalk";
|
|
13344
13435
|
import enquirer8 from "enquirer";
|
|
13345
13436
|
async function add2(url) {
|
|
13346
13437
|
if (!url) {
|
|
@@ -13362,10 +13453,10 @@ async function add2(url) {
|
|
|
13362
13453
|
const { orm } = await getReady();
|
|
13363
13454
|
const added = await addFeed(orm, url);
|
|
13364
13455
|
if (!added) {
|
|
13365
|
-
console.log(
|
|
13456
|
+
console.log(chalk137.yellow("Feed already exists"));
|
|
13366
13457
|
return;
|
|
13367
13458
|
}
|
|
13368
|
-
console.log(
|
|
13459
|
+
console.log(chalk137.green(`Added feed: ${url}`));
|
|
13369
13460
|
}
|
|
13370
13461
|
|
|
13371
13462
|
// src/commands/registerNews.ts
|
|
@@ -13375,7 +13466,7 @@ function registerNews(program2) {
|
|
|
13375
13466
|
}
|
|
13376
13467
|
|
|
13377
13468
|
// src/commands/prompts/printPromptsTable.ts
|
|
13378
|
-
import
|
|
13469
|
+
import chalk138 from "chalk";
|
|
13379
13470
|
function truncate(str, max) {
|
|
13380
13471
|
if (str.length <= max) return str;
|
|
13381
13472
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -13393,14 +13484,14 @@ function printPromptsTable(rows) {
|
|
|
13393
13484
|
"Command".padEnd(commandWidth),
|
|
13394
13485
|
"Repos"
|
|
13395
13486
|
].join(" ");
|
|
13396
|
-
console.log(
|
|
13397
|
-
console.log(
|
|
13487
|
+
console.log(chalk138.dim(header));
|
|
13488
|
+
console.log(chalk138.dim("-".repeat(header.length)));
|
|
13398
13489
|
for (const row of rows) {
|
|
13399
13490
|
const count7 = String(row.count).padStart(countWidth);
|
|
13400
13491
|
const tool = row.tool.padEnd(toolWidth);
|
|
13401
13492
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
13402
13493
|
console.log(
|
|
13403
|
-
`${
|
|
13494
|
+
`${chalk138.yellow(count7)} ${tool} ${command} ${chalk138.dim(row.repos)}`
|
|
13404
13495
|
);
|
|
13405
13496
|
}
|
|
13406
13497
|
}
|
|
@@ -13698,8 +13789,8 @@ function isWallOfText(lines) {
|
|
|
13698
13789
|
if (lines.some(isListLine)) {
|
|
13699
13790
|
return false;
|
|
13700
13791
|
}
|
|
13701
|
-
const
|
|
13702
|
-
return
|
|
13792
|
+
const text7 = lines.join(" ").trim();
|
|
13793
|
+
return text7.length > MAX_PARAGRAPH_CHARS || countSentences(text7) > MAX_PARAGRAPH_SENTENCES;
|
|
13703
13794
|
}
|
|
13704
13795
|
function validatePrContent(title, body) {
|
|
13705
13796
|
if (title.toLowerCase().includes("claude")) {
|
|
@@ -13949,20 +14040,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13949
14040
|
}
|
|
13950
14041
|
|
|
13951
14042
|
// src/commands/prs/listComments/printComments.ts
|
|
13952
|
-
import
|
|
14043
|
+
import chalk139 from "chalk";
|
|
13953
14044
|
function formatForHuman(comment3) {
|
|
13954
14045
|
if (comment3.type === "review") {
|
|
13955
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
14046
|
+
const stateColor = comment3.state === "APPROVED" ? chalk139.green : comment3.state === "CHANGES_REQUESTED" ? chalk139.red : chalk139.yellow;
|
|
13956
14047
|
return [
|
|
13957
|
-
`${
|
|
14048
|
+
`${chalk139.cyan("Review")} by ${chalk139.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13958
14049
|
comment3.body,
|
|
13959
14050
|
""
|
|
13960
14051
|
].join("\n");
|
|
13961
14052
|
}
|
|
13962
14053
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13963
14054
|
return [
|
|
13964
|
-
`${
|
|
13965
|
-
|
|
14055
|
+
`${chalk139.cyan("Line comment")} by ${chalk139.bold(comment3.user)} on ${chalk139.dim(`${comment3.path}${location}`)}`,
|
|
14056
|
+
chalk139.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
13966
14057
|
comment3.body,
|
|
13967
14058
|
""
|
|
13968
14059
|
].join("\n");
|
|
@@ -14052,13 +14143,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
14052
14143
|
import enquirer9 from "enquirer";
|
|
14053
14144
|
|
|
14054
14145
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
14055
|
-
import
|
|
14146
|
+
import chalk140 from "chalk";
|
|
14056
14147
|
var STATUS_MAP = {
|
|
14057
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
14058
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
14148
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk140.magenta("merged"), date: pr.mergedAt } : null,
|
|
14149
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk140.red("closed"), date: pr.closedAt } : null
|
|
14059
14150
|
};
|
|
14060
14151
|
function defaultStatus(pr) {
|
|
14061
|
-
return { label:
|
|
14152
|
+
return { label: chalk140.green("opened"), date: pr.createdAt };
|
|
14062
14153
|
}
|
|
14063
14154
|
function getStatus2(pr) {
|
|
14064
14155
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -14067,11 +14158,11 @@ function formatDate(dateStr) {
|
|
|
14067
14158
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
14068
14159
|
}
|
|
14069
14160
|
function formatPrHeader(pr, status2) {
|
|
14070
|
-
return `${
|
|
14161
|
+
return `${chalk140.cyan(`#${pr.number}`)} ${pr.title} ${chalk140.dim(`(${pr.author.login},`)} ${status2.label} ${chalk140.dim(`${formatDate(status2.date)})`)}`;
|
|
14071
14162
|
}
|
|
14072
14163
|
function logPrDetails(pr) {
|
|
14073
14164
|
console.log(
|
|
14074
|
-
|
|
14165
|
+
chalk140.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
14075
14166
|
);
|
|
14076
14167
|
console.log();
|
|
14077
14168
|
}
|
|
@@ -14378,10 +14469,10 @@ function registerPrs(program2) {
|
|
|
14378
14469
|
}
|
|
14379
14470
|
|
|
14380
14471
|
// src/commands/ravendb/ravendbAuth.ts
|
|
14381
|
-
import
|
|
14472
|
+
import chalk146 from "chalk";
|
|
14382
14473
|
|
|
14383
14474
|
// src/shared/createConnectionAuth.ts
|
|
14384
|
-
import
|
|
14475
|
+
import chalk141 from "chalk";
|
|
14385
14476
|
function listConnections(connections, format) {
|
|
14386
14477
|
if (connections.length === 0) {
|
|
14387
14478
|
console.log("No connections configured.");
|
|
@@ -14394,7 +14485,7 @@ function listConnections(connections, format) {
|
|
|
14394
14485
|
function removeConnection(connections, name, save) {
|
|
14395
14486
|
const filtered = connections.filter((c) => c.name !== name);
|
|
14396
14487
|
if (filtered.length === connections.length) {
|
|
14397
|
-
console.error(
|
|
14488
|
+
console.error(chalk141.red(`Connection "${name}" not found.`));
|
|
14398
14489
|
process.exit(1);
|
|
14399
14490
|
}
|
|
14400
14491
|
save(filtered);
|
|
@@ -14440,15 +14531,15 @@ function saveConnections(connections) {
|
|
|
14440
14531
|
}
|
|
14441
14532
|
|
|
14442
14533
|
// src/commands/ravendb/promptConnection.ts
|
|
14443
|
-
import
|
|
14534
|
+
import chalk144 from "chalk";
|
|
14444
14535
|
|
|
14445
14536
|
// src/commands/ravendb/selectOpSecret.ts
|
|
14446
|
-
import
|
|
14537
|
+
import chalk143 from "chalk";
|
|
14447
14538
|
import Enquirer2 from "enquirer";
|
|
14448
14539
|
|
|
14449
14540
|
// src/commands/ravendb/searchItems.ts
|
|
14450
14541
|
import { execSync as execSync41 } from "child_process";
|
|
14451
|
-
import
|
|
14542
|
+
import chalk142 from "chalk";
|
|
14452
14543
|
function opExec(args) {
|
|
14453
14544
|
return execSync41(`op ${args}`, {
|
|
14454
14545
|
encoding: "utf8",
|
|
@@ -14461,7 +14552,7 @@ function searchItems(search2) {
|
|
|
14461
14552
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
14462
14553
|
} catch {
|
|
14463
14554
|
console.error(
|
|
14464
|
-
|
|
14555
|
+
chalk142.red(
|
|
14465
14556
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
14466
14557
|
)
|
|
14467
14558
|
);
|
|
@@ -14475,7 +14566,7 @@ function getItemFields(itemId) {
|
|
|
14475
14566
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
14476
14567
|
return item.fields.filter((f) => f.reference && f.label);
|
|
14477
14568
|
} catch {
|
|
14478
|
-
console.error(
|
|
14569
|
+
console.error(chalk142.red("Failed to get item details from 1Password."));
|
|
14479
14570
|
process.exit(1);
|
|
14480
14571
|
}
|
|
14481
14572
|
}
|
|
@@ -14494,7 +14585,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14494
14585
|
}).run();
|
|
14495
14586
|
const items2 = searchItems(search2);
|
|
14496
14587
|
if (items2.length === 0) {
|
|
14497
|
-
console.error(
|
|
14588
|
+
console.error(chalk143.red(`No items found matching "${search2}".`));
|
|
14498
14589
|
process.exit(1);
|
|
14499
14590
|
}
|
|
14500
14591
|
const itemId = await selectOne(
|
|
@@ -14503,7 +14594,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14503
14594
|
);
|
|
14504
14595
|
const fields = getItemFields(itemId);
|
|
14505
14596
|
if (fields.length === 0) {
|
|
14506
|
-
console.error(
|
|
14597
|
+
console.error(chalk143.red("No fields with references found on this item."));
|
|
14507
14598
|
process.exit(1);
|
|
14508
14599
|
}
|
|
14509
14600
|
const ref = await selectOne(
|
|
@@ -14517,7 +14608,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14517
14608
|
async function promptConnection(existingNames) {
|
|
14518
14609
|
const name = await promptInput("name", "Connection name:");
|
|
14519
14610
|
if (existingNames.includes(name)) {
|
|
14520
|
-
console.error(
|
|
14611
|
+
console.error(chalk144.red(`Connection "${name}" already exists.`));
|
|
14521
14612
|
process.exit(1);
|
|
14522
14613
|
}
|
|
14523
14614
|
const url = await promptInput(
|
|
@@ -14526,22 +14617,22 @@ async function promptConnection(existingNames) {
|
|
|
14526
14617
|
);
|
|
14527
14618
|
const database = await promptInput("database", "Database name:");
|
|
14528
14619
|
if (!name || !url || !database) {
|
|
14529
|
-
console.error(
|
|
14620
|
+
console.error(chalk144.red("All fields are required."));
|
|
14530
14621
|
process.exit(1);
|
|
14531
14622
|
}
|
|
14532
14623
|
const apiKeyRef = await selectOpSecret();
|
|
14533
|
-
console.log(
|
|
14624
|
+
console.log(chalk144.dim(`Using: ${apiKeyRef}`));
|
|
14534
14625
|
return { name, url, database, apiKeyRef };
|
|
14535
14626
|
}
|
|
14536
14627
|
|
|
14537
14628
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
14538
|
-
import
|
|
14629
|
+
import chalk145 from "chalk";
|
|
14539
14630
|
function ravendbSetConnection(name) {
|
|
14540
14631
|
const raw = loadGlobalConfigRaw();
|
|
14541
14632
|
const ravendb = raw.ravendb ?? {};
|
|
14542
14633
|
const connections = ravendb.connections ?? [];
|
|
14543
14634
|
if (!connections.some((c) => c.name === name)) {
|
|
14544
|
-
console.error(
|
|
14635
|
+
console.error(chalk145.red(`Connection "${name}" not found.`));
|
|
14545
14636
|
console.error(
|
|
14546
14637
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14547
14638
|
);
|
|
@@ -14557,16 +14648,16 @@ function ravendbSetConnection(name) {
|
|
|
14557
14648
|
var ravendbAuth = createConnectionAuth({
|
|
14558
14649
|
load: loadConnections,
|
|
14559
14650
|
save: saveConnections,
|
|
14560
|
-
format: (c) => `${
|
|
14651
|
+
format: (c) => `${chalk146.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
14561
14652
|
promptNew: promptConnection,
|
|
14562
14653
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
14563
14654
|
});
|
|
14564
14655
|
|
|
14565
14656
|
// src/commands/ravendb/ravendbCollections.ts
|
|
14566
|
-
import
|
|
14657
|
+
import chalk150 from "chalk";
|
|
14567
14658
|
|
|
14568
14659
|
// src/commands/ravendb/ravenFetch.ts
|
|
14569
|
-
import
|
|
14660
|
+
import chalk148 from "chalk";
|
|
14570
14661
|
|
|
14571
14662
|
// src/commands/ravendb/getAccessToken.ts
|
|
14572
14663
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -14603,10 +14694,10 @@ ${errorText}`
|
|
|
14603
14694
|
|
|
14604
14695
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
14605
14696
|
import { execSync as execSync42 } from "child_process";
|
|
14606
|
-
import
|
|
14697
|
+
import chalk147 from "chalk";
|
|
14607
14698
|
function resolveOpSecret(reference) {
|
|
14608
14699
|
if (!reference.startsWith("op://")) {
|
|
14609
|
-
console.error(
|
|
14700
|
+
console.error(chalk147.red(`Invalid secret reference: must start with op://`));
|
|
14610
14701
|
process.exit(1);
|
|
14611
14702
|
}
|
|
14612
14703
|
try {
|
|
@@ -14616,7 +14707,7 @@ function resolveOpSecret(reference) {
|
|
|
14616
14707
|
}).trim();
|
|
14617
14708
|
} catch {
|
|
14618
14709
|
console.error(
|
|
14619
|
-
|
|
14710
|
+
chalk147.red(
|
|
14620
14711
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
14621
14712
|
)
|
|
14622
14713
|
);
|
|
@@ -14643,7 +14734,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14643
14734
|
if (!response.ok) {
|
|
14644
14735
|
const body = await response.text();
|
|
14645
14736
|
console.error(
|
|
14646
|
-
|
|
14737
|
+
chalk148.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
14647
14738
|
);
|
|
14648
14739
|
console.error(body.substring(0, 500));
|
|
14649
14740
|
process.exit(1);
|
|
@@ -14652,7 +14743,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14652
14743
|
}
|
|
14653
14744
|
|
|
14654
14745
|
// src/commands/ravendb/resolveConnection.ts
|
|
14655
|
-
import
|
|
14746
|
+
import chalk149 from "chalk";
|
|
14656
14747
|
function loadRavendb() {
|
|
14657
14748
|
const raw = loadGlobalConfigRaw();
|
|
14658
14749
|
const ravendb = raw.ravendb;
|
|
@@ -14666,7 +14757,7 @@ function resolveConnection(name) {
|
|
|
14666
14757
|
const connectionName = name ?? defaultConnection;
|
|
14667
14758
|
if (!connectionName) {
|
|
14668
14759
|
console.error(
|
|
14669
|
-
|
|
14760
|
+
chalk149.red(
|
|
14670
14761
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14671
14762
|
)
|
|
14672
14763
|
);
|
|
@@ -14674,7 +14765,7 @@ function resolveConnection(name) {
|
|
|
14674
14765
|
}
|
|
14675
14766
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14676
14767
|
if (!connection) {
|
|
14677
|
-
console.error(
|
|
14768
|
+
console.error(chalk149.red(`Connection "${connectionName}" not found.`));
|
|
14678
14769
|
console.error(
|
|
14679
14770
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14680
14771
|
);
|
|
@@ -14705,15 +14796,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14705
14796
|
return;
|
|
14706
14797
|
}
|
|
14707
14798
|
for (const c of collections) {
|
|
14708
|
-
console.log(`${
|
|
14799
|
+
console.log(`${chalk150.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14709
14800
|
}
|
|
14710
14801
|
}
|
|
14711
14802
|
|
|
14712
14803
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14713
|
-
import
|
|
14804
|
+
import chalk152 from "chalk";
|
|
14714
14805
|
|
|
14715
14806
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14716
|
-
import
|
|
14807
|
+
import chalk151 from "chalk";
|
|
14717
14808
|
|
|
14718
14809
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14719
14810
|
function buildQueryPath(opts) {
|
|
@@ -14751,7 +14842,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14751
14842
|
allResults.push(...results);
|
|
14752
14843
|
start3 += results.length;
|
|
14753
14844
|
process.stderr.write(
|
|
14754
|
-
`\r${
|
|
14845
|
+
`\r${chalk151.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14755
14846
|
);
|
|
14756
14847
|
if (start3 >= totalResults) break;
|
|
14757
14848
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14766,7 +14857,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14766
14857
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14767
14858
|
const resolved = resolveArgs(connectionName, collection);
|
|
14768
14859
|
if (!resolved.collection && !options2.query) {
|
|
14769
|
-
console.error(
|
|
14860
|
+
console.error(chalk152.red("Provide a collection name or --query filter."));
|
|
14770
14861
|
process.exit(1);
|
|
14771
14862
|
}
|
|
14772
14863
|
const { collection: col } = resolved;
|
|
@@ -14804,7 +14895,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14804
14895
|
import * as path28 from "path";
|
|
14805
14896
|
|
|
14806
14897
|
// src/commands/refactor/logViolations.ts
|
|
14807
|
-
import
|
|
14898
|
+
import chalk153 from "chalk";
|
|
14808
14899
|
var DEFAULT_MAX_LINES = 100;
|
|
14809
14900
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14810
14901
|
if (violations.length === 0) {
|
|
@@ -14813,43 +14904,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14813
14904
|
}
|
|
14814
14905
|
return;
|
|
14815
14906
|
}
|
|
14816
|
-
console.error(
|
|
14907
|
+
console.error(chalk153.red(`
|
|
14817
14908
|
Refactor check failed:
|
|
14818
14909
|
`));
|
|
14819
|
-
console.error(
|
|
14910
|
+
console.error(chalk153.red(` The following files exceed ${maxLines} lines:
|
|
14820
14911
|
`));
|
|
14821
14912
|
for (const violation of violations) {
|
|
14822
|
-
console.error(
|
|
14913
|
+
console.error(chalk153.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14823
14914
|
}
|
|
14824
14915
|
console.error(
|
|
14825
|
-
|
|
14916
|
+
chalk153.yellow(
|
|
14826
14917
|
`
|
|
14827
14918
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14828
14919
|
way to refactor it, ignore it with:
|
|
14829
14920
|
`
|
|
14830
14921
|
)
|
|
14831
14922
|
);
|
|
14832
|
-
console.error(
|
|
14923
|
+
console.error(chalk153.gray(` assist refactor ignore <file>
|
|
14833
14924
|
`));
|
|
14834
14925
|
if (process.env.CLAUDECODE) {
|
|
14835
|
-
console.error(
|
|
14926
|
+
console.error(chalk153.cyan(`
|
|
14836
14927
|
## Extracting Code to New Files
|
|
14837
14928
|
`));
|
|
14838
14929
|
console.error(
|
|
14839
|
-
|
|
14930
|
+
chalk153.cyan(
|
|
14840
14931
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14841
14932
|
`
|
|
14842
14933
|
)
|
|
14843
14934
|
);
|
|
14844
14935
|
console.error(
|
|
14845
|
-
|
|
14936
|
+
chalk153.cyan(
|
|
14846
14937
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14847
14938
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14848
14939
|
`
|
|
14849
14940
|
)
|
|
14850
14941
|
);
|
|
14851
14942
|
console.error(
|
|
14852
|
-
|
|
14943
|
+
chalk153.cyan(
|
|
14853
14944
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14854
14945
|
domains, move it to a common/shared folder.
|
|
14855
14946
|
`
|
|
@@ -15005,7 +15096,7 @@ async function check(pattern2, options2) {
|
|
|
15005
15096
|
|
|
15006
15097
|
// src/commands/refactor/extract/index.ts
|
|
15007
15098
|
import path35 from "path";
|
|
15008
|
-
import
|
|
15099
|
+
import chalk156 from "chalk";
|
|
15009
15100
|
|
|
15010
15101
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
15011
15102
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -15391,9 +15482,9 @@ function resolveImports(target, dependencies, sourceFile, statements = []) {
|
|
|
15391
15482
|
function extractTexts(target, allFunctions, statements) {
|
|
15392
15483
|
const stmtTexts = statements.map((v) => v.getFullText().trim());
|
|
15393
15484
|
const fnTexts = allFunctions.map((fn) => {
|
|
15394
|
-
const
|
|
15395
|
-
if (fn === target && !
|
|
15396
|
-
return
|
|
15485
|
+
const text7 = fn.getFullText().trim();
|
|
15486
|
+
if (fn === target && !text7.startsWith("export ")) return `export ${text7}`;
|
|
15487
|
+
return text7;
|
|
15397
15488
|
});
|
|
15398
15489
|
return [...stmtTexts, ...fnTexts];
|
|
15399
15490
|
}
|
|
@@ -15580,23 +15671,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
15580
15671
|
|
|
15581
15672
|
// src/commands/refactor/extract/displayPlan.ts
|
|
15582
15673
|
import path32 from "path";
|
|
15583
|
-
import
|
|
15674
|
+
import chalk154 from "chalk";
|
|
15584
15675
|
function section(title) {
|
|
15585
15676
|
return `
|
|
15586
|
-
${
|
|
15677
|
+
${chalk154.cyan(title)}`;
|
|
15587
15678
|
}
|
|
15588
15679
|
function displayImporters(plan2, cwd) {
|
|
15589
15680
|
if (plan2.importersToUpdate.length === 0) return;
|
|
15590
15681
|
console.log(section("Update importers:"));
|
|
15591
15682
|
for (const imp of plan2.importersToUpdate) {
|
|
15592
15683
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
15593
|
-
console.log(` ${
|
|
15684
|
+
console.log(` ${chalk154.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
15594
15685
|
}
|
|
15595
15686
|
}
|
|
15596
15687
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
15597
|
-
console.log(
|
|
15688
|
+
console.log(chalk154.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
15598
15689
|
`));
|
|
15599
|
-
console.log(` ${
|
|
15690
|
+
console.log(` ${chalk154.cyan("Functions to move:")}`);
|
|
15600
15691
|
for (const name of plan2.extractedNames) {
|
|
15601
15692
|
console.log(` ${name}`);
|
|
15602
15693
|
}
|
|
@@ -15630,7 +15721,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
15630
15721
|
|
|
15631
15722
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
15632
15723
|
import path34 from "path";
|
|
15633
|
-
import
|
|
15724
|
+
import chalk155 from "chalk";
|
|
15634
15725
|
import { Project as Project4 } from "ts-morph";
|
|
15635
15726
|
|
|
15636
15727
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -15690,7 +15781,7 @@ function loadProjectFile(file) {
|
|
|
15690
15781
|
});
|
|
15691
15782
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15692
15783
|
if (!sourceFile) {
|
|
15693
|
-
console.log(
|
|
15784
|
+
console.log(chalk155.red(`File not found in project: ${file}`));
|
|
15694
15785
|
process.exit(1);
|
|
15695
15786
|
}
|
|
15696
15787
|
return { project, sourceFile };
|
|
@@ -15713,19 +15804,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15713
15804
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15714
15805
|
if (options2.apply) {
|
|
15715
15806
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15716
|
-
console.log(
|
|
15807
|
+
console.log(chalk156.green("\nExtraction complete"));
|
|
15717
15808
|
} else {
|
|
15718
|
-
console.log(
|
|
15809
|
+
console.log(chalk156.dim("\nDry run. Use --apply to execute."));
|
|
15719
15810
|
}
|
|
15720
15811
|
}
|
|
15721
15812
|
|
|
15722
15813
|
// src/commands/refactor/ignore.ts
|
|
15723
15814
|
import fs23 from "fs";
|
|
15724
|
-
import
|
|
15815
|
+
import chalk157 from "chalk";
|
|
15725
15816
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15726
15817
|
function ignore(file) {
|
|
15727
15818
|
if (!fs23.existsSync(file)) {
|
|
15728
|
-
console.error(
|
|
15819
|
+
console.error(chalk157.red(`Error: File does not exist: ${file}`));
|
|
15729
15820
|
process.exit(1);
|
|
15730
15821
|
}
|
|
15731
15822
|
const content = fs23.readFileSync(file, "utf8");
|
|
@@ -15741,7 +15832,7 @@ function ignore(file) {
|
|
|
15741
15832
|
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15742
15833
|
}
|
|
15743
15834
|
console.log(
|
|
15744
|
-
|
|
15835
|
+
chalk157.green(
|
|
15745
15836
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15746
15837
|
)
|
|
15747
15838
|
);
|
|
@@ -15750,12 +15841,12 @@ function ignore(file) {
|
|
|
15750
15841
|
// src/commands/refactor/rename/index.ts
|
|
15751
15842
|
import fs26 from "fs";
|
|
15752
15843
|
import path40 from "path";
|
|
15753
|
-
import
|
|
15844
|
+
import chalk160 from "chalk";
|
|
15754
15845
|
|
|
15755
15846
|
// src/commands/refactor/rename/applyRename.ts
|
|
15756
15847
|
import fs25 from "fs";
|
|
15757
15848
|
import path37 from "path";
|
|
15758
|
-
import
|
|
15849
|
+
import chalk158 from "chalk";
|
|
15759
15850
|
|
|
15760
15851
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15761
15852
|
import path36 from "path";
|
|
@@ -15860,13 +15951,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
15860
15951
|
const updatedContents = applyRewrites(rewrites);
|
|
15861
15952
|
for (const [file, content] of updatedContents) {
|
|
15862
15953
|
fs25.writeFileSync(file, content, "utf8");
|
|
15863
|
-
console.log(
|
|
15954
|
+
console.log(chalk158.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15864
15955
|
}
|
|
15865
15956
|
const destDir = path37.dirname(destPath);
|
|
15866
15957
|
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15867
15958
|
fs25.renameSync(sourcePath, destPath);
|
|
15868
15959
|
console.log(
|
|
15869
|
-
|
|
15960
|
+
chalk158.white(
|
|
15870
15961
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15871
15962
|
)
|
|
15872
15963
|
);
|
|
@@ -15953,16 +16044,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15953
16044
|
|
|
15954
16045
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15955
16046
|
import path39 from "path";
|
|
15956
|
-
import
|
|
16047
|
+
import chalk159 from "chalk";
|
|
15957
16048
|
function printRenamePreview(rewrites, cwd) {
|
|
15958
16049
|
for (const rewrite of rewrites) {
|
|
15959
16050
|
console.log(
|
|
15960
|
-
|
|
16051
|
+
chalk159.dim(
|
|
15961
16052
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15962
16053
|
)
|
|
15963
16054
|
);
|
|
15964
16055
|
}
|
|
15965
|
-
console.log(
|
|
16056
|
+
console.log(chalk159.dim("Dry run. Use --apply to execute."));
|
|
15966
16057
|
}
|
|
15967
16058
|
|
|
15968
16059
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15973,20 +16064,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15973
16064
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15974
16065
|
const relDest = path40.relative(cwd, destPath);
|
|
15975
16066
|
if (!fs26.existsSync(sourcePath)) {
|
|
15976
|
-
console.log(
|
|
16067
|
+
console.log(chalk160.red(`File not found: ${source}`));
|
|
15977
16068
|
process.exit(1);
|
|
15978
16069
|
}
|
|
15979
16070
|
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15980
|
-
console.log(
|
|
16071
|
+
console.log(chalk160.red(`Destination already exists: ${destination}`));
|
|
15981
16072
|
process.exit(1);
|
|
15982
16073
|
}
|
|
15983
|
-
console.log(
|
|
15984
|
-
console.log(
|
|
15985
|
-
console.log(
|
|
16074
|
+
console.log(chalk160.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
16075
|
+
console.log(chalk160.dim("Loading project..."));
|
|
16076
|
+
console.log(chalk160.dim("Scanning imports across the project..."));
|
|
15986
16077
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15987
16078
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15988
16079
|
console.log(
|
|
15989
|
-
|
|
16080
|
+
chalk160.dim(
|
|
15990
16081
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15991
16082
|
)
|
|
15992
16083
|
);
|
|
@@ -15995,11 +16086,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15995
16086
|
return;
|
|
15996
16087
|
}
|
|
15997
16088
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
15998
|
-
console.log(
|
|
16089
|
+
console.log(chalk160.green("Done"));
|
|
15999
16090
|
}
|
|
16000
16091
|
|
|
16001
16092
|
// src/commands/refactor/renameSymbol/index.ts
|
|
16002
|
-
import
|
|
16093
|
+
import chalk161 from "chalk";
|
|
16003
16094
|
|
|
16004
16095
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
16005
16096
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -16045,33 +16136,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
16045
16136
|
const { project, sourceFile } = loadProjectFile(file);
|
|
16046
16137
|
const symbol = findSymbol(sourceFile, oldName);
|
|
16047
16138
|
if (!symbol) {
|
|
16048
|
-
console.log(
|
|
16139
|
+
console.log(chalk161.red(`Symbol "${oldName}" not found in ${file}`));
|
|
16049
16140
|
process.exit(1);
|
|
16050
16141
|
}
|
|
16051
16142
|
const grouped = groupReferences(symbol, cwd);
|
|
16052
16143
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
16053
16144
|
console.log(
|
|
16054
|
-
|
|
16145
|
+
chalk161.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
16055
16146
|
`)
|
|
16056
16147
|
);
|
|
16057
16148
|
for (const [refFile, lines] of grouped) {
|
|
16058
16149
|
console.log(
|
|
16059
|
-
` ${
|
|
16150
|
+
` ${chalk161.dim(refFile)}: lines ${chalk161.cyan(lines.join(", "))}`
|
|
16060
16151
|
);
|
|
16061
16152
|
}
|
|
16062
16153
|
if (options2.apply) {
|
|
16063
16154
|
symbol.rename(newName);
|
|
16064
16155
|
await project.save();
|
|
16065
|
-
console.log(
|
|
16156
|
+
console.log(chalk161.green(`
|
|
16066
16157
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
16067
16158
|
} else {
|
|
16068
|
-
console.log(
|
|
16159
|
+
console.log(chalk161.dim("\nDry run. Use --apply to execute."));
|
|
16069
16160
|
}
|
|
16070
16161
|
}
|
|
16071
16162
|
|
|
16072
16163
|
// src/commands/refactor/restructure/index.ts
|
|
16073
16164
|
import path48 from "path";
|
|
16074
|
-
import
|
|
16165
|
+
import chalk164 from "chalk";
|
|
16075
16166
|
|
|
16076
16167
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
16077
16168
|
import path42 from "path";
|
|
@@ -16150,50 +16241,50 @@ function clusterFiles(graph) {
|
|
|
16150
16241
|
|
|
16151
16242
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
16152
16243
|
import path44 from "path";
|
|
16153
|
-
import
|
|
16244
|
+
import chalk162 from "chalk";
|
|
16154
16245
|
function relPath(filePath) {
|
|
16155
16246
|
return path44.relative(process.cwd(), filePath);
|
|
16156
16247
|
}
|
|
16157
16248
|
function displayMoves(plan2) {
|
|
16158
16249
|
if (plan2.moves.length === 0) return;
|
|
16159
|
-
console.log(
|
|
16250
|
+
console.log(chalk162.bold("\nFile moves:"));
|
|
16160
16251
|
for (const move2 of plan2.moves) {
|
|
16161
16252
|
console.log(
|
|
16162
|
-
` ${
|
|
16253
|
+
` ${chalk162.red(relPath(move2.from))} \u2192 ${chalk162.green(relPath(move2.to))}`
|
|
16163
16254
|
);
|
|
16164
|
-
console.log(
|
|
16255
|
+
console.log(chalk162.dim(` ${move2.reason}`));
|
|
16165
16256
|
}
|
|
16166
16257
|
}
|
|
16167
16258
|
function displayRewrites(rewrites) {
|
|
16168
16259
|
if (rewrites.length === 0) return;
|
|
16169
16260
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
16170
|
-
console.log(
|
|
16261
|
+
console.log(chalk162.bold(`
|
|
16171
16262
|
Import rewrites (${affectedFiles.size} files):`));
|
|
16172
16263
|
for (const file of affectedFiles) {
|
|
16173
|
-
console.log(` ${
|
|
16264
|
+
console.log(` ${chalk162.cyan(relPath(file))}:`);
|
|
16174
16265
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
16175
16266
|
(r) => r.file === file
|
|
16176
16267
|
)) {
|
|
16177
16268
|
console.log(
|
|
16178
|
-
` ${
|
|
16269
|
+
` ${chalk162.red(`"${oldSpecifier}"`)} \u2192 ${chalk162.green(`"${newSpecifier}"`)}`
|
|
16179
16270
|
);
|
|
16180
16271
|
}
|
|
16181
16272
|
}
|
|
16182
16273
|
}
|
|
16183
16274
|
function displayPlan2(plan2) {
|
|
16184
16275
|
if (plan2.warnings.length > 0) {
|
|
16185
|
-
console.log(
|
|
16186
|
-
for (const w of plan2.warnings) console.log(
|
|
16276
|
+
console.log(chalk162.yellow("\nWarnings:"));
|
|
16277
|
+
for (const w of plan2.warnings) console.log(chalk162.yellow(` ${w}`));
|
|
16187
16278
|
}
|
|
16188
16279
|
if (plan2.newDirectories.length > 0) {
|
|
16189
|
-
console.log(
|
|
16280
|
+
console.log(chalk162.bold("\nNew directories:"));
|
|
16190
16281
|
for (const dir of plan2.newDirectories)
|
|
16191
|
-
console.log(
|
|
16282
|
+
console.log(chalk162.green(` ${dir}/`));
|
|
16192
16283
|
}
|
|
16193
16284
|
displayMoves(plan2);
|
|
16194
16285
|
displayRewrites(plan2.rewrites);
|
|
16195
16286
|
console.log(
|
|
16196
|
-
|
|
16287
|
+
chalk162.dim(
|
|
16197
16288
|
`
|
|
16198
16289
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
16199
16290
|
)
|
|
@@ -16203,18 +16294,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
16203
16294
|
// src/commands/refactor/restructure/executePlan.ts
|
|
16204
16295
|
import fs27 from "fs";
|
|
16205
16296
|
import path45 from "path";
|
|
16206
|
-
import
|
|
16297
|
+
import chalk163 from "chalk";
|
|
16207
16298
|
function executePlan(plan2) {
|
|
16208
16299
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
16209
16300
|
for (const [file, content] of updatedContents) {
|
|
16210
16301
|
fs27.writeFileSync(file, content, "utf8");
|
|
16211
16302
|
console.log(
|
|
16212
|
-
|
|
16303
|
+
chalk163.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
16213
16304
|
);
|
|
16214
16305
|
}
|
|
16215
16306
|
for (const dir of plan2.newDirectories) {
|
|
16216
16307
|
fs27.mkdirSync(dir, { recursive: true });
|
|
16217
|
-
console.log(
|
|
16308
|
+
console.log(chalk163.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
16218
16309
|
}
|
|
16219
16310
|
for (const move2 of plan2.moves) {
|
|
16220
16311
|
const targetDir = path45.dirname(move2.to);
|
|
@@ -16223,7 +16314,7 @@ function executePlan(plan2) {
|
|
|
16223
16314
|
}
|
|
16224
16315
|
fs27.renameSync(move2.from, move2.to);
|
|
16225
16316
|
console.log(
|
|
16226
|
-
|
|
16317
|
+
chalk163.white(
|
|
16227
16318
|
` Moved ${path45.relative(process.cwd(), move2.from)} \u2192 ${path45.relative(process.cwd(), move2.to)}`
|
|
16228
16319
|
)
|
|
16229
16320
|
);
|
|
@@ -16238,7 +16329,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
16238
16329
|
if (entries.length === 0) {
|
|
16239
16330
|
fs27.rmdirSync(dir);
|
|
16240
16331
|
console.log(
|
|
16241
|
-
|
|
16332
|
+
chalk163.dim(
|
|
16242
16333
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
16243
16334
|
)
|
|
16244
16335
|
);
|
|
@@ -16371,22 +16462,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
16371
16462
|
const targetPattern = pattern2 ?? "src";
|
|
16372
16463
|
const files = findSourceFiles2(targetPattern);
|
|
16373
16464
|
if (files.length === 0) {
|
|
16374
|
-
console.log(
|
|
16465
|
+
console.log(chalk164.yellow("No files found matching pattern"));
|
|
16375
16466
|
return;
|
|
16376
16467
|
}
|
|
16377
16468
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
16378
16469
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
16379
16470
|
if (plan2.moves.length === 0) {
|
|
16380
|
-
console.log(
|
|
16471
|
+
console.log(chalk164.green("No restructuring needed"));
|
|
16381
16472
|
return;
|
|
16382
16473
|
}
|
|
16383
16474
|
displayPlan2(plan2);
|
|
16384
16475
|
if (options2.apply) {
|
|
16385
|
-
console.log(
|
|
16476
|
+
console.log(chalk164.bold("\nApplying changes..."));
|
|
16386
16477
|
executePlan(plan2);
|
|
16387
|
-
console.log(
|
|
16478
|
+
console.log(chalk164.green("\nRestructuring complete"));
|
|
16388
16479
|
} else {
|
|
16389
|
-
console.log(
|
|
16480
|
+
console.log(chalk164.dim("\nDry run. Use --apply to execute."));
|
|
16390
16481
|
}
|
|
16391
16482
|
}
|
|
16392
16483
|
|
|
@@ -16960,18 +17051,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16960
17051
|
}
|
|
16961
17052
|
|
|
16962
17053
|
// src/commands/review/warnOutOfDiff.ts
|
|
16963
|
-
import
|
|
17054
|
+
import chalk165 from "chalk";
|
|
16964
17055
|
function warnOutOfDiff(outOfDiff) {
|
|
16965
17056
|
if (outOfDiff.length === 0) return;
|
|
16966
17057
|
console.warn(
|
|
16967
|
-
|
|
17058
|
+
chalk165.yellow(
|
|
16968
17059
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16969
17060
|
)
|
|
16970
17061
|
);
|
|
16971
17062
|
for (const finding of outOfDiff) {
|
|
16972
17063
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16973
17064
|
console.warn(
|
|
16974
|
-
` ${
|
|
17065
|
+
` ${chalk165.yellow("\xB7")} ${finding.title} ${chalk165.dim(
|
|
16975
17066
|
`(${finding.file}:${range})`
|
|
16976
17067
|
)}`
|
|
16977
17068
|
);
|
|
@@ -16990,18 +17081,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16990
17081
|
}
|
|
16991
17082
|
|
|
16992
17083
|
// src/commands/review/warnUnlocated.ts
|
|
16993
|
-
import
|
|
17084
|
+
import chalk166 from "chalk";
|
|
16994
17085
|
function warnUnlocated(unlocated) {
|
|
16995
17086
|
if (unlocated.length === 0) return;
|
|
16996
17087
|
console.warn(
|
|
16997
|
-
|
|
17088
|
+
chalk166.yellow(
|
|
16998
17089
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
16999
17090
|
)
|
|
17000
17091
|
);
|
|
17001
17092
|
for (const finding of unlocated) {
|
|
17002
|
-
const where = finding.location ||
|
|
17093
|
+
const where = finding.location || chalk166.dim("missing");
|
|
17003
17094
|
console.warn(
|
|
17004
|
-
` ${
|
|
17095
|
+
` ${chalk166.yellow("\xB7")} ${finding.title} ${chalk166.dim(`(${where})`)}`
|
|
17005
17096
|
);
|
|
17006
17097
|
}
|
|
17007
17098
|
}
|
|
@@ -17234,9 +17325,9 @@ var MultiSpinner = class {
|
|
|
17234
17325
|
elapsedPrefix: prefix2
|
|
17235
17326
|
});
|
|
17236
17327
|
}
|
|
17237
|
-
failRemaining(
|
|
17328
|
+
failRemaining(text7) {
|
|
17238
17329
|
for (const entry of this.entries) {
|
|
17239
|
-
if (entry.state === "running") this.resolve(entry, "failed",
|
|
17330
|
+
if (entry.state === "running") this.resolve(entry, "failed", text7);
|
|
17240
17331
|
}
|
|
17241
17332
|
}
|
|
17242
17333
|
add(entry) {
|
|
@@ -17249,14 +17340,14 @@ var MultiSpinner = class {
|
|
|
17249
17340
|
set text(value) {
|
|
17250
17341
|
entry.text = value;
|
|
17251
17342
|
},
|
|
17252
|
-
succeed: (
|
|
17253
|
-
fail: (
|
|
17343
|
+
succeed: (text7) => this.resolve(entry, "succeeded", text7),
|
|
17344
|
+
fail: (text7) => this.resolve(entry, "failed", text7)
|
|
17254
17345
|
};
|
|
17255
17346
|
}
|
|
17256
|
-
resolve(entry, state,
|
|
17347
|
+
resolve(entry, state, text7) {
|
|
17257
17348
|
if (entry.state !== "running") return;
|
|
17258
17349
|
entry.state = state;
|
|
17259
|
-
if (
|
|
17350
|
+
if (text7 !== void 0) entry.text = text7;
|
|
17260
17351
|
entry.elapsedStart = void 0;
|
|
17261
17352
|
this.render();
|
|
17262
17353
|
this.maybeFinish();
|
|
@@ -17331,12 +17422,12 @@ function skippedCodexResult(outputPath) {
|
|
|
17331
17422
|
// src/commands/review/formatReviewerFailure.ts
|
|
17332
17423
|
var FAST_FAIL_MS = 1e3;
|
|
17333
17424
|
var STDOUT_TAIL_LINES = 20;
|
|
17334
|
-
function indent(
|
|
17335
|
-
return
|
|
17425
|
+
function indent(text7) {
|
|
17426
|
+
return text7.split(/\r?\n/).map((line) => ` ${line}`);
|
|
17336
17427
|
}
|
|
17337
|
-
function tailLines(
|
|
17338
|
-
const lines =
|
|
17339
|
-
return lines.length <= maxLines ?
|
|
17428
|
+
function tailLines(text7, maxLines) {
|
|
17429
|
+
const lines = text7.split(/\r?\n/);
|
|
17430
|
+
return lines.length <= maxLines ? text7 : lines.slice(-maxLines).join("\n");
|
|
17340
17431
|
}
|
|
17341
17432
|
function isFastFail(input) {
|
|
17342
17433
|
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
@@ -18173,7 +18264,7 @@ function registerReview(program2) {
|
|
|
18173
18264
|
}
|
|
18174
18265
|
|
|
18175
18266
|
// src/commands/seq/seqAuth.ts
|
|
18176
|
-
import
|
|
18267
|
+
import chalk168 from "chalk";
|
|
18177
18268
|
|
|
18178
18269
|
// src/commands/seq/loadConnections.ts
|
|
18179
18270
|
function loadConnections2() {
|
|
@@ -18202,10 +18293,10 @@ function setDefaultConnection(name) {
|
|
|
18202
18293
|
}
|
|
18203
18294
|
|
|
18204
18295
|
// src/shared/assertUniqueName.ts
|
|
18205
|
-
import
|
|
18296
|
+
import chalk167 from "chalk";
|
|
18206
18297
|
function assertUniqueName(existingNames, name) {
|
|
18207
18298
|
if (existingNames.includes(name)) {
|
|
18208
|
-
console.error(
|
|
18299
|
+
console.error(chalk167.red(`Connection "${name}" already exists.`));
|
|
18209
18300
|
process.exit(1);
|
|
18210
18301
|
}
|
|
18211
18302
|
}
|
|
@@ -18223,16 +18314,16 @@ async function promptConnection2(existingNames) {
|
|
|
18223
18314
|
var seqAuth = createConnectionAuth({
|
|
18224
18315
|
load: loadConnections2,
|
|
18225
18316
|
save: saveConnections2,
|
|
18226
|
-
format: (c) => `${
|
|
18317
|
+
format: (c) => `${chalk168.bold(c.name)} ${c.url}`,
|
|
18227
18318
|
promptNew: promptConnection2,
|
|
18228
18319
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
18229
18320
|
});
|
|
18230
18321
|
|
|
18231
18322
|
// src/commands/seq/seqQuery.ts
|
|
18232
|
-
import
|
|
18323
|
+
import chalk172 from "chalk";
|
|
18233
18324
|
|
|
18234
18325
|
// src/commands/seq/fetchSeq.ts
|
|
18235
|
-
import
|
|
18326
|
+
import chalk169 from "chalk";
|
|
18236
18327
|
async function fetchSeq(conn, path57, params) {
|
|
18237
18328
|
const url = `${conn.url}${path57}?${params}`;
|
|
18238
18329
|
const response = await fetch(url, {
|
|
@@ -18243,7 +18334,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
18243
18334
|
});
|
|
18244
18335
|
if (!response.ok) {
|
|
18245
18336
|
const body = await response.text();
|
|
18246
|
-
console.error(
|
|
18337
|
+
console.error(chalk169.red(`Seq returned ${response.status}: ${body}`));
|
|
18247
18338
|
process.exit(1);
|
|
18248
18339
|
}
|
|
18249
18340
|
return response;
|
|
@@ -18257,8 +18348,8 @@ function filterToSql(filter) {
|
|
|
18257
18348
|
// src/commands/seq/fetchSeqData.ts
|
|
18258
18349
|
function buildDataParams(filter, count7, from, to) {
|
|
18259
18350
|
const sqlFilter = filterToSql(filter);
|
|
18260
|
-
const
|
|
18261
|
-
const params = new URLSearchParams({ q:
|
|
18351
|
+
const sql8 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count7}`;
|
|
18352
|
+
const params = new URLSearchParams({ q: sql8 });
|
|
18262
18353
|
if (from) params.set("rangeStartUtc", from);
|
|
18263
18354
|
if (to) params.set("rangeEndUtc", to);
|
|
18264
18355
|
return params;
|
|
@@ -18302,23 +18393,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
18302
18393
|
}
|
|
18303
18394
|
|
|
18304
18395
|
// src/commands/seq/formatEvent.ts
|
|
18305
|
-
import
|
|
18396
|
+
import chalk170 from "chalk";
|
|
18306
18397
|
function levelColor(level) {
|
|
18307
18398
|
switch (level) {
|
|
18308
18399
|
case "Fatal":
|
|
18309
|
-
return
|
|
18400
|
+
return chalk170.bgRed.white;
|
|
18310
18401
|
case "Error":
|
|
18311
|
-
return
|
|
18402
|
+
return chalk170.red;
|
|
18312
18403
|
case "Warning":
|
|
18313
|
-
return
|
|
18404
|
+
return chalk170.yellow;
|
|
18314
18405
|
case "Information":
|
|
18315
|
-
return
|
|
18406
|
+
return chalk170.cyan;
|
|
18316
18407
|
case "Debug":
|
|
18317
|
-
return
|
|
18408
|
+
return chalk170.gray;
|
|
18318
18409
|
case "Verbose":
|
|
18319
|
-
return
|
|
18410
|
+
return chalk170.dim;
|
|
18320
18411
|
default:
|
|
18321
|
-
return
|
|
18412
|
+
return chalk170.white;
|
|
18322
18413
|
}
|
|
18323
18414
|
}
|
|
18324
18415
|
function levelAbbrev(level) {
|
|
@@ -18359,12 +18450,12 @@ function formatTimestamp(iso) {
|
|
|
18359
18450
|
function formatEvent(event) {
|
|
18360
18451
|
const color = levelColor(event.Level);
|
|
18361
18452
|
const abbrev = levelAbbrev(event.Level);
|
|
18362
|
-
const ts8 =
|
|
18453
|
+
const ts8 = chalk170.dim(formatTimestamp(event.Timestamp));
|
|
18363
18454
|
const msg = renderMessage(event);
|
|
18364
18455
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
18365
18456
|
if (event.Exception) {
|
|
18366
18457
|
for (const line of event.Exception.split("\n")) {
|
|
18367
|
-
lines.push(
|
|
18458
|
+
lines.push(chalk170.red(` ${line}`));
|
|
18368
18459
|
}
|
|
18369
18460
|
}
|
|
18370
18461
|
return lines.join("\n");
|
|
@@ -18397,11 +18488,11 @@ function rejectTimestampFilter(filter) {
|
|
|
18397
18488
|
}
|
|
18398
18489
|
|
|
18399
18490
|
// src/shared/resolveNamedConnection.ts
|
|
18400
|
-
import
|
|
18491
|
+
import chalk171 from "chalk";
|
|
18401
18492
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
18402
18493
|
if (connections.length === 0) {
|
|
18403
18494
|
console.error(
|
|
18404
|
-
|
|
18495
|
+
chalk171.red(
|
|
18405
18496
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
18406
18497
|
)
|
|
18407
18498
|
);
|
|
@@ -18410,7 +18501,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
18410
18501
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
18411
18502
|
const connection = connections.find((c) => c.name === target);
|
|
18412
18503
|
if (!connection) {
|
|
18413
|
-
console.error(
|
|
18504
|
+
console.error(chalk171.red(`${kind} connection "${target}" not found.`));
|
|
18414
18505
|
process.exit(1);
|
|
18415
18506
|
}
|
|
18416
18507
|
return connection;
|
|
@@ -18439,7 +18530,7 @@ async function seqQuery(filter, options2) {
|
|
|
18439
18530
|
new URLSearchParams({ filter, count: String(count7) })
|
|
18440
18531
|
);
|
|
18441
18532
|
if (events.length === 0) {
|
|
18442
|
-
console.log(
|
|
18533
|
+
console.log(chalk172.yellow("No events found."));
|
|
18443
18534
|
return;
|
|
18444
18535
|
}
|
|
18445
18536
|
if (options2.json) {
|
|
@@ -18450,11 +18541,11 @@ async function seqQuery(filter, options2) {
|
|
|
18450
18541
|
for (const event of chronological) {
|
|
18451
18542
|
console.log(formatEvent(event));
|
|
18452
18543
|
}
|
|
18453
|
-
console.log(
|
|
18544
|
+
console.log(chalk172.dim(`
|
|
18454
18545
|
${events.length} events`));
|
|
18455
18546
|
if (events.length >= count7) {
|
|
18456
18547
|
console.log(
|
|
18457
|
-
|
|
18548
|
+
chalk172.yellow(
|
|
18458
18549
|
`Results limited to ${count7}. Use --count to retrieve more.`
|
|
18459
18550
|
)
|
|
18460
18551
|
);
|
|
@@ -18462,10 +18553,10 @@ ${events.length} events`));
|
|
|
18462
18553
|
}
|
|
18463
18554
|
|
|
18464
18555
|
// src/shared/setNamedDefaultConnection.ts
|
|
18465
|
-
import
|
|
18556
|
+
import chalk173 from "chalk";
|
|
18466
18557
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
18467
18558
|
if (!connections.find((c) => c.name === name)) {
|
|
18468
|
-
console.error(
|
|
18559
|
+
console.error(chalk173.red(`Connection "${name}" not found.`));
|
|
18469
18560
|
process.exit(1);
|
|
18470
18561
|
}
|
|
18471
18562
|
setDefault(name);
|
|
@@ -18513,36 +18604,36 @@ function registerSignal(program2) {
|
|
|
18513
18604
|
}
|
|
18514
18605
|
|
|
18515
18606
|
// src/commands/sql/sqlAuth.ts
|
|
18516
|
-
import
|
|
18607
|
+
import chalk175 from "chalk";
|
|
18517
18608
|
|
|
18518
18609
|
// src/commands/sql/loadConnections.ts
|
|
18519
18610
|
function loadConnections3() {
|
|
18520
18611
|
const raw = loadGlobalConfigRaw();
|
|
18521
|
-
const
|
|
18522
|
-
return
|
|
18612
|
+
const sql8 = raw.sql;
|
|
18613
|
+
return sql8?.connections ?? [];
|
|
18523
18614
|
}
|
|
18524
18615
|
function saveConnections3(connections) {
|
|
18525
18616
|
const raw = loadGlobalConfigRaw();
|
|
18526
|
-
const
|
|
18527
|
-
|
|
18528
|
-
raw.sql =
|
|
18617
|
+
const sql8 = raw.sql ?? {};
|
|
18618
|
+
sql8.connections = connections;
|
|
18619
|
+
raw.sql = sql8;
|
|
18529
18620
|
saveGlobalConfig(raw);
|
|
18530
18621
|
}
|
|
18531
18622
|
function getDefaultConnection2() {
|
|
18532
18623
|
const raw = loadGlobalConfigRaw();
|
|
18533
|
-
const
|
|
18534
|
-
return
|
|
18624
|
+
const sql8 = raw.sql;
|
|
18625
|
+
return sql8?.defaultConnection;
|
|
18535
18626
|
}
|
|
18536
18627
|
function setDefaultConnection2(name) {
|
|
18537
18628
|
const raw = loadGlobalConfigRaw();
|
|
18538
|
-
const
|
|
18539
|
-
|
|
18540
|
-
raw.sql =
|
|
18629
|
+
const sql8 = raw.sql ?? {};
|
|
18630
|
+
sql8.defaultConnection = name;
|
|
18631
|
+
raw.sql = sql8;
|
|
18541
18632
|
saveGlobalConfig(raw);
|
|
18542
18633
|
}
|
|
18543
18634
|
|
|
18544
18635
|
// src/commands/sql/promptConnection.ts
|
|
18545
|
-
import
|
|
18636
|
+
import chalk174 from "chalk";
|
|
18546
18637
|
async function promptConnection3(existingNames) {
|
|
18547
18638
|
const name = await promptInput("name", "Connection name:", "default");
|
|
18548
18639
|
assertUniqueName(existingNames, name);
|
|
@@ -18550,7 +18641,7 @@ async function promptConnection3(existingNames) {
|
|
|
18550
18641
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
18551
18642
|
const port = Number.parseInt(portStr, 10);
|
|
18552
18643
|
if (!Number.isFinite(port)) {
|
|
18553
|
-
console.error(
|
|
18644
|
+
console.error(chalk174.red(`Invalid port "${portStr}".`));
|
|
18554
18645
|
process.exit(1);
|
|
18555
18646
|
}
|
|
18556
18647
|
const user = await promptInput("user", "User:");
|
|
@@ -18563,13 +18654,13 @@ async function promptConnection3(existingNames) {
|
|
|
18563
18654
|
var sqlAuth = createConnectionAuth({
|
|
18564
18655
|
load: loadConnections3,
|
|
18565
18656
|
save: saveConnections3,
|
|
18566
|
-
format: (c) => `${
|
|
18657
|
+
format: (c) => `${chalk175.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
18567
18658
|
promptNew: promptConnection3,
|
|
18568
18659
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
18569
18660
|
});
|
|
18570
18661
|
|
|
18571
18662
|
// src/commands/sql/printTable.ts
|
|
18572
|
-
import
|
|
18663
|
+
import chalk176 from "chalk";
|
|
18573
18664
|
function formatCell(value) {
|
|
18574
18665
|
if (value === null || value === void 0) return "";
|
|
18575
18666
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -18578,7 +18669,7 @@ function formatCell(value) {
|
|
|
18578
18669
|
}
|
|
18579
18670
|
function printTable(rows) {
|
|
18580
18671
|
if (rows.length === 0) {
|
|
18581
|
-
console.log(
|
|
18672
|
+
console.log(chalk176.yellow("(no rows)"));
|
|
18582
18673
|
return;
|
|
18583
18674
|
}
|
|
18584
18675
|
const columns = Object.keys(rows[0]);
|
|
@@ -18586,13 +18677,13 @@ function printTable(rows) {
|
|
|
18586
18677
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
18587
18678
|
);
|
|
18588
18679
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
18589
|
-
console.log(
|
|
18590
|
-
console.log(
|
|
18680
|
+
console.log(chalk176.dim(header));
|
|
18681
|
+
console.log(chalk176.dim("-".repeat(header.length)));
|
|
18591
18682
|
for (const row of rows) {
|
|
18592
18683
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
18593
18684
|
console.log(line);
|
|
18594
18685
|
}
|
|
18595
|
-
console.log(
|
|
18686
|
+
console.log(chalk176.dim(`
|
|
18596
18687
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
18597
18688
|
}
|
|
18598
18689
|
|
|
@@ -18652,7 +18743,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
18652
18743
|
}
|
|
18653
18744
|
|
|
18654
18745
|
// src/commands/sql/sqlMutate.ts
|
|
18655
|
-
import
|
|
18746
|
+
import chalk177 from "chalk";
|
|
18656
18747
|
|
|
18657
18748
|
// src/commands/sql/isMutation.ts
|
|
18658
18749
|
var MUTATION_KEYWORDS = [
|
|
@@ -18673,11 +18764,11 @@ var MUTATION_PATTERN = new RegExp(
|
|
|
18673
18764
|
`\\b(${MUTATION_KEYWORDS.join("|")})\\b`,
|
|
18674
18765
|
"i"
|
|
18675
18766
|
);
|
|
18676
|
-
function stripComments(
|
|
18677
|
-
return
|
|
18767
|
+
function stripComments(sql8) {
|
|
18768
|
+
return sql8.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
|
|
18678
18769
|
}
|
|
18679
|
-
function isMutation(
|
|
18680
|
-
const stripped = stripComments(
|
|
18770
|
+
function isMutation(sql8) {
|
|
18771
|
+
const stripped = stripComments(sql8);
|
|
18681
18772
|
if (MUTATION_PATTERN.test(stripped)) return true;
|
|
18682
18773
|
return /\bSELECT\b[\s\S]+\bINTO\s+\w/i.test(stripped);
|
|
18683
18774
|
}
|
|
@@ -18686,7 +18777,7 @@ function isMutation(sql6) {
|
|
|
18686
18777
|
async function sqlMutate(query, connectionName) {
|
|
18687
18778
|
if (!isMutation(query)) {
|
|
18688
18779
|
console.error(
|
|
18689
|
-
|
|
18780
|
+
chalk177.red(
|
|
18690
18781
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18691
18782
|
)
|
|
18692
18783
|
);
|
|
@@ -18696,18 +18787,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18696
18787
|
const pool = await sqlConnect(conn);
|
|
18697
18788
|
try {
|
|
18698
18789
|
const result = await pool.request().query(query);
|
|
18699
|
-
console.log(
|
|
18790
|
+
console.log(chalk177.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18700
18791
|
} finally {
|
|
18701
18792
|
await pool.close();
|
|
18702
18793
|
}
|
|
18703
18794
|
}
|
|
18704
18795
|
|
|
18705
18796
|
// src/commands/sql/sqlQuery.ts
|
|
18706
|
-
import
|
|
18797
|
+
import chalk178 from "chalk";
|
|
18707
18798
|
async function sqlQuery(query, connectionName) {
|
|
18708
18799
|
if (isMutation(query)) {
|
|
18709
18800
|
console.error(
|
|
18710
|
-
|
|
18801
|
+
chalk178.red(
|
|
18711
18802
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18712
18803
|
)
|
|
18713
18804
|
);
|
|
@@ -18722,7 +18813,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18722
18813
|
printTable(rows);
|
|
18723
18814
|
} else {
|
|
18724
18815
|
console.log(
|
|
18725
|
-
|
|
18816
|
+
chalk178.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18726
18817
|
);
|
|
18727
18818
|
}
|
|
18728
18819
|
} finally {
|
|
@@ -18875,8 +18966,8 @@ import {
|
|
|
18875
18966
|
import { basename as basename10, join as join51 } from "path";
|
|
18876
18967
|
|
|
18877
18968
|
// src/commands/transcript/cleanText.ts
|
|
18878
|
-
function cleanText(
|
|
18879
|
-
const words =
|
|
18969
|
+
function cleanText(text7) {
|
|
18970
|
+
const words = text7.split(/\s+/);
|
|
18880
18971
|
const cleaned = [];
|
|
18881
18972
|
for (let i = 0; i < words.length; i++) {
|
|
18882
18973
|
let isRepeat = false;
|
|
@@ -18896,8 +18987,8 @@ function cleanText(text6) {
|
|
|
18896
18987
|
}
|
|
18897
18988
|
|
|
18898
18989
|
// src/commands/transcript/convert/parseVtt/deduplicateCues/removeSubstringDuplicates.ts
|
|
18899
|
-
function normalizeText(
|
|
18900
|
-
return
|
|
18990
|
+
function normalizeText(text7) {
|
|
18991
|
+
return text7.toLowerCase().trim();
|
|
18901
18992
|
}
|
|
18902
18993
|
function checkSubstringRelation(textI, textJ) {
|
|
18903
18994
|
if (textI.includes(textJ) && textI.length > textJ.length)
|
|
@@ -19026,13 +19117,13 @@ function parseTimestampLine(line) {
|
|
|
19026
19117
|
return { startMs: parseTimestamp(startStr), endMs: parseTimestamp(endStr) };
|
|
19027
19118
|
}
|
|
19028
19119
|
function buildCue(startMs, endMs, fullText) {
|
|
19029
|
-
const { speaker, text:
|
|
19030
|
-
return
|
|
19120
|
+
const { speaker, text: text7 } = extractSpeaker(fullText);
|
|
19121
|
+
return text7 ? { startMs, endMs, speaker, text: text7 } : null;
|
|
19031
19122
|
}
|
|
19032
19123
|
function parseCueLine(lines, i) {
|
|
19033
19124
|
const { startMs, endMs } = parseTimestampLine(lines[i]);
|
|
19034
|
-
const { text:
|
|
19035
|
-
return { cue: buildCue(startMs, endMs,
|
|
19125
|
+
const { text: text7, nextIndex: nextIndex2 } = collectTextLines(lines, i + 1);
|
|
19126
|
+
return { cue: buildCue(startMs, endMs, text7), nextIndex: nextIndex2 };
|
|
19036
19127
|
}
|
|
19037
19128
|
function isCueSeparator(line) {
|
|
19038
19129
|
return line.trim().includes("-->");
|
|
@@ -19419,7 +19510,7 @@ function registerVoice(program2) {
|
|
|
19419
19510
|
|
|
19420
19511
|
// src/commands/roam/auth.ts
|
|
19421
19512
|
import { randomBytes } from "crypto";
|
|
19422
|
-
import
|
|
19513
|
+
import chalk179 from "chalk";
|
|
19423
19514
|
|
|
19424
19515
|
// src/commands/roam/waitForCallback.ts
|
|
19425
19516
|
import { createServer as createServer3 } from "http";
|
|
@@ -19503,8 +19594,8 @@ async function exchangeToken(params) {
|
|
|
19503
19594
|
body: body.toString()
|
|
19504
19595
|
});
|
|
19505
19596
|
if (!response.ok) {
|
|
19506
|
-
const
|
|
19507
|
-
throw new Error(`Token exchange failed (${response.status}): ${
|
|
19597
|
+
const text7 = await response.text();
|
|
19598
|
+
throw new Error(`Token exchange failed (${response.status}): ${text7}`);
|
|
19508
19599
|
}
|
|
19509
19600
|
return response.json();
|
|
19510
19601
|
}
|
|
@@ -19550,13 +19641,13 @@ async function auth() {
|
|
|
19550
19641
|
saveGlobalConfig(config);
|
|
19551
19642
|
const state = randomBytes(16).toString("hex");
|
|
19552
19643
|
console.log(
|
|
19553
|
-
|
|
19644
|
+
chalk179.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19554
19645
|
);
|
|
19555
|
-
console.log(
|
|
19556
|
-
console.log(
|
|
19557
|
-
console.log(
|
|
19646
|
+
console.log(chalk179.white("http://localhost:14523/callback\n"));
|
|
19647
|
+
console.log(chalk179.blue("Opening browser for authorization..."));
|
|
19648
|
+
console.log(chalk179.dim("Waiting for authorization callback..."));
|
|
19558
19649
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19559
|
-
console.log(
|
|
19650
|
+
console.log(chalk179.dim("Exchanging code for tokens..."));
|
|
19560
19651
|
const tokens = await exchangeToken({
|
|
19561
19652
|
code,
|
|
19562
19653
|
clientId,
|
|
@@ -19572,7 +19663,7 @@ async function auth() {
|
|
|
19572
19663
|
};
|
|
19573
19664
|
saveGlobalConfig(config);
|
|
19574
19665
|
console.log(
|
|
19575
|
-
|
|
19666
|
+
chalk179.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19576
19667
|
);
|
|
19577
19668
|
}
|
|
19578
19669
|
|
|
@@ -20024,7 +20115,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
20024
20115
|
import { existsSync as existsSync50, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20025
20116
|
import { tmpdir as tmpdir7 } from "os";
|
|
20026
20117
|
import { join as join61, resolve as resolve15 } from "path";
|
|
20027
|
-
import
|
|
20118
|
+
import chalk180 from "chalk";
|
|
20028
20119
|
|
|
20029
20120
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
20030
20121
|
var captureWindowPs1 = `
|
|
@@ -20175,13 +20266,13 @@ function screenshot(processName) {
|
|
|
20175
20266
|
const config = loadConfig();
|
|
20176
20267
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
20177
20268
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
20178
|
-
console.log(
|
|
20269
|
+
console.log(chalk180.gray(`Capturing window for process "${processName}" ...`));
|
|
20179
20270
|
try {
|
|
20180
20271
|
runPowerShellScript(processName, outputPath);
|
|
20181
|
-
console.log(
|
|
20272
|
+
console.log(chalk180.green(`Screenshot saved: ${outputPath}`));
|
|
20182
20273
|
} catch (error) {
|
|
20183
20274
|
const msg = error instanceof Error ? error.message : String(error);
|
|
20184
|
-
console.error(
|
|
20275
|
+
console.error(chalk180.red(`Failed to capture screenshot: ${msg}`));
|
|
20185
20276
|
process.exit(1);
|
|
20186
20277
|
}
|
|
20187
20278
|
}
|
|
@@ -20773,6 +20864,36 @@ function logSpawnedSession(session) {
|
|
|
20773
20864
|
);
|
|
20774
20865
|
}
|
|
20775
20866
|
|
|
20867
|
+
// src/shared/db/recordPhaseActiveMs.ts
|
|
20868
|
+
import { sql as sql6 } from "drizzle-orm";
|
|
20869
|
+
async function recordPhaseActiveMs(db, itemId, phaseIdx, activeMs) {
|
|
20870
|
+
if (activeMs <= 0) return;
|
|
20871
|
+
await db.insert(phaseUsage).values({ itemId, phaseIdx, activeMs }).onConflictDoUpdate({
|
|
20872
|
+
target: [phaseUsage.itemId, phaseUsage.phaseIdx],
|
|
20873
|
+
set: {
|
|
20874
|
+
activeMs: sql6`${phaseUsage.activeMs} + excluded.active_ms`
|
|
20875
|
+
}
|
|
20876
|
+
});
|
|
20877
|
+
}
|
|
20878
|
+
|
|
20879
|
+
// src/commands/sessions/daemon/persistPhaseActiveMs.ts
|
|
20880
|
+
async function persistPhaseActiveMs(itemId, phaseIdx, activeMs) {
|
|
20881
|
+
try {
|
|
20882
|
+
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url) return;
|
|
20883
|
+
await recordPhaseActiveMs(await getDb(), itemId, phaseIdx, activeMs);
|
|
20884
|
+
} catch (error) {
|
|
20885
|
+
daemonLog(`phase-active-ms persist failed: ${String(error)}`);
|
|
20886
|
+
}
|
|
20887
|
+
}
|
|
20888
|
+
|
|
20889
|
+
// src/commands/sessions/daemon/sessionBacklogPhase.ts
|
|
20890
|
+
function sessionBacklogPhase(session) {
|
|
20891
|
+
const activity2 = session.activity;
|
|
20892
|
+
if (activity2?.kind !== "backlog") return void 0;
|
|
20893
|
+
if (activity2.itemId == null || activity2.phase == null) return void 0;
|
|
20894
|
+
return { itemId: activity2.itemId, phaseIdx: activity2.phase - 1 };
|
|
20895
|
+
}
|
|
20896
|
+
|
|
20776
20897
|
// src/commands/sessions/daemon/setStatus.ts
|
|
20777
20898
|
function setStatus2(session, newStatus) {
|
|
20778
20899
|
const now = Date.now();
|
|
@@ -20783,6 +20904,30 @@ function setStatus2(session, newStatus) {
|
|
|
20783
20904
|
session.status = newStatus;
|
|
20784
20905
|
}
|
|
20785
20906
|
|
|
20907
|
+
// src/commands/sessions/daemon/shouldAutoDismiss.ts
|
|
20908
|
+
function shouldAutoDismiss(session, exitCode) {
|
|
20909
|
+
if (session.status !== "done" || exitCode !== 0) {
|
|
20910
|
+
return false;
|
|
20911
|
+
}
|
|
20912
|
+
if (session.reviewStarted) {
|
|
20913
|
+
return session.autoAdvance === true;
|
|
20914
|
+
}
|
|
20915
|
+
const args = session.assistArgs;
|
|
20916
|
+
if (args === void 0) return false;
|
|
20917
|
+
if (args[0] === "update") return true;
|
|
20918
|
+
return args.includes("--once") && args[0] !== "next";
|
|
20919
|
+
}
|
|
20920
|
+
|
|
20921
|
+
// src/commands/sessions/daemon/shouldAutoRun.ts
|
|
20922
|
+
function shouldAutoRun(session, exitCode) {
|
|
20923
|
+
if (!session.autoRun) return false;
|
|
20924
|
+
if (session.status !== "done" || exitCode !== 0) return false;
|
|
20925
|
+
if (session.commandType !== "assist") return false;
|
|
20926
|
+
const cmd = session.assistArgs?.[0];
|
|
20927
|
+
if (cmd !== "draft" && cmd !== "bug" && cmd !== "refine") return false;
|
|
20928
|
+
return session.activity?.itemId != null;
|
|
20929
|
+
}
|
|
20930
|
+
|
|
20786
20931
|
// src/commands/sessions/daemon/watchEscInterrupt.ts
|
|
20787
20932
|
var ESC2 = "\x1B";
|
|
20788
20933
|
var SETTLE_MS = 1e3;
|
|
@@ -20813,35 +20958,22 @@ function disarmEscInterrupt(session) {
|
|
|
20813
20958
|
session.escInterruptTimer = void 0;
|
|
20814
20959
|
}
|
|
20815
20960
|
|
|
20816
|
-
// src/commands/sessions/daemon/shouldAutoDismiss.ts
|
|
20817
|
-
function shouldAutoDismiss(session, exitCode) {
|
|
20818
|
-
if (session.status !== "done" || exitCode !== 0) {
|
|
20819
|
-
return false;
|
|
20820
|
-
}
|
|
20821
|
-
if (session.reviewStarted) {
|
|
20822
|
-
return session.autoAdvance === true;
|
|
20823
|
-
}
|
|
20824
|
-
const args = session.assistArgs;
|
|
20825
|
-
if (args === void 0) return false;
|
|
20826
|
-
if (args[0] === "update") return true;
|
|
20827
|
-
return args.includes("--once") && args[0] !== "next";
|
|
20828
|
-
}
|
|
20829
|
-
|
|
20830
|
-
// src/commands/sessions/daemon/shouldAutoRun.ts
|
|
20831
|
-
function shouldAutoRun(session, exitCode) {
|
|
20832
|
-
if (!session.autoRun) return false;
|
|
20833
|
-
if (session.status !== "done" || exitCode !== 0) return false;
|
|
20834
|
-
if (session.commandType !== "assist") return false;
|
|
20835
|
-
const cmd = session.assistArgs?.[0];
|
|
20836
|
-
if (cmd !== "draft" && cmd !== "bug" && cmd !== "refine") return false;
|
|
20837
|
-
return session.activity?.itemId != null;
|
|
20838
|
-
}
|
|
20839
|
-
|
|
20840
20961
|
// src/commands/sessions/daemon/applyStatusChange.ts
|
|
20962
|
+
function accumulateActiveTime(session) {
|
|
20963
|
+
if (session.status !== "running" || session.runningSince == null) return;
|
|
20964
|
+
const phase = sessionBacklogPhase(session);
|
|
20965
|
+
if (!phase) return;
|
|
20966
|
+
void persistPhaseActiveMs(
|
|
20967
|
+
phase.itemId,
|
|
20968
|
+
phase.phaseIdx,
|
|
20969
|
+
Date.now() - session.runningSince
|
|
20970
|
+
);
|
|
20971
|
+
}
|
|
20841
20972
|
function applyStatusChange(session, status2, exitCode, dismiss, notify2, reuseForRun) {
|
|
20842
20973
|
disarmEscInterrupt(session);
|
|
20843
20974
|
if (session.status === status2) return;
|
|
20844
20975
|
daemonLog(`session ${session.id} status: ${session.status} -> ${status2}`);
|
|
20976
|
+
accumulateActiveTime(session);
|
|
20845
20977
|
setStatus2(session, status2);
|
|
20846
20978
|
if (shouldAutoRun(session, exitCode) && session.activity?.itemId != null) {
|
|
20847
20979
|
reuseForRun(session, session.activity.itemId);
|
|
@@ -20857,6 +20989,41 @@ function makeStatusChangeHandler(dismiss, notify2, reuseForRun) {
|
|
|
20857
20989
|
return (s, status2, exitCode) => applyStatusChange(s, status2, exitCode, dismiss, notify2, reuseForRun);
|
|
20858
20990
|
}
|
|
20859
20991
|
|
|
20992
|
+
// src/shared/db/recordPhaseTokens.ts
|
|
20993
|
+
import { sql as sql7 } from "drizzle-orm";
|
|
20994
|
+
async function recordPhaseTokens(db, itemId, phaseIdx, totalIn, totalOut) {
|
|
20995
|
+
await db.insert(phaseUsage).values({ itemId, phaseIdx, lastTotalIn: totalIn, lastTotalOut: totalOut }).onConflictDoUpdate({
|
|
20996
|
+
target: [phaseUsage.itemId, phaseUsage.phaseIdx],
|
|
20997
|
+
set: {
|
|
20998
|
+
tokensDown: sql7`${phaseUsage.tokensDown} + CASE WHEN ${phaseUsage.lastTotalIn} IS NULL THEN 0 ELSE GREATEST(excluded.last_total_in - ${phaseUsage.lastTotalIn}, 0) END`,
|
|
20999
|
+
tokensUp: sql7`${phaseUsage.tokensUp} + CASE WHEN ${phaseUsage.lastTotalOut} IS NULL THEN 0 ELSE GREATEST(excluded.last_total_out - ${phaseUsage.lastTotalOut}, 0) END`,
|
|
21000
|
+
lastTotalIn: sql7`excluded.last_total_in`,
|
|
21001
|
+
lastTotalOut: sql7`excluded.last_total_out`
|
|
21002
|
+
}
|
|
21003
|
+
});
|
|
21004
|
+
}
|
|
21005
|
+
|
|
21006
|
+
// src/commands/sessions/daemon/persistPhaseTokens.ts
|
|
21007
|
+
async function persistPhaseTokens(itemId, phaseIdx, totalIn, totalOut) {
|
|
21008
|
+
try {
|
|
21009
|
+
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url) return;
|
|
21010
|
+
await recordPhaseTokens(await getDb(), itemId, phaseIdx, totalIn, totalOut);
|
|
21011
|
+
} catch (error) {
|
|
21012
|
+
daemonLog(`phase-tokens persist failed: ${String(error)}`);
|
|
21013
|
+
}
|
|
21014
|
+
}
|
|
21015
|
+
|
|
21016
|
+
// src/commands/sessions/daemon/recordSessionUsage.ts
|
|
21017
|
+
function recordSessionUsage(sessions, claudeSessionId, totalIn, totalOut) {
|
|
21018
|
+
for (const session of sessions) {
|
|
21019
|
+
if (session.claudeSessionId !== claudeSessionId) continue;
|
|
21020
|
+
const phase = sessionBacklogPhase(session);
|
|
21021
|
+
if (phase)
|
|
21022
|
+
void persistPhaseTokens(phase.itemId, phase.phaseIdx, totalIn, totalOut);
|
|
21023
|
+
return;
|
|
21024
|
+
}
|
|
21025
|
+
}
|
|
21026
|
+
|
|
20860
21027
|
// src/commands/sessions/daemon/restoreBase.ts
|
|
20861
21028
|
function restoreBase(id2, persisted) {
|
|
20862
21029
|
return {
|
|
@@ -21953,6 +22120,16 @@ var SessionManager = class {
|
|
|
21953
22120
|
}
|
|
21954
22121
|
this.onStatusChange(session, status2);
|
|
21955
22122
|
}
|
|
22123
|
+
/* why: the status line relays token totals keyed by Claude's session id; join
|
|
22124
|
+
* it to the running backlog phase so the spend accumulates against that row. */
|
|
22125
|
+
recordUsage(claudeSessionId, totalIn, totalOut) {
|
|
22126
|
+
recordSessionUsage(
|
|
22127
|
+
this.sessions.values(),
|
|
22128
|
+
claudeSessionId,
|
|
22129
|
+
totalIn,
|
|
22130
|
+
totalOut
|
|
22131
|
+
);
|
|
22132
|
+
}
|
|
21956
22133
|
listSessions = () => {
|
|
21957
22134
|
const local = [...this.sessions.values()].map(toSessionInfo);
|
|
21958
22135
|
return local.concat(this.windowsProxy.sessions());
|
|
@@ -22009,8 +22186,8 @@ function deriveSessionType(commandName, name) {
|
|
|
22009
22186
|
}
|
|
22010
22187
|
|
|
22011
22188
|
// src/commands/sessions/shared/backlogRunMarkers.ts
|
|
22012
|
-
function backlogRunMarkers(
|
|
22013
|
-
const match =
|
|
22189
|
+
function backlogRunMarkers(text7) {
|
|
22190
|
+
const match = text7.match(/backlog item #(\d+):[ \t]*([^\n]*)/);
|
|
22014
22191
|
if (!match) return { commandName: "", commandArgs: "" };
|
|
22015
22192
|
const title = match[2].trim();
|
|
22016
22193
|
return {
|
|
@@ -22064,11 +22241,11 @@ function messageText(entry) {
|
|
|
22064
22241
|
const content = msg?.content;
|
|
22065
22242
|
return typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
22066
22243
|
}
|
|
22067
|
-
function stripMarkers(
|
|
22068
|
-
return
|
|
22244
|
+
function stripMarkers(text7) {
|
|
22245
|
+
return text7.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
22069
22246
|
}
|
|
22070
|
-
function matchMarker(
|
|
22071
|
-
const match =
|
|
22247
|
+
function matchMarker(text7, tag) {
|
|
22248
|
+
const match = text7.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
|
|
22072
22249
|
return match ? match[1].trim() : "";
|
|
22073
22250
|
}
|
|
22074
22251
|
|
|
@@ -22186,17 +22363,17 @@ function entryMessages(entry) {
|
|
|
22186
22363
|
return [];
|
|
22187
22364
|
}
|
|
22188
22365
|
function userMessages(content) {
|
|
22189
|
-
if (typeof content === "string") return
|
|
22366
|
+
if (typeof content === "string") return text6("user", cleanUserText(content));
|
|
22190
22367
|
if (!Array.isArray(content)) return [];
|
|
22191
|
-
return content.filter((c) => c.type === "text").flatMap((c) =>
|
|
22368
|
+
return content.filter((c) => c.type === "text").flatMap((c) => text6("user", cleanUserText(c.text ?? "")));
|
|
22192
22369
|
}
|
|
22193
22370
|
function assistantMessages(content) {
|
|
22194
|
-
if (typeof content === "string") return
|
|
22371
|
+
if (typeof content === "string") return text6("assistant", content.trim());
|
|
22195
22372
|
if (!Array.isArray(content)) return [];
|
|
22196
22373
|
return content.flatMap((c) => assistantItem(c));
|
|
22197
22374
|
}
|
|
22198
22375
|
function assistantItem(c) {
|
|
22199
|
-
if (c.type === "text") return
|
|
22376
|
+
if (c.type === "text") return text6("assistant", (c.text ?? "").trim());
|
|
22200
22377
|
if (c.type === "tool_use")
|
|
22201
22378
|
return [
|
|
22202
22379
|
{
|
|
@@ -22207,7 +22384,7 @@ function assistantItem(c) {
|
|
|
22207
22384
|
];
|
|
22208
22385
|
return [];
|
|
22209
22386
|
}
|
|
22210
|
-
function
|
|
22387
|
+
function text6(role, value) {
|
|
22211
22388
|
return value ? [{ role, text: value }] : [];
|
|
22212
22389
|
}
|
|
22213
22390
|
function cleanUserText(value) {
|
|
@@ -22330,6 +22507,11 @@ var messageHandlers = {
|
|
|
22330
22507
|
...lifecycleHandlers,
|
|
22331
22508
|
drain: (client, m) => sendTo(client, { type: "drained", count: m.drain() }),
|
|
22332
22509
|
limits: (_client, m, d) => m.clients.updateLimits(d.rateLimits),
|
|
22510
|
+
usage: (_client, m, d) => m.recordUsage(
|
|
22511
|
+
d.claudeSessionId,
|
|
22512
|
+
d.totalIn,
|
|
22513
|
+
d.totalOut
|
|
22514
|
+
),
|
|
22333
22515
|
input: routed(
|
|
22334
22516
|
(_client, m, d) => m.writeToSession(d.sessionId, d.data)
|
|
22335
22517
|
),
|
|
@@ -22535,7 +22717,7 @@ function registerDaemon(program2) {
|
|
|
22535
22717
|
|
|
22536
22718
|
// src/commands/sessions/summarise/index.ts
|
|
22537
22719
|
import * as fs35 from "fs";
|
|
22538
|
-
import
|
|
22720
|
+
import chalk181 from "chalk";
|
|
22539
22721
|
|
|
22540
22722
|
// src/commands/sessions/summarise/shared.ts
|
|
22541
22723
|
import * as fs33 from "fs";
|
|
@@ -22567,16 +22749,16 @@ function parseUserLine(line) {
|
|
|
22567
22749
|
if (entry.type !== "user") return void 0;
|
|
22568
22750
|
const msg = entry.message;
|
|
22569
22751
|
const c = msg?.content;
|
|
22570
|
-
let
|
|
22752
|
+
let text7;
|
|
22571
22753
|
if (typeof c === "string") {
|
|
22572
|
-
|
|
22754
|
+
text7 = c;
|
|
22573
22755
|
} else if (Array.isArray(c)) {
|
|
22574
22756
|
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
22575
|
-
|
|
22757
|
+
text7 = collected || void 0;
|
|
22576
22758
|
}
|
|
22577
|
-
if (!
|
|
22759
|
+
if (!text7) return void 0;
|
|
22578
22760
|
return {
|
|
22579
|
-
text:
|
|
22761
|
+
text: text7,
|
|
22580
22762
|
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
22581
22763
|
};
|
|
22582
22764
|
}
|
|
@@ -22605,13 +22787,13 @@ function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
|
22605
22787
|
|
|
22606
22788
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
22607
22789
|
function extractFirstUserMessage(filePath) {
|
|
22608
|
-
for (const
|
|
22609
|
-
return truncate3(
|
|
22790
|
+
for (const text7 of iterateUserMessages(filePath)) {
|
|
22791
|
+
return truncate3(text7);
|
|
22610
22792
|
}
|
|
22611
22793
|
return void 0;
|
|
22612
22794
|
}
|
|
22613
|
-
function truncate3(
|
|
22614
|
-
const trimmed =
|
|
22795
|
+
function truncate3(text7, maxChars = 500) {
|
|
22796
|
+
const trimmed = text7.trim();
|
|
22615
22797
|
if (trimmed.length <= maxChars) return trimmed;
|
|
22616
22798
|
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
22617
22799
|
}
|
|
@@ -22619,28 +22801,28 @@ function truncate3(text6, maxChars = 500) {
|
|
|
22619
22801
|
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
22620
22802
|
function scanSessionBacklogRefs(filePath) {
|
|
22621
22803
|
const ids = /* @__PURE__ */ new Set();
|
|
22622
|
-
for (const
|
|
22623
|
-
for (const id2 of extractBacklogIds(
|
|
22804
|
+
for (const text7 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
22805
|
+
for (const id2 of extractBacklogIds(text7)) {
|
|
22624
22806
|
ids.add(id2);
|
|
22625
22807
|
}
|
|
22626
22808
|
}
|
|
22627
22809
|
return [...ids].sort((a, b) => a - b);
|
|
22628
22810
|
}
|
|
22629
|
-
function extractBacklogIds(
|
|
22811
|
+
function extractBacklogIds(text7) {
|
|
22630
22812
|
const ids = [];
|
|
22631
|
-
for (const m of
|
|
22813
|
+
for (const m of text7.matchAll(/backlog\s+run\s+(\d+)/gi)) {
|
|
22632
22814
|
ids.push(Number.parseInt(m[1], 10));
|
|
22633
22815
|
}
|
|
22634
|
-
for (const m of
|
|
22816
|
+
for (const m of text7.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
|
|
22635
22817
|
ids.push(Number.parseInt(m[1], 10));
|
|
22636
22818
|
}
|
|
22637
|
-
for (const m of
|
|
22819
|
+
for (const m of text7.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
|
|
22638
22820
|
ids.push(Number.parseInt(m[1], 10));
|
|
22639
22821
|
}
|
|
22640
|
-
for (const m of
|
|
22822
|
+
for (const m of text7.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
|
|
22641
22823
|
ids.push(Number.parseInt(m[1], 10));
|
|
22642
22824
|
}
|
|
22643
|
-
for (const m of
|
|
22825
|
+
for (const m of text7.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
22644
22826
|
ids.push(Number.parseInt(m[1], 10));
|
|
22645
22827
|
}
|
|
22646
22828
|
return ids;
|
|
@@ -22689,22 +22871,22 @@ ${firstMessage}`);
|
|
|
22689
22871
|
async function summarise2(options2) {
|
|
22690
22872
|
const files = await discoverSessionFiles();
|
|
22691
22873
|
if (files.length === 0) {
|
|
22692
|
-
console.log(
|
|
22874
|
+
console.log(chalk181.yellow("No sessions found."));
|
|
22693
22875
|
return;
|
|
22694
22876
|
}
|
|
22695
22877
|
const toProcess = selectCandidates(files, options2);
|
|
22696
22878
|
if (toProcess.length === 0) {
|
|
22697
|
-
console.log(
|
|
22879
|
+
console.log(chalk181.green("All sessions already summarised."));
|
|
22698
22880
|
return;
|
|
22699
22881
|
}
|
|
22700
22882
|
console.log(
|
|
22701
|
-
|
|
22883
|
+
chalk181.cyan(
|
|
22702
22884
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22703
22885
|
)
|
|
22704
22886
|
);
|
|
22705
22887
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22706
22888
|
console.log(
|
|
22707
|
-
|
|
22889
|
+
chalk181.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk181.yellow(`, ${failed2} skipped`) : "")
|
|
22708
22890
|
);
|
|
22709
22891
|
}
|
|
22710
22892
|
function selectCandidates(files, options2) {
|
|
@@ -22724,16 +22906,16 @@ function processSessions(files) {
|
|
|
22724
22906
|
let failed2 = 0;
|
|
22725
22907
|
for (let i = 0; i < files.length; i++) {
|
|
22726
22908
|
const file = files[i];
|
|
22727
|
-
process.stdout.write(
|
|
22909
|
+
process.stdout.write(chalk181.dim(` [${i + 1}/${files.length}] `));
|
|
22728
22910
|
const summary = summariseSession(file);
|
|
22729
22911
|
if (summary) {
|
|
22730
22912
|
writeSummary(file, summary);
|
|
22731
22913
|
succeeded++;
|
|
22732
|
-
process.stdout.write(`${
|
|
22914
|
+
process.stdout.write(`${chalk181.green("\u2713")} ${summary}
|
|
22733
22915
|
`);
|
|
22734
22916
|
} else {
|
|
22735
22917
|
failed2++;
|
|
22736
|
-
process.stdout.write(` ${
|
|
22918
|
+
process.stdout.write(` ${chalk181.yellow("skip")}
|
|
22737
22919
|
`);
|
|
22738
22920
|
}
|
|
22739
22921
|
}
|
|
@@ -22751,10 +22933,10 @@ function registerSessions(program2) {
|
|
|
22751
22933
|
}
|
|
22752
22934
|
|
|
22753
22935
|
// src/commands/statusLine.ts
|
|
22754
|
-
import
|
|
22936
|
+
import chalk183 from "chalk";
|
|
22755
22937
|
|
|
22756
22938
|
// src/commands/buildLimitsSegment.ts
|
|
22757
|
-
import
|
|
22939
|
+
import chalk182 from "chalk";
|
|
22758
22940
|
|
|
22759
22941
|
// src/shared/rateLimitLevel.ts
|
|
22760
22942
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22785,9 +22967,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22785
22967
|
|
|
22786
22968
|
// src/commands/buildLimitsSegment.ts
|
|
22787
22969
|
var LEVEL_COLOR = {
|
|
22788
|
-
ok:
|
|
22789
|
-
warn:
|
|
22790
|
-
over:
|
|
22970
|
+
ok: chalk182.green,
|
|
22971
|
+
warn: chalk182.yellow,
|
|
22972
|
+
over: chalk182.red
|
|
22791
22973
|
};
|
|
22792
22974
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22793
22975
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22826,15 +23008,24 @@ async function relayRateLimits(rateLimits) {
|
|
|
22826
23008
|
}
|
|
22827
23009
|
}
|
|
22828
23010
|
|
|
23011
|
+
// src/commands/relayUsage.ts
|
|
23012
|
+
async function relayUsage(claudeSessionId, totalIn, totalOut) {
|
|
23013
|
+
if (!claudeSessionId) return;
|
|
23014
|
+
try {
|
|
23015
|
+
await sendToDaemon({ type: "usage", claudeSessionId, totalIn, totalOut });
|
|
23016
|
+
} catch {
|
|
23017
|
+
}
|
|
23018
|
+
}
|
|
23019
|
+
|
|
22829
23020
|
// src/commands/statusLine.ts
|
|
22830
|
-
|
|
23021
|
+
chalk183.level = 3;
|
|
22831
23022
|
function formatNumber(num) {
|
|
22832
23023
|
return num.toLocaleString("en-US");
|
|
22833
23024
|
}
|
|
22834
23025
|
function colorizePercent(pct) {
|
|
22835
23026
|
const label2 = `${Math.round(pct)}%`;
|
|
22836
|
-
if (pct > 80) return
|
|
22837
|
-
if (pct > 40) return
|
|
23027
|
+
if (pct > 80) return chalk183.red(label2);
|
|
23028
|
+
if (pct > 40) return chalk183.yellow(label2);
|
|
22838
23029
|
return label2;
|
|
22839
23030
|
}
|
|
22840
23031
|
async function statusLine() {
|
|
@@ -22847,6 +23038,7 @@ async function statusLine() {
|
|
|
22847
23038
|
`${model} | Tokens - ${formatNumber(totalOut)} \u2191 : ${formatNumber(totalIn)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
|
|
22848
23039
|
);
|
|
22849
23040
|
await relayRateLimits(data.rate_limits);
|
|
23041
|
+
await relayUsage(data.session_id, totalIn, totalOut);
|
|
22850
23042
|
}
|
|
22851
23043
|
|
|
22852
23044
|
// src/commands/sync.ts
|
|
@@ -22858,7 +23050,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
22858
23050
|
// src/commands/sync/syncClaudeMd.ts
|
|
22859
23051
|
import * as fs36 from "fs";
|
|
22860
23052
|
import * as path53 from "path";
|
|
22861
|
-
import
|
|
23053
|
+
import chalk184 from "chalk";
|
|
22862
23054
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22863
23055
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22864
23056
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
@@ -22867,12 +23059,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22867
23059
|
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22868
23060
|
if (sourceContent !== targetContent) {
|
|
22869
23061
|
console.log(
|
|
22870
|
-
|
|
23062
|
+
chalk184.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22871
23063
|
);
|
|
22872
23064
|
console.log();
|
|
22873
23065
|
printDiff(targetContent, sourceContent);
|
|
22874
23066
|
const confirm = options2?.yes || await promptConfirm(
|
|
22875
|
-
|
|
23067
|
+
chalk184.red("Overwrite existing CLAUDE.md?"),
|
|
22876
23068
|
false
|
|
22877
23069
|
);
|
|
22878
23070
|
if (!confirm) {
|
|
@@ -22888,7 +23080,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22888
23080
|
// src/commands/sync/syncSettings.ts
|
|
22889
23081
|
import * as fs37 from "fs";
|
|
22890
23082
|
import * as path54 from "path";
|
|
22891
|
-
import
|
|
23083
|
+
import chalk185 from "chalk";
|
|
22892
23084
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22893
23085
|
const source = path54.join(claudeDir, "settings.json");
|
|
22894
23086
|
const target = path54.join(targetBase, "settings.json");
|
|
@@ -22904,14 +23096,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22904
23096
|
if (mergedContent !== normalizedTarget) {
|
|
22905
23097
|
if (!options2?.yes) {
|
|
22906
23098
|
console.log(
|
|
22907
|
-
|
|
23099
|
+
chalk185.yellow(
|
|
22908
23100
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22909
23101
|
)
|
|
22910
23102
|
);
|
|
22911
23103
|
console.log();
|
|
22912
23104
|
printDiff(targetContent, mergedContent);
|
|
22913
23105
|
const confirm = await promptConfirm(
|
|
22914
|
-
|
|
23106
|
+
chalk185.red("Overwrite existing settings.json?"),
|
|
22915
23107
|
false
|
|
22916
23108
|
);
|
|
22917
23109
|
if (!confirm) {
|