@staff0rd/assist 0.342.2 → 0.344.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 +889 -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.344.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"
|
|
@@ -6200,9 +6262,9 @@ function excerpt(xml, ...tags) {
|
|
|
6200
6262
|
for (const tag of tags) {
|
|
6201
6263
|
const raw = extractText(xml, tag);
|
|
6202
6264
|
if (!raw) continue;
|
|
6203
|
-
const
|
|
6204
|
-
if (
|
|
6205
|
-
return `${
|
|
6265
|
+
const text7 = stripHtml(raw);
|
|
6266
|
+
if (text7.length <= MAX_EXCERPT) return text7;
|
|
6267
|
+
return `${text7.slice(0, MAX_EXCERPT)}\u2026`;
|
|
6206
6268
|
}
|
|
6207
6269
|
return "";
|
|
6208
6270
|
}
|
|
@@ -7005,10 +7067,10 @@ function registerAssociateJiraCommand(cmd) {
|
|
|
7005
7067
|
|
|
7006
7068
|
// src/commands/backlog/comment/index.ts
|
|
7007
7069
|
import chalk58 from "chalk";
|
|
7008
|
-
async function comment(id2,
|
|
7070
|
+
async function comment(id2, text7) {
|
|
7009
7071
|
const found = await findOneItem(id2);
|
|
7010
7072
|
if (!found) process.exit(1);
|
|
7011
|
-
await appendComment(found.orm, found.item.id,
|
|
7073
|
+
await appendComment(found.orm, found.item.id, text7);
|
|
7012
7074
|
console.log(chalk58.green(`Comment added to item #${id2}.`));
|
|
7013
7075
|
}
|
|
7014
7076
|
|
|
@@ -7102,9 +7164,9 @@ function readLine(dump, start3) {
|
|
|
7102
7164
|
return { text: dump.subarray(start3, eol).toString("utf8"), next: eol + 1 };
|
|
7103
7165
|
}
|
|
7104
7166
|
function parseHeader(dump) {
|
|
7105
|
-
const { text:
|
|
7167
|
+
const { text: text7, next: next3 } = readLine(dump, 0);
|
|
7106
7168
|
try {
|
|
7107
|
-
return { header: JSON.parse(
|
|
7169
|
+
return { header: JSON.parse(text7), bodyStart: next3 };
|
|
7108
7170
|
} catch {
|
|
7109
7171
|
return invalid("header is not valid JSON.");
|
|
7110
7172
|
}
|
|
@@ -7113,9 +7175,9 @@ function parseSections(dump, bodyStart) {
|
|
|
7113
7175
|
const sections = /* @__PURE__ */ new Map();
|
|
7114
7176
|
let cursor = bodyStart;
|
|
7115
7177
|
while (cursor < dump.length) {
|
|
7116
|
-
const { text:
|
|
7117
|
-
const match =
|
|
7118
|
-
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}".`);
|
|
7119
7181
|
const [, name, bytes] = match;
|
|
7120
7182
|
const end = next3 + Number(bytes);
|
|
7121
7183
|
if (end > dump.length) invalid(`section "${name}" overruns the dump.`);
|
|
@@ -7191,8 +7253,8 @@ async function readStdinBuffer() {
|
|
|
7191
7253
|
import { finished } from "stream/promises";
|
|
7192
7254
|
import { from as copyFrom } from "pg-copy-streams";
|
|
7193
7255
|
async function copyTableIn(client, table, data) {
|
|
7194
|
-
const
|
|
7195
|
-
const stream = client.query(copyFrom(
|
|
7256
|
+
const sql8 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
|
|
7257
|
+
const stream = client.query(copyFrom(sql8));
|
|
7196
7258
|
stream.end(data);
|
|
7197
7259
|
await finished(stream);
|
|
7198
7260
|
}
|
|
@@ -7237,8 +7299,8 @@ async function replaceData(client, parsed) {
|
|
|
7237
7299
|
await copyTableIn(client, table, data);
|
|
7238
7300
|
}
|
|
7239
7301
|
for (const col of await introspectIdentityColumns(client)) {
|
|
7240
|
-
const { text:
|
|
7241
|
-
await client.query(
|
|
7302
|
+
const { text: text7, values } = resyncIdentitySql(col);
|
|
7303
|
+
await client.query(text7, values);
|
|
7242
7304
|
}
|
|
7243
7305
|
}
|
|
7244
7306
|
async function restore(client, parsed) {
|
|
@@ -8049,15 +8111,39 @@ async function done(id2, summary) {
|
|
|
8049
8111
|
console.log(chalk78.green(`Completed item #${id2}: ${item.name}`));
|
|
8050
8112
|
}
|
|
8051
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
|
+
|
|
8052
8138
|
// src/commands/backlog/star/index.ts
|
|
8053
|
-
import
|
|
8139
|
+
import chalk81 from "chalk";
|
|
8054
8140
|
|
|
8055
8141
|
// src/commands/backlog/setStarred.ts
|
|
8056
|
-
import
|
|
8142
|
+
import chalk80 from "chalk";
|
|
8057
8143
|
async function setStarred(id2, starred) {
|
|
8058
8144
|
const { orm } = await getReady();
|
|
8059
8145
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
8060
|
-
if (name === void 0) console.log(
|
|
8146
|
+
if (name === void 0) console.log(chalk80.red(`Item #${id2} not found.`));
|
|
8061
8147
|
return name;
|
|
8062
8148
|
}
|
|
8063
8149
|
|
|
@@ -8065,45 +8151,45 @@ async function setStarred(id2, starred) {
|
|
|
8065
8151
|
async function star(id2) {
|
|
8066
8152
|
const name = await setStarred(id2, true);
|
|
8067
8153
|
if (name) {
|
|
8068
|
-
console.log(
|
|
8154
|
+
console.log(chalk81.green(`Starred item #${id2}: ${name}`));
|
|
8069
8155
|
}
|
|
8070
8156
|
}
|
|
8071
8157
|
|
|
8072
8158
|
// src/commands/backlog/start/index.ts
|
|
8073
|
-
import
|
|
8159
|
+
import chalk82 from "chalk";
|
|
8074
8160
|
async function start(id2) {
|
|
8075
8161
|
const name = await setStatus(id2, "in-progress");
|
|
8076
8162
|
if (name) {
|
|
8077
|
-
console.log(
|
|
8163
|
+
console.log(chalk82.green(`Started item #${id2}: ${name}`));
|
|
8078
8164
|
}
|
|
8079
8165
|
}
|
|
8080
8166
|
|
|
8081
8167
|
// src/commands/backlog/stop/index.ts
|
|
8082
|
-
import
|
|
8168
|
+
import chalk83 from "chalk";
|
|
8083
8169
|
import { and as and7, eq as eq25 } from "drizzle-orm";
|
|
8084
8170
|
async function stop() {
|
|
8085
8171
|
const { orm } = await getReady();
|
|
8086
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 });
|
|
8087
8173
|
if (stopped.length === 0) {
|
|
8088
|
-
console.log(
|
|
8174
|
+
console.log(chalk83.yellow("No in-progress items to stop."));
|
|
8089
8175
|
return;
|
|
8090
8176
|
}
|
|
8091
8177
|
for (const item of stopped) {
|
|
8092
|
-
console.log(
|
|
8178
|
+
console.log(chalk83.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
8093
8179
|
}
|
|
8094
8180
|
}
|
|
8095
8181
|
|
|
8096
8182
|
// src/commands/backlog/unstar/index.ts
|
|
8097
|
-
import
|
|
8183
|
+
import chalk84 from "chalk";
|
|
8098
8184
|
async function unstar(id2) {
|
|
8099
8185
|
const name = await setStarred(id2, false);
|
|
8100
8186
|
if (name) {
|
|
8101
|
-
console.log(
|
|
8187
|
+
console.log(chalk84.green(`Unstarred item #${id2}: ${name}`));
|
|
8102
8188
|
}
|
|
8103
8189
|
}
|
|
8104
8190
|
|
|
8105
8191
|
// src/commands/backlog/wontdo/index.ts
|
|
8106
|
-
import
|
|
8192
|
+
import chalk85 from "chalk";
|
|
8107
8193
|
async function wontdo(id2, reason) {
|
|
8108
8194
|
const found = await findOneItem(id2);
|
|
8109
8195
|
if (!found) return;
|
|
@@ -8113,7 +8199,7 @@ async function wontdo(id2, reason) {
|
|
|
8113
8199
|
const phase = item.currentPhase ?? 1;
|
|
8114
8200
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
8115
8201
|
}
|
|
8116
|
-
console.log(
|
|
8202
|
+
console.log(chalk85.red(`Won't do item #${id2}: ${item.name}`));
|
|
8117
8203
|
}
|
|
8118
8204
|
|
|
8119
8205
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -8122,17 +8208,20 @@ function registerStatusCommands(cmd) {
|
|
|
8122
8208
|
cmd.command("stop").description("Revert all in-progress backlog items to todo").action(stop);
|
|
8123
8209
|
cmd.command("done <id> [summary]").description("Set a backlog item to done").action(done);
|
|
8124
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);
|
|
8125
8214
|
cmd.command("star <id>").description("Star a backlog item to pin it in the web view").action(star);
|
|
8126
8215
|
cmd.command("unstar <id>").description("Remove the star from a backlog item").action(unstar);
|
|
8127
8216
|
cmd.command("delete <id>").alias("remove").description("Delete a backlog item").action(del);
|
|
8128
8217
|
}
|
|
8129
8218
|
|
|
8130
8219
|
// src/commands/backlog/removePhase.ts
|
|
8131
|
-
import
|
|
8220
|
+
import chalk87 from "chalk";
|
|
8132
8221
|
import { and as and10, eq as eq28 } from "drizzle-orm";
|
|
8133
8222
|
|
|
8134
8223
|
// src/commands/backlog/findPhase.ts
|
|
8135
|
-
import
|
|
8224
|
+
import chalk86 from "chalk";
|
|
8136
8225
|
import { and as and8, count as count5, eq as eq26 } from "drizzle-orm";
|
|
8137
8226
|
async function findPhase(id2, phase) {
|
|
8138
8227
|
const found = await findOneItem(id2);
|
|
@@ -8143,7 +8232,7 @@ async function findPhase(id2, phase) {
|
|
|
8143
8232
|
const [row] = await orm.select({ cnt: count5() }).from(planPhases).where(and8(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
|
|
8144
8233
|
if (!row || row.cnt === 0) {
|
|
8145
8234
|
console.log(
|
|
8146
|
-
|
|
8235
|
+
chalk86.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
8147
8236
|
);
|
|
8148
8237
|
process.exitCode = 1;
|
|
8149
8238
|
return void 0;
|
|
@@ -8190,12 +8279,12 @@ async function removePhase(id2, phase) {
|
|
|
8190
8279
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
8191
8280
|
});
|
|
8192
8281
|
console.log(
|
|
8193
|
-
|
|
8282
|
+
chalk87.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
8194
8283
|
);
|
|
8195
8284
|
}
|
|
8196
8285
|
|
|
8197
8286
|
// src/commands/backlog/update/index.ts
|
|
8198
|
-
import
|
|
8287
|
+
import chalk89 from "chalk";
|
|
8199
8288
|
import { eq as eq29 } from "drizzle-orm";
|
|
8200
8289
|
|
|
8201
8290
|
// src/commands/backlog/update/parseListIndex.ts
|
|
@@ -8271,16 +8360,16 @@ function applyAcMutations(current, options2) {
|
|
|
8271
8360
|
}
|
|
8272
8361
|
|
|
8273
8362
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
8274
|
-
import
|
|
8363
|
+
import chalk88 from "chalk";
|
|
8275
8364
|
function buildUpdateValues(options2) {
|
|
8276
8365
|
const { name, desc: desc6, type, ac } = options2;
|
|
8277
8366
|
if (!name && !desc6 && !type && !ac) {
|
|
8278
|
-
console.log(
|
|
8367
|
+
console.log(chalk88.red("Nothing to update. Provide at least one flag."));
|
|
8279
8368
|
process.exitCode = 1;
|
|
8280
8369
|
return void 0;
|
|
8281
8370
|
}
|
|
8282
8371
|
if (type && type !== "story" && type !== "bug") {
|
|
8283
|
-
console.log(
|
|
8372
|
+
console.log(chalk88.red('Invalid type. Must be "story" or "bug".'));
|
|
8284
8373
|
process.exitCode = 1;
|
|
8285
8374
|
return void 0;
|
|
8286
8375
|
}
|
|
@@ -8313,14 +8402,14 @@ async function update(id2, options2) {
|
|
|
8313
8402
|
if (hasAcMutations(options2)) {
|
|
8314
8403
|
if (options2.ac) {
|
|
8315
8404
|
console.log(
|
|
8316
|
-
|
|
8405
|
+
chalk89.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8317
8406
|
);
|
|
8318
8407
|
process.exitCode = 1;
|
|
8319
8408
|
return;
|
|
8320
8409
|
}
|
|
8321
8410
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8322
8411
|
if (!mutation.ok) {
|
|
8323
|
-
console.log(
|
|
8412
|
+
console.log(chalk89.red(mutation.error));
|
|
8324
8413
|
process.exitCode = 1;
|
|
8325
8414
|
return;
|
|
8326
8415
|
}
|
|
@@ -8331,11 +8420,11 @@ async function update(id2, options2) {
|
|
|
8331
8420
|
const { orm } = found;
|
|
8332
8421
|
const itemId = found.item.id;
|
|
8333
8422
|
await orm.update(items).set(built.set).where(eq29(items.id, itemId));
|
|
8334
|
-
console.log(
|
|
8423
|
+
console.log(chalk89.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
8335
8424
|
}
|
|
8336
8425
|
|
|
8337
8426
|
// src/commands/backlog/updatePhase.ts
|
|
8338
|
-
import
|
|
8427
|
+
import chalk90 from "chalk";
|
|
8339
8428
|
|
|
8340
8429
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8341
8430
|
import { and as and11, eq as eq30 } from "drizzle-orm";
|
|
@@ -8439,7 +8528,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8439
8528
|
const { item, orm, itemId, phaseIdx } = found;
|
|
8440
8529
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
8441
8530
|
if (!resolved.ok) {
|
|
8442
|
-
console.log(
|
|
8531
|
+
console.log(chalk90.red(resolved.error));
|
|
8443
8532
|
process.exitCode = 1;
|
|
8444
8533
|
return;
|
|
8445
8534
|
}
|
|
@@ -8451,7 +8540,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
8451
8540
|
manualCheck && "manual checks"
|
|
8452
8541
|
].filter(Boolean).join(", ");
|
|
8453
8542
|
console.log(
|
|
8454
|
-
|
|
8543
|
+
chalk90.green(
|
|
8455
8544
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8456
8545
|
)
|
|
8457
8546
|
);
|
|
@@ -8666,8 +8755,8 @@ var RAW_BUILTIN_DENIES = BUILTIN_DENIES.map((rule) => ({
|
|
|
8666
8755
|
...rule,
|
|
8667
8756
|
regex: rawDenyRegex(rule.pattern)
|
|
8668
8757
|
}));
|
|
8669
|
-
function matchBuiltinDeny(
|
|
8670
|
-
return RAW_BUILTIN_DENIES.find((rule) => rule.regex.test(
|
|
8758
|
+
function matchBuiltinDeny(text7) {
|
|
8759
|
+
return RAW_BUILTIN_DENIES.find((rule) => rule.regex.test(text7));
|
|
8671
8760
|
}
|
|
8672
8761
|
function toDecision(rule) {
|
|
8673
8762
|
if (!rule) return void 0;
|
|
@@ -9184,11 +9273,11 @@ function assertCliExists(cli) {
|
|
|
9184
9273
|
}
|
|
9185
9274
|
|
|
9186
9275
|
// src/commands/permitCliReads/colorize.ts
|
|
9187
|
-
import
|
|
9276
|
+
import chalk91 from "chalk";
|
|
9188
9277
|
function colorize(plainOutput) {
|
|
9189
9278
|
return plainOutput.split("\n").map((line) => {
|
|
9190
|
-
if (line.startsWith(" R ")) return
|
|
9191
|
-
if (line.startsWith(" W ")) return
|
|
9279
|
+
if (line.startsWith(" R ")) return chalk91.green(line);
|
|
9280
|
+
if (line.startsWith(" W ")) return chalk91.red(line);
|
|
9192
9281
|
return line;
|
|
9193
9282
|
}).join("\n");
|
|
9194
9283
|
}
|
|
@@ -9407,8 +9496,8 @@ function formatHuman(cli, commands) {
|
|
|
9407
9496
|
`];
|
|
9408
9497
|
for (const cmd of sorted) {
|
|
9409
9498
|
const full = `${cli} ${cmd.path.join(" ")}`;
|
|
9410
|
-
const
|
|
9411
|
-
lines.push(`${prefix(classifyVerb(cmd.path))}${
|
|
9499
|
+
const text7 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
|
|
9500
|
+
lines.push(`${prefix(classifyVerb(cmd.path))}${text7}`);
|
|
9412
9501
|
}
|
|
9413
9502
|
return lines.join("\n");
|
|
9414
9503
|
}
|
|
@@ -9486,7 +9575,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
9486
9575
|
}
|
|
9487
9576
|
|
|
9488
9577
|
// src/commands/deny/denyAdd.ts
|
|
9489
|
-
import
|
|
9578
|
+
import chalk92 from "chalk";
|
|
9490
9579
|
|
|
9491
9580
|
// src/commands/deny/loadDenyConfig.ts
|
|
9492
9581
|
function loadDenyConfig(global) {
|
|
@@ -9506,16 +9595,16 @@ function loadDenyConfig(global) {
|
|
|
9506
9595
|
function denyAdd(pattern2, message, options2) {
|
|
9507
9596
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9508
9597
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
9509
|
-
console.log(
|
|
9598
|
+
console.log(chalk92.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
9510
9599
|
return;
|
|
9511
9600
|
}
|
|
9512
9601
|
deny.push({ pattern: pattern2, message });
|
|
9513
9602
|
saveDeny(deny);
|
|
9514
|
-
console.log(
|
|
9603
|
+
console.log(chalk92.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
9515
9604
|
}
|
|
9516
9605
|
|
|
9517
9606
|
// src/commands/deny/denyList.ts
|
|
9518
|
-
import
|
|
9607
|
+
import chalk93 from "chalk";
|
|
9519
9608
|
function denyList() {
|
|
9520
9609
|
const globalRaw = loadGlobalConfigRaw();
|
|
9521
9610
|
const projectRaw = loadProjectConfig();
|
|
@@ -9526,7 +9615,7 @@ function denyList() {
|
|
|
9526
9615
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
9527
9616
|
);
|
|
9528
9617
|
if (!merged || merged.length === 0) {
|
|
9529
|
-
console.log(
|
|
9618
|
+
console.log(chalk93.dim("No deny rules configured."));
|
|
9530
9619
|
return;
|
|
9531
9620
|
}
|
|
9532
9621
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -9534,23 +9623,23 @@ function denyList() {
|
|
|
9534
9623
|
for (const rule of merged) {
|
|
9535
9624
|
const inProject = projectPatterns.has(rule.pattern);
|
|
9536
9625
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
9537
|
-
const label2 = inProject && inGlobal ?
|
|
9538
|
-
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}`);
|
|
9539
9628
|
}
|
|
9540
9629
|
}
|
|
9541
9630
|
|
|
9542
9631
|
// src/commands/deny/denyRemove.ts
|
|
9543
|
-
import
|
|
9632
|
+
import chalk94 from "chalk";
|
|
9544
9633
|
function denyRemove(pattern2, options2) {
|
|
9545
9634
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
9546
9635
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
9547
9636
|
if (index3 === -1) {
|
|
9548
|
-
console.log(
|
|
9637
|
+
console.log(chalk94.yellow(`No deny rule found for: ${pattern2}`));
|
|
9549
9638
|
return;
|
|
9550
9639
|
}
|
|
9551
9640
|
deny.splice(index3, 1);
|
|
9552
9641
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
9553
|
-
console.log(
|
|
9642
|
+
console.log(chalk94.green(`Removed deny rule: ${pattern2}`));
|
|
9554
9643
|
}
|
|
9555
9644
|
|
|
9556
9645
|
// src/commands/registerDeny.ts
|
|
@@ -9580,7 +9669,7 @@ function registerCliHook(program2) {
|
|
|
9580
9669
|
|
|
9581
9670
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9582
9671
|
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9583
|
-
import
|
|
9672
|
+
import chalk95 from "chalk";
|
|
9584
9673
|
|
|
9585
9674
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
9586
9675
|
import { homedir as homedir13 } from "os";
|
|
@@ -9630,12 +9719,12 @@ function codeCommentConfirm(pin) {
|
|
|
9630
9719
|
sweepRestrictedDir();
|
|
9631
9720
|
const state = readPinState(pin);
|
|
9632
9721
|
if (!state) {
|
|
9633
|
-
console.error(
|
|
9722
|
+
console.error(chalk95.red(`No pending comment for pin: ${pin}`));
|
|
9634
9723
|
process.exitCode = 1;
|
|
9635
9724
|
return;
|
|
9636
9725
|
}
|
|
9637
9726
|
if (!existsSync28(state.file)) {
|
|
9638
|
-
console.error(
|
|
9727
|
+
console.error(chalk95.red(`Target file no longer exists: ${state.file}`));
|
|
9639
9728
|
process.exitCode = 1;
|
|
9640
9729
|
return;
|
|
9641
9730
|
}
|
|
@@ -9644,7 +9733,7 @@ function codeCommentConfirm(pin) {
|
|
|
9644
9733
|
const index3 = state.line - 1;
|
|
9645
9734
|
if (index3 > lines.length) {
|
|
9646
9735
|
console.error(
|
|
9647
|
-
|
|
9736
|
+
chalk95.red(
|
|
9648
9737
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
9649
9738
|
)
|
|
9650
9739
|
);
|
|
@@ -9657,48 +9746,48 @@ function codeCommentConfirm(pin) {
|
|
|
9657
9746
|
writeFileSync22(state.file, lines.join("\n"));
|
|
9658
9747
|
unlinkSync8(getPinStatePath(pin));
|
|
9659
9748
|
console.log(
|
|
9660
|
-
|
|
9749
|
+
chalk95.green(`Inserted "// ${state.text}" at ${state.file}:${state.line}`)
|
|
9661
9750
|
);
|
|
9662
9751
|
}
|
|
9663
9752
|
|
|
9664
9753
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9665
|
-
import
|
|
9754
|
+
import chalk96 from "chalk";
|
|
9666
9755
|
|
|
9667
9756
|
// src/commands/codeComment/validateCommentText.ts
|
|
9668
9757
|
var MAX_COMMENT_LENGTH = 50;
|
|
9669
9758
|
function validateCommentText(raw) {
|
|
9670
|
-
const
|
|
9671
|
-
if (/[\r\n]/.test(
|
|
9759
|
+
const text7 = raw.replace(/^\/\/\s?/, "");
|
|
9760
|
+
if (/[\r\n]/.test(text7)) {
|
|
9672
9761
|
return {
|
|
9673
9762
|
ok: false,
|
|
9674
9763
|
reason: "Comment must be a single line \u2014 multi-line comments are not allowed."
|
|
9675
9764
|
};
|
|
9676
9765
|
}
|
|
9677
|
-
if (
|
|
9766
|
+
if (text7.includes("/*") || text7.includes("*/")) {
|
|
9678
9767
|
return {
|
|
9679
9768
|
ok: false,
|
|
9680
9769
|
reason: "Block comments (/* */) are not allowed \u2014 only single-line // comments."
|
|
9681
9770
|
};
|
|
9682
9771
|
}
|
|
9683
|
-
if (
|
|
9772
|
+
if (text7.length > MAX_COMMENT_LENGTH) {
|
|
9684
9773
|
return {
|
|
9685
9774
|
ok: false,
|
|
9686
|
-
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.`
|
|
9687
9776
|
};
|
|
9688
9777
|
}
|
|
9689
|
-
return { ok: true, text:
|
|
9778
|
+
return { ok: true, text: text7 };
|
|
9690
9779
|
}
|
|
9691
9780
|
|
|
9692
9781
|
// src/commands/codeComment/issuePin.ts
|
|
9693
9782
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync23 } from "fs";
|
|
9694
9783
|
import { randomInt } from "crypto";
|
|
9695
|
-
function issuePin(file, lineNumber,
|
|
9784
|
+
function issuePin(file, lineNumber, text7) {
|
|
9696
9785
|
const pin = generatePin();
|
|
9697
9786
|
mkdirSync12(getRestrictedDir(), { recursive: true });
|
|
9698
9787
|
sweepRestrictedDir();
|
|
9699
9788
|
writeFileSync23(
|
|
9700
9789
|
getPinStatePath(pin),
|
|
9701
|
-
JSON.stringify({ pin, file, line: lineNumber, text:
|
|
9790
|
+
JSON.stringify({ pin, file, line: lineNumber, text: text7 })
|
|
9702
9791
|
);
|
|
9703
9792
|
return showNotification({
|
|
9704
9793
|
title: "assist code-comment pin",
|
|
@@ -9710,29 +9799,29 @@ function generatePin() {
|
|
|
9710
9799
|
}
|
|
9711
9800
|
|
|
9712
9801
|
// src/commands/codeComment/codeCommentSet.ts
|
|
9713
|
-
function codeCommentSet(file, line,
|
|
9802
|
+
function codeCommentSet(file, line, text7) {
|
|
9714
9803
|
const lineNumber = Number.parseInt(line, 10);
|
|
9715
9804
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
9716
|
-
console.error(
|
|
9805
|
+
console.error(chalk96.red(`Invalid line number: ${line}`));
|
|
9717
9806
|
process.exitCode = 1;
|
|
9718
9807
|
return;
|
|
9719
9808
|
}
|
|
9720
|
-
const validation = validateCommentText(
|
|
9809
|
+
const validation = validateCommentText(text7);
|
|
9721
9810
|
if (!validation.ok) {
|
|
9722
|
-
console.error(
|
|
9723
|
-
console.error(
|
|
9811
|
+
console.error(chalk96.red(`Refused: ${validation.reason}`));
|
|
9812
|
+
console.error(chalk96.red("No pin issued."));
|
|
9724
9813
|
process.exitCode = 1;
|
|
9725
9814
|
return;
|
|
9726
9815
|
}
|
|
9727
9816
|
console.error(
|
|
9728
|
-
|
|
9817
|
+
chalk96.yellow.bold(
|
|
9729
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."
|
|
9730
9819
|
)
|
|
9731
9820
|
);
|
|
9732
9821
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
9733
9822
|
if (!delivered) {
|
|
9734
9823
|
console.error(
|
|
9735
|
-
|
|
9824
|
+
chalk96.red(
|
|
9736
9825
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
9737
9826
|
)
|
|
9738
9827
|
);
|
|
@@ -9742,7 +9831,7 @@ function codeCommentSet(file, line, text6) {
|
|
|
9742
9831
|
console.log(
|
|
9743
9832
|
`A confirmation pin was sent to your desktop notifications.
|
|
9744
9833
|
To insert "// ${validation.text}" at ${file}:${lineNumber}, run:
|
|
9745
|
-
${
|
|
9834
|
+
${chalk96.cyan(" assist code-comment confirm <PIN>")}
|
|
9746
9835
|
using the pin from that notification.`
|
|
9747
9836
|
);
|
|
9748
9837
|
}
|
|
@@ -9762,15 +9851,15 @@ function registerCodeComment(parent) {
|
|
|
9762
9851
|
}
|
|
9763
9852
|
|
|
9764
9853
|
// src/commands/complexity/analyze.ts
|
|
9765
|
-
import
|
|
9854
|
+
import chalk105 from "chalk";
|
|
9766
9855
|
|
|
9767
9856
|
// src/commands/complexity/cyclomatic.ts
|
|
9768
|
-
import
|
|
9857
|
+
import chalk98 from "chalk";
|
|
9769
9858
|
|
|
9770
9859
|
// src/commands/complexity/shared/index.ts
|
|
9771
9860
|
import fs16 from "fs";
|
|
9772
9861
|
import path21 from "path";
|
|
9773
|
-
import
|
|
9862
|
+
import chalk97 from "chalk";
|
|
9774
9863
|
import ts5 from "typescript";
|
|
9775
9864
|
|
|
9776
9865
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -10021,7 +10110,7 @@ function createSourceFromFile(filePath) {
|
|
|
10021
10110
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
10022
10111
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
10023
10112
|
if (files.length === 0) {
|
|
10024
|
-
console.log(
|
|
10113
|
+
console.log(chalk97.yellow("No files found matching pattern"));
|
|
10025
10114
|
return void 0;
|
|
10026
10115
|
}
|
|
10027
10116
|
return callback(files);
|
|
@@ -10054,11 +10143,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10054
10143
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
10055
10144
|
for (const { file, name, complexity } of results) {
|
|
10056
10145
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
10057
|
-
const color = exceedsThreshold ?
|
|
10058
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
10146
|
+
const color = exceedsThreshold ? chalk98.red : chalk98.white;
|
|
10147
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk98.cyan(complexity)}`);
|
|
10059
10148
|
}
|
|
10060
10149
|
console.log(
|
|
10061
|
-
|
|
10150
|
+
chalk98.dim(
|
|
10062
10151
|
`
|
|
10063
10152
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10064
10153
|
)
|
|
@@ -10070,7 +10159,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10070
10159
|
}
|
|
10071
10160
|
|
|
10072
10161
|
// src/commands/complexity/halstead.ts
|
|
10073
|
-
import
|
|
10162
|
+
import chalk99 from "chalk";
|
|
10074
10163
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
10075
10164
|
withSourceFiles(pattern2, (files) => {
|
|
10076
10165
|
const results = [];
|
|
@@ -10085,13 +10174,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10085
10174
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
10086
10175
|
for (const { file, name, metrics } of results) {
|
|
10087
10176
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
10088
|
-
const color = exceedsThreshold ?
|
|
10177
|
+
const color = exceedsThreshold ? chalk99.red : chalk99.white;
|
|
10089
10178
|
console.log(
|
|
10090
|
-
`${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))}`
|
|
10091
10180
|
);
|
|
10092
10181
|
}
|
|
10093
10182
|
console.log(
|
|
10094
|
-
|
|
10183
|
+
chalk99.dim(
|
|
10095
10184
|
`
|
|
10096
10185
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10097
10186
|
)
|
|
@@ -10103,27 +10192,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10103
10192
|
}
|
|
10104
10193
|
|
|
10105
10194
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
10106
|
-
import
|
|
10195
|
+
import chalk102 from "chalk";
|
|
10107
10196
|
|
|
10108
10197
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
10109
|
-
import
|
|
10198
|
+
import chalk100 from "chalk";
|
|
10110
10199
|
function formatResultLine(entry, failing) {
|
|
10111
10200
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
10112
|
-
const name = failing ?
|
|
10113
|
-
const suffix = override !== void 0 ?
|
|
10114
|
-
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}`;
|
|
10115
10204
|
}
|
|
10116
10205
|
|
|
10117
10206
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
10118
|
-
import
|
|
10207
|
+
import chalk101 from "chalk";
|
|
10119
10208
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
10120
10209
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
10121
10210
|
console.error(
|
|
10122
|
-
|
|
10211
|
+
chalk101.red(
|
|
10123
10212
|
`
|
|
10124
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.
|
|
10125
10214
|
|
|
10126
|
-
\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.
|
|
10127
10216
|
|
|
10128
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.`
|
|
10129
10218
|
)
|
|
@@ -10135,7 +10224,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
10135
10224
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
10136
10225
|
if (!gating) {
|
|
10137
10226
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
10138
|
-
console.log(
|
|
10227
|
+
console.log(chalk102.dim(`
|
|
10139
10228
|
Analyzed ${results.length} files`));
|
|
10140
10229
|
return;
|
|
10141
10230
|
}
|
|
@@ -10144,7 +10233,7 @@ Analyzed ${results.length} files`));
|
|
|
10144
10233
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
10145
10234
|
});
|
|
10146
10235
|
if (failing.length === 0) {
|
|
10147
|
-
console.log(
|
|
10236
|
+
console.log(chalk102.green("All files pass maintainability threshold"));
|
|
10148
10237
|
} else {
|
|
10149
10238
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
10150
10239
|
}
|
|
@@ -10153,7 +10242,7 @@ Analyzed ${results.length} files`));
|
|
|
10153
10242
|
);
|
|
10154
10243
|
for (const entry of passingOverrides)
|
|
10155
10244
|
console.log(formatResultLine(entry, false));
|
|
10156
|
-
console.log(
|
|
10245
|
+
console.log(chalk102.dim(`
|
|
10157
10246
|
Analyzed ${results.length} files`));
|
|
10158
10247
|
if (failing.length > 0) {
|
|
10159
10248
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -10162,10 +10251,10 @@ Analyzed ${results.length} files`));
|
|
|
10162
10251
|
}
|
|
10163
10252
|
|
|
10164
10253
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
10165
|
-
import
|
|
10254
|
+
import chalk103 from "chalk";
|
|
10166
10255
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
10167
10256
|
function printMaintainabilityFormula() {
|
|
10168
|
-
console.log(
|
|
10257
|
+
console.log(chalk103.dim(MI_FORMULA));
|
|
10169
10258
|
}
|
|
10170
10259
|
|
|
10171
10260
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -10241,7 +10330,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10241
10330
|
|
|
10242
10331
|
// src/commands/complexity/sloc.ts
|
|
10243
10332
|
import fs18 from "fs";
|
|
10244
|
-
import
|
|
10333
|
+
import chalk104 from "chalk";
|
|
10245
10334
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
10246
10335
|
withSourceFiles(pattern2, (files) => {
|
|
10247
10336
|
const results = [];
|
|
@@ -10257,12 +10346,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10257
10346
|
results.sort((a, b) => b.lines - a.lines);
|
|
10258
10347
|
for (const { file, lines } of results) {
|
|
10259
10348
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
10260
|
-
const color = exceedsThreshold ?
|
|
10261
|
-
console.log(`${color(file)} \u2192 ${
|
|
10349
|
+
const color = exceedsThreshold ? chalk104.red : chalk104.white;
|
|
10350
|
+
console.log(`${color(file)} \u2192 ${chalk104.cyan(lines)} lines`);
|
|
10262
10351
|
}
|
|
10263
10352
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
10264
10353
|
console.log(
|
|
10265
|
-
|
|
10354
|
+
chalk104.dim(`
|
|
10266
10355
|
Total: ${total} lines across ${files.length} files`)
|
|
10267
10356
|
);
|
|
10268
10357
|
if (hasViolation) {
|
|
@@ -10276,25 +10365,25 @@ async function analyze(pattern2) {
|
|
|
10276
10365
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
10277
10366
|
const files = findSourceFiles2(searchPattern);
|
|
10278
10367
|
if (files.length === 0) {
|
|
10279
|
-
console.log(
|
|
10368
|
+
console.log(chalk105.yellow("No files found matching pattern"));
|
|
10280
10369
|
return;
|
|
10281
10370
|
}
|
|
10282
10371
|
if (files.length === 1) {
|
|
10283
10372
|
const file = files[0];
|
|
10284
|
-
console.log(
|
|
10373
|
+
console.log(chalk105.bold.underline("SLOC"));
|
|
10285
10374
|
await sloc(file);
|
|
10286
10375
|
console.log();
|
|
10287
|
-
console.log(
|
|
10376
|
+
console.log(chalk105.bold.underline("Cyclomatic Complexity"));
|
|
10288
10377
|
await cyclomatic(file);
|
|
10289
10378
|
console.log();
|
|
10290
|
-
console.log(
|
|
10379
|
+
console.log(chalk105.bold.underline("Halstead Metrics"));
|
|
10291
10380
|
await halstead(file);
|
|
10292
10381
|
console.log();
|
|
10293
|
-
console.log(
|
|
10382
|
+
console.log(chalk105.bold.underline("Maintainability Index"));
|
|
10294
10383
|
await maintainability(file);
|
|
10295
10384
|
console.log();
|
|
10296
10385
|
console.log(
|
|
10297
|
-
|
|
10386
|
+
chalk105.dim(
|
|
10298
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."
|
|
10299
10388
|
)
|
|
10300
10389
|
);
|
|
@@ -10328,7 +10417,7 @@ function registerComplexity(program2) {
|
|
|
10328
10417
|
}
|
|
10329
10418
|
|
|
10330
10419
|
// src/commands/config/index.ts
|
|
10331
|
-
import
|
|
10420
|
+
import chalk106 from "chalk";
|
|
10332
10421
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
10333
10422
|
|
|
10334
10423
|
// src/commands/config/setNestedValue.ts
|
|
@@ -10391,7 +10480,7 @@ function formatIssuePath(issue, key) {
|
|
|
10391
10480
|
function printValidationErrors(issues, key) {
|
|
10392
10481
|
for (const issue of issues) {
|
|
10393
10482
|
console.error(
|
|
10394
|
-
|
|
10483
|
+
chalk106.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
10395
10484
|
);
|
|
10396
10485
|
}
|
|
10397
10486
|
}
|
|
@@ -10408,7 +10497,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
10408
10497
|
function assertNotGlobalOnly(key, global) {
|
|
10409
10498
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
10410
10499
|
console.error(
|
|
10411
|
-
|
|
10500
|
+
chalk106.red(
|
|
10412
10501
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
10413
10502
|
)
|
|
10414
10503
|
);
|
|
@@ -10431,7 +10520,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
10431
10520
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
10432
10521
|
const target = options2.global ? "global" : "project";
|
|
10433
10522
|
console.log(
|
|
10434
|
-
|
|
10523
|
+
chalk106.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
10435
10524
|
);
|
|
10436
10525
|
}
|
|
10437
10526
|
function configList() {
|
|
@@ -10440,7 +10529,7 @@ function configList() {
|
|
|
10440
10529
|
}
|
|
10441
10530
|
|
|
10442
10531
|
// src/commands/config/configGet.ts
|
|
10443
|
-
import
|
|
10532
|
+
import chalk107 from "chalk";
|
|
10444
10533
|
|
|
10445
10534
|
// src/commands/config/getNestedValue.ts
|
|
10446
10535
|
function isTraversable(value) {
|
|
@@ -10472,7 +10561,7 @@ function requireNestedValue(config, key) {
|
|
|
10472
10561
|
return value;
|
|
10473
10562
|
}
|
|
10474
10563
|
function exitKeyNotSet(key) {
|
|
10475
|
-
console.error(
|
|
10564
|
+
console.error(chalk107.red(`Key "${key}" is not set`));
|
|
10476
10565
|
process.exit(1);
|
|
10477
10566
|
}
|
|
10478
10567
|
|
|
@@ -10486,7 +10575,7 @@ function registerConfig(program2) {
|
|
|
10486
10575
|
|
|
10487
10576
|
// src/commands/deploy/redirect.ts
|
|
10488
10577
|
import { existsSync as existsSync29, readFileSync as readFileSync24, writeFileSync as writeFileSync24 } from "fs";
|
|
10489
|
-
import
|
|
10578
|
+
import chalk108 from "chalk";
|
|
10490
10579
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10491
10580
|
if (!window.location.pathname.endsWith('/')) {
|
|
10492
10581
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -10495,23 +10584,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10495
10584
|
function redirect() {
|
|
10496
10585
|
const indexPath = "index.html";
|
|
10497
10586
|
if (!existsSync29(indexPath)) {
|
|
10498
|
-
console.log(
|
|
10587
|
+
console.log(chalk108.yellow("No index.html found"));
|
|
10499
10588
|
return;
|
|
10500
10589
|
}
|
|
10501
10590
|
const content = readFileSync24(indexPath, "utf8");
|
|
10502
10591
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10503
|
-
console.log(
|
|
10592
|
+
console.log(chalk108.dim("Trailing slash script already present"));
|
|
10504
10593
|
return;
|
|
10505
10594
|
}
|
|
10506
10595
|
const headCloseIndex = content.indexOf("</head>");
|
|
10507
10596
|
if (headCloseIndex === -1) {
|
|
10508
|
-
console.log(
|
|
10597
|
+
console.log(chalk108.red("Could not find </head> tag in index.html"));
|
|
10509
10598
|
return;
|
|
10510
10599
|
}
|
|
10511
10600
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
10512
10601
|
${content.slice(headCloseIndex)}`;
|
|
10513
10602
|
writeFileSync24(indexPath, newContent);
|
|
10514
|
-
console.log(
|
|
10603
|
+
console.log(chalk108.green("Added trailing slash redirect to index.html"));
|
|
10515
10604
|
}
|
|
10516
10605
|
|
|
10517
10606
|
// src/commands/registerDeploy.ts
|
|
@@ -10538,7 +10627,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
10538
10627
|
|
|
10539
10628
|
// src/commands/devlog/shared.ts
|
|
10540
10629
|
import { execSync as execSync24 } from "child_process";
|
|
10541
|
-
import
|
|
10630
|
+
import chalk109 from "chalk";
|
|
10542
10631
|
|
|
10543
10632
|
// src/shared/getRepoName.ts
|
|
10544
10633
|
import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
|
|
@@ -10647,13 +10736,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
10647
10736
|
}
|
|
10648
10737
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
10649
10738
|
for (const commit2 of commits2) {
|
|
10650
|
-
console.log(` ${
|
|
10739
|
+
console.log(` ${chalk109.yellow(commit2.hash)} ${commit2.message}`);
|
|
10651
10740
|
if (verbose) {
|
|
10652
10741
|
const visibleFiles = commit2.files.filter(
|
|
10653
10742
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
10654
10743
|
);
|
|
10655
10744
|
for (const file of visibleFiles) {
|
|
10656
|
-
console.log(` ${
|
|
10745
|
+
console.log(` ${chalk109.dim(file)}`);
|
|
10657
10746
|
}
|
|
10658
10747
|
}
|
|
10659
10748
|
}
|
|
@@ -10678,15 +10767,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
10678
10767
|
}
|
|
10679
10768
|
|
|
10680
10769
|
// src/commands/devlog/list/printDateHeader.ts
|
|
10681
|
-
import
|
|
10770
|
+
import chalk110 from "chalk";
|
|
10682
10771
|
function printDateHeader(date, isSkipped, entries) {
|
|
10683
10772
|
if (isSkipped) {
|
|
10684
|
-
console.log(`${
|
|
10773
|
+
console.log(`${chalk110.bold.blue(date)} ${chalk110.dim("skipped")}`);
|
|
10685
10774
|
} else if (entries && entries.length > 0) {
|
|
10686
|
-
const entryInfo = entries.map((e) => `${
|
|
10687
|
-
console.log(`${
|
|
10775
|
+
const entryInfo = entries.map((e) => `${chalk110.green(e.version)} ${e.title}`).join(" | ");
|
|
10776
|
+
console.log(`${chalk110.bold.blue(date)} ${entryInfo}`);
|
|
10688
10777
|
} else {
|
|
10689
|
-
console.log(`${
|
|
10778
|
+
console.log(`${chalk110.bold.blue(date)} ${chalk110.red("\u26A0 devlog missing")}`);
|
|
10690
10779
|
}
|
|
10691
10780
|
}
|
|
10692
10781
|
|
|
@@ -10790,24 +10879,24 @@ function bumpVersion(version2, type) {
|
|
|
10790
10879
|
|
|
10791
10880
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
10792
10881
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
10793
|
-
import
|
|
10882
|
+
import chalk112 from "chalk";
|
|
10794
10883
|
|
|
10795
10884
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
10796
|
-
import
|
|
10885
|
+
import chalk111 from "chalk";
|
|
10797
10886
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
10798
10887
|
if (conventional && firstHash) {
|
|
10799
10888
|
const version2 = getVersionAtCommit(firstHash);
|
|
10800
10889
|
if (version2) {
|
|
10801
|
-
console.log(`${
|
|
10890
|
+
console.log(`${chalk111.bold("version:")} ${stripToMinor(version2)}`);
|
|
10802
10891
|
} else {
|
|
10803
|
-
console.log(`${
|
|
10892
|
+
console.log(`${chalk111.bold("version:")} ${chalk111.red("unknown")}`);
|
|
10804
10893
|
}
|
|
10805
10894
|
} else if (patchVersion && minorVersion) {
|
|
10806
10895
|
console.log(
|
|
10807
|
-
`${
|
|
10896
|
+
`${chalk111.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
10808
10897
|
);
|
|
10809
10898
|
} else {
|
|
10810
|
-
console.log(`${
|
|
10899
|
+
console.log(`${chalk111.bold("version:")} v0.1 (initial)`);
|
|
10811
10900
|
}
|
|
10812
10901
|
}
|
|
10813
10902
|
|
|
@@ -10855,16 +10944,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
10855
10944
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
10856
10945
|
}
|
|
10857
10946
|
function logName(repoName) {
|
|
10858
|
-
console.log(`${
|
|
10947
|
+
console.log(`${chalk112.bold("name:")} ${repoName}`);
|
|
10859
10948
|
}
|
|
10860
10949
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
10861
10950
|
logName(ctx.repoName);
|
|
10862
10951
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
10863
|
-
console.log(
|
|
10952
|
+
console.log(chalk112.bold.blue(targetDate));
|
|
10864
10953
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
10865
10954
|
}
|
|
10866
10955
|
function logNoCommits(lastInfo) {
|
|
10867
|
-
console.log(
|
|
10956
|
+
console.log(chalk112.dim(noCommitsMessage(!!lastInfo)));
|
|
10868
10957
|
}
|
|
10869
10958
|
|
|
10870
10959
|
// src/commands/devlog/next/index.ts
|
|
@@ -10905,11 +10994,11 @@ function next2(options2) {
|
|
|
10905
10994
|
import { execSync as execSync26 } from "child_process";
|
|
10906
10995
|
|
|
10907
10996
|
// src/commands/devlog/repos/printReposTable.ts
|
|
10908
|
-
import
|
|
10997
|
+
import chalk113 from "chalk";
|
|
10909
10998
|
function colorStatus(status2) {
|
|
10910
|
-
if (status2 === "missing") return
|
|
10911
|
-
if (status2 === "outdated") return
|
|
10912
|
-
return
|
|
10999
|
+
if (status2 === "missing") return chalk113.red(status2);
|
|
11000
|
+
if (status2 === "outdated") return chalk113.yellow(status2);
|
|
11001
|
+
return chalk113.green(status2);
|
|
10913
11002
|
}
|
|
10914
11003
|
function formatRow(row, nameWidth) {
|
|
10915
11004
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -10923,8 +11012,8 @@ function printReposTable(rows) {
|
|
|
10923
11012
|
"Last Devlog".padEnd(11),
|
|
10924
11013
|
"Status"
|
|
10925
11014
|
].join(" ");
|
|
10926
|
-
console.log(
|
|
10927
|
-
console.log(
|
|
11015
|
+
console.log(chalk113.dim(header));
|
|
11016
|
+
console.log(chalk113.dim("-".repeat(header.length)));
|
|
10928
11017
|
for (const row of rows) {
|
|
10929
11018
|
console.log(formatRow(row, nameWidth));
|
|
10930
11019
|
}
|
|
@@ -10982,14 +11071,14 @@ function repos(options2) {
|
|
|
10982
11071
|
// src/commands/devlog/skip.ts
|
|
10983
11072
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
10984
11073
|
import { join as join32 } from "path";
|
|
10985
|
-
import
|
|
11074
|
+
import chalk114 from "chalk";
|
|
10986
11075
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10987
11076
|
function getBlogConfigPath() {
|
|
10988
11077
|
return join32(BLOG_REPO_ROOT, "assist.yml");
|
|
10989
11078
|
}
|
|
10990
11079
|
function skip(date) {
|
|
10991
11080
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
10992
|
-
console.log(
|
|
11081
|
+
console.log(chalk114.red("Invalid date format. Use YYYY-MM-DD"));
|
|
10993
11082
|
process.exit(1);
|
|
10994
11083
|
}
|
|
10995
11084
|
const repoName = getRepoName();
|
|
@@ -11000,7 +11089,7 @@ function skip(date) {
|
|
|
11000
11089
|
const skipDays = skip2[repoName] ?? [];
|
|
11001
11090
|
if (skipDays.includes(date)) {
|
|
11002
11091
|
console.log(
|
|
11003
|
-
|
|
11092
|
+
chalk114.yellow(`${date} is already in skip list for ${repoName}`)
|
|
11004
11093
|
);
|
|
11005
11094
|
return;
|
|
11006
11095
|
}
|
|
@@ -11010,20 +11099,20 @@ function skip(date) {
|
|
|
11010
11099
|
devlog.skip = skip2;
|
|
11011
11100
|
config.devlog = devlog;
|
|
11012
11101
|
writeFileSync25(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
11013
|
-
console.log(
|
|
11102
|
+
console.log(chalk114.green(`Added ${date} to skip list for ${repoName}`));
|
|
11014
11103
|
}
|
|
11015
11104
|
|
|
11016
11105
|
// src/commands/devlog/version.ts
|
|
11017
|
-
import
|
|
11106
|
+
import chalk115 from "chalk";
|
|
11018
11107
|
function version() {
|
|
11019
11108
|
const config = loadConfig();
|
|
11020
11109
|
const name = getRepoName();
|
|
11021
11110
|
const lastInfo = getLastVersionInfo(name, config);
|
|
11022
11111
|
const lastVersion = lastInfo?.version ?? null;
|
|
11023
11112
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
11024
|
-
console.log(`${
|
|
11025
|
-
console.log(`${
|
|
11026
|
-
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")}`);
|
|
11027
11116
|
}
|
|
11028
11117
|
|
|
11029
11118
|
// src/commands/registerDevlog.ts
|
|
@@ -11047,7 +11136,7 @@ function registerDevlog(program2) {
|
|
|
11047
11136
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
11048
11137
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync4 } from "fs";
|
|
11049
11138
|
import { join as join33 } from "path";
|
|
11050
|
-
import
|
|
11139
|
+
import chalk116 from "chalk";
|
|
11051
11140
|
|
|
11052
11141
|
// src/shared/findRepoRoot.ts
|
|
11053
11142
|
import { existsSync as existsSync31 } from "fs";
|
|
@@ -11110,14 +11199,14 @@ function checkBuildLocks(startDir) {
|
|
|
11110
11199
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
11111
11200
|
if (locked) {
|
|
11112
11201
|
console.error(
|
|
11113
|
-
|
|
11202
|
+
chalk116.red("Build output locked (is VS debugging?): ") + locked
|
|
11114
11203
|
);
|
|
11115
11204
|
process.exit(1);
|
|
11116
11205
|
}
|
|
11117
11206
|
}
|
|
11118
11207
|
async function checkBuildLocksCommand() {
|
|
11119
11208
|
checkBuildLocks();
|
|
11120
|
-
console.log(
|
|
11209
|
+
console.log(chalk116.green("No build locks detected"));
|
|
11121
11210
|
}
|
|
11122
11211
|
|
|
11123
11212
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -11216,30 +11305,30 @@ function escapeRegex(s) {
|
|
|
11216
11305
|
}
|
|
11217
11306
|
|
|
11218
11307
|
// src/commands/dotnet/printTree.ts
|
|
11219
|
-
import
|
|
11308
|
+
import chalk117 from "chalk";
|
|
11220
11309
|
function printNodes(nodes, prefix2) {
|
|
11221
11310
|
for (let i = 0; i < nodes.length; i++) {
|
|
11222
11311
|
const isLast = i === nodes.length - 1;
|
|
11223
11312
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
11224
11313
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
11225
11314
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
11226
|
-
const label2 = isMissing ?
|
|
11315
|
+
const label2 = isMissing ? chalk117.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
11227
11316
|
console.log(`${prefix2}${connector}${label2}`);
|
|
11228
11317
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
11229
11318
|
}
|
|
11230
11319
|
}
|
|
11231
11320
|
function printTree(tree, totalCount, solutions) {
|
|
11232
|
-
console.log(
|
|
11233
|
-
console.log(
|
|
11321
|
+
console.log(chalk117.bold("\nProject Dependency Tree"));
|
|
11322
|
+
console.log(chalk117.cyan(tree.relativePath));
|
|
11234
11323
|
printNodes(tree.children, "");
|
|
11235
|
-
console.log(
|
|
11324
|
+
console.log(chalk117.dim(`
|
|
11236
11325
|
${totalCount} projects total (including root)`));
|
|
11237
|
-
console.log(
|
|
11326
|
+
console.log(chalk117.bold("\nSolution Membership"));
|
|
11238
11327
|
if (solutions.length === 0) {
|
|
11239
|
-
console.log(
|
|
11328
|
+
console.log(chalk117.yellow(" Not found in any .sln"));
|
|
11240
11329
|
} else {
|
|
11241
11330
|
for (const sln of solutions) {
|
|
11242
|
-
console.log(` ${
|
|
11331
|
+
console.log(` ${chalk117.green(sln)}`);
|
|
11243
11332
|
}
|
|
11244
11333
|
}
|
|
11245
11334
|
console.log();
|
|
@@ -11268,16 +11357,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
11268
11357
|
// src/commands/dotnet/resolveCsproj.ts
|
|
11269
11358
|
import { existsSync as existsSync32 } from "fs";
|
|
11270
11359
|
import path25 from "path";
|
|
11271
|
-
import
|
|
11360
|
+
import chalk118 from "chalk";
|
|
11272
11361
|
function resolveCsproj(csprojPath) {
|
|
11273
11362
|
const resolved = path25.resolve(csprojPath);
|
|
11274
11363
|
if (!existsSync32(resolved)) {
|
|
11275
|
-
console.error(
|
|
11364
|
+
console.error(chalk118.red(`File not found: ${resolved}`));
|
|
11276
11365
|
process.exit(1);
|
|
11277
11366
|
}
|
|
11278
11367
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
11279
11368
|
if (!repoRoot) {
|
|
11280
|
-
console.error(
|
|
11369
|
+
console.error(chalk118.red("Could not find git repository root"));
|
|
11281
11370
|
process.exit(1);
|
|
11282
11371
|
}
|
|
11283
11372
|
return { resolved, repoRoot };
|
|
@@ -11327,12 +11416,12 @@ function getChangedCsFiles(scope) {
|
|
|
11327
11416
|
}
|
|
11328
11417
|
|
|
11329
11418
|
// src/commands/dotnet/inSln.ts
|
|
11330
|
-
import
|
|
11419
|
+
import chalk119 from "chalk";
|
|
11331
11420
|
async function inSln(csprojPath) {
|
|
11332
11421
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
11333
11422
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
11334
11423
|
if (solutions.length === 0) {
|
|
11335
|
-
console.log(
|
|
11424
|
+
console.log(chalk119.yellow("Not found in any .sln file"));
|
|
11336
11425
|
process.exit(1);
|
|
11337
11426
|
}
|
|
11338
11427
|
for (const sln of solutions) {
|
|
@@ -11341,7 +11430,7 @@ async function inSln(csprojPath) {
|
|
|
11341
11430
|
}
|
|
11342
11431
|
|
|
11343
11432
|
// src/commands/dotnet/inspect.ts
|
|
11344
|
-
import
|
|
11433
|
+
import chalk125 from "chalk";
|
|
11345
11434
|
|
|
11346
11435
|
// src/shared/formatElapsed.ts
|
|
11347
11436
|
function formatElapsed(ms) {
|
|
@@ -11353,12 +11442,12 @@ function formatElapsed(ms) {
|
|
|
11353
11442
|
}
|
|
11354
11443
|
|
|
11355
11444
|
// src/commands/dotnet/displayIssues.ts
|
|
11356
|
-
import
|
|
11445
|
+
import chalk120 from "chalk";
|
|
11357
11446
|
var SEVERITY_COLOR = {
|
|
11358
|
-
ERROR:
|
|
11359
|
-
WARNING:
|
|
11360
|
-
SUGGESTION:
|
|
11361
|
-
HINT:
|
|
11447
|
+
ERROR: chalk120.red,
|
|
11448
|
+
WARNING: chalk120.yellow,
|
|
11449
|
+
SUGGESTION: chalk120.cyan,
|
|
11450
|
+
HINT: chalk120.dim
|
|
11362
11451
|
};
|
|
11363
11452
|
function groupByFile(issues) {
|
|
11364
11453
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -11374,15 +11463,15 @@ function groupByFile(issues) {
|
|
|
11374
11463
|
}
|
|
11375
11464
|
function displayIssues(issues) {
|
|
11376
11465
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
11377
|
-
console.log(
|
|
11466
|
+
console.log(chalk120.bold(file));
|
|
11378
11467
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
11379
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
11468
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk120.white;
|
|
11380
11469
|
console.log(
|
|
11381
|
-
` ${
|
|
11470
|
+
` ${chalk120.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
11382
11471
|
);
|
|
11383
11472
|
}
|
|
11384
11473
|
}
|
|
11385
|
-
console.log(
|
|
11474
|
+
console.log(chalk120.dim(`
|
|
11386
11475
|
${issues.length} issue(s) found`));
|
|
11387
11476
|
}
|
|
11388
11477
|
|
|
@@ -11441,12 +11530,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11441
11530
|
// src/commands/dotnet/resolveSolution.ts
|
|
11442
11531
|
import { existsSync as existsSync33 } from "fs";
|
|
11443
11532
|
import path26 from "path";
|
|
11444
|
-
import
|
|
11533
|
+
import chalk122 from "chalk";
|
|
11445
11534
|
|
|
11446
11535
|
// src/commands/dotnet/findSolution.ts
|
|
11447
11536
|
import { readdirSync as readdirSync6 } from "fs";
|
|
11448
11537
|
import { dirname as dirname20, join as join34 } from "path";
|
|
11449
|
-
import
|
|
11538
|
+
import chalk121 from "chalk";
|
|
11450
11539
|
function findSlnInDir(dir) {
|
|
11451
11540
|
try {
|
|
11452
11541
|
return readdirSync6(dir).filter((f) => f.endsWith(".sln")).map((f) => join34(dir, f));
|
|
@@ -11462,17 +11551,17 @@ function findSolution() {
|
|
|
11462
11551
|
const slnFiles = findSlnInDir(current);
|
|
11463
11552
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
11464
11553
|
if (slnFiles.length > 1) {
|
|
11465
|
-
console.error(
|
|
11554
|
+
console.error(chalk121.red(`Multiple .sln files found in ${current}:`));
|
|
11466
11555
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
11467
11556
|
console.error(
|
|
11468
|
-
|
|
11557
|
+
chalk121.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
11469
11558
|
);
|
|
11470
11559
|
process.exit(1);
|
|
11471
11560
|
}
|
|
11472
11561
|
if (current === ceiling) break;
|
|
11473
11562
|
current = dirname20(current);
|
|
11474
11563
|
}
|
|
11475
|
-
console.error(
|
|
11564
|
+
console.error(chalk121.red("No .sln file found between cwd and repo root"));
|
|
11476
11565
|
process.exit(1);
|
|
11477
11566
|
}
|
|
11478
11567
|
|
|
@@ -11481,7 +11570,7 @@ function resolveSolution(sln) {
|
|
|
11481
11570
|
if (sln) {
|
|
11482
11571
|
const resolved = path26.resolve(sln);
|
|
11483
11572
|
if (!existsSync33(resolved)) {
|
|
11484
|
-
console.error(
|
|
11573
|
+
console.error(chalk122.red(`Solution file not found: ${resolved}`));
|
|
11485
11574
|
process.exit(1);
|
|
11486
11575
|
}
|
|
11487
11576
|
return resolved;
|
|
@@ -11523,14 +11612,14 @@ import { execSync as execSync28 } from "child_process";
|
|
|
11523
11612
|
import { existsSync as existsSync34, readFileSync as readFileSync29, unlinkSync as unlinkSync9 } from "fs";
|
|
11524
11613
|
import { tmpdir as tmpdir3 } from "os";
|
|
11525
11614
|
import path27 from "path";
|
|
11526
|
-
import
|
|
11615
|
+
import chalk123 from "chalk";
|
|
11527
11616
|
function assertJbInstalled() {
|
|
11528
11617
|
try {
|
|
11529
11618
|
execSync28("jb inspectcode --version", { stdio: "pipe" });
|
|
11530
11619
|
} catch {
|
|
11531
|
-
console.error(
|
|
11620
|
+
console.error(chalk123.red("jb is not installed. Install with:"));
|
|
11532
11621
|
console.error(
|
|
11533
|
-
|
|
11622
|
+
chalk123.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
11534
11623
|
);
|
|
11535
11624
|
process.exit(1);
|
|
11536
11625
|
}
|
|
@@ -11548,11 +11637,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11548
11637
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
11549
11638
|
process.stderr.write(error.stderr);
|
|
11550
11639
|
}
|
|
11551
|
-
console.error(
|
|
11640
|
+
console.error(chalk123.red("jb inspectcode failed"));
|
|
11552
11641
|
process.exit(1);
|
|
11553
11642
|
}
|
|
11554
11643
|
if (!existsSync34(reportPath)) {
|
|
11555
|
-
console.error(
|
|
11644
|
+
console.error(chalk123.red("Report file not generated"));
|
|
11556
11645
|
process.exit(1);
|
|
11557
11646
|
}
|
|
11558
11647
|
const xml = readFileSync29(reportPath, "utf8");
|
|
@@ -11562,7 +11651,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11562
11651
|
|
|
11563
11652
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
11564
11653
|
import { execSync as execSync29 } from "child_process";
|
|
11565
|
-
import
|
|
11654
|
+
import chalk124 from "chalk";
|
|
11566
11655
|
function resolveMsbuildPath() {
|
|
11567
11656
|
const { run: run4 } = loadConfig();
|
|
11568
11657
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -11574,9 +11663,9 @@ function assertMsbuildInstalled() {
|
|
|
11574
11663
|
try {
|
|
11575
11664
|
execSync29(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
11576
11665
|
} catch {
|
|
11577
|
-
console.error(
|
|
11666
|
+
console.error(chalk124.red(`msbuild not found at: ${msbuild}`));
|
|
11578
11667
|
console.error(
|
|
11579
|
-
|
|
11668
|
+
chalk124.yellow(
|
|
11580
11669
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
11581
11670
|
)
|
|
11582
11671
|
);
|
|
@@ -11623,17 +11712,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
11623
11712
|
// src/commands/dotnet/inspect.ts
|
|
11624
11713
|
function logScope(changedFiles) {
|
|
11625
11714
|
if (changedFiles === null) {
|
|
11626
|
-
console.log(
|
|
11715
|
+
console.log(chalk125.dim("Inspecting full solution..."));
|
|
11627
11716
|
} else {
|
|
11628
11717
|
console.log(
|
|
11629
|
-
|
|
11718
|
+
chalk125.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
11630
11719
|
);
|
|
11631
11720
|
}
|
|
11632
11721
|
}
|
|
11633
11722
|
function reportResults(issues, elapsed) {
|
|
11634
11723
|
if (issues.length > 0) displayIssues(issues);
|
|
11635
|
-
else console.log(
|
|
11636
|
-
console.log(
|
|
11724
|
+
else console.log(chalk125.green("No issues found"));
|
|
11725
|
+
console.log(chalk125.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
11637
11726
|
if (issues.length > 0) process.exit(1);
|
|
11638
11727
|
}
|
|
11639
11728
|
async function inspect(sln, options2) {
|
|
@@ -11644,7 +11733,7 @@ async function inspect(sln, options2) {
|
|
|
11644
11733
|
const scope = parseScope(options2.scope);
|
|
11645
11734
|
const changedFiles = getChangedCsFiles(scope);
|
|
11646
11735
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
11647
|
-
console.log(
|
|
11736
|
+
console.log(chalk125.green("No changed .cs files found"));
|
|
11648
11737
|
return;
|
|
11649
11738
|
}
|
|
11650
11739
|
logScope(changedFiles);
|
|
@@ -11687,12 +11776,12 @@ function isSourceFile(filePath) {
|
|
|
11687
11776
|
if (!filePath) return false;
|
|
11688
11777
|
return SOURCE_EXTENSIONS2.some((ext) => filePath.endsWith(ext));
|
|
11689
11778
|
}
|
|
11690
|
-
function blankNonNewline(
|
|
11691
|
-
return
|
|
11779
|
+
function blankNonNewline(text7) {
|
|
11780
|
+
return text7.replace(/[^\n]/g, " ");
|
|
11692
11781
|
}
|
|
11693
|
-
function extractComments(
|
|
11782
|
+
function extractComments(text7) {
|
|
11694
11783
|
const comments3 = [];
|
|
11695
|
-
let work =
|
|
11784
|
+
let work = text7.replace(
|
|
11696
11785
|
/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`/g,
|
|
11697
11786
|
blankNonNewline
|
|
11698
11787
|
);
|
|
@@ -11947,25 +12036,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
11947
12036
|
}
|
|
11948
12037
|
|
|
11949
12038
|
// src/commands/github/printCountTable.ts
|
|
11950
|
-
import
|
|
12039
|
+
import chalk126 from "chalk";
|
|
11951
12040
|
function printCountTable(labelHeader, rows) {
|
|
11952
12041
|
const labelWidth = Math.max(
|
|
11953
12042
|
labelHeader.length,
|
|
11954
12043
|
...rows.map((row) => row.label.length)
|
|
11955
12044
|
);
|
|
11956
12045
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
11957
|
-
console.log(
|
|
11958
|
-
console.log(
|
|
12046
|
+
console.log(chalk126.dim(header));
|
|
12047
|
+
console.log(chalk126.dim("-".repeat(header.length)));
|
|
11959
12048
|
for (const row of rows) {
|
|
11960
12049
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
11961
12050
|
}
|
|
11962
12051
|
}
|
|
11963
12052
|
|
|
11964
12053
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
11965
|
-
import
|
|
12054
|
+
import chalk127 from "chalk";
|
|
11966
12055
|
function printRepoAuthorBreakdown(repos2) {
|
|
11967
12056
|
for (const repo of repos2) {
|
|
11968
|
-
console.log(
|
|
12057
|
+
console.log(chalk127.bold(repo.name));
|
|
11969
12058
|
const authorWidth = Math.max(
|
|
11970
12059
|
0,
|
|
11971
12060
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -12283,13 +12372,13 @@ function registerHandover(program2) {
|
|
|
12283
12372
|
}
|
|
12284
12373
|
|
|
12285
12374
|
// src/commands/jira/acceptanceCriteria.ts
|
|
12286
|
-
import
|
|
12375
|
+
import chalk128 from "chalk";
|
|
12287
12376
|
|
|
12288
12377
|
// src/commands/jira/adfToText.ts
|
|
12289
12378
|
function renderInline(node) {
|
|
12290
|
-
const
|
|
12291
|
-
if (node.marks?.some((m) => m.type === "code")) return `\`${
|
|
12292
|
-
return
|
|
12379
|
+
const text7 = node.text ?? "";
|
|
12380
|
+
if (node.marks?.some((m) => m.type === "code")) return `\`${text7}\``;
|
|
12381
|
+
return text7;
|
|
12293
12382
|
}
|
|
12294
12383
|
function renderChildren(node, indent2) {
|
|
12295
12384
|
return renderNodes(node.content ?? [], indent2);
|
|
@@ -12331,8 +12420,8 @@ function isListNode(node) {
|
|
|
12331
12420
|
function renderListChild(child, indent2, pad, marker, isFirst) {
|
|
12332
12421
|
if (isListNode(child)) return renderNodes([child], indent2 + 1);
|
|
12333
12422
|
if (child.type !== "paragraph") return renderNode(child, indent2);
|
|
12334
|
-
const
|
|
12335
|
-
return isFirst ? `${pad}${marker} ${
|
|
12423
|
+
const text7 = renderChildren(child, indent2);
|
|
12424
|
+
return isFirst ? `${pad}${marker} ${text7}` : `${pad} ${text7}`;
|
|
12336
12425
|
}
|
|
12337
12426
|
function renderListItem(node, indent2, marker) {
|
|
12338
12427
|
const pad = " ".repeat(indent2);
|
|
@@ -12350,7 +12439,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
12350
12439
|
const parsed = fetchIssue(issueKey, field);
|
|
12351
12440
|
const acValue = parsed?.fields?.[field];
|
|
12352
12441
|
if (!acValue) {
|
|
12353
|
-
console.log(
|
|
12442
|
+
console.log(chalk128.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
12354
12443
|
return;
|
|
12355
12444
|
}
|
|
12356
12445
|
if (typeof acValue === "string") {
|
|
@@ -12445,14 +12534,14 @@ async function jiraAuth() {
|
|
|
12445
12534
|
}
|
|
12446
12535
|
|
|
12447
12536
|
// src/commands/jira/viewIssue.ts
|
|
12448
|
-
import
|
|
12537
|
+
import chalk129 from "chalk";
|
|
12449
12538
|
function viewIssue(issueKey) {
|
|
12450
12539
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
12451
12540
|
const fields = parsed?.fields;
|
|
12452
12541
|
const summary = fields?.summary;
|
|
12453
12542
|
const description = fields?.description;
|
|
12454
12543
|
if (summary) {
|
|
12455
|
-
console.log(
|
|
12544
|
+
console.log(chalk129.bold(summary));
|
|
12456
12545
|
}
|
|
12457
12546
|
if (description) {
|
|
12458
12547
|
if (summary) console.log();
|
|
@@ -12466,7 +12555,7 @@ function viewIssue(issueKey) {
|
|
|
12466
12555
|
}
|
|
12467
12556
|
if (!summary && !description) {
|
|
12468
12557
|
console.log(
|
|
12469
|
-
|
|
12558
|
+
chalk129.yellow(`No summary or description found on ${issueKey}.`)
|
|
12470
12559
|
);
|
|
12471
12560
|
}
|
|
12472
12561
|
}
|
|
@@ -12482,13 +12571,13 @@ function registerJira(program2) {
|
|
|
12482
12571
|
// src/commands/reviewComments.ts
|
|
12483
12572
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
12484
12573
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
12485
|
-
import
|
|
12574
|
+
import chalk130 from "chalk";
|
|
12486
12575
|
async function reviewComments(number) {
|
|
12487
12576
|
if (number) {
|
|
12488
12577
|
try {
|
|
12489
12578
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
12490
12579
|
} catch {
|
|
12491
|
-
console.error(
|
|
12580
|
+
console.error(chalk130.red(`gh pr checkout ${number} failed; aborting.`));
|
|
12492
12581
|
process.exit(1);
|
|
12493
12582
|
}
|
|
12494
12583
|
}
|
|
@@ -12513,9 +12602,9 @@ function registerDescriptionLaunch(program2, name, slashCommand, description, al
|
|
|
12513
12602
|
"[description]",
|
|
12514
12603
|
`Text to forward to the /${slashCommand} slash command`
|
|
12515
12604
|
).description(description).option("--once", "Exit when the initial task completes").option("--resume-session <id>", RESUME_SESSION_FLAG).action(
|
|
12516
|
-
(
|
|
12605
|
+
(text7, opts) => launchMode(slashCommand, {
|
|
12517
12606
|
once: opts.once,
|
|
12518
|
-
description:
|
|
12607
|
+
description: text7,
|
|
12519
12608
|
resumeSessionId: opts.resumeSession
|
|
12520
12609
|
})
|
|
12521
12610
|
);
|
|
@@ -12562,15 +12651,15 @@ function registerList(program2) {
|
|
|
12562
12651
|
// src/commands/mermaid/index.ts
|
|
12563
12652
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync8 } from "fs";
|
|
12564
12653
|
import { resolve as resolve11 } from "path";
|
|
12565
|
-
import
|
|
12654
|
+
import chalk133 from "chalk";
|
|
12566
12655
|
|
|
12567
12656
|
// src/commands/mermaid/exportFile.ts
|
|
12568
12657
|
import { readFileSync as readFileSync32, writeFileSync as writeFileSync28 } from "fs";
|
|
12569
12658
|
import { basename as basename8, extname, resolve as resolve10 } from "path";
|
|
12570
|
-
import
|
|
12659
|
+
import chalk132 from "chalk";
|
|
12571
12660
|
|
|
12572
12661
|
// src/commands/mermaid/renderBlock.ts
|
|
12573
|
-
import
|
|
12662
|
+
import chalk131 from "chalk";
|
|
12574
12663
|
async function renderBlock(krokiUrl, source) {
|
|
12575
12664
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
12576
12665
|
method: "POST",
|
|
@@ -12579,7 +12668,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12579
12668
|
});
|
|
12580
12669
|
if (!response.ok) {
|
|
12581
12670
|
console.error(
|
|
12582
|
-
|
|
12671
|
+
chalk131.red(
|
|
12583
12672
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
12584
12673
|
)
|
|
12585
12674
|
);
|
|
@@ -12597,19 +12686,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12597
12686
|
if (onlyIndex !== void 0) {
|
|
12598
12687
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
12599
12688
|
console.error(
|
|
12600
|
-
|
|
12689
|
+
chalk132.red(
|
|
12601
12690
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
12602
12691
|
)
|
|
12603
12692
|
);
|
|
12604
12693
|
process.exit(1);
|
|
12605
12694
|
}
|
|
12606
12695
|
console.log(
|
|
12607
|
-
|
|
12696
|
+
chalk132.gray(
|
|
12608
12697
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
12609
12698
|
)
|
|
12610
12699
|
);
|
|
12611
12700
|
} else {
|
|
12612
|
-
console.log(
|
|
12701
|
+
console.log(chalk132.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
12613
12702
|
}
|
|
12614
12703
|
for (const [i, source] of blocks.entries()) {
|
|
12615
12704
|
const idx = i + 1;
|
|
@@ -12617,7 +12706,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
12617
12706
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
12618
12707
|
const svg = await renderBlock(krokiUrl, source);
|
|
12619
12708
|
writeFileSync28(outPath, svg, "utf8");
|
|
12620
|
-
console.log(
|
|
12709
|
+
console.log(chalk132.green(` \u2192 ${outPath}`));
|
|
12621
12710
|
}
|
|
12622
12711
|
}
|
|
12623
12712
|
function extractMermaidBlocks(markdown) {
|
|
@@ -12633,18 +12722,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
12633
12722
|
if (options2.index !== void 0) {
|
|
12634
12723
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
12635
12724
|
console.error(
|
|
12636
|
-
|
|
12725
|
+
chalk133.red(`--index must be a positive integer (got ${options2.index})`)
|
|
12637
12726
|
);
|
|
12638
12727
|
process.exit(1);
|
|
12639
12728
|
}
|
|
12640
12729
|
if (!file) {
|
|
12641
|
-
console.error(
|
|
12730
|
+
console.error(chalk133.red("--index requires a file argument"));
|
|
12642
12731
|
process.exit(1);
|
|
12643
12732
|
}
|
|
12644
12733
|
}
|
|
12645
12734
|
const files = file ? [file] : readdirSync8(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
12646
12735
|
if (files.length === 0) {
|
|
12647
|
-
console.log(
|
|
12736
|
+
console.log(chalk133.gray("No markdown files found in current directory."));
|
|
12648
12737
|
return;
|
|
12649
12738
|
}
|
|
12650
12739
|
for (const f of files) {
|
|
@@ -12670,7 +12759,7 @@ function registerMermaid(program2) {
|
|
|
12670
12759
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12671
12760
|
import { createServer as createServer2 } from "http";
|
|
12672
12761
|
import { dirname as dirname22 } from "path";
|
|
12673
|
-
import
|
|
12762
|
+
import chalk135 from "chalk";
|
|
12674
12763
|
|
|
12675
12764
|
// src/commands/netcap/corsHeaders.ts
|
|
12676
12765
|
var corsHeaders = {
|
|
@@ -12749,7 +12838,7 @@ function createNetcapHandler(options2) {
|
|
|
12749
12838
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12750
12839
|
import { networkInterfaces } from "os";
|
|
12751
12840
|
import { join as join41 } from "path";
|
|
12752
|
-
import
|
|
12841
|
+
import chalk134 from "chalk";
|
|
12753
12842
|
|
|
12754
12843
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12755
12844
|
import { dirname as dirname21, join as join40 } from "path";
|
|
@@ -12793,7 +12882,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12793
12882
|
const host = lanIPv4();
|
|
12794
12883
|
if (!host) {
|
|
12795
12884
|
console.log(
|
|
12796
|
-
|
|
12885
|
+
chalk134.yellow("could not determine the WSL IP for the extension")
|
|
12797
12886
|
);
|
|
12798
12887
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
12799
12888
|
return source;
|
|
@@ -12804,7 +12893,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12804
12893
|
return WSL_WINDOWS_PATH;
|
|
12805
12894
|
} catch {
|
|
12806
12895
|
console.log(
|
|
12807
|
-
|
|
12896
|
+
chalk134.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
12808
12897
|
);
|
|
12809
12898
|
return source;
|
|
12810
12899
|
}
|
|
@@ -12837,30 +12926,30 @@ async function netcap(options2) {
|
|
|
12837
12926
|
let count7 = 0;
|
|
12838
12927
|
const handler = createNetcapHandler({
|
|
12839
12928
|
outPath,
|
|
12840
|
-
onPing: () => console.log(
|
|
12929
|
+
onPing: () => console.log(chalk135.dim("ping from extension")),
|
|
12841
12930
|
onCapture: (entry) => {
|
|
12842
12931
|
count7 += 1;
|
|
12843
12932
|
console.log(
|
|
12844
|
-
|
|
12845
|
-
|
|
12933
|
+
chalk135.green(`captured #${count7}`),
|
|
12934
|
+
chalk135.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
12846
12935
|
);
|
|
12847
12936
|
}
|
|
12848
12937
|
});
|
|
12849
12938
|
const server = createServer2(handler);
|
|
12850
12939
|
server.listen(port, () => {
|
|
12851
12940
|
console.log(
|
|
12852
|
-
|
|
12941
|
+
chalk135.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
12853
12942
|
);
|
|
12854
|
-
console.log(
|
|
12943
|
+
console.log(chalk135.dim(`appending captures to ${outPath}`));
|
|
12855
12944
|
if (filter)
|
|
12856
|
-
console.log(
|
|
12857
|
-
console.log(
|
|
12858
|
-
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"));
|
|
12859
12948
|
});
|
|
12860
12949
|
process.on("SIGINT", () => {
|
|
12861
12950
|
server.close();
|
|
12862
12951
|
console.log(
|
|
12863
|
-
|
|
12952
|
+
chalk135.bold(
|
|
12864
12953
|
`
|
|
12865
12954
|
netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
12866
12955
|
)
|
|
@@ -12872,7 +12961,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
|
|
|
12872
12961
|
// src/commands/netcap/netcapExtract.ts
|
|
12873
12962
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
12874
12963
|
import { join as join44 } from "path";
|
|
12875
|
-
import
|
|
12964
|
+
import chalk136 from "chalk";
|
|
12876
12965
|
|
|
12877
12966
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12878
12967
|
import { readFileSync as readFileSync33 } from "fs";
|
|
@@ -13010,8 +13099,8 @@ function dedupeLinks(links2) {
|
|
|
13010
13099
|
}
|
|
13011
13100
|
|
|
13012
13101
|
// src/commands/netcap/linkifyMentions.ts
|
|
13013
|
-
function linkifyMentions(
|
|
13014
|
-
let out =
|
|
13102
|
+
function linkifyMentions(text7, mentions) {
|
|
13103
|
+
let out = text7;
|
|
13015
13104
|
for (const m of mentions) {
|
|
13016
13105
|
if (m.name && out.includes(m.name)) {
|
|
13017
13106
|
out = out.replace(m.name, `[${m.name}](${m.url})`);
|
|
@@ -13038,13 +13127,13 @@ function resolveAuthor(mentionMap, author) {
|
|
|
13038
13127
|
return mentionMap.get(author) ?? { slug: author, url: profileUrl(author) };
|
|
13039
13128
|
}
|
|
13040
13129
|
function buildPost(raw, mentionMap, author) {
|
|
13041
|
-
const
|
|
13042
|
-
if (!
|
|
13130
|
+
const text7 = joinText(raw.text);
|
|
13131
|
+
if (!text7) return void 0;
|
|
13043
13132
|
const mentions = resolveMentions(raw, mentionMap, author);
|
|
13044
13133
|
const relatedPosts = [...new Set(raw.related)];
|
|
13045
13134
|
return {
|
|
13046
|
-
text:
|
|
13047
|
-
markdown: linkifyMentions(
|
|
13135
|
+
text: text7,
|
|
13136
|
+
markdown: linkifyMentions(text7, mentions),
|
|
13048
13137
|
mentions,
|
|
13049
13138
|
hashtags: [...new Set(raw.hashtags)],
|
|
13050
13139
|
links: dedupeLinks(raw.links),
|
|
@@ -13185,8 +13274,8 @@ function activityUrnOf(update3) {
|
|
|
13185
13274
|
return typeof urn === "string" ? urn : void 0;
|
|
13186
13275
|
}
|
|
13187
13276
|
function buildVoyagerPost(update3, profiles) {
|
|
13188
|
-
const
|
|
13189
|
-
if (!
|
|
13277
|
+
const text7 = commentaryText(update3);
|
|
13278
|
+
if (!text7) return void 0;
|
|
13190
13279
|
const author = resolveVoyagerAuthor(update3);
|
|
13191
13280
|
const { mentions, hashtags, links: links2 } = collectVoyagerAttributes(
|
|
13192
13281
|
update3,
|
|
@@ -13195,8 +13284,8 @@ function buildVoyagerPost(update3, profiles) {
|
|
|
13195
13284
|
);
|
|
13196
13285
|
const activityUrn = activityUrnOf(update3);
|
|
13197
13286
|
return {
|
|
13198
|
-
text:
|
|
13199
|
-
markdown: linkifyMentions(
|
|
13287
|
+
text: text7,
|
|
13288
|
+
markdown: linkifyMentions(text7, mentions),
|
|
13200
13289
|
mentions,
|
|
13201
13290
|
hashtags,
|
|
13202
13291
|
links: links2,
|
|
@@ -13320,8 +13409,8 @@ function netcapExtract(file) {
|
|
|
13320
13409
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13321
13410
|
`);
|
|
13322
13411
|
console.log(
|
|
13323
|
-
|
|
13324
|
-
|
|
13412
|
+
chalk136.green(`extracted ${posts.length} posts`),
|
|
13413
|
+
chalk136.dim(`-> ${outFile}`)
|
|
13325
13414
|
);
|
|
13326
13415
|
}
|
|
13327
13416
|
|
|
@@ -13342,7 +13431,7 @@ function registerNetcap(program2) {
|
|
|
13342
13431
|
}
|
|
13343
13432
|
|
|
13344
13433
|
// src/commands/news/add/index.ts
|
|
13345
|
-
import
|
|
13434
|
+
import chalk137 from "chalk";
|
|
13346
13435
|
import enquirer8 from "enquirer";
|
|
13347
13436
|
async function add2(url) {
|
|
13348
13437
|
if (!url) {
|
|
@@ -13364,10 +13453,10 @@ async function add2(url) {
|
|
|
13364
13453
|
const { orm } = await getReady();
|
|
13365
13454
|
const added = await addFeed(orm, url);
|
|
13366
13455
|
if (!added) {
|
|
13367
|
-
console.log(
|
|
13456
|
+
console.log(chalk137.yellow("Feed already exists"));
|
|
13368
13457
|
return;
|
|
13369
13458
|
}
|
|
13370
|
-
console.log(
|
|
13459
|
+
console.log(chalk137.green(`Added feed: ${url}`));
|
|
13371
13460
|
}
|
|
13372
13461
|
|
|
13373
13462
|
// src/commands/registerNews.ts
|
|
@@ -13377,7 +13466,7 @@ function registerNews(program2) {
|
|
|
13377
13466
|
}
|
|
13378
13467
|
|
|
13379
13468
|
// src/commands/prompts/printPromptsTable.ts
|
|
13380
|
-
import
|
|
13469
|
+
import chalk138 from "chalk";
|
|
13381
13470
|
function truncate(str, max) {
|
|
13382
13471
|
if (str.length <= max) return str;
|
|
13383
13472
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -13395,14 +13484,14 @@ function printPromptsTable(rows) {
|
|
|
13395
13484
|
"Command".padEnd(commandWidth),
|
|
13396
13485
|
"Repos"
|
|
13397
13486
|
].join(" ");
|
|
13398
|
-
console.log(
|
|
13399
|
-
console.log(
|
|
13487
|
+
console.log(chalk138.dim(header));
|
|
13488
|
+
console.log(chalk138.dim("-".repeat(header.length)));
|
|
13400
13489
|
for (const row of rows) {
|
|
13401
13490
|
const count7 = String(row.count).padStart(countWidth);
|
|
13402
13491
|
const tool = row.tool.padEnd(toolWidth);
|
|
13403
13492
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
13404
13493
|
console.log(
|
|
13405
|
-
`${
|
|
13494
|
+
`${chalk138.yellow(count7)} ${tool} ${command} ${chalk138.dim(row.repos)}`
|
|
13406
13495
|
);
|
|
13407
13496
|
}
|
|
13408
13497
|
}
|
|
@@ -13700,8 +13789,8 @@ function isWallOfText(lines) {
|
|
|
13700
13789
|
if (lines.some(isListLine)) {
|
|
13701
13790
|
return false;
|
|
13702
13791
|
}
|
|
13703
|
-
const
|
|
13704
|
-
return
|
|
13792
|
+
const text7 = lines.join(" ").trim();
|
|
13793
|
+
return text7.length > MAX_PARAGRAPH_CHARS || countSentences(text7) > MAX_PARAGRAPH_SENTENCES;
|
|
13705
13794
|
}
|
|
13706
13795
|
function validatePrContent(title, body) {
|
|
13707
13796
|
if (title.toLowerCase().includes("claude")) {
|
|
@@ -13951,20 +14040,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
13951
14040
|
}
|
|
13952
14041
|
|
|
13953
14042
|
// src/commands/prs/listComments/printComments.ts
|
|
13954
|
-
import
|
|
14043
|
+
import chalk139 from "chalk";
|
|
13955
14044
|
function formatForHuman(comment3) {
|
|
13956
14045
|
if (comment3.type === "review") {
|
|
13957
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
14046
|
+
const stateColor = comment3.state === "APPROVED" ? chalk139.green : comment3.state === "CHANGES_REQUESTED" ? chalk139.red : chalk139.yellow;
|
|
13958
14047
|
return [
|
|
13959
|
-
`${
|
|
14048
|
+
`${chalk139.cyan("Review")} by ${chalk139.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
13960
14049
|
comment3.body,
|
|
13961
14050
|
""
|
|
13962
14051
|
].join("\n");
|
|
13963
14052
|
}
|
|
13964
14053
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
13965
14054
|
return [
|
|
13966
|
-
`${
|
|
13967
|
-
|
|
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")),
|
|
13968
14057
|
comment3.body,
|
|
13969
14058
|
""
|
|
13970
14059
|
].join("\n");
|
|
@@ -14054,13 +14143,13 @@ import { execSync as execSync38 } from "child_process";
|
|
|
14054
14143
|
import enquirer9 from "enquirer";
|
|
14055
14144
|
|
|
14056
14145
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
14057
|
-
import
|
|
14146
|
+
import chalk140 from "chalk";
|
|
14058
14147
|
var STATUS_MAP = {
|
|
14059
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
14060
|
-
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
|
|
14061
14150
|
};
|
|
14062
14151
|
function defaultStatus(pr) {
|
|
14063
|
-
return { label:
|
|
14152
|
+
return { label: chalk140.green("opened"), date: pr.createdAt };
|
|
14064
14153
|
}
|
|
14065
14154
|
function getStatus2(pr) {
|
|
14066
14155
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -14069,11 +14158,11 @@ function formatDate(dateStr) {
|
|
|
14069
14158
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
14070
14159
|
}
|
|
14071
14160
|
function formatPrHeader(pr, status2) {
|
|
14072
|
-
return `${
|
|
14161
|
+
return `${chalk140.cyan(`#${pr.number}`)} ${pr.title} ${chalk140.dim(`(${pr.author.login},`)} ${status2.label} ${chalk140.dim(`${formatDate(status2.date)})`)}`;
|
|
14073
14162
|
}
|
|
14074
14163
|
function logPrDetails(pr) {
|
|
14075
14164
|
console.log(
|
|
14076
|
-
|
|
14165
|
+
chalk140.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
14077
14166
|
);
|
|
14078
14167
|
console.log();
|
|
14079
14168
|
}
|
|
@@ -14380,10 +14469,10 @@ function registerPrs(program2) {
|
|
|
14380
14469
|
}
|
|
14381
14470
|
|
|
14382
14471
|
// src/commands/ravendb/ravendbAuth.ts
|
|
14383
|
-
import
|
|
14472
|
+
import chalk146 from "chalk";
|
|
14384
14473
|
|
|
14385
14474
|
// src/shared/createConnectionAuth.ts
|
|
14386
|
-
import
|
|
14475
|
+
import chalk141 from "chalk";
|
|
14387
14476
|
function listConnections(connections, format) {
|
|
14388
14477
|
if (connections.length === 0) {
|
|
14389
14478
|
console.log("No connections configured.");
|
|
@@ -14396,7 +14485,7 @@ function listConnections(connections, format) {
|
|
|
14396
14485
|
function removeConnection(connections, name, save) {
|
|
14397
14486
|
const filtered = connections.filter((c) => c.name !== name);
|
|
14398
14487
|
if (filtered.length === connections.length) {
|
|
14399
|
-
console.error(
|
|
14488
|
+
console.error(chalk141.red(`Connection "${name}" not found.`));
|
|
14400
14489
|
process.exit(1);
|
|
14401
14490
|
}
|
|
14402
14491
|
save(filtered);
|
|
@@ -14442,15 +14531,15 @@ function saveConnections(connections) {
|
|
|
14442
14531
|
}
|
|
14443
14532
|
|
|
14444
14533
|
// src/commands/ravendb/promptConnection.ts
|
|
14445
|
-
import
|
|
14534
|
+
import chalk144 from "chalk";
|
|
14446
14535
|
|
|
14447
14536
|
// src/commands/ravendb/selectOpSecret.ts
|
|
14448
|
-
import
|
|
14537
|
+
import chalk143 from "chalk";
|
|
14449
14538
|
import Enquirer2 from "enquirer";
|
|
14450
14539
|
|
|
14451
14540
|
// src/commands/ravendb/searchItems.ts
|
|
14452
14541
|
import { execSync as execSync41 } from "child_process";
|
|
14453
|
-
import
|
|
14542
|
+
import chalk142 from "chalk";
|
|
14454
14543
|
function opExec(args) {
|
|
14455
14544
|
return execSync41(`op ${args}`, {
|
|
14456
14545
|
encoding: "utf8",
|
|
@@ -14463,7 +14552,7 @@ function searchItems(search2) {
|
|
|
14463
14552
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
14464
14553
|
} catch {
|
|
14465
14554
|
console.error(
|
|
14466
|
-
|
|
14555
|
+
chalk142.red(
|
|
14467
14556
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
14468
14557
|
)
|
|
14469
14558
|
);
|
|
@@ -14477,7 +14566,7 @@ function getItemFields(itemId) {
|
|
|
14477
14566
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
14478
14567
|
return item.fields.filter((f) => f.reference && f.label);
|
|
14479
14568
|
} catch {
|
|
14480
|
-
console.error(
|
|
14569
|
+
console.error(chalk142.red("Failed to get item details from 1Password."));
|
|
14481
14570
|
process.exit(1);
|
|
14482
14571
|
}
|
|
14483
14572
|
}
|
|
@@ -14496,7 +14585,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14496
14585
|
}).run();
|
|
14497
14586
|
const items2 = searchItems(search2);
|
|
14498
14587
|
if (items2.length === 0) {
|
|
14499
|
-
console.error(
|
|
14588
|
+
console.error(chalk143.red(`No items found matching "${search2}".`));
|
|
14500
14589
|
process.exit(1);
|
|
14501
14590
|
}
|
|
14502
14591
|
const itemId = await selectOne(
|
|
@@ -14505,7 +14594,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14505
14594
|
);
|
|
14506
14595
|
const fields = getItemFields(itemId);
|
|
14507
14596
|
if (fields.length === 0) {
|
|
14508
|
-
console.error(
|
|
14597
|
+
console.error(chalk143.red("No fields with references found on this item."));
|
|
14509
14598
|
process.exit(1);
|
|
14510
14599
|
}
|
|
14511
14600
|
const ref = await selectOne(
|
|
@@ -14519,7 +14608,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
14519
14608
|
async function promptConnection(existingNames) {
|
|
14520
14609
|
const name = await promptInput("name", "Connection name:");
|
|
14521
14610
|
if (existingNames.includes(name)) {
|
|
14522
|
-
console.error(
|
|
14611
|
+
console.error(chalk144.red(`Connection "${name}" already exists.`));
|
|
14523
14612
|
process.exit(1);
|
|
14524
14613
|
}
|
|
14525
14614
|
const url = await promptInput(
|
|
@@ -14528,22 +14617,22 @@ async function promptConnection(existingNames) {
|
|
|
14528
14617
|
);
|
|
14529
14618
|
const database = await promptInput("database", "Database name:");
|
|
14530
14619
|
if (!name || !url || !database) {
|
|
14531
|
-
console.error(
|
|
14620
|
+
console.error(chalk144.red("All fields are required."));
|
|
14532
14621
|
process.exit(1);
|
|
14533
14622
|
}
|
|
14534
14623
|
const apiKeyRef = await selectOpSecret();
|
|
14535
|
-
console.log(
|
|
14624
|
+
console.log(chalk144.dim(`Using: ${apiKeyRef}`));
|
|
14536
14625
|
return { name, url, database, apiKeyRef };
|
|
14537
14626
|
}
|
|
14538
14627
|
|
|
14539
14628
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
14540
|
-
import
|
|
14629
|
+
import chalk145 from "chalk";
|
|
14541
14630
|
function ravendbSetConnection(name) {
|
|
14542
14631
|
const raw = loadGlobalConfigRaw();
|
|
14543
14632
|
const ravendb = raw.ravendb ?? {};
|
|
14544
14633
|
const connections = ravendb.connections ?? [];
|
|
14545
14634
|
if (!connections.some((c) => c.name === name)) {
|
|
14546
|
-
console.error(
|
|
14635
|
+
console.error(chalk145.red(`Connection "${name}" not found.`));
|
|
14547
14636
|
console.error(
|
|
14548
14637
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14549
14638
|
);
|
|
@@ -14559,16 +14648,16 @@ function ravendbSetConnection(name) {
|
|
|
14559
14648
|
var ravendbAuth = createConnectionAuth({
|
|
14560
14649
|
load: loadConnections,
|
|
14561
14650
|
save: saveConnections,
|
|
14562
|
-
format: (c) => `${
|
|
14651
|
+
format: (c) => `${chalk146.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
14563
14652
|
promptNew: promptConnection,
|
|
14564
14653
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
14565
14654
|
});
|
|
14566
14655
|
|
|
14567
14656
|
// src/commands/ravendb/ravendbCollections.ts
|
|
14568
|
-
import
|
|
14657
|
+
import chalk150 from "chalk";
|
|
14569
14658
|
|
|
14570
14659
|
// src/commands/ravendb/ravenFetch.ts
|
|
14571
|
-
import
|
|
14660
|
+
import chalk148 from "chalk";
|
|
14572
14661
|
|
|
14573
14662
|
// src/commands/ravendb/getAccessToken.ts
|
|
14574
14663
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -14605,10 +14694,10 @@ ${errorText}`
|
|
|
14605
14694
|
|
|
14606
14695
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
14607
14696
|
import { execSync as execSync42 } from "child_process";
|
|
14608
|
-
import
|
|
14697
|
+
import chalk147 from "chalk";
|
|
14609
14698
|
function resolveOpSecret(reference) {
|
|
14610
14699
|
if (!reference.startsWith("op://")) {
|
|
14611
|
-
console.error(
|
|
14700
|
+
console.error(chalk147.red(`Invalid secret reference: must start with op://`));
|
|
14612
14701
|
process.exit(1);
|
|
14613
14702
|
}
|
|
14614
14703
|
try {
|
|
@@ -14618,7 +14707,7 @@ function resolveOpSecret(reference) {
|
|
|
14618
14707
|
}).trim();
|
|
14619
14708
|
} catch {
|
|
14620
14709
|
console.error(
|
|
14621
|
-
|
|
14710
|
+
chalk147.red(
|
|
14622
14711
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
14623
14712
|
)
|
|
14624
14713
|
);
|
|
@@ -14645,7 +14734,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14645
14734
|
if (!response.ok) {
|
|
14646
14735
|
const body = await response.text();
|
|
14647
14736
|
console.error(
|
|
14648
|
-
|
|
14737
|
+
chalk148.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
14649
14738
|
);
|
|
14650
14739
|
console.error(body.substring(0, 500));
|
|
14651
14740
|
process.exit(1);
|
|
@@ -14654,7 +14743,7 @@ async function ravenFetch(connection, path57) {
|
|
|
14654
14743
|
}
|
|
14655
14744
|
|
|
14656
14745
|
// src/commands/ravendb/resolveConnection.ts
|
|
14657
|
-
import
|
|
14746
|
+
import chalk149 from "chalk";
|
|
14658
14747
|
function loadRavendb() {
|
|
14659
14748
|
const raw = loadGlobalConfigRaw();
|
|
14660
14749
|
const ravendb = raw.ravendb;
|
|
@@ -14668,7 +14757,7 @@ function resolveConnection(name) {
|
|
|
14668
14757
|
const connectionName = name ?? defaultConnection;
|
|
14669
14758
|
if (!connectionName) {
|
|
14670
14759
|
console.error(
|
|
14671
|
-
|
|
14760
|
+
chalk149.red(
|
|
14672
14761
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
14673
14762
|
)
|
|
14674
14763
|
);
|
|
@@ -14676,7 +14765,7 @@ function resolveConnection(name) {
|
|
|
14676
14765
|
}
|
|
14677
14766
|
const connection = connections.find((c) => c.name === connectionName);
|
|
14678
14767
|
if (!connection) {
|
|
14679
|
-
console.error(
|
|
14768
|
+
console.error(chalk149.red(`Connection "${connectionName}" not found.`));
|
|
14680
14769
|
console.error(
|
|
14681
14770
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
14682
14771
|
);
|
|
@@ -14707,15 +14796,15 @@ async function ravendbCollections(connectionName) {
|
|
|
14707
14796
|
return;
|
|
14708
14797
|
}
|
|
14709
14798
|
for (const c of collections) {
|
|
14710
|
-
console.log(`${
|
|
14799
|
+
console.log(`${chalk150.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
14711
14800
|
}
|
|
14712
14801
|
}
|
|
14713
14802
|
|
|
14714
14803
|
// src/commands/ravendb/ravendbQuery.ts
|
|
14715
|
-
import
|
|
14804
|
+
import chalk152 from "chalk";
|
|
14716
14805
|
|
|
14717
14806
|
// src/commands/ravendb/fetchAllPages.ts
|
|
14718
|
-
import
|
|
14807
|
+
import chalk151 from "chalk";
|
|
14719
14808
|
|
|
14720
14809
|
// src/commands/ravendb/buildQueryPath.ts
|
|
14721
14810
|
function buildQueryPath(opts) {
|
|
@@ -14753,7 +14842,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14753
14842
|
allResults.push(...results);
|
|
14754
14843
|
start3 += results.length;
|
|
14755
14844
|
process.stderr.write(
|
|
14756
|
-
`\r${
|
|
14845
|
+
`\r${chalk151.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
14757
14846
|
);
|
|
14758
14847
|
if (start3 >= totalResults) break;
|
|
14759
14848
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -14768,7 +14857,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
14768
14857
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
14769
14858
|
const resolved = resolveArgs(connectionName, collection);
|
|
14770
14859
|
if (!resolved.collection && !options2.query) {
|
|
14771
|
-
console.error(
|
|
14860
|
+
console.error(chalk152.red("Provide a collection name or --query filter."));
|
|
14772
14861
|
process.exit(1);
|
|
14773
14862
|
}
|
|
14774
14863
|
const { collection: col } = resolved;
|
|
@@ -14806,7 +14895,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
14806
14895
|
import * as path28 from "path";
|
|
14807
14896
|
|
|
14808
14897
|
// src/commands/refactor/logViolations.ts
|
|
14809
|
-
import
|
|
14898
|
+
import chalk153 from "chalk";
|
|
14810
14899
|
var DEFAULT_MAX_LINES = 100;
|
|
14811
14900
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
14812
14901
|
if (violations.length === 0) {
|
|
@@ -14815,43 +14904,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
14815
14904
|
}
|
|
14816
14905
|
return;
|
|
14817
14906
|
}
|
|
14818
|
-
console.error(
|
|
14907
|
+
console.error(chalk153.red(`
|
|
14819
14908
|
Refactor check failed:
|
|
14820
14909
|
`));
|
|
14821
|
-
console.error(
|
|
14910
|
+
console.error(chalk153.red(` The following files exceed ${maxLines} lines:
|
|
14822
14911
|
`));
|
|
14823
14912
|
for (const violation of violations) {
|
|
14824
|
-
console.error(
|
|
14913
|
+
console.error(chalk153.red(` ${violation.file} (${violation.lines} lines)`));
|
|
14825
14914
|
}
|
|
14826
14915
|
console.error(
|
|
14827
|
-
|
|
14916
|
+
chalk153.yellow(
|
|
14828
14917
|
`
|
|
14829
14918
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
14830
14919
|
way to refactor it, ignore it with:
|
|
14831
14920
|
`
|
|
14832
14921
|
)
|
|
14833
14922
|
);
|
|
14834
|
-
console.error(
|
|
14923
|
+
console.error(chalk153.gray(` assist refactor ignore <file>
|
|
14835
14924
|
`));
|
|
14836
14925
|
if (process.env.CLAUDECODE) {
|
|
14837
|
-
console.error(
|
|
14926
|
+
console.error(chalk153.cyan(`
|
|
14838
14927
|
## Extracting Code to New Files
|
|
14839
14928
|
`));
|
|
14840
14929
|
console.error(
|
|
14841
|
-
|
|
14930
|
+
chalk153.cyan(
|
|
14842
14931
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
14843
14932
|
`
|
|
14844
14933
|
)
|
|
14845
14934
|
);
|
|
14846
14935
|
console.error(
|
|
14847
|
-
|
|
14936
|
+
chalk153.cyan(
|
|
14848
14937
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
14849
14938
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
14850
14939
|
`
|
|
14851
14940
|
)
|
|
14852
14941
|
);
|
|
14853
14942
|
console.error(
|
|
14854
|
-
|
|
14943
|
+
chalk153.cyan(
|
|
14855
14944
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
14856
14945
|
domains, move it to a common/shared folder.
|
|
14857
14946
|
`
|
|
@@ -15007,7 +15096,7 @@ async function check(pattern2, options2) {
|
|
|
15007
15096
|
|
|
15008
15097
|
// src/commands/refactor/extract/index.ts
|
|
15009
15098
|
import path35 from "path";
|
|
15010
|
-
import
|
|
15099
|
+
import chalk156 from "chalk";
|
|
15011
15100
|
|
|
15012
15101
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
15013
15102
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -15393,9 +15482,9 @@ function resolveImports(target, dependencies, sourceFile, statements = []) {
|
|
|
15393
15482
|
function extractTexts(target, allFunctions, statements) {
|
|
15394
15483
|
const stmtTexts = statements.map((v) => v.getFullText().trim());
|
|
15395
15484
|
const fnTexts = allFunctions.map((fn) => {
|
|
15396
|
-
const
|
|
15397
|
-
if (fn === target && !
|
|
15398
|
-
return
|
|
15485
|
+
const text7 = fn.getFullText().trim();
|
|
15486
|
+
if (fn === target && !text7.startsWith("export ")) return `export ${text7}`;
|
|
15487
|
+
return text7;
|
|
15399
15488
|
});
|
|
15400
15489
|
return [...stmtTexts, ...fnTexts];
|
|
15401
15490
|
}
|
|
@@ -15582,23 +15671,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
15582
15671
|
|
|
15583
15672
|
// src/commands/refactor/extract/displayPlan.ts
|
|
15584
15673
|
import path32 from "path";
|
|
15585
|
-
import
|
|
15674
|
+
import chalk154 from "chalk";
|
|
15586
15675
|
function section(title) {
|
|
15587
15676
|
return `
|
|
15588
|
-
${
|
|
15677
|
+
${chalk154.cyan(title)}`;
|
|
15589
15678
|
}
|
|
15590
15679
|
function displayImporters(plan2, cwd) {
|
|
15591
15680
|
if (plan2.importersToUpdate.length === 0) return;
|
|
15592
15681
|
console.log(section("Update importers:"));
|
|
15593
15682
|
for (const imp of plan2.importersToUpdate) {
|
|
15594
15683
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
15595
|
-
console.log(` ${
|
|
15684
|
+
console.log(` ${chalk154.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
15596
15685
|
}
|
|
15597
15686
|
}
|
|
15598
15687
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
15599
|
-
console.log(
|
|
15688
|
+
console.log(chalk154.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
15600
15689
|
`));
|
|
15601
|
-
console.log(` ${
|
|
15690
|
+
console.log(` ${chalk154.cyan("Functions to move:")}`);
|
|
15602
15691
|
for (const name of plan2.extractedNames) {
|
|
15603
15692
|
console.log(` ${name}`);
|
|
15604
15693
|
}
|
|
@@ -15632,7 +15721,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
15632
15721
|
|
|
15633
15722
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
15634
15723
|
import path34 from "path";
|
|
15635
|
-
import
|
|
15724
|
+
import chalk155 from "chalk";
|
|
15636
15725
|
import { Project as Project4 } from "ts-morph";
|
|
15637
15726
|
|
|
15638
15727
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -15692,7 +15781,7 @@ function loadProjectFile(file) {
|
|
|
15692
15781
|
});
|
|
15693
15782
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
15694
15783
|
if (!sourceFile) {
|
|
15695
|
-
console.log(
|
|
15784
|
+
console.log(chalk155.red(`File not found in project: ${file}`));
|
|
15696
15785
|
process.exit(1);
|
|
15697
15786
|
}
|
|
15698
15787
|
return { project, sourceFile };
|
|
@@ -15715,19 +15804,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
15715
15804
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
15716
15805
|
if (options2.apply) {
|
|
15717
15806
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
15718
|
-
console.log(
|
|
15807
|
+
console.log(chalk156.green("\nExtraction complete"));
|
|
15719
15808
|
} else {
|
|
15720
|
-
console.log(
|
|
15809
|
+
console.log(chalk156.dim("\nDry run. Use --apply to execute."));
|
|
15721
15810
|
}
|
|
15722
15811
|
}
|
|
15723
15812
|
|
|
15724
15813
|
// src/commands/refactor/ignore.ts
|
|
15725
15814
|
import fs23 from "fs";
|
|
15726
|
-
import
|
|
15815
|
+
import chalk157 from "chalk";
|
|
15727
15816
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
15728
15817
|
function ignore(file) {
|
|
15729
15818
|
if (!fs23.existsSync(file)) {
|
|
15730
|
-
console.error(
|
|
15819
|
+
console.error(chalk157.red(`Error: File does not exist: ${file}`));
|
|
15731
15820
|
process.exit(1);
|
|
15732
15821
|
}
|
|
15733
15822
|
const content = fs23.readFileSync(file, "utf8");
|
|
@@ -15743,7 +15832,7 @@ function ignore(file) {
|
|
|
15743
15832
|
fs23.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
15744
15833
|
}
|
|
15745
15834
|
console.log(
|
|
15746
|
-
|
|
15835
|
+
chalk157.green(
|
|
15747
15836
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
15748
15837
|
)
|
|
15749
15838
|
);
|
|
@@ -15752,12 +15841,12 @@ function ignore(file) {
|
|
|
15752
15841
|
// src/commands/refactor/rename/index.ts
|
|
15753
15842
|
import fs26 from "fs";
|
|
15754
15843
|
import path40 from "path";
|
|
15755
|
-
import
|
|
15844
|
+
import chalk160 from "chalk";
|
|
15756
15845
|
|
|
15757
15846
|
// src/commands/refactor/rename/applyRename.ts
|
|
15758
15847
|
import fs25 from "fs";
|
|
15759
15848
|
import path37 from "path";
|
|
15760
|
-
import
|
|
15849
|
+
import chalk158 from "chalk";
|
|
15761
15850
|
|
|
15762
15851
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
15763
15852
|
import path36 from "path";
|
|
@@ -15862,13 +15951,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
15862
15951
|
const updatedContents = applyRewrites(rewrites);
|
|
15863
15952
|
for (const [file, content] of updatedContents) {
|
|
15864
15953
|
fs25.writeFileSync(file, content, "utf8");
|
|
15865
|
-
console.log(
|
|
15954
|
+
console.log(chalk158.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
15866
15955
|
}
|
|
15867
15956
|
const destDir = path37.dirname(destPath);
|
|
15868
15957
|
if (!fs25.existsSync(destDir)) fs25.mkdirSync(destDir, { recursive: true });
|
|
15869
15958
|
fs25.renameSync(sourcePath, destPath);
|
|
15870
15959
|
console.log(
|
|
15871
|
-
|
|
15960
|
+
chalk158.white(
|
|
15872
15961
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
15873
15962
|
)
|
|
15874
15963
|
);
|
|
@@ -15955,16 +16044,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
15955
16044
|
|
|
15956
16045
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
15957
16046
|
import path39 from "path";
|
|
15958
|
-
import
|
|
16047
|
+
import chalk159 from "chalk";
|
|
15959
16048
|
function printRenamePreview(rewrites, cwd) {
|
|
15960
16049
|
for (const rewrite of rewrites) {
|
|
15961
16050
|
console.log(
|
|
15962
|
-
|
|
16051
|
+
chalk159.dim(
|
|
15963
16052
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
15964
16053
|
)
|
|
15965
16054
|
);
|
|
15966
16055
|
}
|
|
15967
|
-
console.log(
|
|
16056
|
+
console.log(chalk159.dim("Dry run. Use --apply to execute."));
|
|
15968
16057
|
}
|
|
15969
16058
|
|
|
15970
16059
|
// src/commands/refactor/rename/index.ts
|
|
@@ -15975,20 +16064,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15975
16064
|
const relSource = path40.relative(cwd, sourcePath);
|
|
15976
16065
|
const relDest = path40.relative(cwd, destPath);
|
|
15977
16066
|
if (!fs26.existsSync(sourcePath)) {
|
|
15978
|
-
console.log(
|
|
16067
|
+
console.log(chalk160.red(`File not found: ${source}`));
|
|
15979
16068
|
process.exit(1);
|
|
15980
16069
|
}
|
|
15981
16070
|
if (destPath !== sourcePath && fs26.existsSync(destPath)) {
|
|
15982
|
-
console.log(
|
|
16071
|
+
console.log(chalk160.red(`Destination already exists: ${destination}`));
|
|
15983
16072
|
process.exit(1);
|
|
15984
16073
|
}
|
|
15985
|
-
console.log(
|
|
15986
|
-
console.log(
|
|
15987
|
-
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..."));
|
|
15988
16077
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
15989
16078
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
15990
16079
|
console.log(
|
|
15991
|
-
|
|
16080
|
+
chalk160.dim(
|
|
15992
16081
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
15993
16082
|
)
|
|
15994
16083
|
);
|
|
@@ -15997,11 +16086,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
15997
16086
|
return;
|
|
15998
16087
|
}
|
|
15999
16088
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
16000
|
-
console.log(
|
|
16089
|
+
console.log(chalk160.green("Done"));
|
|
16001
16090
|
}
|
|
16002
16091
|
|
|
16003
16092
|
// src/commands/refactor/renameSymbol/index.ts
|
|
16004
|
-
import
|
|
16093
|
+
import chalk161 from "chalk";
|
|
16005
16094
|
|
|
16006
16095
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
16007
16096
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -16047,33 +16136,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
16047
16136
|
const { project, sourceFile } = loadProjectFile(file);
|
|
16048
16137
|
const symbol = findSymbol(sourceFile, oldName);
|
|
16049
16138
|
if (!symbol) {
|
|
16050
|
-
console.log(
|
|
16139
|
+
console.log(chalk161.red(`Symbol "${oldName}" not found in ${file}`));
|
|
16051
16140
|
process.exit(1);
|
|
16052
16141
|
}
|
|
16053
16142
|
const grouped = groupReferences(symbol, cwd);
|
|
16054
16143
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
16055
16144
|
console.log(
|
|
16056
|
-
|
|
16145
|
+
chalk161.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
16057
16146
|
`)
|
|
16058
16147
|
);
|
|
16059
16148
|
for (const [refFile, lines] of grouped) {
|
|
16060
16149
|
console.log(
|
|
16061
|
-
` ${
|
|
16150
|
+
` ${chalk161.dim(refFile)}: lines ${chalk161.cyan(lines.join(", "))}`
|
|
16062
16151
|
);
|
|
16063
16152
|
}
|
|
16064
16153
|
if (options2.apply) {
|
|
16065
16154
|
symbol.rename(newName);
|
|
16066
16155
|
await project.save();
|
|
16067
|
-
console.log(
|
|
16156
|
+
console.log(chalk161.green(`
|
|
16068
16157
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
16069
16158
|
} else {
|
|
16070
|
-
console.log(
|
|
16159
|
+
console.log(chalk161.dim("\nDry run. Use --apply to execute."));
|
|
16071
16160
|
}
|
|
16072
16161
|
}
|
|
16073
16162
|
|
|
16074
16163
|
// src/commands/refactor/restructure/index.ts
|
|
16075
16164
|
import path48 from "path";
|
|
16076
|
-
import
|
|
16165
|
+
import chalk164 from "chalk";
|
|
16077
16166
|
|
|
16078
16167
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
16079
16168
|
import path42 from "path";
|
|
@@ -16152,50 +16241,50 @@ function clusterFiles(graph) {
|
|
|
16152
16241
|
|
|
16153
16242
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
16154
16243
|
import path44 from "path";
|
|
16155
|
-
import
|
|
16244
|
+
import chalk162 from "chalk";
|
|
16156
16245
|
function relPath(filePath) {
|
|
16157
16246
|
return path44.relative(process.cwd(), filePath);
|
|
16158
16247
|
}
|
|
16159
16248
|
function displayMoves(plan2) {
|
|
16160
16249
|
if (plan2.moves.length === 0) return;
|
|
16161
|
-
console.log(
|
|
16250
|
+
console.log(chalk162.bold("\nFile moves:"));
|
|
16162
16251
|
for (const move2 of plan2.moves) {
|
|
16163
16252
|
console.log(
|
|
16164
|
-
` ${
|
|
16253
|
+
` ${chalk162.red(relPath(move2.from))} \u2192 ${chalk162.green(relPath(move2.to))}`
|
|
16165
16254
|
);
|
|
16166
|
-
console.log(
|
|
16255
|
+
console.log(chalk162.dim(` ${move2.reason}`));
|
|
16167
16256
|
}
|
|
16168
16257
|
}
|
|
16169
16258
|
function displayRewrites(rewrites) {
|
|
16170
16259
|
if (rewrites.length === 0) return;
|
|
16171
16260
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
16172
|
-
console.log(
|
|
16261
|
+
console.log(chalk162.bold(`
|
|
16173
16262
|
Import rewrites (${affectedFiles.size} files):`));
|
|
16174
16263
|
for (const file of affectedFiles) {
|
|
16175
|
-
console.log(` ${
|
|
16264
|
+
console.log(` ${chalk162.cyan(relPath(file))}:`);
|
|
16176
16265
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
16177
16266
|
(r) => r.file === file
|
|
16178
16267
|
)) {
|
|
16179
16268
|
console.log(
|
|
16180
|
-
` ${
|
|
16269
|
+
` ${chalk162.red(`"${oldSpecifier}"`)} \u2192 ${chalk162.green(`"${newSpecifier}"`)}`
|
|
16181
16270
|
);
|
|
16182
16271
|
}
|
|
16183
16272
|
}
|
|
16184
16273
|
}
|
|
16185
16274
|
function displayPlan2(plan2) {
|
|
16186
16275
|
if (plan2.warnings.length > 0) {
|
|
16187
|
-
console.log(
|
|
16188
|
-
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}`));
|
|
16189
16278
|
}
|
|
16190
16279
|
if (plan2.newDirectories.length > 0) {
|
|
16191
|
-
console.log(
|
|
16280
|
+
console.log(chalk162.bold("\nNew directories:"));
|
|
16192
16281
|
for (const dir of plan2.newDirectories)
|
|
16193
|
-
console.log(
|
|
16282
|
+
console.log(chalk162.green(` ${dir}/`));
|
|
16194
16283
|
}
|
|
16195
16284
|
displayMoves(plan2);
|
|
16196
16285
|
displayRewrites(plan2.rewrites);
|
|
16197
16286
|
console.log(
|
|
16198
|
-
|
|
16287
|
+
chalk162.dim(
|
|
16199
16288
|
`
|
|
16200
16289
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
16201
16290
|
)
|
|
@@ -16205,18 +16294,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
16205
16294
|
// src/commands/refactor/restructure/executePlan.ts
|
|
16206
16295
|
import fs27 from "fs";
|
|
16207
16296
|
import path45 from "path";
|
|
16208
|
-
import
|
|
16297
|
+
import chalk163 from "chalk";
|
|
16209
16298
|
function executePlan(plan2) {
|
|
16210
16299
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
16211
16300
|
for (const [file, content] of updatedContents) {
|
|
16212
16301
|
fs27.writeFileSync(file, content, "utf8");
|
|
16213
16302
|
console.log(
|
|
16214
|
-
|
|
16303
|
+
chalk163.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
16215
16304
|
);
|
|
16216
16305
|
}
|
|
16217
16306
|
for (const dir of plan2.newDirectories) {
|
|
16218
16307
|
fs27.mkdirSync(dir, { recursive: true });
|
|
16219
|
-
console.log(
|
|
16308
|
+
console.log(chalk163.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
16220
16309
|
}
|
|
16221
16310
|
for (const move2 of plan2.moves) {
|
|
16222
16311
|
const targetDir = path45.dirname(move2.to);
|
|
@@ -16225,7 +16314,7 @@ function executePlan(plan2) {
|
|
|
16225
16314
|
}
|
|
16226
16315
|
fs27.renameSync(move2.from, move2.to);
|
|
16227
16316
|
console.log(
|
|
16228
|
-
|
|
16317
|
+
chalk163.white(
|
|
16229
16318
|
` Moved ${path45.relative(process.cwd(), move2.from)} \u2192 ${path45.relative(process.cwd(), move2.to)}`
|
|
16230
16319
|
)
|
|
16231
16320
|
);
|
|
@@ -16240,7 +16329,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
16240
16329
|
if (entries.length === 0) {
|
|
16241
16330
|
fs27.rmdirSync(dir);
|
|
16242
16331
|
console.log(
|
|
16243
|
-
|
|
16332
|
+
chalk163.dim(
|
|
16244
16333
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
16245
16334
|
)
|
|
16246
16335
|
);
|
|
@@ -16373,22 +16462,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
16373
16462
|
const targetPattern = pattern2 ?? "src";
|
|
16374
16463
|
const files = findSourceFiles2(targetPattern);
|
|
16375
16464
|
if (files.length === 0) {
|
|
16376
|
-
console.log(
|
|
16465
|
+
console.log(chalk164.yellow("No files found matching pattern"));
|
|
16377
16466
|
return;
|
|
16378
16467
|
}
|
|
16379
16468
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
16380
16469
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
16381
16470
|
if (plan2.moves.length === 0) {
|
|
16382
|
-
console.log(
|
|
16471
|
+
console.log(chalk164.green("No restructuring needed"));
|
|
16383
16472
|
return;
|
|
16384
16473
|
}
|
|
16385
16474
|
displayPlan2(plan2);
|
|
16386
16475
|
if (options2.apply) {
|
|
16387
|
-
console.log(
|
|
16476
|
+
console.log(chalk164.bold("\nApplying changes..."));
|
|
16388
16477
|
executePlan(plan2);
|
|
16389
|
-
console.log(
|
|
16478
|
+
console.log(chalk164.green("\nRestructuring complete"));
|
|
16390
16479
|
} else {
|
|
16391
|
-
console.log(
|
|
16480
|
+
console.log(chalk164.dim("\nDry run. Use --apply to execute."));
|
|
16392
16481
|
}
|
|
16393
16482
|
}
|
|
16394
16483
|
|
|
@@ -16962,18 +17051,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
16962
17051
|
}
|
|
16963
17052
|
|
|
16964
17053
|
// src/commands/review/warnOutOfDiff.ts
|
|
16965
|
-
import
|
|
17054
|
+
import chalk165 from "chalk";
|
|
16966
17055
|
function warnOutOfDiff(outOfDiff) {
|
|
16967
17056
|
if (outOfDiff.length === 0) return;
|
|
16968
17057
|
console.warn(
|
|
16969
|
-
|
|
17058
|
+
chalk165.yellow(
|
|
16970
17059
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
16971
17060
|
)
|
|
16972
17061
|
);
|
|
16973
17062
|
for (const finding of outOfDiff) {
|
|
16974
17063
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
16975
17064
|
console.warn(
|
|
16976
|
-
` ${
|
|
17065
|
+
` ${chalk165.yellow("\xB7")} ${finding.title} ${chalk165.dim(
|
|
16977
17066
|
`(${finding.file}:${range})`
|
|
16978
17067
|
)}`
|
|
16979
17068
|
);
|
|
@@ -16992,18 +17081,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
16992
17081
|
}
|
|
16993
17082
|
|
|
16994
17083
|
// src/commands/review/warnUnlocated.ts
|
|
16995
|
-
import
|
|
17084
|
+
import chalk166 from "chalk";
|
|
16996
17085
|
function warnUnlocated(unlocated) {
|
|
16997
17086
|
if (unlocated.length === 0) return;
|
|
16998
17087
|
console.warn(
|
|
16999
|
-
|
|
17088
|
+
chalk166.yellow(
|
|
17000
17089
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
17001
17090
|
)
|
|
17002
17091
|
);
|
|
17003
17092
|
for (const finding of unlocated) {
|
|
17004
|
-
const where = finding.location ||
|
|
17093
|
+
const where = finding.location || chalk166.dim("missing");
|
|
17005
17094
|
console.warn(
|
|
17006
|
-
` ${
|
|
17095
|
+
` ${chalk166.yellow("\xB7")} ${finding.title} ${chalk166.dim(`(${where})`)}`
|
|
17007
17096
|
);
|
|
17008
17097
|
}
|
|
17009
17098
|
}
|
|
@@ -17236,9 +17325,9 @@ var MultiSpinner = class {
|
|
|
17236
17325
|
elapsedPrefix: prefix2
|
|
17237
17326
|
});
|
|
17238
17327
|
}
|
|
17239
|
-
failRemaining(
|
|
17328
|
+
failRemaining(text7) {
|
|
17240
17329
|
for (const entry of this.entries) {
|
|
17241
|
-
if (entry.state === "running") this.resolve(entry, "failed",
|
|
17330
|
+
if (entry.state === "running") this.resolve(entry, "failed", text7);
|
|
17242
17331
|
}
|
|
17243
17332
|
}
|
|
17244
17333
|
add(entry) {
|
|
@@ -17251,14 +17340,14 @@ var MultiSpinner = class {
|
|
|
17251
17340
|
set text(value) {
|
|
17252
17341
|
entry.text = value;
|
|
17253
17342
|
},
|
|
17254
|
-
succeed: (
|
|
17255
|
-
fail: (
|
|
17343
|
+
succeed: (text7) => this.resolve(entry, "succeeded", text7),
|
|
17344
|
+
fail: (text7) => this.resolve(entry, "failed", text7)
|
|
17256
17345
|
};
|
|
17257
17346
|
}
|
|
17258
|
-
resolve(entry, state,
|
|
17347
|
+
resolve(entry, state, text7) {
|
|
17259
17348
|
if (entry.state !== "running") return;
|
|
17260
17349
|
entry.state = state;
|
|
17261
|
-
if (
|
|
17350
|
+
if (text7 !== void 0) entry.text = text7;
|
|
17262
17351
|
entry.elapsedStart = void 0;
|
|
17263
17352
|
this.render();
|
|
17264
17353
|
this.maybeFinish();
|
|
@@ -17333,12 +17422,12 @@ function skippedCodexResult(outputPath) {
|
|
|
17333
17422
|
// src/commands/review/formatReviewerFailure.ts
|
|
17334
17423
|
var FAST_FAIL_MS = 1e3;
|
|
17335
17424
|
var STDOUT_TAIL_LINES = 20;
|
|
17336
|
-
function indent(
|
|
17337
|
-
return
|
|
17425
|
+
function indent(text7) {
|
|
17426
|
+
return text7.split(/\r?\n/).map((line) => ` ${line}`);
|
|
17338
17427
|
}
|
|
17339
|
-
function tailLines(
|
|
17340
|
-
const lines =
|
|
17341
|
-
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");
|
|
17342
17431
|
}
|
|
17343
17432
|
function isFastFail(input) {
|
|
17344
17433
|
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
@@ -18175,7 +18264,7 @@ function registerReview(program2) {
|
|
|
18175
18264
|
}
|
|
18176
18265
|
|
|
18177
18266
|
// src/commands/seq/seqAuth.ts
|
|
18178
|
-
import
|
|
18267
|
+
import chalk168 from "chalk";
|
|
18179
18268
|
|
|
18180
18269
|
// src/commands/seq/loadConnections.ts
|
|
18181
18270
|
function loadConnections2() {
|
|
@@ -18204,10 +18293,10 @@ function setDefaultConnection(name) {
|
|
|
18204
18293
|
}
|
|
18205
18294
|
|
|
18206
18295
|
// src/shared/assertUniqueName.ts
|
|
18207
|
-
import
|
|
18296
|
+
import chalk167 from "chalk";
|
|
18208
18297
|
function assertUniqueName(existingNames, name) {
|
|
18209
18298
|
if (existingNames.includes(name)) {
|
|
18210
|
-
console.error(
|
|
18299
|
+
console.error(chalk167.red(`Connection "${name}" already exists.`));
|
|
18211
18300
|
process.exit(1);
|
|
18212
18301
|
}
|
|
18213
18302
|
}
|
|
@@ -18225,16 +18314,16 @@ async function promptConnection2(existingNames) {
|
|
|
18225
18314
|
var seqAuth = createConnectionAuth({
|
|
18226
18315
|
load: loadConnections2,
|
|
18227
18316
|
save: saveConnections2,
|
|
18228
|
-
format: (c) => `${
|
|
18317
|
+
format: (c) => `${chalk168.bold(c.name)} ${c.url}`,
|
|
18229
18318
|
promptNew: promptConnection2,
|
|
18230
18319
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
18231
18320
|
});
|
|
18232
18321
|
|
|
18233
18322
|
// src/commands/seq/seqQuery.ts
|
|
18234
|
-
import
|
|
18323
|
+
import chalk172 from "chalk";
|
|
18235
18324
|
|
|
18236
18325
|
// src/commands/seq/fetchSeq.ts
|
|
18237
|
-
import
|
|
18326
|
+
import chalk169 from "chalk";
|
|
18238
18327
|
async function fetchSeq(conn, path57, params) {
|
|
18239
18328
|
const url = `${conn.url}${path57}?${params}`;
|
|
18240
18329
|
const response = await fetch(url, {
|
|
@@ -18245,7 +18334,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
18245
18334
|
});
|
|
18246
18335
|
if (!response.ok) {
|
|
18247
18336
|
const body = await response.text();
|
|
18248
|
-
console.error(
|
|
18337
|
+
console.error(chalk169.red(`Seq returned ${response.status}: ${body}`));
|
|
18249
18338
|
process.exit(1);
|
|
18250
18339
|
}
|
|
18251
18340
|
return response;
|
|
@@ -18259,8 +18348,8 @@ function filterToSql(filter) {
|
|
|
18259
18348
|
// src/commands/seq/fetchSeqData.ts
|
|
18260
18349
|
function buildDataParams(filter, count7, from, to) {
|
|
18261
18350
|
const sqlFilter = filterToSql(filter);
|
|
18262
|
-
const
|
|
18263
|
-
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 });
|
|
18264
18353
|
if (from) params.set("rangeStartUtc", from);
|
|
18265
18354
|
if (to) params.set("rangeEndUtc", to);
|
|
18266
18355
|
return params;
|
|
@@ -18304,23 +18393,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
18304
18393
|
}
|
|
18305
18394
|
|
|
18306
18395
|
// src/commands/seq/formatEvent.ts
|
|
18307
|
-
import
|
|
18396
|
+
import chalk170 from "chalk";
|
|
18308
18397
|
function levelColor(level) {
|
|
18309
18398
|
switch (level) {
|
|
18310
18399
|
case "Fatal":
|
|
18311
|
-
return
|
|
18400
|
+
return chalk170.bgRed.white;
|
|
18312
18401
|
case "Error":
|
|
18313
|
-
return
|
|
18402
|
+
return chalk170.red;
|
|
18314
18403
|
case "Warning":
|
|
18315
|
-
return
|
|
18404
|
+
return chalk170.yellow;
|
|
18316
18405
|
case "Information":
|
|
18317
|
-
return
|
|
18406
|
+
return chalk170.cyan;
|
|
18318
18407
|
case "Debug":
|
|
18319
|
-
return
|
|
18408
|
+
return chalk170.gray;
|
|
18320
18409
|
case "Verbose":
|
|
18321
|
-
return
|
|
18410
|
+
return chalk170.dim;
|
|
18322
18411
|
default:
|
|
18323
|
-
return
|
|
18412
|
+
return chalk170.white;
|
|
18324
18413
|
}
|
|
18325
18414
|
}
|
|
18326
18415
|
function levelAbbrev(level) {
|
|
@@ -18361,12 +18450,12 @@ function formatTimestamp(iso) {
|
|
|
18361
18450
|
function formatEvent(event) {
|
|
18362
18451
|
const color = levelColor(event.Level);
|
|
18363
18452
|
const abbrev = levelAbbrev(event.Level);
|
|
18364
|
-
const ts8 =
|
|
18453
|
+
const ts8 = chalk170.dim(formatTimestamp(event.Timestamp));
|
|
18365
18454
|
const msg = renderMessage(event);
|
|
18366
18455
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
18367
18456
|
if (event.Exception) {
|
|
18368
18457
|
for (const line of event.Exception.split("\n")) {
|
|
18369
|
-
lines.push(
|
|
18458
|
+
lines.push(chalk170.red(` ${line}`));
|
|
18370
18459
|
}
|
|
18371
18460
|
}
|
|
18372
18461
|
return lines.join("\n");
|
|
@@ -18399,11 +18488,11 @@ function rejectTimestampFilter(filter) {
|
|
|
18399
18488
|
}
|
|
18400
18489
|
|
|
18401
18490
|
// src/shared/resolveNamedConnection.ts
|
|
18402
|
-
import
|
|
18491
|
+
import chalk171 from "chalk";
|
|
18403
18492
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
18404
18493
|
if (connections.length === 0) {
|
|
18405
18494
|
console.error(
|
|
18406
|
-
|
|
18495
|
+
chalk171.red(
|
|
18407
18496
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
18408
18497
|
)
|
|
18409
18498
|
);
|
|
@@ -18412,7 +18501,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
18412
18501
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
18413
18502
|
const connection = connections.find((c) => c.name === target);
|
|
18414
18503
|
if (!connection) {
|
|
18415
|
-
console.error(
|
|
18504
|
+
console.error(chalk171.red(`${kind} connection "${target}" not found.`));
|
|
18416
18505
|
process.exit(1);
|
|
18417
18506
|
}
|
|
18418
18507
|
return connection;
|
|
@@ -18441,7 +18530,7 @@ async function seqQuery(filter, options2) {
|
|
|
18441
18530
|
new URLSearchParams({ filter, count: String(count7) })
|
|
18442
18531
|
);
|
|
18443
18532
|
if (events.length === 0) {
|
|
18444
|
-
console.log(
|
|
18533
|
+
console.log(chalk172.yellow("No events found."));
|
|
18445
18534
|
return;
|
|
18446
18535
|
}
|
|
18447
18536
|
if (options2.json) {
|
|
@@ -18452,11 +18541,11 @@ async function seqQuery(filter, options2) {
|
|
|
18452
18541
|
for (const event of chronological) {
|
|
18453
18542
|
console.log(formatEvent(event));
|
|
18454
18543
|
}
|
|
18455
|
-
console.log(
|
|
18544
|
+
console.log(chalk172.dim(`
|
|
18456
18545
|
${events.length} events`));
|
|
18457
18546
|
if (events.length >= count7) {
|
|
18458
18547
|
console.log(
|
|
18459
|
-
|
|
18548
|
+
chalk172.yellow(
|
|
18460
18549
|
`Results limited to ${count7}. Use --count to retrieve more.`
|
|
18461
18550
|
)
|
|
18462
18551
|
);
|
|
@@ -18464,10 +18553,10 @@ ${events.length} events`));
|
|
|
18464
18553
|
}
|
|
18465
18554
|
|
|
18466
18555
|
// src/shared/setNamedDefaultConnection.ts
|
|
18467
|
-
import
|
|
18556
|
+
import chalk173 from "chalk";
|
|
18468
18557
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
18469
18558
|
if (!connections.find((c) => c.name === name)) {
|
|
18470
|
-
console.error(
|
|
18559
|
+
console.error(chalk173.red(`Connection "${name}" not found.`));
|
|
18471
18560
|
process.exit(1);
|
|
18472
18561
|
}
|
|
18473
18562
|
setDefault(name);
|
|
@@ -18515,36 +18604,36 @@ function registerSignal(program2) {
|
|
|
18515
18604
|
}
|
|
18516
18605
|
|
|
18517
18606
|
// src/commands/sql/sqlAuth.ts
|
|
18518
|
-
import
|
|
18607
|
+
import chalk175 from "chalk";
|
|
18519
18608
|
|
|
18520
18609
|
// src/commands/sql/loadConnections.ts
|
|
18521
18610
|
function loadConnections3() {
|
|
18522
18611
|
const raw = loadGlobalConfigRaw();
|
|
18523
|
-
const
|
|
18524
|
-
return
|
|
18612
|
+
const sql8 = raw.sql;
|
|
18613
|
+
return sql8?.connections ?? [];
|
|
18525
18614
|
}
|
|
18526
18615
|
function saveConnections3(connections) {
|
|
18527
18616
|
const raw = loadGlobalConfigRaw();
|
|
18528
|
-
const
|
|
18529
|
-
|
|
18530
|
-
raw.sql =
|
|
18617
|
+
const sql8 = raw.sql ?? {};
|
|
18618
|
+
sql8.connections = connections;
|
|
18619
|
+
raw.sql = sql8;
|
|
18531
18620
|
saveGlobalConfig(raw);
|
|
18532
18621
|
}
|
|
18533
18622
|
function getDefaultConnection2() {
|
|
18534
18623
|
const raw = loadGlobalConfigRaw();
|
|
18535
|
-
const
|
|
18536
|
-
return
|
|
18624
|
+
const sql8 = raw.sql;
|
|
18625
|
+
return sql8?.defaultConnection;
|
|
18537
18626
|
}
|
|
18538
18627
|
function setDefaultConnection2(name) {
|
|
18539
18628
|
const raw = loadGlobalConfigRaw();
|
|
18540
|
-
const
|
|
18541
|
-
|
|
18542
|
-
raw.sql =
|
|
18629
|
+
const sql8 = raw.sql ?? {};
|
|
18630
|
+
sql8.defaultConnection = name;
|
|
18631
|
+
raw.sql = sql8;
|
|
18543
18632
|
saveGlobalConfig(raw);
|
|
18544
18633
|
}
|
|
18545
18634
|
|
|
18546
18635
|
// src/commands/sql/promptConnection.ts
|
|
18547
|
-
import
|
|
18636
|
+
import chalk174 from "chalk";
|
|
18548
18637
|
async function promptConnection3(existingNames) {
|
|
18549
18638
|
const name = await promptInput("name", "Connection name:", "default");
|
|
18550
18639
|
assertUniqueName(existingNames, name);
|
|
@@ -18552,7 +18641,7 @@ async function promptConnection3(existingNames) {
|
|
|
18552
18641
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
18553
18642
|
const port = Number.parseInt(portStr, 10);
|
|
18554
18643
|
if (!Number.isFinite(port)) {
|
|
18555
|
-
console.error(
|
|
18644
|
+
console.error(chalk174.red(`Invalid port "${portStr}".`));
|
|
18556
18645
|
process.exit(1);
|
|
18557
18646
|
}
|
|
18558
18647
|
const user = await promptInput("user", "User:");
|
|
@@ -18565,13 +18654,13 @@ async function promptConnection3(existingNames) {
|
|
|
18565
18654
|
var sqlAuth = createConnectionAuth({
|
|
18566
18655
|
load: loadConnections3,
|
|
18567
18656
|
save: saveConnections3,
|
|
18568
|
-
format: (c) => `${
|
|
18657
|
+
format: (c) => `${chalk175.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
18569
18658
|
promptNew: promptConnection3,
|
|
18570
18659
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
18571
18660
|
});
|
|
18572
18661
|
|
|
18573
18662
|
// src/commands/sql/printTable.ts
|
|
18574
|
-
import
|
|
18663
|
+
import chalk176 from "chalk";
|
|
18575
18664
|
function formatCell(value) {
|
|
18576
18665
|
if (value === null || value === void 0) return "";
|
|
18577
18666
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -18580,7 +18669,7 @@ function formatCell(value) {
|
|
|
18580
18669
|
}
|
|
18581
18670
|
function printTable(rows) {
|
|
18582
18671
|
if (rows.length === 0) {
|
|
18583
|
-
console.log(
|
|
18672
|
+
console.log(chalk176.yellow("(no rows)"));
|
|
18584
18673
|
return;
|
|
18585
18674
|
}
|
|
18586
18675
|
const columns = Object.keys(rows[0]);
|
|
@@ -18588,13 +18677,13 @@ function printTable(rows) {
|
|
|
18588
18677
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
18589
18678
|
);
|
|
18590
18679
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
18591
|
-
console.log(
|
|
18592
|
-
console.log(
|
|
18680
|
+
console.log(chalk176.dim(header));
|
|
18681
|
+
console.log(chalk176.dim("-".repeat(header.length)));
|
|
18593
18682
|
for (const row of rows) {
|
|
18594
18683
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
18595
18684
|
console.log(line);
|
|
18596
18685
|
}
|
|
18597
|
-
console.log(
|
|
18686
|
+
console.log(chalk176.dim(`
|
|
18598
18687
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
18599
18688
|
}
|
|
18600
18689
|
|
|
@@ -18654,7 +18743,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
18654
18743
|
}
|
|
18655
18744
|
|
|
18656
18745
|
// src/commands/sql/sqlMutate.ts
|
|
18657
|
-
import
|
|
18746
|
+
import chalk177 from "chalk";
|
|
18658
18747
|
|
|
18659
18748
|
// src/commands/sql/isMutation.ts
|
|
18660
18749
|
var MUTATION_KEYWORDS = [
|
|
@@ -18675,11 +18764,11 @@ var MUTATION_PATTERN = new RegExp(
|
|
|
18675
18764
|
`\\b(${MUTATION_KEYWORDS.join("|")})\\b`,
|
|
18676
18765
|
"i"
|
|
18677
18766
|
);
|
|
18678
|
-
function stripComments(
|
|
18679
|
-
return
|
|
18767
|
+
function stripComments(sql8) {
|
|
18768
|
+
return sql8.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
|
|
18680
18769
|
}
|
|
18681
|
-
function isMutation(
|
|
18682
|
-
const stripped = stripComments(
|
|
18770
|
+
function isMutation(sql8) {
|
|
18771
|
+
const stripped = stripComments(sql8);
|
|
18683
18772
|
if (MUTATION_PATTERN.test(stripped)) return true;
|
|
18684
18773
|
return /\bSELECT\b[\s\S]+\bINTO\s+\w/i.test(stripped);
|
|
18685
18774
|
}
|
|
@@ -18688,7 +18777,7 @@ function isMutation(sql6) {
|
|
|
18688
18777
|
async function sqlMutate(query, connectionName) {
|
|
18689
18778
|
if (!isMutation(query)) {
|
|
18690
18779
|
console.error(
|
|
18691
|
-
|
|
18780
|
+
chalk177.red(
|
|
18692
18781
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
18693
18782
|
)
|
|
18694
18783
|
);
|
|
@@ -18698,18 +18787,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
18698
18787
|
const pool = await sqlConnect(conn);
|
|
18699
18788
|
try {
|
|
18700
18789
|
const result = await pool.request().query(query);
|
|
18701
|
-
console.log(
|
|
18790
|
+
console.log(chalk177.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
18702
18791
|
} finally {
|
|
18703
18792
|
await pool.close();
|
|
18704
18793
|
}
|
|
18705
18794
|
}
|
|
18706
18795
|
|
|
18707
18796
|
// src/commands/sql/sqlQuery.ts
|
|
18708
|
-
import
|
|
18797
|
+
import chalk178 from "chalk";
|
|
18709
18798
|
async function sqlQuery(query, connectionName) {
|
|
18710
18799
|
if (isMutation(query)) {
|
|
18711
18800
|
console.error(
|
|
18712
|
-
|
|
18801
|
+
chalk178.red(
|
|
18713
18802
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
18714
18803
|
)
|
|
18715
18804
|
);
|
|
@@ -18724,7 +18813,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
18724
18813
|
printTable(rows);
|
|
18725
18814
|
} else {
|
|
18726
18815
|
console.log(
|
|
18727
|
-
|
|
18816
|
+
chalk178.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
18728
18817
|
);
|
|
18729
18818
|
}
|
|
18730
18819
|
} finally {
|
|
@@ -18877,8 +18966,8 @@ import {
|
|
|
18877
18966
|
import { basename as basename10, join as join51 } from "path";
|
|
18878
18967
|
|
|
18879
18968
|
// src/commands/transcript/cleanText.ts
|
|
18880
|
-
function cleanText(
|
|
18881
|
-
const words =
|
|
18969
|
+
function cleanText(text7) {
|
|
18970
|
+
const words = text7.split(/\s+/);
|
|
18882
18971
|
const cleaned = [];
|
|
18883
18972
|
for (let i = 0; i < words.length; i++) {
|
|
18884
18973
|
let isRepeat = false;
|
|
@@ -18898,8 +18987,8 @@ function cleanText(text6) {
|
|
|
18898
18987
|
}
|
|
18899
18988
|
|
|
18900
18989
|
// src/commands/transcript/convert/parseVtt/deduplicateCues/removeSubstringDuplicates.ts
|
|
18901
|
-
function normalizeText(
|
|
18902
|
-
return
|
|
18990
|
+
function normalizeText(text7) {
|
|
18991
|
+
return text7.toLowerCase().trim();
|
|
18903
18992
|
}
|
|
18904
18993
|
function checkSubstringRelation(textI, textJ) {
|
|
18905
18994
|
if (textI.includes(textJ) && textI.length > textJ.length)
|
|
@@ -19028,13 +19117,13 @@ function parseTimestampLine(line) {
|
|
|
19028
19117
|
return { startMs: parseTimestamp(startStr), endMs: parseTimestamp(endStr) };
|
|
19029
19118
|
}
|
|
19030
19119
|
function buildCue(startMs, endMs, fullText) {
|
|
19031
|
-
const { speaker, text:
|
|
19032
|
-
return
|
|
19120
|
+
const { speaker, text: text7 } = extractSpeaker(fullText);
|
|
19121
|
+
return text7 ? { startMs, endMs, speaker, text: text7 } : null;
|
|
19033
19122
|
}
|
|
19034
19123
|
function parseCueLine(lines, i) {
|
|
19035
19124
|
const { startMs, endMs } = parseTimestampLine(lines[i]);
|
|
19036
|
-
const { text:
|
|
19037
|
-
return { cue: buildCue(startMs, endMs,
|
|
19125
|
+
const { text: text7, nextIndex: nextIndex2 } = collectTextLines(lines, i + 1);
|
|
19126
|
+
return { cue: buildCue(startMs, endMs, text7), nextIndex: nextIndex2 };
|
|
19038
19127
|
}
|
|
19039
19128
|
function isCueSeparator(line) {
|
|
19040
19129
|
return line.trim().includes("-->");
|
|
@@ -19421,7 +19510,7 @@ function registerVoice(program2) {
|
|
|
19421
19510
|
|
|
19422
19511
|
// src/commands/roam/auth.ts
|
|
19423
19512
|
import { randomBytes } from "crypto";
|
|
19424
|
-
import
|
|
19513
|
+
import chalk179 from "chalk";
|
|
19425
19514
|
|
|
19426
19515
|
// src/commands/roam/waitForCallback.ts
|
|
19427
19516
|
import { createServer as createServer3 } from "http";
|
|
@@ -19505,8 +19594,8 @@ async function exchangeToken(params) {
|
|
|
19505
19594
|
body: body.toString()
|
|
19506
19595
|
});
|
|
19507
19596
|
if (!response.ok) {
|
|
19508
|
-
const
|
|
19509
|
-
throw new Error(`Token exchange failed (${response.status}): ${
|
|
19597
|
+
const text7 = await response.text();
|
|
19598
|
+
throw new Error(`Token exchange failed (${response.status}): ${text7}`);
|
|
19510
19599
|
}
|
|
19511
19600
|
return response.json();
|
|
19512
19601
|
}
|
|
@@ -19552,13 +19641,13 @@ async function auth() {
|
|
|
19552
19641
|
saveGlobalConfig(config);
|
|
19553
19642
|
const state = randomBytes(16).toString("hex");
|
|
19554
19643
|
console.log(
|
|
19555
|
-
|
|
19644
|
+
chalk179.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
19556
19645
|
);
|
|
19557
|
-
console.log(
|
|
19558
|
-
console.log(
|
|
19559
|
-
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..."));
|
|
19560
19649
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
19561
|
-
console.log(
|
|
19650
|
+
console.log(chalk179.dim("Exchanging code for tokens..."));
|
|
19562
19651
|
const tokens = await exchangeToken({
|
|
19563
19652
|
code,
|
|
19564
19653
|
clientId,
|
|
@@ -19574,7 +19663,7 @@ async function auth() {
|
|
|
19574
19663
|
};
|
|
19575
19664
|
saveGlobalConfig(config);
|
|
19576
19665
|
console.log(
|
|
19577
|
-
|
|
19666
|
+
chalk179.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
19578
19667
|
);
|
|
19579
19668
|
}
|
|
19580
19669
|
|
|
@@ -20026,7 +20115,7 @@ import { execSync as execSync50 } from "child_process";
|
|
|
20026
20115
|
import { existsSync as existsSync50, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20027
20116
|
import { tmpdir as tmpdir7 } from "os";
|
|
20028
20117
|
import { join as join61, resolve as resolve15 } from "path";
|
|
20029
|
-
import
|
|
20118
|
+
import chalk180 from "chalk";
|
|
20030
20119
|
|
|
20031
20120
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
20032
20121
|
var captureWindowPs1 = `
|
|
@@ -20177,13 +20266,13 @@ function screenshot(processName) {
|
|
|
20177
20266
|
const config = loadConfig();
|
|
20178
20267
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
20179
20268
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
20180
|
-
console.log(
|
|
20269
|
+
console.log(chalk180.gray(`Capturing window for process "${processName}" ...`));
|
|
20181
20270
|
try {
|
|
20182
20271
|
runPowerShellScript(processName, outputPath);
|
|
20183
|
-
console.log(
|
|
20272
|
+
console.log(chalk180.green(`Screenshot saved: ${outputPath}`));
|
|
20184
20273
|
} catch (error) {
|
|
20185
20274
|
const msg = error instanceof Error ? error.message : String(error);
|
|
20186
|
-
console.error(
|
|
20275
|
+
console.error(chalk180.red(`Failed to capture screenshot: ${msg}`));
|
|
20187
20276
|
process.exit(1);
|
|
20188
20277
|
}
|
|
20189
20278
|
}
|
|
@@ -20775,6 +20864,36 @@ function logSpawnedSession(session) {
|
|
|
20775
20864
|
);
|
|
20776
20865
|
}
|
|
20777
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
|
+
|
|
20778
20897
|
// src/commands/sessions/daemon/setStatus.ts
|
|
20779
20898
|
function setStatus2(session, newStatus) {
|
|
20780
20899
|
const now = Date.now();
|
|
@@ -20785,6 +20904,30 @@ function setStatus2(session, newStatus) {
|
|
|
20785
20904
|
session.status = newStatus;
|
|
20786
20905
|
}
|
|
20787
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
|
+
|
|
20788
20931
|
// src/commands/sessions/daemon/watchEscInterrupt.ts
|
|
20789
20932
|
var ESC2 = "\x1B";
|
|
20790
20933
|
var SETTLE_MS = 1e3;
|
|
@@ -20815,35 +20958,22 @@ function disarmEscInterrupt(session) {
|
|
|
20815
20958
|
session.escInterruptTimer = void 0;
|
|
20816
20959
|
}
|
|
20817
20960
|
|
|
20818
|
-
// src/commands/sessions/daemon/shouldAutoDismiss.ts
|
|
20819
|
-
function shouldAutoDismiss(session, exitCode) {
|
|
20820
|
-
if (session.status !== "done" || exitCode !== 0) {
|
|
20821
|
-
return false;
|
|
20822
|
-
}
|
|
20823
|
-
if (session.reviewStarted) {
|
|
20824
|
-
return session.autoAdvance === true;
|
|
20825
|
-
}
|
|
20826
|
-
const args = session.assistArgs;
|
|
20827
|
-
if (args === void 0) return false;
|
|
20828
|
-
if (args[0] === "update") return true;
|
|
20829
|
-
return args.includes("--once") && args[0] !== "next";
|
|
20830
|
-
}
|
|
20831
|
-
|
|
20832
|
-
// src/commands/sessions/daemon/shouldAutoRun.ts
|
|
20833
|
-
function shouldAutoRun(session, exitCode) {
|
|
20834
|
-
if (!session.autoRun) return false;
|
|
20835
|
-
if (session.status !== "done" || exitCode !== 0) return false;
|
|
20836
|
-
if (session.commandType !== "assist") return false;
|
|
20837
|
-
const cmd = session.assistArgs?.[0];
|
|
20838
|
-
if (cmd !== "draft" && cmd !== "bug" && cmd !== "refine") return false;
|
|
20839
|
-
return session.activity?.itemId != null;
|
|
20840
|
-
}
|
|
20841
|
-
|
|
20842
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
|
+
}
|
|
20843
20972
|
function applyStatusChange(session, status2, exitCode, dismiss, notify2, reuseForRun) {
|
|
20844
20973
|
disarmEscInterrupt(session);
|
|
20845
20974
|
if (session.status === status2) return;
|
|
20846
20975
|
daemonLog(`session ${session.id} status: ${session.status} -> ${status2}`);
|
|
20976
|
+
accumulateActiveTime(session);
|
|
20847
20977
|
setStatus2(session, status2);
|
|
20848
20978
|
if (shouldAutoRun(session, exitCode) && session.activity?.itemId != null) {
|
|
20849
20979
|
reuseForRun(session, session.activity.itemId);
|
|
@@ -20859,6 +20989,41 @@ function makeStatusChangeHandler(dismiss, notify2, reuseForRun) {
|
|
|
20859
20989
|
return (s, status2, exitCode) => applyStatusChange(s, status2, exitCode, dismiss, notify2, reuseForRun);
|
|
20860
20990
|
}
|
|
20861
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
|
+
|
|
20862
21027
|
// src/commands/sessions/daemon/restoreBase.ts
|
|
20863
21028
|
function restoreBase(id2, persisted) {
|
|
20864
21029
|
return {
|
|
@@ -21093,6 +21258,42 @@ function applyReviewPause(session, activity2) {
|
|
|
21093
21258
|
}
|
|
21094
21259
|
}
|
|
21095
21260
|
|
|
21261
|
+
// src/shared/db/getPhaseActiveMs.ts
|
|
21262
|
+
import { and as and15, eq as eq34 } from "drizzle-orm";
|
|
21263
|
+
async function getPhaseActiveMs(db, itemId, phaseIdx) {
|
|
21264
|
+
const [row] = await db.select({ activeMs: phaseUsage.activeMs }).from(phaseUsage).where(
|
|
21265
|
+
and15(eq34(phaseUsage.itemId, itemId), eq34(phaseUsage.phaseIdx, phaseIdx))
|
|
21266
|
+
);
|
|
21267
|
+
return row?.activeMs ?? 0;
|
|
21268
|
+
}
|
|
21269
|
+
|
|
21270
|
+
// src/commands/sessions/daemon/loadPhaseActiveMs.ts
|
|
21271
|
+
async function loadPhaseActiveMs(itemId, phaseIdx) {
|
|
21272
|
+
try {
|
|
21273
|
+
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url)
|
|
21274
|
+
return null;
|
|
21275
|
+
return await getPhaseActiveMs(await getDb(), itemId, phaseIdx);
|
|
21276
|
+
} catch (error) {
|
|
21277
|
+
daemonLog(`phase-active-ms load failed: ${String(error)}`);
|
|
21278
|
+
return null;
|
|
21279
|
+
}
|
|
21280
|
+
}
|
|
21281
|
+
|
|
21282
|
+
// src/commands/sessions/daemon/seedRunningMsFromUsage.ts
|
|
21283
|
+
async function seedRunningMsFromUsage(session, notify2) {
|
|
21284
|
+
if (session.usageSeeded) return;
|
|
21285
|
+
const phase = sessionBacklogPhase(session);
|
|
21286
|
+
if (!phase) return;
|
|
21287
|
+
session.usageSeeded = true;
|
|
21288
|
+
const priorMs = await loadPhaseActiveMs(phase.itemId, phase.phaseIdx);
|
|
21289
|
+
if (priorMs == null || priorMs <= session.runningMs) return;
|
|
21290
|
+
session.runningMs = priorMs;
|
|
21291
|
+
daemonLog(
|
|
21292
|
+
`session ${session.id} seeded runningMs=${priorMs} from item ${phase.itemId} phase ${phase.phaseIdx} recorded usage`
|
|
21293
|
+
);
|
|
21294
|
+
notify2();
|
|
21295
|
+
}
|
|
21296
|
+
|
|
21096
21297
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
21097
21298
|
var DEBOUNCE_MS = 50;
|
|
21098
21299
|
function watchActivity(session, notify2) {
|
|
@@ -21114,6 +21315,7 @@ function watchActivity(session, notify2) {
|
|
|
21114
21315
|
if (activity2.claudeSessionId)
|
|
21115
21316
|
session.claudeSessionId = activity2.claudeSessionId;
|
|
21116
21317
|
applyReviewPause(session, activity2);
|
|
21318
|
+
void seedRunningMsFromUsage(session, notify2);
|
|
21117
21319
|
notify2();
|
|
21118
21320
|
};
|
|
21119
21321
|
session.activityWatcher = watch(dir, (_event, filename) => {
|
|
@@ -21199,6 +21401,7 @@ function reuseSessionForRun(session, itemId, clients, onStatusChange) {
|
|
|
21199
21401
|
session.startedAt = Date.now();
|
|
21200
21402
|
session.runningMs = 0;
|
|
21201
21403
|
session.runningSince = null;
|
|
21404
|
+
session.usageSeeded = false;
|
|
21202
21405
|
setStatus2(session, "running");
|
|
21203
21406
|
session.restored = void 0;
|
|
21204
21407
|
session.pty = spawnPty(["assist", ...assistArgs], session.cwd, session.id);
|
|
@@ -21955,6 +22158,16 @@ var SessionManager = class {
|
|
|
21955
22158
|
}
|
|
21956
22159
|
this.onStatusChange(session, status2);
|
|
21957
22160
|
}
|
|
22161
|
+
/* why: the status line relays token totals keyed by Claude's session id; join
|
|
22162
|
+
* it to the running backlog phase so the spend accumulates against that row. */
|
|
22163
|
+
recordUsage(claudeSessionId, totalIn, totalOut) {
|
|
22164
|
+
recordSessionUsage(
|
|
22165
|
+
this.sessions.values(),
|
|
22166
|
+
claudeSessionId,
|
|
22167
|
+
totalIn,
|
|
22168
|
+
totalOut
|
|
22169
|
+
);
|
|
22170
|
+
}
|
|
21958
22171
|
listSessions = () => {
|
|
21959
22172
|
const local = [...this.sessions.values()].map(toSessionInfo);
|
|
21960
22173
|
return local.concat(this.windowsProxy.sessions());
|
|
@@ -22011,8 +22224,8 @@ function deriveSessionType(commandName, name) {
|
|
|
22011
22224
|
}
|
|
22012
22225
|
|
|
22013
22226
|
// src/commands/sessions/shared/backlogRunMarkers.ts
|
|
22014
|
-
function backlogRunMarkers(
|
|
22015
|
-
const match =
|
|
22227
|
+
function backlogRunMarkers(text7) {
|
|
22228
|
+
const match = text7.match(/backlog item #(\d+):[ \t]*([^\n]*)/);
|
|
22016
22229
|
if (!match) return { commandName: "", commandArgs: "" };
|
|
22017
22230
|
const title = match[2].trim();
|
|
22018
22231
|
return {
|
|
@@ -22066,11 +22279,11 @@ function messageText(entry) {
|
|
|
22066
22279
|
const content = msg?.content;
|
|
22067
22280
|
return typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
22068
22281
|
}
|
|
22069
|
-
function stripMarkers(
|
|
22070
|
-
return
|
|
22282
|
+
function stripMarkers(text7) {
|
|
22283
|
+
return text7.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
22071
22284
|
}
|
|
22072
|
-
function matchMarker(
|
|
22073
|
-
const match =
|
|
22285
|
+
function matchMarker(text7, tag) {
|
|
22286
|
+
const match = text7.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
|
|
22074
22287
|
return match ? match[1].trim() : "";
|
|
22075
22288
|
}
|
|
22076
22289
|
|
|
@@ -22188,17 +22401,17 @@ function entryMessages(entry) {
|
|
|
22188
22401
|
return [];
|
|
22189
22402
|
}
|
|
22190
22403
|
function userMessages(content) {
|
|
22191
|
-
if (typeof content === "string") return
|
|
22404
|
+
if (typeof content === "string") return text6("user", cleanUserText(content));
|
|
22192
22405
|
if (!Array.isArray(content)) return [];
|
|
22193
|
-
return content.filter((c) => c.type === "text").flatMap((c) =>
|
|
22406
|
+
return content.filter((c) => c.type === "text").flatMap((c) => text6("user", cleanUserText(c.text ?? "")));
|
|
22194
22407
|
}
|
|
22195
22408
|
function assistantMessages(content) {
|
|
22196
|
-
if (typeof content === "string") return
|
|
22409
|
+
if (typeof content === "string") return text6("assistant", content.trim());
|
|
22197
22410
|
if (!Array.isArray(content)) return [];
|
|
22198
22411
|
return content.flatMap((c) => assistantItem(c));
|
|
22199
22412
|
}
|
|
22200
22413
|
function assistantItem(c) {
|
|
22201
|
-
if (c.type === "text") return
|
|
22414
|
+
if (c.type === "text") return text6("assistant", (c.text ?? "").trim());
|
|
22202
22415
|
if (c.type === "tool_use")
|
|
22203
22416
|
return [
|
|
22204
22417
|
{
|
|
@@ -22209,7 +22422,7 @@ function assistantItem(c) {
|
|
|
22209
22422
|
];
|
|
22210
22423
|
return [];
|
|
22211
22424
|
}
|
|
22212
|
-
function
|
|
22425
|
+
function text6(role, value) {
|
|
22213
22426
|
return value ? [{ role, text: value }] : [];
|
|
22214
22427
|
}
|
|
22215
22428
|
function cleanUserText(value) {
|
|
@@ -22332,6 +22545,11 @@ var messageHandlers = {
|
|
|
22332
22545
|
...lifecycleHandlers,
|
|
22333
22546
|
drain: (client, m) => sendTo(client, { type: "drained", count: m.drain() }),
|
|
22334
22547
|
limits: (_client, m, d) => m.clients.updateLimits(d.rateLimits),
|
|
22548
|
+
usage: (_client, m, d) => m.recordUsage(
|
|
22549
|
+
d.claudeSessionId,
|
|
22550
|
+
d.totalIn,
|
|
22551
|
+
d.totalOut
|
|
22552
|
+
),
|
|
22335
22553
|
input: routed(
|
|
22336
22554
|
(_client, m, d) => m.writeToSession(d.sessionId, d.data)
|
|
22337
22555
|
),
|
|
@@ -22537,7 +22755,7 @@ function registerDaemon(program2) {
|
|
|
22537
22755
|
|
|
22538
22756
|
// src/commands/sessions/summarise/index.ts
|
|
22539
22757
|
import * as fs35 from "fs";
|
|
22540
|
-
import
|
|
22758
|
+
import chalk181 from "chalk";
|
|
22541
22759
|
|
|
22542
22760
|
// src/commands/sessions/summarise/shared.ts
|
|
22543
22761
|
import * as fs33 from "fs";
|
|
@@ -22569,16 +22787,16 @@ function parseUserLine(line) {
|
|
|
22569
22787
|
if (entry.type !== "user") return void 0;
|
|
22570
22788
|
const msg = entry.message;
|
|
22571
22789
|
const c = msg?.content;
|
|
22572
|
-
let
|
|
22790
|
+
let text7;
|
|
22573
22791
|
if (typeof c === "string") {
|
|
22574
|
-
|
|
22792
|
+
text7 = c;
|
|
22575
22793
|
} else if (Array.isArray(c)) {
|
|
22576
22794
|
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
22577
|
-
|
|
22795
|
+
text7 = collected || void 0;
|
|
22578
22796
|
}
|
|
22579
|
-
if (!
|
|
22797
|
+
if (!text7) return void 0;
|
|
22580
22798
|
return {
|
|
22581
|
-
text:
|
|
22799
|
+
text: text7,
|
|
22582
22800
|
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
22583
22801
|
};
|
|
22584
22802
|
}
|
|
@@ -22607,13 +22825,13 @@ function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
|
22607
22825
|
|
|
22608
22826
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
22609
22827
|
function extractFirstUserMessage(filePath) {
|
|
22610
|
-
for (const
|
|
22611
|
-
return truncate3(
|
|
22828
|
+
for (const text7 of iterateUserMessages(filePath)) {
|
|
22829
|
+
return truncate3(text7);
|
|
22612
22830
|
}
|
|
22613
22831
|
return void 0;
|
|
22614
22832
|
}
|
|
22615
|
-
function truncate3(
|
|
22616
|
-
const trimmed =
|
|
22833
|
+
function truncate3(text7, maxChars = 500) {
|
|
22834
|
+
const trimmed = text7.trim();
|
|
22617
22835
|
if (trimmed.length <= maxChars) return trimmed;
|
|
22618
22836
|
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
22619
22837
|
}
|
|
@@ -22621,28 +22839,28 @@ function truncate3(text6, maxChars = 500) {
|
|
|
22621
22839
|
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
22622
22840
|
function scanSessionBacklogRefs(filePath) {
|
|
22623
22841
|
const ids = /* @__PURE__ */ new Set();
|
|
22624
|
-
for (const
|
|
22625
|
-
for (const id2 of extractBacklogIds(
|
|
22842
|
+
for (const text7 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
22843
|
+
for (const id2 of extractBacklogIds(text7)) {
|
|
22626
22844
|
ids.add(id2);
|
|
22627
22845
|
}
|
|
22628
22846
|
}
|
|
22629
22847
|
return [...ids].sort((a, b) => a - b);
|
|
22630
22848
|
}
|
|
22631
|
-
function extractBacklogIds(
|
|
22849
|
+
function extractBacklogIds(text7) {
|
|
22632
22850
|
const ids = [];
|
|
22633
|
-
for (const m of
|
|
22851
|
+
for (const m of text7.matchAll(/backlog\s+run\s+(\d+)/gi)) {
|
|
22634
22852
|
ids.push(Number.parseInt(m[1], 10));
|
|
22635
22853
|
}
|
|
22636
|
-
for (const m of
|
|
22854
|
+
for (const m of text7.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
|
|
22637
22855
|
ids.push(Number.parseInt(m[1], 10));
|
|
22638
22856
|
}
|
|
22639
|
-
for (const m of
|
|
22857
|
+
for (const m of text7.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
|
|
22640
22858
|
ids.push(Number.parseInt(m[1], 10));
|
|
22641
22859
|
}
|
|
22642
|
-
for (const m of
|
|
22860
|
+
for (const m of text7.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
|
|
22643
22861
|
ids.push(Number.parseInt(m[1], 10));
|
|
22644
22862
|
}
|
|
22645
|
-
for (const m of
|
|
22863
|
+
for (const m of text7.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
22646
22864
|
ids.push(Number.parseInt(m[1], 10));
|
|
22647
22865
|
}
|
|
22648
22866
|
return ids;
|
|
@@ -22691,22 +22909,22 @@ ${firstMessage}`);
|
|
|
22691
22909
|
async function summarise2(options2) {
|
|
22692
22910
|
const files = await discoverSessionFiles();
|
|
22693
22911
|
if (files.length === 0) {
|
|
22694
|
-
console.log(
|
|
22912
|
+
console.log(chalk181.yellow("No sessions found."));
|
|
22695
22913
|
return;
|
|
22696
22914
|
}
|
|
22697
22915
|
const toProcess = selectCandidates(files, options2);
|
|
22698
22916
|
if (toProcess.length === 0) {
|
|
22699
|
-
console.log(
|
|
22917
|
+
console.log(chalk181.green("All sessions already summarised."));
|
|
22700
22918
|
return;
|
|
22701
22919
|
}
|
|
22702
22920
|
console.log(
|
|
22703
|
-
|
|
22921
|
+
chalk181.cyan(
|
|
22704
22922
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
22705
22923
|
)
|
|
22706
22924
|
);
|
|
22707
22925
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
22708
22926
|
console.log(
|
|
22709
|
-
|
|
22927
|
+
chalk181.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk181.yellow(`, ${failed2} skipped`) : "")
|
|
22710
22928
|
);
|
|
22711
22929
|
}
|
|
22712
22930
|
function selectCandidates(files, options2) {
|
|
@@ -22726,16 +22944,16 @@ function processSessions(files) {
|
|
|
22726
22944
|
let failed2 = 0;
|
|
22727
22945
|
for (let i = 0; i < files.length; i++) {
|
|
22728
22946
|
const file = files[i];
|
|
22729
|
-
process.stdout.write(
|
|
22947
|
+
process.stdout.write(chalk181.dim(` [${i + 1}/${files.length}] `));
|
|
22730
22948
|
const summary = summariseSession(file);
|
|
22731
22949
|
if (summary) {
|
|
22732
22950
|
writeSummary(file, summary);
|
|
22733
22951
|
succeeded++;
|
|
22734
|
-
process.stdout.write(`${
|
|
22952
|
+
process.stdout.write(`${chalk181.green("\u2713")} ${summary}
|
|
22735
22953
|
`);
|
|
22736
22954
|
} else {
|
|
22737
22955
|
failed2++;
|
|
22738
|
-
process.stdout.write(` ${
|
|
22956
|
+
process.stdout.write(` ${chalk181.yellow("skip")}
|
|
22739
22957
|
`);
|
|
22740
22958
|
}
|
|
22741
22959
|
}
|
|
@@ -22753,10 +22971,10 @@ function registerSessions(program2) {
|
|
|
22753
22971
|
}
|
|
22754
22972
|
|
|
22755
22973
|
// src/commands/statusLine.ts
|
|
22756
|
-
import
|
|
22974
|
+
import chalk183 from "chalk";
|
|
22757
22975
|
|
|
22758
22976
|
// src/commands/buildLimitsSegment.ts
|
|
22759
|
-
import
|
|
22977
|
+
import chalk182 from "chalk";
|
|
22760
22978
|
|
|
22761
22979
|
// src/shared/rateLimitLevel.ts
|
|
22762
22980
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -22787,9 +23005,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
22787
23005
|
|
|
22788
23006
|
// src/commands/buildLimitsSegment.ts
|
|
22789
23007
|
var LEVEL_COLOR = {
|
|
22790
|
-
ok:
|
|
22791
|
-
warn:
|
|
22792
|
-
over:
|
|
23008
|
+
ok: chalk182.green,
|
|
23009
|
+
warn: chalk182.yellow,
|
|
23010
|
+
over: chalk182.red
|
|
22793
23011
|
};
|
|
22794
23012
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
22795
23013
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -22828,15 +23046,24 @@ async function relayRateLimits(rateLimits) {
|
|
|
22828
23046
|
}
|
|
22829
23047
|
}
|
|
22830
23048
|
|
|
23049
|
+
// src/commands/relayUsage.ts
|
|
23050
|
+
async function relayUsage(claudeSessionId, totalIn, totalOut) {
|
|
23051
|
+
if (!claudeSessionId) return;
|
|
23052
|
+
try {
|
|
23053
|
+
await sendToDaemon({ type: "usage", claudeSessionId, totalIn, totalOut });
|
|
23054
|
+
} catch {
|
|
23055
|
+
}
|
|
23056
|
+
}
|
|
23057
|
+
|
|
22831
23058
|
// src/commands/statusLine.ts
|
|
22832
|
-
|
|
23059
|
+
chalk183.level = 3;
|
|
22833
23060
|
function formatNumber(num) {
|
|
22834
23061
|
return num.toLocaleString("en-US");
|
|
22835
23062
|
}
|
|
22836
23063
|
function colorizePercent(pct) {
|
|
22837
23064
|
const label2 = `${Math.round(pct)}%`;
|
|
22838
|
-
if (pct > 80) return
|
|
22839
|
-
if (pct > 40) return
|
|
23065
|
+
if (pct > 80) return chalk183.red(label2);
|
|
23066
|
+
if (pct > 40) return chalk183.yellow(label2);
|
|
22840
23067
|
return label2;
|
|
22841
23068
|
}
|
|
22842
23069
|
async function statusLine() {
|
|
@@ -22849,6 +23076,7 @@ async function statusLine() {
|
|
|
22849
23076
|
`${model} | Tokens - ${formatNumber(totalOut)} \u2191 : ${formatNumber(totalIn)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
|
|
22850
23077
|
);
|
|
22851
23078
|
await relayRateLimits(data.rate_limits);
|
|
23079
|
+
await relayUsage(data.session_id, totalIn, totalOut);
|
|
22852
23080
|
}
|
|
22853
23081
|
|
|
22854
23082
|
// src/commands/sync.ts
|
|
@@ -22860,7 +23088,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
22860
23088
|
// src/commands/sync/syncClaudeMd.ts
|
|
22861
23089
|
import * as fs36 from "fs";
|
|
22862
23090
|
import * as path53 from "path";
|
|
22863
|
-
import
|
|
23091
|
+
import chalk184 from "chalk";
|
|
22864
23092
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
22865
23093
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
22866
23094
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
@@ -22869,12 +23097,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22869
23097
|
const targetContent = fs36.readFileSync(target, "utf8");
|
|
22870
23098
|
if (sourceContent !== targetContent) {
|
|
22871
23099
|
console.log(
|
|
22872
|
-
|
|
23100
|
+
chalk184.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
22873
23101
|
);
|
|
22874
23102
|
console.log();
|
|
22875
23103
|
printDiff(targetContent, sourceContent);
|
|
22876
23104
|
const confirm = options2?.yes || await promptConfirm(
|
|
22877
|
-
|
|
23105
|
+
chalk184.red("Overwrite existing CLAUDE.md?"),
|
|
22878
23106
|
false
|
|
22879
23107
|
);
|
|
22880
23108
|
if (!confirm) {
|
|
@@ -22890,7 +23118,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
22890
23118
|
// src/commands/sync/syncSettings.ts
|
|
22891
23119
|
import * as fs37 from "fs";
|
|
22892
23120
|
import * as path54 from "path";
|
|
22893
|
-
import
|
|
23121
|
+
import chalk185 from "chalk";
|
|
22894
23122
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
22895
23123
|
const source = path54.join(claudeDir, "settings.json");
|
|
22896
23124
|
const target = path54.join(targetBase, "settings.json");
|
|
@@ -22906,14 +23134,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
22906
23134
|
if (mergedContent !== normalizedTarget) {
|
|
22907
23135
|
if (!options2?.yes) {
|
|
22908
23136
|
console.log(
|
|
22909
|
-
|
|
23137
|
+
chalk185.yellow(
|
|
22910
23138
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
22911
23139
|
)
|
|
22912
23140
|
);
|
|
22913
23141
|
console.log();
|
|
22914
23142
|
printDiff(targetContent, mergedContent);
|
|
22915
23143
|
const confirm = await promptConfirm(
|
|
22916
|
-
|
|
23144
|
+
chalk185.red("Overwrite existing settings.json?"),
|
|
22917
23145
|
false
|
|
22918
23146
|
);
|
|
22919
23147
|
if (!confirm) {
|