@staff0rd/assist 0.342.1 → 0.343.0

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