@staff0rd/assist 0.281.3 → 0.282.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.281.3",
9
+ version: "0.282.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -230,9 +230,6 @@ var assistConfigSchema = z2.strictObject({
230
230
  run: z2.array(z2.union([runConfigSchema, runLinkSchema])).optional(),
231
231
  transcript: transcriptConfigSchema.optional(),
232
232
  cliReadVerbs: z2.record(z2.string(), z2.array(z2.string())).optional(),
233
- news: z2.strictObject({
234
- feeds: z2.array(z2.string()).default([])
235
- }).default({ feeds: [] }),
236
233
  dotnet: z2.strictObject({
237
234
  inspect: z2.strictObject({
238
235
  suppress: z2.array(z2.string()).default([])
@@ -340,6 +337,7 @@ function loadConfig() {
340
337
  const globalRaw = loadRawYaml(getGlobalConfigPath());
341
338
  const projectRaw = loadRawYaml(getConfigPath());
342
339
  const merged = mergeRawConfigs(globalRaw, projectRaw);
340
+ delete merged.news;
343
341
  return assistConfigSchema.parse(merged);
344
342
  }
345
343
  function loadProjectConfig() {
@@ -444,13 +442,18 @@ var metadata = pgTable("metadata", {
444
442
  key: text().primaryKey(),
445
443
  value: text().notNull()
446
444
  });
445
+ var feeds = pgTable("feeds", {
446
+ id: integer().generatedByDefaultAsIdentity().primaryKey(),
447
+ url: text().notNull().unique()
448
+ });
447
449
  var backlogSchema = {
448
450
  items,
449
451
  comments,
450
452
  links,
451
453
  planPhases,
452
454
  planTasks,
453
- metadata
455
+ metadata,
456
+ feeds
454
457
  };
455
458
 
456
459
  // src/commands/backlog/BacklogOrm.ts
@@ -512,11 +515,45 @@ var SCHEMA = `
512
515
  key TEXT PRIMARY KEY,
513
516
  value TEXT NOT NULL
514
517
  );
518
+
519
+ CREATE TABLE IF NOT EXISTS feeds (
520
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
521
+ url TEXT NOT NULL UNIQUE
522
+ );
515
523
  `;
516
524
  async function ensureSchema(exec3) {
517
525
  await exec3(SCHEMA);
518
526
  }
519
527
 
528
+ // src/commands/backlog/addFeed.ts
529
+ async function addFeed(db, url) {
530
+ const inserted = await db.insert(feeds).values({ url }).onConflictDoNothing({ target: feeds.url }).returning({ id: feeds.id });
531
+ return inserted.length > 0;
532
+ }
533
+
534
+ // src/commands/backlog/listFeeds.ts
535
+ import { asc } from "drizzle-orm";
536
+ async function listFeeds(db) {
537
+ const rows = await db.select({ url: feeds.url }).from(feeds).orderBy(asc(feeds.id));
538
+ return rows.map((r) => r.url);
539
+ }
540
+
541
+ // src/commands/backlog/seedNewsFeeds.ts
542
+ function legacyFeeds(raw) {
543
+ const news = raw.news;
544
+ const feeds2 = news?.feeds;
545
+ return Array.isArray(feeds2) ? feeds2.filter((f) => typeof f === "string") : [];
546
+ }
547
+ async function seedNewsFeeds(db) {
548
+ const existing = await listFeeds(db);
549
+ if (existing.length > 0) return;
550
+ const projectFeeds = legacyFeeds(loadProjectConfig());
551
+ const configFeeds = projectFeeds.length > 0 ? projectFeeds : legacyFeeds(loadGlobalConfigRaw());
552
+ for (const url of configFeeds) {
553
+ await addFeed(db, url);
554
+ }
555
+ }
556
+
520
557
  // src/commands/backlog/getBacklogOrm.ts
521
558
  var DATABASE_URL_ENV = "ASSIST_BACKLOG_DATABASE_URL";
522
559
  var MISSING_URL_MESSAGE = `No backlog database configured.
@@ -549,6 +586,7 @@ function getBacklogOrm() {
549
586
  _pool = pool;
550
587
  await ensureSchema((sql4) => pool.query(sql4));
551
588
  _orm = makeOrmFromPool(pool);
589
+ await seedNewsFeeds(_orm);
552
590
  return _orm;
553
591
  })();
554
592
  return _connecting;
@@ -1835,7 +1873,7 @@ import { Project as Project2 } from "ts-morph";
1835
1873
  function collectComments(sourceFile) {
1836
1874
  const seen = /* @__PURE__ */ new Set();
1837
1875
  const comments3 = [];
1838
- const collect3 = (node) => {
1876
+ const collect4 = (node) => {
1839
1877
  for (const range of [
1840
1878
  ...node.getLeadingCommentRanges(),
1841
1879
  ...node.getTrailingCommentRanges()
@@ -1846,8 +1884,8 @@ function collectComments(sourceFile) {
1846
1884
  comments3.push({ pos, text: range.getText() });
1847
1885
  }
1848
1886
  };
1849
- collect3(sourceFile);
1850
- sourceFile.forEachDescendant(collect3);
1887
+ collect4(sourceFile);
1888
+ sourceFile.forEachDescendant(collect4);
1851
1889
  return comments3;
1852
1890
  }
1853
1891
 
@@ -3190,10 +3228,10 @@ async function importItemsRemapped(orm, items2, origin) {
3190
3228
  }
3191
3229
 
3192
3230
  // src/commands/backlog/loadAllItems.ts
3193
- import { asc as asc2, eq as eq2 } from "drizzle-orm";
3231
+ import { asc as asc3, eq as eq2 } from "drizzle-orm";
3194
3232
 
3195
3233
  // src/commands/backlog/loadRelations.ts
3196
- import { asc, inArray } from "drizzle-orm";
3234
+ import { asc as asc2, inArray } from "drizzle-orm";
3197
3235
  function groupByItem(rows) {
3198
3236
  const map = /* @__PURE__ */ new Map();
3199
3237
  for (const row of rows) {
@@ -3203,13 +3241,13 @@ function groupByItem(rows) {
3203
3241
  }
3204
3242
  return map;
3205
3243
  }
3206
- var selectComments = (orm, ids) => orm.select().from(comments).where(inArray(comments.itemId, ids)).orderBy(asc(comments.itemId), asc(comments.idx));
3207
- var selectLinks = (orm, ids) => orm.select().from(links).where(inArray(links.itemId, ids)).orderBy(asc(links.itemId));
3208
- var selectPhases = (orm, ids) => orm.select().from(planPhases).where(inArray(planPhases.itemId, ids)).orderBy(asc(planPhases.itemId), asc(planPhases.idx));
3244
+ var selectComments = (orm, ids) => orm.select().from(comments).where(inArray(comments.itemId, ids)).orderBy(asc2(comments.itemId), asc2(comments.idx));
3245
+ var selectLinks = (orm, ids) => orm.select().from(links).where(inArray(links.itemId, ids)).orderBy(asc2(links.itemId));
3246
+ var selectPhases = (orm, ids) => orm.select().from(planPhases).where(inArray(planPhases.itemId, ids)).orderBy(asc2(planPhases.itemId), asc2(planPhases.idx));
3209
3247
  var selectTasks = (orm, ids) => orm.select().from(planTasks).where(inArray(planTasks.itemId, ids)).orderBy(
3210
- asc(planTasks.itemId),
3211
- asc(planTasks.phaseIdx),
3212
- asc(planTasks.idx)
3248
+ asc2(planTasks.itemId),
3249
+ asc2(planTasks.phaseIdx),
3250
+ asc2(planTasks.idx)
3213
3251
  );
3214
3252
  async function loadRelations(orm, ids, { includeComments = true, includeTasks = true } = {}) {
3215
3253
  const [commentRows, linkRows, phaseRows, taskRows] = await Promise.all([
@@ -3299,7 +3337,7 @@ function rowToItem(row, rel) {
3299
3337
 
3300
3338
  // src/commands/backlog/loadAllItems.ts
3301
3339
  async function loadAllItems(orm, origin) {
3302
- const rows = await orm.select().from(items).where(origin === void 0 ? void 0 : eq2(items.origin, origin)).orderBy(asc2(items.id));
3340
+ const rows = await orm.select().from(items).where(origin === void 0 ? void 0 : eq2(items.origin, origin)).orderBy(asc3(items.id));
3303
3341
  if (rows.length === 0) return [];
3304
3342
  const rel = await loadRelations(
3305
3343
  orm,
@@ -3492,7 +3530,7 @@ import { eq as eq5, sql } from "drizzle-orm";
3492
3530
  import { eq as eq4 } from "drizzle-orm";
3493
3531
 
3494
3532
  // src/commands/backlog/searchItemIds.ts
3495
- import { and, asc as asc3, eq as eq6, ilike, or } from "drizzle-orm";
3533
+ import { and, asc as asc4, eq as eq6, ilike, or } from "drizzle-orm";
3496
3534
  async function searchItemIds(orm, query, origin) {
3497
3535
  const pattern2 = `%${query}%`;
3498
3536
  const rows = await orm.selectDistinct({ id: items.id }).from(items).leftJoin(comments, eq6(comments.itemId, items.id)).leftJoin(planPhases, eq6(planPhases.itemId, items.id)).where(
@@ -3506,7 +3544,7 @@ async function searchItemIds(orm, query, origin) {
3506
3544
  ilike(planPhases.name, pattern2)
3507
3545
  )
3508
3546
  )
3509
- ).orderBy(asc3(items.id));
3547
+ ).orderBy(asc4(items.id));
3510
3548
  return rows.map((r) => r.id);
3511
3549
  }
3512
3550
 
@@ -4395,20 +4433,20 @@ function respondJson(res, status2, data) {
4395
4433
  res.writeHead(status2, { "Content-Type": "application/json" });
4396
4434
  res.end(JSON.stringify(data));
4397
4435
  }
4398
- function createHtmlHandler(getHtml3) {
4436
+ function createHtmlHandler(getHtml2) {
4399
4437
  return (_req, res) => {
4400
4438
  res.writeHead(200, { "Content-Type": "text/html" });
4401
- res.end(getHtml3());
4439
+ res.end(getHtml2());
4402
4440
  };
4403
4441
  }
4404
4442
  function parseRoute(req, port) {
4405
4443
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
4406
4444
  return { method: req.method ?? "GET", pathname: url.pathname };
4407
4445
  }
4408
- function createRouteHandler(routes3) {
4446
+ function createRouteHandler(routes2) {
4409
4447
  return async (req, res, port) => {
4410
4448
  const { method, pathname } = parseRoute(req, port);
4411
- const handler = routes3[`${method} ${pathname}`];
4449
+ const handler = routes2[`${method} ${pathname}`];
4412
4450
  if (handler) {
4413
4451
  await handler(req, res);
4414
4452
  return;
@@ -4570,12 +4608,12 @@ function createBundleHandler(importMetaUrl, bundlePath) {
4570
4608
  }
4571
4609
 
4572
4610
  // src/shared/createFallbackHandler.ts
4573
- function createFallbackHandler(routes3, htmlHandler2, extra) {
4574
- const baseHandler = createRouteHandler(routes3);
4611
+ function createFallbackHandler(routes2, htmlHandler2, extra) {
4612
+ const baseHandler = createRouteHandler(routes2);
4575
4613
  return async (req, res, port) => {
4576
4614
  const { method, pathname } = parseRoute(req, port);
4577
4615
  if (extra && await extra(req, res, pathname)) return;
4578
- if (routes3[`${method} ${pathname}`]) {
4616
+ if (routes2[`${method} ${pathname}`]) {
4579
4617
  await baseHandler(req, res, port);
4580
4618
  return;
4581
4619
  }
@@ -4634,7 +4672,7 @@ async function createItem(req, res) {
4634
4672
  import { eq as eq11 } from "drizzle-orm";
4635
4673
 
4636
4674
  // src/commands/backlog/loadItemSummaries.ts
4637
- import { asc as asc4, eq as eq10 } from "drizzle-orm";
4675
+ import { asc as asc5, eq as eq10 } from "drizzle-orm";
4638
4676
  async function loadItemSummaries(orm, origin) {
4639
4677
  const rows = await orm.select({
4640
4678
  id: items.id,
@@ -4642,7 +4680,7 @@ async function loadItemSummaries(orm, origin) {
4642
4680
  type: items.type,
4643
4681
  name: items.name,
4644
4682
  status: items.status
4645
- }).from(items).where(origin === void 0 ? void 0 : eq10(items.origin, origin)).orderBy(asc4(items.id));
4683
+ }).from(items).where(origin === void 0 ? void 0 : eq10(items.origin, origin)).orderBy(asc5(items.id));
4646
4684
  return rows.map((row) => ({
4647
4685
  id: row.id,
4648
4686
  origin: row.origin,
@@ -5008,6 +5046,129 @@ function gitStatus(req, res) {
5008
5046
  }
5009
5047
  }
5010
5048
 
5049
+ // src/commands/news/shared.ts
5050
+ import { decodeHTML } from "entities";
5051
+ function extractText(xml, tag) {
5052
+ const cdataMatch = xml.match(
5053
+ new RegExp(`<${tag}>\\s*<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\\s*</${tag}>`)
5054
+ );
5055
+ if (cdataMatch) return cdataMatch[1].trim();
5056
+ const match = xml.match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`));
5057
+ return match ? match[1].trim() : "";
5058
+ }
5059
+ function extractLink(itemXml) {
5060
+ const atomLink = itemXml.match(
5061
+ /<link[^>]*rel=["']alternate["'][^>]*href=["']([^"']+)["']/
5062
+ );
5063
+ if (atomLink) return atomLink[1];
5064
+ const atomLink2 = itemXml.match(/<link[^>]*href=["']([^"']+)["']/);
5065
+ if (atomLink2) return atomLink2[1];
5066
+ return extractText(itemXml, "link");
5067
+ }
5068
+ function parseDate(dateStr) {
5069
+ if (!dateStr) return (/* @__PURE__ */ new Date(0)).toISOString();
5070
+ try {
5071
+ return new Date(dateStr).toISOString();
5072
+ } catch {
5073
+ return (/* @__PURE__ */ new Date(0)).toISOString();
5074
+ }
5075
+ }
5076
+ function stripHtml(html) {
5077
+ const decoded = decodeHTML(html);
5078
+ const stripped = decoded.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
5079
+ return decodeHTML(stripped);
5080
+ }
5081
+ function matchAll(xml, regex) {
5082
+ const results = [];
5083
+ for (const m of xml.matchAll(regex)) {
5084
+ results.push(m[1]);
5085
+ }
5086
+ return results;
5087
+ }
5088
+ var MAX_EXCERPT = 500;
5089
+ function excerpt(xml, ...tags) {
5090
+ for (const tag of tags) {
5091
+ const raw = extractText(xml, tag);
5092
+ if (!raw) continue;
5093
+ const text3 = stripHtml(raw);
5094
+ if (text3.length <= MAX_EXCERPT) return text3;
5095
+ return `${text3.slice(0, MAX_EXCERPT)}\u2026`;
5096
+ }
5097
+ return "";
5098
+ }
5099
+
5100
+ // src/commands/news/parseFeed.ts
5101
+ function parseRss(xml, feedOrigin) {
5102
+ const feedTitle = extractText(xml, "title");
5103
+ return matchAll(xml, /<item[\s>]([\s\S]*?)<\/item>/g).map((itemXml) => ({
5104
+ title: extractText(itemXml, "title"),
5105
+ link: extractLink(itemXml),
5106
+ pubDate: parseDate(
5107
+ extractText(itemXml, "pubDate") || extractText(itemXml, "dc:date")
5108
+ ),
5109
+ feedTitle,
5110
+ feedOrigin,
5111
+ excerpt: excerpt(itemXml, "description", "content:encoded")
5112
+ }));
5113
+ }
5114
+ function parseAtom(xml, feedOrigin) {
5115
+ const feedTitle = extractText(xml, "title");
5116
+ return matchAll(xml, /<entry[\s>]([\s\S]*?)<\/entry>/g).map((entryXml) => ({
5117
+ title: extractText(entryXml, "title"),
5118
+ link: extractLink(entryXml),
5119
+ pubDate: parseDate(
5120
+ extractText(entryXml, "published") || extractText(entryXml, "updated")
5121
+ ),
5122
+ feedTitle,
5123
+ feedOrigin,
5124
+ excerpt: excerpt(entryXml, "summary", "content")
5125
+ }));
5126
+ }
5127
+ function parseFeed(xml, feedOrigin) {
5128
+ if (xml.includes("<feed")) return parseAtom(xml, feedOrigin);
5129
+ return parseRss(xml, feedOrigin);
5130
+ }
5131
+
5132
+ // src/commands/news/fetchFeeds.ts
5133
+ async function fetchFeeds(urls, onProgress) {
5134
+ let done2 = 0;
5135
+ const results = await Promise.allSettled(
5136
+ urls.map(async (url) => {
5137
+ const origin = new URL(url).origin;
5138
+ const res = await fetch(url);
5139
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
5140
+ const items3 = parseFeed(await res.text(), origin);
5141
+ done2++;
5142
+ onProgress?.(done2, urls.length);
5143
+ return items3;
5144
+ })
5145
+ );
5146
+ const items2 = [];
5147
+ for (const result of results) {
5148
+ if (result.status === "fulfilled") {
5149
+ items2.push(...result.value);
5150
+ }
5151
+ }
5152
+ items2.sort(
5153
+ (a, b) => new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime()
5154
+ );
5155
+ return items2;
5156
+ }
5157
+
5158
+ // src/commands/sessions/web/listNewsItems.ts
5159
+ var cachedItems;
5160
+ var inflight;
5161
+ async function listNewsItems(_req, res) {
5162
+ if (!cachedItems) {
5163
+ if (!inflight)
5164
+ inflight = getReady().then(
5165
+ ({ orm }) => listFeeds(orm).then((urls) => fetchFeeds(urls))
5166
+ );
5167
+ cachedItems = await inflight;
5168
+ }
5169
+ respondJson(res, 200, cachedItems);
5170
+ }
5171
+
5011
5172
  // src/commands/sessions/web/openInCode.ts
5012
5173
  import { exec } from "child_process";
5013
5174
  import { promisify } from "util";
@@ -5052,7 +5213,8 @@ var routes = {
5052
5213
  "POST /api/backlog/init": initBacklog,
5053
5214
  "POST /api/open-in-code": openInCode,
5054
5215
  "GET /api/github-url": githubUrl,
5055
- "GET /api/git-status": gitStatus
5216
+ "GET /api/git-status": gitStatus,
5217
+ "GET /api/news/items": listNewsItems
5056
5218
  };
5057
5219
  var handleRequest = createFallbackHandler(
5058
5220
  routes,
@@ -6621,9 +6783,9 @@ async function findPhase(id, phase) {
6621
6783
  }
6622
6784
 
6623
6785
  // src/commands/backlog/reindexPhases.ts
6624
- import { and as and7, asc as asc5, count as count5, eq as eq24 } from "drizzle-orm";
6786
+ import { and as and7, asc as asc6, count as count5, eq as eq24 } from "drizzle-orm";
6625
6787
  async function reindexPhases(db, itemId) {
6626
- const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq24(planPhases.itemId, itemId)).orderBy(asc5(planPhases.idx));
6788
+ const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq24(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
6627
6789
  for (let i = 0; i < remaining.length; i++) {
6628
6790
  const oldIdx = remaining[i].idx;
6629
6791
  if (oldIdx === i) continue;
@@ -7433,7 +7595,7 @@ function matchesConfigDeny(command) {
7433
7595
  var BUILTIN_DENIES = [
7434
7596
  {
7435
7597
  pattern: "gh pr create",
7436
- message: "Do not run 'gh pr create' directly. Use 'assist prs create --title <title> --body <body>' instead \u2014 it validates the title and body before delegating to gh pr create. Before running it, get explicit approval via the AskUserQuestion tool, regardless of permission mode, with the full proposed title and body in the approve option's preview field so the user actually sees them."
7598
+ message: "Do not run 'gh pr create' directly. Use 'assist prs raise --title <title> --what <what> --why <why>' instead \u2014 it assembles and validates the body before delegating to gh. Before running it, get explicit approval via the AskUserQuestion tool, regardless of permission mode, with the full proposed title and body in the approve option's preview field so the user actually sees them."
7437
7599
  },
7438
7600
  {
7439
7601
  pattern: "git commit",
@@ -10729,212 +10891,23 @@ async function add2(url) {
10729
10891
  });
10730
10892
  url = response.url;
10731
10893
  }
10732
- const config = loadGlobalConfigRaw();
10733
- const news = config.news ?? {};
10734
- const feeds = news.feeds ?? [];
10735
- if (feeds.includes(url)) {
10736
- console.log(chalk118.yellow("Feed already exists in config"));
10894
+ const { orm } = await getReady();
10895
+ const added = await addFeed(orm, url);
10896
+ if (!added) {
10897
+ console.log(chalk118.yellow("Feed already exists"));
10737
10898
  return;
10738
10899
  }
10739
- feeds.push(url);
10740
- config.news = { ...news, feeds };
10741
- saveGlobalConfig(config);
10742
10900
  console.log(chalk118.green(`Added feed: ${url}`));
10743
10901
  }
10744
10902
 
10745
- // src/commands/news/web/handleRequest.ts
10746
- import chalk119 from "chalk";
10747
-
10748
- // src/commands/news/web/shared.ts
10749
- import { decodeHTML } from "entities";
10750
- function extractText(xml, tag) {
10751
- const cdataMatch = xml.match(
10752
- new RegExp(`<${tag}>\\s*<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\\s*</${tag}>`)
10753
- );
10754
- if (cdataMatch) return cdataMatch[1].trim();
10755
- const match = xml.match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`));
10756
- return match ? match[1].trim() : "";
10757
- }
10758
- function extractLink(itemXml) {
10759
- const atomLink = itemXml.match(
10760
- /<link[^>]*rel=["']alternate["'][^>]*href=["']([^"']+)["']/
10761
- );
10762
- if (atomLink) return atomLink[1];
10763
- const atomLink2 = itemXml.match(/<link[^>]*href=["']([^"']+)["']/);
10764
- if (atomLink2) return atomLink2[1];
10765
- return extractText(itemXml, "link");
10766
- }
10767
- function parseDate(dateStr) {
10768
- if (!dateStr) return (/* @__PURE__ */ new Date(0)).toISOString();
10769
- try {
10770
- return new Date(dateStr).toISOString();
10771
- } catch {
10772
- return (/* @__PURE__ */ new Date(0)).toISOString();
10773
- }
10774
- }
10775
- function stripHtml(html) {
10776
- const decoded = decodeHTML(html);
10777
- const stripped = decoded.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
10778
- return decodeHTML(stripped);
10779
- }
10780
- function matchAll(xml, regex) {
10781
- const results = [];
10782
- for (const m of xml.matchAll(regex)) {
10783
- results.push(m[1]);
10784
- }
10785
- return results;
10786
- }
10787
- var MAX_EXCERPT = 500;
10788
- function excerpt(xml, ...tags) {
10789
- for (const tag of tags) {
10790
- const raw = extractText(xml, tag);
10791
- if (!raw) continue;
10792
- const text3 = stripHtml(raw);
10793
- if (text3.length <= MAX_EXCERPT) return text3;
10794
- return `${text3.slice(0, MAX_EXCERPT)}\u2026`;
10795
- }
10796
- return "";
10797
- }
10798
-
10799
- // src/commands/news/web/parseFeed.ts
10800
- function parseRss(xml, feedOrigin) {
10801
- const feedTitle = extractText(xml, "title");
10802
- return matchAll(xml, /<item[\s>]([\s\S]*?)<\/item>/g).map((itemXml) => ({
10803
- title: extractText(itemXml, "title"),
10804
- link: extractLink(itemXml),
10805
- pubDate: parseDate(
10806
- extractText(itemXml, "pubDate") || extractText(itemXml, "dc:date")
10807
- ),
10808
- feedTitle,
10809
- feedOrigin,
10810
- excerpt: excerpt(itemXml, "description", "content:encoded")
10811
- }));
10812
- }
10813
- function parseAtom(xml, feedOrigin) {
10814
- const feedTitle = extractText(xml, "title");
10815
- return matchAll(xml, /<entry[\s>]([\s\S]*?)<\/entry>/g).map((entryXml) => ({
10816
- title: extractText(entryXml, "title"),
10817
- link: extractLink(entryXml),
10818
- pubDate: parseDate(
10819
- extractText(entryXml, "published") || extractText(entryXml, "updated")
10820
- ),
10821
- feedTitle,
10822
- feedOrigin,
10823
- excerpt: excerpt(entryXml, "summary", "content")
10824
- }));
10825
- }
10826
- function parseFeed(xml, feedOrigin) {
10827
- if (xml.includes("<feed")) return parseAtom(xml, feedOrigin);
10828
- return parseRss(xml, feedOrigin);
10829
- }
10830
-
10831
- // src/commands/news/web/fetchFeeds.ts
10832
- async function fetchFeeds(urls, onProgress) {
10833
- let done2 = 0;
10834
- const results = await Promise.allSettled(
10835
- urls.map(async (url) => {
10836
- const origin = new URL(url).origin;
10837
- const res = await fetch(url);
10838
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
10839
- const items3 = parseFeed(await res.text(), origin);
10840
- done2++;
10841
- onProgress?.(done2, urls.length);
10842
- return items3;
10843
- })
10844
- );
10845
- const items2 = [];
10846
- for (const result of results) {
10847
- if (result.status === "fulfilled") {
10848
- items2.push(...result.value);
10849
- }
10850
- }
10851
- items2.sort(
10852
- (a, b) => new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime()
10853
- );
10854
- return items2;
10855
- }
10856
-
10857
- // src/commands/news/web/getHtml.ts
10858
- function getHtml2() {
10859
- return `<!DOCTYPE html>
10860
- <html lang="en" class="dark">
10861
- <head>
10862
- <meta charset="UTF-8">
10863
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
10864
- <title>News</title>
10865
- <script src="https://cdn.tailwindcss.com"></script>
10866
- <script>tailwind.config={darkMode:'class'}</script>
10867
- </head>
10868
- <body class="font-[-apple-system,BlinkMacSystemFont,'Segoe_UI',Roboto,sans-serif] bg-gray-950 text-gray-200 leading-normal">
10869
- <div class="max-w-3xl mx-auto px-4 py-6" id="app"></div>
10870
- <script src="/bundle.js"></script>
10871
- </body>
10872
- </html>`;
10873
- }
10874
-
10875
- // src/commands/news/web/handleRequest.ts
10876
- var cachedItems;
10877
- var prefetchPromise;
10878
- function prefetch() {
10879
- const config = loadConfig();
10880
- const total = config.news.feeds.length;
10881
- if (total === 0) return;
10882
- process.stdout.write(chalk119.dim(`Fetching ${total} feed(s)\u2026 `));
10883
- prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
10884
- const width = 20;
10885
- const filled = Math.round(done2 / t * width);
10886
- const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
10887
- process.stdout.write(
10888
- `\r${chalk119.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
10889
- );
10890
- }).then((items2) => {
10891
- process.stdout.write(
10892
- `\r${chalk119.green(`Fetched ${items2.length} items from ${total} feed(s)`)}
10893
- `
10894
- );
10895
- cachedItems = items2;
10896
- return items2;
10897
- });
10898
- }
10899
- async function listItems2(_req, res) {
10900
- if (!cachedItems && prefetchPromise) {
10901
- await prefetchPromise;
10902
- }
10903
- if (!cachedItems) {
10904
- const config = loadConfig();
10905
- cachedItems = await fetchFeeds(config.news.feeds);
10906
- }
10907
- respondJson(res, 200, cachedItems);
10908
- }
10909
- var routes2 = {
10910
- "GET /": createHtmlHandler(getHtml2),
10911
- "GET /bundle.js": createBundleHandler(
10912
- import.meta.url,
10913
- "commands/news/web/bundle.js"
10914
- ),
10915
- "GET /api/items": listItems2
10916
- };
10917
- var handleRequest2 = createRouteHandler(routes2);
10918
-
10919
- // src/commands/news/web/index.ts
10920
- async function web3(options2) {
10921
- prefetch();
10922
- startWebServer(
10923
- "News web view",
10924
- Number.parseInt(options2.port, 10),
10925
- handleRequest2
10926
- );
10927
- }
10928
-
10929
10903
  // src/commands/registerNews.ts
10930
10904
  function registerNews(program2) {
10931
- const newsCommand = program2.command("news").description("View latest news from configured RSS feeds").action(() => web3({ port: "3001" }));
10932
- newsCommand.command("add").description("Add an RSS feed URL to the config").argument("<url>", "RSS feed URL").action(add2);
10933
- newsCommand.command("web").description("Start a web view of the news feeds").option("-p, --port <number>", "Port to listen on", "3001").action(web3);
10905
+ const newsCommand = program2.command("news").description("Manage RSS news feeds");
10906
+ newsCommand.command("add").description("Add an RSS feed URL").argument("<url>", "RSS feed URL").action(add2);
10934
10907
  }
10935
10908
 
10936
10909
  // src/commands/prompts/printPromptsTable.ts
10937
- import chalk120 from "chalk";
10910
+ import chalk119 from "chalk";
10938
10911
  function truncate(str, max) {
10939
10912
  if (str.length <= max) return str;
10940
10913
  return `${str.slice(0, max - 1)}\u2026`;
@@ -10952,14 +10925,14 @@ function printPromptsTable(rows) {
10952
10925
  "Command".padEnd(commandWidth),
10953
10926
  "Repos"
10954
10927
  ].join(" ");
10955
- console.log(chalk120.dim(header));
10956
- console.log(chalk120.dim("-".repeat(header.length)));
10928
+ console.log(chalk119.dim(header));
10929
+ console.log(chalk119.dim("-".repeat(header.length)));
10957
10930
  for (const row of rows) {
10958
10931
  const count6 = String(row.count).padStart(countWidth);
10959
10932
  const tool = row.tool.padEnd(toolWidth);
10960
10933
  const command = truncate(row.command, 60).padEnd(commandWidth);
10961
10934
  console.log(
10962
- `${chalk120.yellow(count6)} ${tool} ${command} ${chalk120.dim(row.repos)}`
10935
+ `${chalk119.yellow(count6)} ${tool} ${command} ${chalk119.dim(row.repos)}`
10963
10936
  );
10964
10937
  }
10965
10938
  }
@@ -11035,6 +11008,17 @@ function getCurrentPrNumber() {
11035
11008
  throw error;
11036
11009
  }
11037
11010
  }
11011
+ function getCurrentPr() {
11012
+ try {
11013
+ return viewCurrentPr("number,body");
11014
+ } catch (error) {
11015
+ if (error instanceof Error && error.message.includes("no pull requests")) {
11016
+ console.error("Error: No pull request found for the current branch.");
11017
+ process.exit(1);
11018
+ }
11019
+ throw error;
11020
+ }
11021
+ }
11038
11022
  function getCurrentPrNodeId() {
11039
11023
  try {
11040
11024
  return viewCurrentPr("id").id;
@@ -11111,37 +11095,102 @@ function comment2(path54, line, body, startLine) {
11111
11095
  }
11112
11096
  }
11113
11097
 
11114
- // src/commands/prs/create.ts
11098
+ // src/commands/prs/edit.ts
11115
11099
  import { execSync as execSync33 } from "child_process";
11116
11100
 
11117
- // src/commands/prs/buildCreateArgs.ts
11118
- function buildCreateArgs(title, body, options2) {
11119
- const args = [
11120
- "gh pr create",
11121
- `--title ${shellQuote(title)}`,
11122
- `--body ${shellQuote(body)}`
11123
- ];
11124
- const valueFlags = [
11125
- ["--base", options2.base],
11126
- ["--head", options2.head],
11127
- ["--milestone", options2.milestone]
11128
- ];
11129
- for (const [flag, value] of valueFlags) {
11130
- if (value) args.push(`${flag} ${shellQuote(value)}`);
11101
+ // src/commands/prs/buildPrBody.ts
11102
+ function jiraBrowseUrl(key) {
11103
+ const { site } = loadJson("jira.json");
11104
+ return site ? `https://${site}/browse/${key}` : key;
11105
+ }
11106
+ function renderWhy(why, resolves) {
11107
+ if (resolves && resolves.length > 0) {
11108
+ const urls = resolves.map(jiraBrowseUrl).join(", ");
11109
+ return `${why}
11110
+
11111
+ Resolves ${urls}`;
11131
11112
  }
11132
- if (options2.draft) args.push("--draft");
11133
- if (options2.web) args.push("--web");
11134
- const repeatableFlags = [
11135
- ["--label", options2.label],
11136
- ["--assignee", options2.assignee],
11137
- ["--reviewer", options2.reviewer]
11113
+ return why;
11114
+ }
11115
+ function buildPrBody(sections) {
11116
+ const parts = [
11117
+ `## What
11118
+
11119
+ ${sections.what}`,
11120
+ `## Why
11121
+
11122
+ ${renderWhy(sections.why, sections.resolves)}`
11138
11123
  ];
11139
- for (const [flag, values] of repeatableFlags) {
11140
- for (const value of values ?? []) {
11141
- args.push(`${flag} ${shellQuote(value)}`);
11124
+ if (sections.how) {
11125
+ parts.push(`## How
11126
+
11127
+ ${sections.how}`);
11128
+ }
11129
+ return parts.join("\n\n");
11130
+ }
11131
+
11132
+ // src/commands/prs/parsePrBody.ts
11133
+ function parsePrBody(body) {
11134
+ const sections = [];
11135
+ let current = null;
11136
+ const flush = () => {
11137
+ if (current) {
11138
+ sections.push({
11139
+ heading: current.heading,
11140
+ content: current.lines.join("\n").trim()
11141
+ });
11142
+ }
11143
+ };
11144
+ for (const line of body.split("\n")) {
11145
+ const match = /^##\s+(.+?)\s*$/.exec(line);
11146
+ if (match) {
11147
+ flush();
11148
+ current = { heading: match[1], lines: [] };
11149
+ } else if (current) {
11150
+ current.lines.push(line);
11142
11151
  }
11143
11152
  }
11144
- return args;
11153
+ flush();
11154
+ return sections;
11155
+ }
11156
+ function serializePrBody(sections) {
11157
+ return sections.map((section2) => `## ${section2.heading}
11158
+
11159
+ ${section2.content}`).join("\n\n");
11160
+ }
11161
+
11162
+ // src/commands/prs/editPrBody.ts
11163
+ function stripResolves(content) {
11164
+ return content.replace(/\n+Resolves [^\n]*$/, "").trimEnd();
11165
+ }
11166
+ function extractResolves(content) {
11167
+ const match = /\n+(Resolves [^\n]*)$/.exec(content);
11168
+ return match ? match[1] : "";
11169
+ }
11170
+ function editPrBody(body, sections) {
11171
+ const parsed = parsePrBody(body);
11172
+ const find = (heading) => parsed.find((s) => s.heading.toLowerCase() === heading.toLowerCase());
11173
+ const upsert = (heading, content) => {
11174
+ const existing = find(heading);
11175
+ if (existing) existing.content = content;
11176
+ else parsed.push({ heading, content });
11177
+ };
11178
+ if (sections.what !== void 0) upsert("What", sections.what);
11179
+ const hasResolves = (sections.resolves?.length ?? 0) > 0;
11180
+ if (sections.why !== void 0 || hasResolves) {
11181
+ const existingWhy = find("Why")?.content ?? "";
11182
+ const baseWhy = sections.why !== void 0 ? sections.why : stripResolves(existingWhy);
11183
+ if (hasResolves) {
11184
+ upsert("Why", renderWhy(baseWhy, sections.resolves));
11185
+ } else {
11186
+ const resolves = extractResolves(existingWhy);
11187
+ upsert("Why", resolves ? `${baseWhy}
11188
+
11189
+ ${resolves}` : baseWhy);
11190
+ }
11191
+ }
11192
+ if (sections.how !== void 0) upsert("How", sections.how);
11193
+ return serializePrBody(parsed);
11145
11194
  }
11146
11195
 
11147
11196
  // src/commands/prs/validatePrContent.ts
@@ -11156,16 +11205,22 @@ function validatePrContent(title, body) {
11156
11205
  }
11157
11206
  }
11158
11207
 
11159
- // src/commands/prs/create.ts
11160
- function create(options2) {
11161
- if (!options2.title || !options2.body) {
11208
+ // src/commands/prs/edit.ts
11209
+ function edit(options2) {
11210
+ const hasResolves = (options2.resolves?.length ?? 0) > 0;
11211
+ const hasSection = options2.what !== void 0 || options2.why !== void 0 || options2.how !== void 0 || hasResolves;
11212
+ if (!options2.title && !hasSection) {
11162
11213
  console.error(
11163
- "Usage: assist prs create --title <title> --body <body> [--base <branch>] [--head <branch>] [--draft] [--web] [--label <label>] [--assignee <login>] [--reviewer <handle>] [--milestone <name>]"
11214
+ "Usage: assist prs edit [--title <title>] [--what <what>] [--why <why>] [--how <how>] [--resolves <key>]"
11164
11215
  );
11165
11216
  process.exit(1);
11166
11217
  }
11167
- validatePrContent(options2.title, options2.body);
11168
- const args = buildCreateArgs(options2.title, options2.body, options2);
11218
+ const { number, body } = getCurrentPr();
11219
+ const newBody = editPrBody(body, options2);
11220
+ validatePrContent(options2.title ?? "", newBody);
11221
+ const args = [`gh pr edit ${number}`];
11222
+ if (options2.title) args.push(`--title ${shellQuote(options2.title)}`);
11223
+ args.push(`--body ${shellQuote(newBody)}`);
11169
11224
  try {
11170
11225
  execSync33(args.join(" "), { stdio: "inherit" });
11171
11226
  } catch (_error) {
@@ -11376,20 +11431,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
11376
11431
  }
11377
11432
 
11378
11433
  // src/commands/prs/listComments/printComments.ts
11379
- import chalk121 from "chalk";
11434
+ import chalk120 from "chalk";
11380
11435
  function formatForHuman(comment3) {
11381
11436
  if (comment3.type === "review") {
11382
- const stateColor = comment3.state === "APPROVED" ? chalk121.green : comment3.state === "CHANGES_REQUESTED" ? chalk121.red : chalk121.yellow;
11437
+ const stateColor = comment3.state === "APPROVED" ? chalk120.green : comment3.state === "CHANGES_REQUESTED" ? chalk120.red : chalk120.yellow;
11383
11438
  return [
11384
- `${chalk121.cyan("Review")} by ${chalk121.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
11439
+ `${chalk120.cyan("Review")} by ${chalk120.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
11385
11440
  comment3.body,
11386
11441
  ""
11387
11442
  ].join("\n");
11388
11443
  }
11389
11444
  const location = comment3.line ? `:${comment3.line}` : "";
11390
11445
  return [
11391
- `${chalk121.cyan("Line comment")} by ${chalk121.bold(comment3.user)} on ${chalk121.dim(`${comment3.path}${location}`)}`,
11392
- chalk121.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
11446
+ `${chalk120.cyan("Line comment")} by ${chalk120.bold(comment3.user)} on ${chalk120.dim(`${comment3.path}${location}`)}`,
11447
+ chalk120.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
11393
11448
  comment3.body,
11394
11449
  ""
11395
11450
  ].join("\n");
@@ -11479,13 +11534,13 @@ import { execSync as execSync38 } from "child_process";
11479
11534
  import enquirer9 from "enquirer";
11480
11535
 
11481
11536
  // src/commands/prs/prs/displayPaginated/printPr.ts
11482
- import chalk122 from "chalk";
11537
+ import chalk121 from "chalk";
11483
11538
  var STATUS_MAP = {
11484
- MERGED: (pr) => pr.mergedAt ? { label: chalk122.magenta("merged"), date: pr.mergedAt } : null,
11485
- CLOSED: (pr) => pr.closedAt ? { label: chalk122.red("closed"), date: pr.closedAt } : null
11539
+ MERGED: (pr) => pr.mergedAt ? { label: chalk121.magenta("merged"), date: pr.mergedAt } : null,
11540
+ CLOSED: (pr) => pr.closedAt ? { label: chalk121.red("closed"), date: pr.closedAt } : null
11486
11541
  };
11487
11542
  function defaultStatus(pr) {
11488
- return { label: chalk122.green("opened"), date: pr.createdAt };
11543
+ return { label: chalk121.green("opened"), date: pr.createdAt };
11489
11544
  }
11490
11545
  function getStatus2(pr) {
11491
11546
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -11494,11 +11549,11 @@ function formatDate(dateStr) {
11494
11549
  return new Date(dateStr).toISOString().split("T")[0];
11495
11550
  }
11496
11551
  function formatPrHeader(pr, status2) {
11497
- return `${chalk122.cyan(`#${pr.number}`)} ${pr.title} ${chalk122.dim(`(${pr.author.login},`)} ${status2.label} ${chalk122.dim(`${formatDate(status2.date)})`)}`;
11552
+ return `${chalk121.cyan(`#${pr.number}`)} ${pr.title} ${chalk121.dim(`(${pr.author.login},`)} ${status2.label} ${chalk121.dim(`${formatDate(status2.date)})`)}`;
11498
11553
  }
11499
11554
  function logPrDetails(pr) {
11500
11555
  console.log(
11501
- chalk122.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
11556
+ chalk121.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
11502
11557
  );
11503
11558
  console.log();
11504
11559
  }
@@ -11602,8 +11657,75 @@ async function prs(options2) {
11602
11657
  }
11603
11658
  }
11604
11659
 
11605
- // src/commands/prs/wontfix.ts
11660
+ // src/commands/prs/raise.ts
11606
11661
  import { execSync as execSync39 } from "child_process";
11662
+
11663
+ // src/commands/prs/buildCreateArgs.ts
11664
+ function buildCreateArgs(title, body, options2) {
11665
+ const args = [
11666
+ "gh pr create",
11667
+ `--title ${shellQuote(title)}`,
11668
+ `--body ${shellQuote(body)}`
11669
+ ];
11670
+ const valueFlags = [
11671
+ ["--base", options2.base],
11672
+ ["--head", options2.head],
11673
+ ["--milestone", options2.milestone]
11674
+ ];
11675
+ for (const [flag, value] of valueFlags) {
11676
+ if (value) args.push(`${flag} ${shellQuote(value)}`);
11677
+ }
11678
+ if (options2.draft) args.push("--draft");
11679
+ if (options2.web) args.push("--web");
11680
+ const repeatableFlags = [
11681
+ ["--label", options2.label],
11682
+ ["--assignee", options2.assignee],
11683
+ ["--reviewer", options2.reviewer]
11684
+ ];
11685
+ for (const [flag, values] of repeatableFlags) {
11686
+ for (const value of values ?? []) {
11687
+ args.push(`${flag} ${shellQuote(value)}`);
11688
+ }
11689
+ }
11690
+ return args;
11691
+ }
11692
+
11693
+ // src/commands/prs/raise.ts
11694
+ function raise(options2) {
11695
+ if (!options2.title || !options2.what || !options2.why) {
11696
+ console.error(
11697
+ "Usage: assist prs raise --title <title> --what <what> --why <why> [--how <how>] [--resolves <key>] [--force]"
11698
+ );
11699
+ process.exit(1);
11700
+ }
11701
+ const body = buildPrBody({
11702
+ what: options2.what,
11703
+ why: options2.why,
11704
+ how: options2.how,
11705
+ resolves: options2.resolves
11706
+ });
11707
+ validatePrContent(options2.title, body);
11708
+ const existing = findCurrentPrNumber();
11709
+ if (existing !== null && !options2.force) {
11710
+ console.error(
11711
+ `Error: A pull request already exists for this branch (#${existing}). Pass --force to overwrite it, or use 'assist prs edit' to update individual sections.`
11712
+ );
11713
+ process.exit(1);
11714
+ }
11715
+ const args = existing !== null ? [
11716
+ `gh pr edit ${existing}`,
11717
+ `--title ${shellQuote(options2.title)}`,
11718
+ `--body ${shellQuote(body)}`
11719
+ ] : buildCreateArgs(options2.title, body, options2);
11720
+ try {
11721
+ execSync39(args.join(" "), { stdio: "inherit" });
11722
+ } catch (_error) {
11723
+ process.exit(1);
11724
+ }
11725
+ }
11726
+
11727
+ // src/commands/prs/wontfix.ts
11728
+ import { execSync as execSync40 } from "child_process";
11607
11729
  function validateReason(reason) {
11608
11730
  const lowerReason = reason.toLowerCase();
11609
11731
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -11620,7 +11742,7 @@ function validateShaReferences(reason) {
11620
11742
  const invalidShas = [];
11621
11743
  for (const sha of shas) {
11622
11744
  try {
11623
- execSync39(`git cat-file -t ${sha}`, { stdio: "pipe" });
11745
+ execSync40(`git cat-file -t ${sha}`, { stdio: "pipe" });
11624
11746
  } catch {
11625
11747
  invalidShas.push(sha);
11626
11748
  }
@@ -11647,30 +11769,54 @@ function wontfix(commentId, reason) {
11647
11769
  }
11648
11770
  }
11649
11771
 
11650
- // src/commands/registerPrsCreate.ts
11772
+ // src/commands/registerPrsEdit.ts
11651
11773
  function collect2(value, previous) {
11652
11774
  return previous.concat([value]);
11653
11775
  }
11654
- function registerPrsCreate(prsCommand) {
11655
- prsCommand.command("create").description(
11656
- "Create a pull request via gh pr create, validating the title and body first"
11657
- ).option("-t, --title <title>", "Title for the pull request").option("-b, --body <body>", "Body for the pull request").option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)", collect2, []).option(
11776
+ function registerPrsEdit(prsCommand) {
11777
+ prsCommand.command("edit").description(
11778
+ "Update individual sections of the current branch's pull request"
11779
+ ).option("-t, --title <title>", "New title for the pull request").option("--what <what>", "Replace the ## What section").option("--why <why>", "Replace the ## Why section").option("--how <how>", "Replace the ## How section").option(
11780
+ "--resolves <key>",
11781
+ "Jira issue key resolved by this PR, appended to ## Why (repeatable)",
11782
+ collect2,
11783
+ []
11784
+ ).action(edit);
11785
+ }
11786
+
11787
+ // src/commands/registerPrsRaise.ts
11788
+ function collect3(value, previous) {
11789
+ return previous.concat([value]);
11790
+ }
11791
+ function registerPrsRaise(prsCommand) {
11792
+ prsCommand.command("raise").description(
11793
+ "Raise a pull request, assembling the body from discrete sections"
11794
+ ).option("-t, --title <title>", "Title for the pull request").option("--what <what>", "What the change does (## What section)").option("--why <why>", "Why the change is needed (## Why section)").option("--how <how>", "How the change works (optional ## How section)").option(
11795
+ "--resolves <key>",
11796
+ "Jira issue key resolved by this PR, appended to ## Why (repeatable)",
11797
+ collect3,
11798
+ []
11799
+ ).option(
11800
+ "--force",
11801
+ "Overwrite the title and body of an existing pull request"
11802
+ ).option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)", collect3, []).option(
11658
11803
  "-a, --assignee <login>",
11659
11804
  "Assign a person by login (repeatable)",
11660
- collect2,
11805
+ collect3,
11661
11806
  []
11662
11807
  ).option(
11663
11808
  "-r, --reviewer <handle>",
11664
11809
  "Request a review (repeatable)",
11665
- collect2,
11810
+ collect3,
11666
11811
  []
11667
- ).option("-m, --milestone <name>", "Add the pull request to a milestone").action(create);
11812
+ ).option("-m, --milestone <name>", "Add the pull request to a milestone").action(raise);
11668
11813
  }
11669
11814
 
11670
11815
  // src/commands/registerPrs.ts
11671
11816
  function registerPrs(program2) {
11672
11817
  const prsCommand = program2.command("prs").description("Pull request utilities").option("--open", "List only open pull requests").option("--closed", "List only closed pull requests").action(prs);
11673
- registerPrsCreate(prsCommand);
11818
+ registerPrsRaise(prsCommand);
11819
+ registerPrsEdit(prsCommand);
11674
11820
  prsCommand.command("list-comments").description("List all comments on the current branch's pull request").action(() => {
11675
11821
  listComments().then(printComments2);
11676
11822
  });
@@ -11686,10 +11832,10 @@ function registerPrs(program2) {
11686
11832
  }
11687
11833
 
11688
11834
  // src/commands/ravendb/ravendbAuth.ts
11689
- import chalk128 from "chalk";
11835
+ import chalk127 from "chalk";
11690
11836
 
11691
11837
  // src/shared/createConnectionAuth.ts
11692
- import chalk123 from "chalk";
11838
+ import chalk122 from "chalk";
11693
11839
  function listConnections(connections, format2) {
11694
11840
  if (connections.length === 0) {
11695
11841
  console.log("No connections configured.");
@@ -11702,7 +11848,7 @@ function listConnections(connections, format2) {
11702
11848
  function removeConnection(connections, name, save) {
11703
11849
  const filtered = connections.filter((c) => c.name !== name);
11704
11850
  if (filtered.length === connections.length) {
11705
- console.error(chalk123.red(`Connection "${name}" not found.`));
11851
+ console.error(chalk122.red(`Connection "${name}" not found.`));
11706
11852
  process.exit(1);
11707
11853
  }
11708
11854
  save(filtered);
@@ -11748,17 +11894,17 @@ function saveConnections(connections) {
11748
11894
  }
11749
11895
 
11750
11896
  // src/commands/ravendb/promptConnection.ts
11751
- import chalk126 from "chalk";
11897
+ import chalk125 from "chalk";
11752
11898
 
11753
11899
  // src/commands/ravendb/selectOpSecret.ts
11754
- import chalk125 from "chalk";
11900
+ import chalk124 from "chalk";
11755
11901
  import Enquirer2 from "enquirer";
11756
11902
 
11757
11903
  // src/commands/ravendb/searchItems.ts
11758
- import { execSync as execSync40 } from "child_process";
11759
- import chalk124 from "chalk";
11904
+ import { execSync as execSync41 } from "child_process";
11905
+ import chalk123 from "chalk";
11760
11906
  function opExec(args) {
11761
- return execSync40(`op ${args}`, {
11907
+ return execSync41(`op ${args}`, {
11762
11908
  encoding: "utf-8",
11763
11909
  stdio: ["pipe", "pipe", "pipe"]
11764
11910
  }).trim();
@@ -11769,7 +11915,7 @@ function searchItems(search2) {
11769
11915
  items2 = JSON.parse(opExec("item list --format=json"));
11770
11916
  } catch {
11771
11917
  console.error(
11772
- chalk124.red(
11918
+ chalk123.red(
11773
11919
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
11774
11920
  )
11775
11921
  );
@@ -11783,7 +11929,7 @@ function getItemFields(itemId) {
11783
11929
  const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
11784
11930
  return item.fields.filter((f) => f.reference && f.label);
11785
11931
  } catch {
11786
- console.error(chalk124.red("Failed to get item details from 1Password."));
11932
+ console.error(chalk123.red("Failed to get item details from 1Password."));
11787
11933
  process.exit(1);
11788
11934
  }
11789
11935
  }
@@ -11802,7 +11948,7 @@ async function selectOpSecret(searchTerm) {
11802
11948
  }).run();
11803
11949
  const items2 = searchItems(search2);
11804
11950
  if (items2.length === 0) {
11805
- console.error(chalk125.red(`No items found matching "${search2}".`));
11951
+ console.error(chalk124.red(`No items found matching "${search2}".`));
11806
11952
  process.exit(1);
11807
11953
  }
11808
11954
  const itemId = await selectOne(
@@ -11811,7 +11957,7 @@ async function selectOpSecret(searchTerm) {
11811
11957
  );
11812
11958
  const fields = getItemFields(itemId);
11813
11959
  if (fields.length === 0) {
11814
- console.error(chalk125.red("No fields with references found on this item."));
11960
+ console.error(chalk124.red("No fields with references found on this item."));
11815
11961
  process.exit(1);
11816
11962
  }
11817
11963
  const ref = await selectOne(
@@ -11825,7 +11971,7 @@ async function selectOpSecret(searchTerm) {
11825
11971
  async function promptConnection(existingNames) {
11826
11972
  const name = await promptInput("name", "Connection name:");
11827
11973
  if (existingNames.includes(name)) {
11828
- console.error(chalk126.red(`Connection "${name}" already exists.`));
11974
+ console.error(chalk125.red(`Connection "${name}" already exists.`));
11829
11975
  process.exit(1);
11830
11976
  }
11831
11977
  const url = await promptInput(
@@ -11834,22 +11980,22 @@ async function promptConnection(existingNames) {
11834
11980
  );
11835
11981
  const database = await promptInput("database", "Database name:");
11836
11982
  if (!name || !url || !database) {
11837
- console.error(chalk126.red("All fields are required."));
11983
+ console.error(chalk125.red("All fields are required."));
11838
11984
  process.exit(1);
11839
11985
  }
11840
11986
  const apiKeyRef = await selectOpSecret();
11841
- console.log(chalk126.dim(`Using: ${apiKeyRef}`));
11987
+ console.log(chalk125.dim(`Using: ${apiKeyRef}`));
11842
11988
  return { name, url, database, apiKeyRef };
11843
11989
  }
11844
11990
 
11845
11991
  // src/commands/ravendb/ravendbSetConnection.ts
11846
- import chalk127 from "chalk";
11992
+ import chalk126 from "chalk";
11847
11993
  function ravendbSetConnection(name) {
11848
11994
  const raw = loadGlobalConfigRaw();
11849
11995
  const ravendb = raw.ravendb ?? {};
11850
11996
  const connections = ravendb.connections ?? [];
11851
11997
  if (!connections.some((c) => c.name === name)) {
11852
- console.error(chalk127.red(`Connection "${name}" not found.`));
11998
+ console.error(chalk126.red(`Connection "${name}" not found.`));
11853
11999
  console.error(
11854
12000
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
11855
12001
  );
@@ -11865,16 +12011,16 @@ function ravendbSetConnection(name) {
11865
12011
  var ravendbAuth = createConnectionAuth({
11866
12012
  load: loadConnections,
11867
12013
  save: saveConnections,
11868
- format: (c) => `${chalk128.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
12014
+ format: (c) => `${chalk127.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
11869
12015
  promptNew: promptConnection,
11870
12016
  onFirst: (c) => ravendbSetConnection(c.name)
11871
12017
  });
11872
12018
 
11873
12019
  // src/commands/ravendb/ravendbCollections.ts
11874
- import chalk132 from "chalk";
12020
+ import chalk131 from "chalk";
11875
12021
 
11876
12022
  // src/commands/ravendb/ravenFetch.ts
11877
- import chalk130 from "chalk";
12023
+ import chalk129 from "chalk";
11878
12024
 
11879
12025
  // src/commands/ravendb/getAccessToken.ts
11880
12026
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -11910,21 +12056,21 @@ ${errorText}`
11910
12056
  }
11911
12057
 
11912
12058
  // src/commands/ravendb/resolveOpSecret.ts
11913
- import { execSync as execSync41 } from "child_process";
11914
- import chalk129 from "chalk";
12059
+ import { execSync as execSync42 } from "child_process";
12060
+ import chalk128 from "chalk";
11915
12061
  function resolveOpSecret(reference) {
11916
12062
  if (!reference.startsWith("op://")) {
11917
- console.error(chalk129.red(`Invalid secret reference: must start with op://`));
12063
+ console.error(chalk128.red(`Invalid secret reference: must start with op://`));
11918
12064
  process.exit(1);
11919
12065
  }
11920
12066
  try {
11921
- return execSync41(`op read "${reference}"`, {
12067
+ return execSync42(`op read "${reference}"`, {
11922
12068
  encoding: "utf-8",
11923
12069
  stdio: ["pipe", "pipe", "pipe"]
11924
12070
  }).trim();
11925
12071
  } catch {
11926
12072
  console.error(
11927
- chalk129.red(
12073
+ chalk128.red(
11928
12074
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
11929
12075
  )
11930
12076
  );
@@ -11951,7 +12097,7 @@ async function ravenFetch(connection, path54) {
11951
12097
  if (!response.ok) {
11952
12098
  const body = await response.text();
11953
12099
  console.error(
11954
- chalk130.red(`RavenDB error: ${response.status} ${response.statusText}`)
12100
+ chalk129.red(`RavenDB error: ${response.status} ${response.statusText}`)
11955
12101
  );
11956
12102
  console.error(body.substring(0, 500));
11957
12103
  process.exit(1);
@@ -11960,7 +12106,7 @@ async function ravenFetch(connection, path54) {
11960
12106
  }
11961
12107
 
11962
12108
  // src/commands/ravendb/resolveConnection.ts
11963
- import chalk131 from "chalk";
12109
+ import chalk130 from "chalk";
11964
12110
  function loadRavendb() {
11965
12111
  const raw = loadGlobalConfigRaw();
11966
12112
  const ravendb = raw.ravendb;
@@ -11974,7 +12120,7 @@ function resolveConnection(name) {
11974
12120
  const connectionName = name ?? defaultConnection;
11975
12121
  if (!connectionName) {
11976
12122
  console.error(
11977
- chalk131.red(
12123
+ chalk130.red(
11978
12124
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
11979
12125
  )
11980
12126
  );
@@ -11982,7 +12128,7 @@ function resolveConnection(name) {
11982
12128
  }
11983
12129
  const connection = connections.find((c) => c.name === connectionName);
11984
12130
  if (!connection) {
11985
- console.error(chalk131.red(`Connection "${connectionName}" not found.`));
12131
+ console.error(chalk130.red(`Connection "${connectionName}" not found.`));
11986
12132
  console.error(
11987
12133
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
11988
12134
  );
@@ -12013,15 +12159,15 @@ async function ravendbCollections(connectionName) {
12013
12159
  return;
12014
12160
  }
12015
12161
  for (const c of collections) {
12016
- console.log(`${chalk132.bold(c.Name)} ${c.CountOfDocuments} docs`);
12162
+ console.log(`${chalk131.bold(c.Name)} ${c.CountOfDocuments} docs`);
12017
12163
  }
12018
12164
  }
12019
12165
 
12020
12166
  // src/commands/ravendb/ravendbQuery.ts
12021
- import chalk134 from "chalk";
12167
+ import chalk133 from "chalk";
12022
12168
 
12023
12169
  // src/commands/ravendb/fetchAllPages.ts
12024
- import chalk133 from "chalk";
12170
+ import chalk132 from "chalk";
12025
12171
 
12026
12172
  // src/commands/ravendb/buildQueryPath.ts
12027
12173
  function buildQueryPath(opts) {
@@ -12059,7 +12205,7 @@ async function fetchAllPages(connection, opts) {
12059
12205
  allResults.push(...results);
12060
12206
  start3 += results.length;
12061
12207
  process.stderr.write(
12062
- `\r${chalk133.dim(`Fetched ${allResults.length}/${totalResults}`)}`
12208
+ `\r${chalk132.dim(`Fetched ${allResults.length}/${totalResults}`)}`
12063
12209
  );
12064
12210
  if (start3 >= totalResults) break;
12065
12211
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -12074,7 +12220,7 @@ async function fetchAllPages(connection, opts) {
12074
12220
  async function ravendbQuery(connectionName, collection, options2) {
12075
12221
  const resolved = resolveArgs(connectionName, collection);
12076
12222
  if (!resolved.collection && !options2.query) {
12077
- console.error(chalk134.red("Provide a collection name or --query filter."));
12223
+ console.error(chalk133.red("Provide a collection name or --query filter."));
12078
12224
  process.exit(1);
12079
12225
  }
12080
12226
  const { collection: col } = resolved;
@@ -12112,7 +12258,7 @@ import { spawn as spawn5 } from "child_process";
12112
12258
  import * as path26 from "path";
12113
12259
 
12114
12260
  // src/commands/refactor/logViolations.ts
12115
- import chalk135 from "chalk";
12261
+ import chalk134 from "chalk";
12116
12262
  var DEFAULT_MAX_LINES = 100;
12117
12263
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
12118
12264
  if (violations.length === 0) {
@@ -12121,43 +12267,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
12121
12267
  }
12122
12268
  return;
12123
12269
  }
12124
- console.error(chalk135.red(`
12270
+ console.error(chalk134.red(`
12125
12271
  Refactor check failed:
12126
12272
  `));
12127
- console.error(chalk135.red(` The following files exceed ${maxLines} lines:
12273
+ console.error(chalk134.red(` The following files exceed ${maxLines} lines:
12128
12274
  `));
12129
12275
  for (const violation of violations) {
12130
- console.error(chalk135.red(` ${violation.file} (${violation.lines} lines)`));
12276
+ console.error(chalk134.red(` ${violation.file} (${violation.lines} lines)`));
12131
12277
  }
12132
12278
  console.error(
12133
- chalk135.yellow(
12279
+ chalk134.yellow(
12134
12280
  `
12135
12281
  Each file needs to be sensibly refactored, or if there is no sensible
12136
12282
  way to refactor it, ignore it with:
12137
12283
  `
12138
12284
  )
12139
12285
  );
12140
- console.error(chalk135.gray(` assist refactor ignore <file>
12286
+ console.error(chalk134.gray(` assist refactor ignore <file>
12141
12287
  `));
12142
12288
  if (process.env.CLAUDECODE) {
12143
- console.error(chalk135.cyan(`
12289
+ console.error(chalk134.cyan(`
12144
12290
  ## Extracting Code to New Files
12145
12291
  `));
12146
12292
  console.error(
12147
- chalk135.cyan(
12293
+ chalk134.cyan(
12148
12294
  ` When extracting logic from one file to another, consider where the extracted code belongs:
12149
12295
  `
12150
12296
  )
12151
12297
  );
12152
12298
  console.error(
12153
- chalk135.cyan(
12299
+ chalk134.cyan(
12154
12300
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
12155
12301
  original file's domain, create a new folder containing both the original and extracted files.
12156
12302
  `
12157
12303
  )
12158
12304
  );
12159
12305
  console.error(
12160
- chalk135.cyan(
12306
+ chalk134.cyan(
12161
12307
  ` 2. Share common utilities: If the extracted code can be reused across multiple
12162
12308
  domains, move it to a common/shared folder.
12163
12309
  `
@@ -12167,7 +12313,7 @@ Refactor check failed:
12167
12313
  }
12168
12314
 
12169
12315
  // src/commands/refactor/check/getViolations/index.ts
12170
- import { execSync as execSync42 } from "child_process";
12316
+ import { execSync as execSync43 } from "child_process";
12171
12317
  import fs18 from "fs";
12172
12318
  import { minimatch as minimatch5 } from "minimatch";
12173
12319
 
@@ -12217,7 +12363,7 @@ function getGitFiles(options2) {
12217
12363
  }
12218
12364
  const files = /* @__PURE__ */ new Set();
12219
12365
  if (options2.staged || options2.modified) {
12220
- const staged = execSync42("git diff --cached --name-only", {
12366
+ const staged = execSync43("git diff --cached --name-only", {
12221
12367
  encoding: "utf-8"
12222
12368
  });
12223
12369
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -12225,7 +12371,7 @@ function getGitFiles(options2) {
12225
12371
  }
12226
12372
  }
12227
12373
  if (options2.unstaged || options2.modified) {
12228
- const unstaged = execSync42("git diff --name-only", { encoding: "utf-8" });
12374
+ const unstaged = execSync43("git diff --name-only", { encoding: "utf-8" });
12229
12375
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
12230
12376
  files.add(file);
12231
12377
  }
@@ -12313,7 +12459,7 @@ async function check(pattern2, options2) {
12313
12459
 
12314
12460
  // src/commands/refactor/extract/index.ts
12315
12461
  import path33 from "path";
12316
- import chalk138 from "chalk";
12462
+ import chalk137 from "chalk";
12317
12463
 
12318
12464
  // src/commands/refactor/extract/applyExtraction.ts
12319
12465
  import { SyntaxKind as SyntaxKind4 } from "ts-morph";
@@ -12888,23 +13034,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
12888
13034
 
12889
13035
  // src/commands/refactor/extract/displayPlan.ts
12890
13036
  import path30 from "path";
12891
- import chalk136 from "chalk";
13037
+ import chalk135 from "chalk";
12892
13038
  function section(title) {
12893
13039
  return `
12894
- ${chalk136.cyan(title)}`;
13040
+ ${chalk135.cyan(title)}`;
12895
13041
  }
12896
13042
  function displayImporters(plan2, cwd) {
12897
13043
  if (plan2.importersToUpdate.length === 0) return;
12898
13044
  console.log(section("Update importers:"));
12899
13045
  for (const imp of plan2.importersToUpdate) {
12900
13046
  const rel = path30.relative(cwd, imp.file.getFilePath());
12901
- console.log(` ${chalk136.dim(rel)}: \u2192 import from "${imp.relPath}"`);
13047
+ console.log(` ${chalk135.dim(rel)}: \u2192 import from "${imp.relPath}"`);
12902
13048
  }
12903
13049
  }
12904
13050
  function displayPlan(functionName, relDest, plan2, cwd) {
12905
- console.log(chalk136.bold(`Extract: ${functionName} \u2192 ${relDest}
13051
+ console.log(chalk135.bold(`Extract: ${functionName} \u2192 ${relDest}
12906
13052
  `));
12907
- console.log(` ${chalk136.cyan("Functions to move:")}`);
13053
+ console.log(` ${chalk135.cyan("Functions to move:")}`);
12908
13054
  for (const name of plan2.extractedNames) {
12909
13055
  console.log(` ${name}`);
12910
13056
  }
@@ -12938,7 +13084,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
12938
13084
 
12939
13085
  // src/commands/refactor/extract/loadProjectFile.ts
12940
13086
  import path32 from "path";
12941
- import chalk137 from "chalk";
13087
+ import chalk136 from "chalk";
12942
13088
  import { Project as Project4 } from "ts-morph";
12943
13089
 
12944
13090
  // src/commands/refactor/extract/findTsConfig.ts
@@ -12998,7 +13144,7 @@ function loadProjectFile(file) {
12998
13144
  });
12999
13145
  const sourceFile = project.getSourceFile(sourcePath);
13000
13146
  if (!sourceFile) {
13001
- console.log(chalk137.red(`File not found in project: ${file}`));
13147
+ console.log(chalk136.red(`File not found in project: ${file}`));
13002
13148
  process.exit(1);
13003
13149
  }
13004
13150
  return { project, sourceFile };
@@ -13021,19 +13167,19 @@ async function extract(file, functionName, destination, options2 = {}) {
13021
13167
  displayPlan(functionName, relDest, plan2, cwd);
13022
13168
  if (options2.apply) {
13023
13169
  await applyExtraction(functionName, sourceFile, destPath, plan2, project);
13024
- console.log(chalk138.green("\nExtraction complete"));
13170
+ console.log(chalk137.green("\nExtraction complete"));
13025
13171
  } else {
13026
- console.log(chalk138.dim("\nDry run. Use --apply to execute."));
13172
+ console.log(chalk137.dim("\nDry run. Use --apply to execute."));
13027
13173
  }
13028
13174
  }
13029
13175
 
13030
13176
  // src/commands/refactor/ignore.ts
13031
13177
  import fs20 from "fs";
13032
- import chalk139 from "chalk";
13178
+ import chalk138 from "chalk";
13033
13179
  var REFACTOR_YML_PATH2 = "refactor.yml";
13034
13180
  function ignore(file) {
13035
13181
  if (!fs20.existsSync(file)) {
13036
- console.error(chalk139.red(`Error: File does not exist: ${file}`));
13182
+ console.error(chalk138.red(`Error: File does not exist: ${file}`));
13037
13183
  process.exit(1);
13038
13184
  }
13039
13185
  const content = fs20.readFileSync(file, "utf-8");
@@ -13049,7 +13195,7 @@ function ignore(file) {
13049
13195
  fs20.writeFileSync(REFACTOR_YML_PATH2, entry);
13050
13196
  }
13051
13197
  console.log(
13052
- chalk139.green(
13198
+ chalk138.green(
13053
13199
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
13054
13200
  )
13055
13201
  );
@@ -13057,25 +13203,25 @@ function ignore(file) {
13057
13203
 
13058
13204
  // src/commands/refactor/rename/index.ts
13059
13205
  import path34 from "path";
13060
- import chalk140 from "chalk";
13206
+ import chalk139 from "chalk";
13061
13207
  async function rename(source, destination, options2 = {}) {
13062
13208
  const destPath = path34.resolve(destination);
13063
13209
  const cwd = process.cwd();
13064
13210
  const relSource = path34.relative(cwd, path34.resolve(source));
13065
13211
  const relDest = path34.relative(cwd, destPath);
13066
13212
  const { project, sourceFile } = loadProjectFile(source);
13067
- console.log(chalk140.bold(`Rename: ${relSource} \u2192 ${relDest}`));
13213
+ console.log(chalk139.bold(`Rename: ${relSource} \u2192 ${relDest}`));
13068
13214
  if (options2.apply) {
13069
13215
  sourceFile.move(destPath);
13070
13216
  await project.save();
13071
- console.log(chalk140.green("Done"));
13217
+ console.log(chalk139.green("Done"));
13072
13218
  } else {
13073
- console.log(chalk140.dim("Dry run. Use --apply to execute."));
13219
+ console.log(chalk139.dim("Dry run. Use --apply to execute."));
13074
13220
  }
13075
13221
  }
13076
13222
 
13077
13223
  // src/commands/refactor/renameSymbol/index.ts
13078
- import chalk141 from "chalk";
13224
+ import chalk140 from "chalk";
13079
13225
 
13080
13226
  // src/commands/refactor/renameSymbol/findSymbol.ts
13081
13227
  import { SyntaxKind as SyntaxKind14 } from "ts-morph";
@@ -13121,33 +13267,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
13121
13267
  const { project, sourceFile } = loadProjectFile(file);
13122
13268
  const symbol = findSymbol(sourceFile, oldName);
13123
13269
  if (!symbol) {
13124
- console.log(chalk141.red(`Symbol "${oldName}" not found in ${file}`));
13270
+ console.log(chalk140.red(`Symbol "${oldName}" not found in ${file}`));
13125
13271
  process.exit(1);
13126
13272
  }
13127
13273
  const grouped = groupReferences(symbol, cwd);
13128
13274
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
13129
13275
  console.log(
13130
- chalk141.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
13276
+ chalk140.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
13131
13277
  `)
13132
13278
  );
13133
13279
  for (const [refFile, lines] of grouped) {
13134
13280
  console.log(
13135
- ` ${chalk141.dim(refFile)}: lines ${chalk141.cyan(lines.join(", "))}`
13281
+ ` ${chalk140.dim(refFile)}: lines ${chalk140.cyan(lines.join(", "))}`
13136
13282
  );
13137
13283
  }
13138
13284
  if (options2.apply) {
13139
13285
  symbol.rename(newName);
13140
13286
  await project.save();
13141
- console.log(chalk141.green(`
13287
+ console.log(chalk140.green(`
13142
13288
  Renamed ${oldName} \u2192 ${newName}`));
13143
13289
  } else {
13144
- console.log(chalk141.dim("\nDry run. Use --apply to execute."));
13290
+ console.log(chalk140.dim("\nDry run. Use --apply to execute."));
13145
13291
  }
13146
13292
  }
13147
13293
 
13148
13294
  // src/commands/refactor/restructure/index.ts
13149
13295
  import path44 from "path";
13150
- import chalk144 from "chalk";
13296
+ import chalk143 from "chalk";
13151
13297
 
13152
13298
  // src/commands/refactor/restructure/buildImportGraph/index.ts
13153
13299
  import path36 from "path";
@@ -13390,50 +13536,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
13390
13536
 
13391
13537
  // src/commands/refactor/restructure/displayPlan.ts
13392
13538
  import path40 from "path";
13393
- import chalk142 from "chalk";
13539
+ import chalk141 from "chalk";
13394
13540
  function relPath(filePath) {
13395
13541
  return path40.relative(process.cwd(), filePath);
13396
13542
  }
13397
13543
  function displayMoves(plan2) {
13398
13544
  if (plan2.moves.length === 0) return;
13399
- console.log(chalk142.bold("\nFile moves:"));
13545
+ console.log(chalk141.bold("\nFile moves:"));
13400
13546
  for (const move of plan2.moves) {
13401
13547
  console.log(
13402
- ` ${chalk142.red(relPath(move.from))} \u2192 ${chalk142.green(relPath(move.to))}`
13548
+ ` ${chalk141.red(relPath(move.from))} \u2192 ${chalk141.green(relPath(move.to))}`
13403
13549
  );
13404
- console.log(chalk142.dim(` ${move.reason}`));
13550
+ console.log(chalk141.dim(` ${move.reason}`));
13405
13551
  }
13406
13552
  }
13407
13553
  function displayRewrites(rewrites) {
13408
13554
  if (rewrites.length === 0) return;
13409
13555
  const affectedFiles = new Set(rewrites.map((r) => r.file));
13410
- console.log(chalk142.bold(`
13556
+ console.log(chalk141.bold(`
13411
13557
  Import rewrites (${affectedFiles.size} files):`));
13412
13558
  for (const file of affectedFiles) {
13413
- console.log(` ${chalk142.cyan(relPath(file))}:`);
13559
+ console.log(` ${chalk141.cyan(relPath(file))}:`);
13414
13560
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
13415
13561
  (r) => r.file === file
13416
13562
  )) {
13417
13563
  console.log(
13418
- ` ${chalk142.red(`"${oldSpecifier}"`)} \u2192 ${chalk142.green(`"${newSpecifier}"`)}`
13564
+ ` ${chalk141.red(`"${oldSpecifier}"`)} \u2192 ${chalk141.green(`"${newSpecifier}"`)}`
13419
13565
  );
13420
13566
  }
13421
13567
  }
13422
13568
  }
13423
13569
  function displayPlan2(plan2) {
13424
13570
  if (plan2.warnings.length > 0) {
13425
- console.log(chalk142.yellow("\nWarnings:"));
13426
- for (const w of plan2.warnings) console.log(chalk142.yellow(` ${w}`));
13571
+ console.log(chalk141.yellow("\nWarnings:"));
13572
+ for (const w of plan2.warnings) console.log(chalk141.yellow(` ${w}`));
13427
13573
  }
13428
13574
  if (plan2.newDirectories.length > 0) {
13429
- console.log(chalk142.bold("\nNew directories:"));
13575
+ console.log(chalk141.bold("\nNew directories:"));
13430
13576
  for (const dir of plan2.newDirectories)
13431
- console.log(chalk142.green(` ${dir}/`));
13577
+ console.log(chalk141.green(` ${dir}/`));
13432
13578
  }
13433
13579
  displayMoves(plan2);
13434
13580
  displayRewrites(plan2.rewrites);
13435
13581
  console.log(
13436
- chalk142.dim(
13582
+ chalk141.dim(
13437
13583
  `
13438
13584
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
13439
13585
  )
@@ -13443,18 +13589,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
13443
13589
  // src/commands/refactor/restructure/executePlan.ts
13444
13590
  import fs22 from "fs";
13445
13591
  import path41 from "path";
13446
- import chalk143 from "chalk";
13592
+ import chalk142 from "chalk";
13447
13593
  function executePlan(plan2) {
13448
13594
  const updatedContents = applyRewrites(plan2.rewrites);
13449
13595
  for (const [file, content] of updatedContents) {
13450
13596
  fs22.writeFileSync(file, content, "utf-8");
13451
13597
  console.log(
13452
- chalk143.cyan(` Rewrote imports in ${path41.relative(process.cwd(), file)}`)
13598
+ chalk142.cyan(` Rewrote imports in ${path41.relative(process.cwd(), file)}`)
13453
13599
  );
13454
13600
  }
13455
13601
  for (const dir of plan2.newDirectories) {
13456
13602
  fs22.mkdirSync(dir, { recursive: true });
13457
- console.log(chalk143.green(` Created ${path41.relative(process.cwd(), dir)}/`));
13603
+ console.log(chalk142.green(` Created ${path41.relative(process.cwd(), dir)}/`));
13458
13604
  }
13459
13605
  for (const move of plan2.moves) {
13460
13606
  const targetDir = path41.dirname(move.to);
@@ -13463,7 +13609,7 @@ function executePlan(plan2) {
13463
13609
  }
13464
13610
  fs22.renameSync(move.from, move.to);
13465
13611
  console.log(
13466
- chalk143.white(
13612
+ chalk142.white(
13467
13613
  ` Moved ${path41.relative(process.cwd(), move.from)} \u2192 ${path41.relative(process.cwd(), move.to)}`
13468
13614
  )
13469
13615
  );
@@ -13478,7 +13624,7 @@ function removeEmptyDirectories(dirs) {
13478
13624
  if (entries.length === 0) {
13479
13625
  fs22.rmdirSync(dir);
13480
13626
  console.log(
13481
- chalk143.dim(
13627
+ chalk142.dim(
13482
13628
  ` Removed empty directory ${path41.relative(process.cwd(), dir)}`
13483
13629
  )
13484
13630
  );
@@ -13611,22 +13757,22 @@ async function restructure(pattern2, options2 = {}) {
13611
13757
  const targetPattern = pattern2 ?? "src";
13612
13758
  const files = findSourceFiles2(targetPattern);
13613
13759
  if (files.length === 0) {
13614
- console.log(chalk144.yellow("No files found matching pattern"));
13760
+ console.log(chalk143.yellow("No files found matching pattern"));
13615
13761
  return;
13616
13762
  }
13617
13763
  const tsConfigPath = path44.resolve("tsconfig.json");
13618
13764
  const plan2 = buildPlan3(files, tsConfigPath);
13619
13765
  if (plan2.moves.length === 0) {
13620
- console.log(chalk144.green("No restructuring needed"));
13766
+ console.log(chalk143.green("No restructuring needed"));
13621
13767
  return;
13622
13768
  }
13623
13769
  displayPlan2(plan2);
13624
13770
  if (options2.apply) {
13625
- console.log(chalk144.bold("\nApplying changes..."));
13771
+ console.log(chalk143.bold("\nApplying changes..."));
13626
13772
  executePlan(plan2);
13627
- console.log(chalk144.green("\nRestructuring complete"));
13773
+ console.log(chalk143.green("\nRestructuring complete"));
13628
13774
  } else {
13629
- console.log(chalk144.dim("\nDry run. Use --apply to execute."));
13775
+ console.log(chalk143.dim("\nDry run. Use --apply to execute."));
13630
13776
  }
13631
13777
  }
13632
13778
 
@@ -13801,9 +13947,9 @@ function buildReviewPaths(repoRoot, key) {
13801
13947
  }
13802
13948
 
13803
13949
  // src/commands/review/fetchExistingComments.ts
13804
- import { execSync as execSync43 } from "child_process";
13950
+ import { execSync as execSync44 } from "child_process";
13805
13951
  function fetchRawComments(org, repo, prNumber) {
13806
- const out = execSync43(
13952
+ const out = execSync44(
13807
13953
  `gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
13808
13954
  { encoding: "utf-8", maxBuffer: 64 * 1024 * 1024 }
13809
13955
  );
@@ -13834,14 +13980,14 @@ function fetchExistingComments() {
13834
13980
  }
13835
13981
 
13836
13982
  // src/commands/review/gatherContext.ts
13837
- import { execSync as execSync46 } from "child_process";
13983
+ import { execSync as execSync47 } from "child_process";
13838
13984
 
13839
13985
  // src/commands/review/fetchPrDiff.ts
13840
- import { execSync as execSync44 } from "child_process";
13986
+ import { execSync as execSync45 } from "child_process";
13841
13987
  function fetchPrDiff(prNumber, baseSha, headSha) {
13842
13988
  const { org, repo } = getRepoInfo();
13843
13989
  try {
13844
- return execSync44(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
13990
+ return execSync45(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
13845
13991
  encoding: "utf-8",
13846
13992
  maxBuffer: 256 * 1024 * 1024,
13847
13993
  stdio: ["ignore", "pipe", "pipe"]
@@ -13856,19 +14002,19 @@ function isDiffTooLarge(error) {
13856
14002
  }
13857
14003
  function fetchDiffViaGit(baseSha, headSha) {
13858
14004
  try {
13859
- execSync44(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
14005
+ execSync45(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
13860
14006
  } catch {
13861
14007
  }
13862
- return execSync44(`git diff ${baseSha}...${headSha}`, {
14008
+ return execSync45(`git diff ${baseSha}...${headSha}`, {
13863
14009
  encoding: "utf-8",
13864
14010
  maxBuffer: 256 * 1024 * 1024
13865
14011
  });
13866
14012
  }
13867
14013
 
13868
14014
  // src/commands/review/fetchPrDiffInfo.ts
13869
- import { execSync as execSync45 } from "child_process";
14015
+ import { execSync as execSync46 } from "child_process";
13870
14016
  function getCurrentBranch2() {
13871
- return execSync45("git rev-parse --abbrev-ref HEAD", {
14017
+ return execSync46("git rev-parse --abbrev-ref HEAD", {
13872
14018
  encoding: "utf-8"
13873
14019
  }).trim();
13874
14020
  }
@@ -13878,7 +14024,7 @@ function fetchPrDiffInfo() {
13878
14024
  const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
13879
14025
  let raw;
13880
14026
  try {
13881
- raw = execSync45(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
14027
+ raw = execSync46(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
13882
14028
  encoding: "utf-8",
13883
14029
  stdio: ["ignore", "pipe", "pipe"]
13884
14030
  });
@@ -13902,7 +14048,7 @@ function fetchPrDiffInfo() {
13902
14048
  }
13903
14049
  function fetchPrChangedFiles(prNumber) {
13904
14050
  const { org, repo } = getRepoInfo();
13905
- const out = execSync45(
14051
+ const out = execSync46(
13906
14052
  `gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
13907
14053
  {
13908
14054
  encoding: "utf-8",
@@ -13914,11 +14060,11 @@ function fetchPrChangedFiles(prNumber) {
13914
14060
 
13915
14061
  // src/commands/review/gatherContext.ts
13916
14062
  function gatherContext() {
13917
- const branch = execSync46("git rev-parse --abbrev-ref HEAD", {
14063
+ const branch = execSync47("git rev-parse --abbrev-ref HEAD", {
13918
14064
  encoding: "utf-8"
13919
14065
  }).trim();
13920
- const sha = execSync46("git rev-parse HEAD", { encoding: "utf-8" }).trim();
13921
- const shortSha = execSync46("git rev-parse --short=7 HEAD", {
14066
+ const sha = execSync47("git rev-parse HEAD", { encoding: "utf-8" }).trim();
14067
+ const shortSha = execSync47("git rev-parse --short=7 HEAD", {
13922
14068
  encoding: "utf-8"
13923
14069
  }).trim();
13924
14070
  const prInfo = fetchPrDiffInfo();
@@ -14195,18 +14341,18 @@ function partitionFindingsByDiff(findings, index2) {
14195
14341
  }
14196
14342
 
14197
14343
  // src/commands/review/warnOutOfDiff.ts
14198
- import chalk145 from "chalk";
14344
+ import chalk144 from "chalk";
14199
14345
  function warnOutOfDiff(outOfDiff) {
14200
14346
  if (outOfDiff.length === 0) return;
14201
14347
  console.warn(
14202
- chalk145.yellow(
14348
+ chalk144.yellow(
14203
14349
  `Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
14204
14350
  )
14205
14351
  );
14206
14352
  for (const finding of outOfDiff) {
14207
14353
  const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
14208
14354
  console.warn(
14209
- ` ${chalk145.yellow("\xB7")} ${finding.title} ${chalk145.dim(
14355
+ ` ${chalk144.yellow("\xB7")} ${finding.title} ${chalk144.dim(
14210
14356
  `(${finding.file}:${range})`
14211
14357
  )}`
14212
14358
  );
@@ -14225,18 +14371,18 @@ function selectInDiffFindings(lineBound, prDiff) {
14225
14371
  }
14226
14372
 
14227
14373
  // src/commands/review/warnUnlocated.ts
14228
- import chalk146 from "chalk";
14374
+ import chalk145 from "chalk";
14229
14375
  function warnUnlocated(unlocated) {
14230
14376
  if (unlocated.length === 0) return;
14231
14377
  console.warn(
14232
- chalk146.yellow(
14378
+ chalk145.yellow(
14233
14379
  `Skipped ${unlocated.length} finding(s) without a parseable file:line:`
14234
14380
  )
14235
14381
  );
14236
14382
  for (const finding of unlocated) {
14237
- const where = finding.location || chalk146.dim("missing");
14383
+ const where = finding.location || chalk145.dim("missing");
14238
14384
  console.warn(
14239
- ` ${chalk146.yellow("\xB7")} ${finding.title} ${chalk146.dim(`(${where})`)}`
14385
+ ` ${chalk145.yellow("\xB7")} ${finding.title} ${chalk145.dim(`(${where})`)}`
14240
14386
  );
14241
14387
  }
14242
14388
  }
@@ -15409,7 +15555,7 @@ function registerReview(program2) {
15409
15555
  }
15410
15556
 
15411
15557
  // src/commands/seq/seqAuth.ts
15412
- import chalk148 from "chalk";
15558
+ import chalk147 from "chalk";
15413
15559
 
15414
15560
  // src/commands/seq/loadConnections.ts
15415
15561
  function loadConnections2() {
@@ -15438,10 +15584,10 @@ function setDefaultConnection(name) {
15438
15584
  }
15439
15585
 
15440
15586
  // src/shared/assertUniqueName.ts
15441
- import chalk147 from "chalk";
15587
+ import chalk146 from "chalk";
15442
15588
  function assertUniqueName(existingNames, name) {
15443
15589
  if (existingNames.includes(name)) {
15444
- console.error(chalk147.red(`Connection "${name}" already exists.`));
15590
+ console.error(chalk146.red(`Connection "${name}" already exists.`));
15445
15591
  process.exit(1);
15446
15592
  }
15447
15593
  }
@@ -15459,16 +15605,16 @@ async function promptConnection2(existingNames) {
15459
15605
  var seqAuth = createConnectionAuth({
15460
15606
  load: loadConnections2,
15461
15607
  save: saveConnections2,
15462
- format: (c) => `${chalk148.bold(c.name)} ${c.url}`,
15608
+ format: (c) => `${chalk147.bold(c.name)} ${c.url}`,
15463
15609
  promptNew: promptConnection2,
15464
15610
  onFirst: (c) => setDefaultConnection(c.name)
15465
15611
  });
15466
15612
 
15467
15613
  // src/commands/seq/seqQuery.ts
15468
- import chalk152 from "chalk";
15614
+ import chalk151 from "chalk";
15469
15615
 
15470
15616
  // src/commands/seq/fetchSeq.ts
15471
- import chalk149 from "chalk";
15617
+ import chalk148 from "chalk";
15472
15618
  async function fetchSeq(conn, path54, params) {
15473
15619
  const url = `${conn.url}${path54}?${params}`;
15474
15620
  const response = await fetch(url, {
@@ -15479,7 +15625,7 @@ async function fetchSeq(conn, path54, params) {
15479
15625
  });
15480
15626
  if (!response.ok) {
15481
15627
  const body = await response.text();
15482
- console.error(chalk149.red(`Seq returned ${response.status}: ${body}`));
15628
+ console.error(chalk148.red(`Seq returned ${response.status}: ${body}`));
15483
15629
  process.exit(1);
15484
15630
  }
15485
15631
  return response;
@@ -15534,23 +15680,23 @@ async function fetchSeqEvents(conn, params) {
15534
15680
  }
15535
15681
 
15536
15682
  // src/commands/seq/formatEvent.ts
15537
- import chalk150 from "chalk";
15683
+ import chalk149 from "chalk";
15538
15684
  function levelColor(level) {
15539
15685
  switch (level) {
15540
15686
  case "Fatal":
15541
- return chalk150.bgRed.white;
15687
+ return chalk149.bgRed.white;
15542
15688
  case "Error":
15543
- return chalk150.red;
15689
+ return chalk149.red;
15544
15690
  case "Warning":
15545
- return chalk150.yellow;
15691
+ return chalk149.yellow;
15546
15692
  case "Information":
15547
- return chalk150.cyan;
15693
+ return chalk149.cyan;
15548
15694
  case "Debug":
15549
- return chalk150.gray;
15695
+ return chalk149.gray;
15550
15696
  case "Verbose":
15551
- return chalk150.dim;
15697
+ return chalk149.dim;
15552
15698
  default:
15553
- return chalk150.white;
15699
+ return chalk149.white;
15554
15700
  }
15555
15701
  }
15556
15702
  function levelAbbrev(level) {
@@ -15591,12 +15737,12 @@ function formatTimestamp(iso) {
15591
15737
  function formatEvent(event) {
15592
15738
  const color = levelColor(event.Level);
15593
15739
  const abbrev = levelAbbrev(event.Level);
15594
- const ts8 = chalk150.dim(formatTimestamp(event.Timestamp));
15740
+ const ts8 = chalk149.dim(formatTimestamp(event.Timestamp));
15595
15741
  const msg = renderMessage(event);
15596
15742
  const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
15597
15743
  if (event.Exception) {
15598
15744
  for (const line of event.Exception.split("\n")) {
15599
- lines.push(chalk150.red(` ${line}`));
15745
+ lines.push(chalk149.red(` ${line}`));
15600
15746
  }
15601
15747
  }
15602
15748
  return lines.join("\n");
@@ -15629,11 +15775,11 @@ function rejectTimestampFilter(filter) {
15629
15775
  }
15630
15776
 
15631
15777
  // src/shared/resolveNamedConnection.ts
15632
- import chalk151 from "chalk";
15778
+ import chalk150 from "chalk";
15633
15779
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
15634
15780
  if (connections.length === 0) {
15635
15781
  console.error(
15636
- chalk151.red(
15782
+ chalk150.red(
15637
15783
  `No ${kind} connections configured. Run '${authCommand}' first.`
15638
15784
  )
15639
15785
  );
@@ -15642,7 +15788,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
15642
15788
  const target = requested ?? defaultName ?? connections[0].name;
15643
15789
  const connection = connections.find((c) => c.name === target);
15644
15790
  if (!connection) {
15645
- console.error(chalk151.red(`${kind} connection "${target}" not found.`));
15791
+ console.error(chalk150.red(`${kind} connection "${target}" not found.`));
15646
15792
  process.exit(1);
15647
15793
  }
15648
15794
  return connection;
@@ -15671,7 +15817,7 @@ async function seqQuery(filter, options2) {
15671
15817
  new URLSearchParams({ filter, count: String(count6) })
15672
15818
  );
15673
15819
  if (events.length === 0) {
15674
- console.log(chalk152.yellow("No events found."));
15820
+ console.log(chalk151.yellow("No events found."));
15675
15821
  return;
15676
15822
  }
15677
15823
  if (options2.json) {
@@ -15682,11 +15828,11 @@ async function seqQuery(filter, options2) {
15682
15828
  for (const event of chronological) {
15683
15829
  console.log(formatEvent(event));
15684
15830
  }
15685
- console.log(chalk152.dim(`
15831
+ console.log(chalk151.dim(`
15686
15832
  ${events.length} events`));
15687
15833
  if (events.length >= count6) {
15688
15834
  console.log(
15689
- chalk152.yellow(
15835
+ chalk151.yellow(
15690
15836
  `Results limited to ${count6}. Use --count to retrieve more.`
15691
15837
  )
15692
15838
  );
@@ -15694,10 +15840,10 @@ ${events.length} events`));
15694
15840
  }
15695
15841
 
15696
15842
  // src/shared/setNamedDefaultConnection.ts
15697
- import chalk153 from "chalk";
15843
+ import chalk152 from "chalk";
15698
15844
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
15699
15845
  if (!connections.find((c) => c.name === name)) {
15700
- console.error(chalk153.red(`Connection "${name}" not found.`));
15846
+ console.error(chalk152.red(`Connection "${name}" not found.`));
15701
15847
  process.exit(1);
15702
15848
  }
15703
15849
  setDefault(name);
@@ -15745,7 +15891,7 @@ function registerSignal(program2) {
15745
15891
  }
15746
15892
 
15747
15893
  // src/commands/sql/sqlAuth.ts
15748
- import chalk155 from "chalk";
15894
+ import chalk154 from "chalk";
15749
15895
 
15750
15896
  // src/commands/sql/loadConnections.ts
15751
15897
  function loadConnections3() {
@@ -15774,7 +15920,7 @@ function setDefaultConnection2(name) {
15774
15920
  }
15775
15921
 
15776
15922
  // src/commands/sql/promptConnection.ts
15777
- import chalk154 from "chalk";
15923
+ import chalk153 from "chalk";
15778
15924
  async function promptConnection3(existingNames) {
15779
15925
  const name = await promptInput("name", "Connection name:", "default");
15780
15926
  assertUniqueName(existingNames, name);
@@ -15782,7 +15928,7 @@ async function promptConnection3(existingNames) {
15782
15928
  const portStr = await promptInput("port", "Port:", "1433");
15783
15929
  const port = Number.parseInt(portStr, 10);
15784
15930
  if (!Number.isFinite(port)) {
15785
- console.error(chalk154.red(`Invalid port "${portStr}".`));
15931
+ console.error(chalk153.red(`Invalid port "${portStr}".`));
15786
15932
  process.exit(1);
15787
15933
  }
15788
15934
  const user = await promptInput("user", "User:");
@@ -15795,13 +15941,13 @@ async function promptConnection3(existingNames) {
15795
15941
  var sqlAuth = createConnectionAuth({
15796
15942
  load: loadConnections3,
15797
15943
  save: saveConnections3,
15798
- format: (c) => `${chalk155.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
15944
+ format: (c) => `${chalk154.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
15799
15945
  promptNew: promptConnection3,
15800
15946
  onFirst: (c) => setDefaultConnection2(c.name)
15801
15947
  });
15802
15948
 
15803
15949
  // src/commands/sql/printTable.ts
15804
- import chalk156 from "chalk";
15950
+ import chalk155 from "chalk";
15805
15951
  function formatCell(value) {
15806
15952
  if (value === null || value === void 0) return "";
15807
15953
  if (value instanceof Date) return value.toISOString();
@@ -15810,7 +15956,7 @@ function formatCell(value) {
15810
15956
  }
15811
15957
  function printTable(rows) {
15812
15958
  if (rows.length === 0) {
15813
- console.log(chalk156.yellow("(no rows)"));
15959
+ console.log(chalk155.yellow("(no rows)"));
15814
15960
  return;
15815
15961
  }
15816
15962
  const columns = Object.keys(rows[0]);
@@ -15818,13 +15964,13 @@ function printTable(rows) {
15818
15964
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
15819
15965
  );
15820
15966
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
15821
- console.log(chalk156.dim(header));
15822
- console.log(chalk156.dim("-".repeat(header.length)));
15967
+ console.log(chalk155.dim(header));
15968
+ console.log(chalk155.dim("-".repeat(header.length)));
15823
15969
  for (const row of rows) {
15824
15970
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
15825
15971
  console.log(line);
15826
15972
  }
15827
- console.log(chalk156.dim(`
15973
+ console.log(chalk155.dim(`
15828
15974
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
15829
15975
  }
15830
15976
 
@@ -15884,7 +16030,7 @@ async function sqlColumns(table, connectionName) {
15884
16030
  }
15885
16031
 
15886
16032
  // src/commands/sql/sqlMutate.ts
15887
- import chalk157 from "chalk";
16033
+ import chalk156 from "chalk";
15888
16034
 
15889
16035
  // src/commands/sql/isMutation.ts
15890
16036
  var MUTATION_KEYWORDS = [
@@ -15918,7 +16064,7 @@ function isMutation(sql4) {
15918
16064
  async function sqlMutate(query, connectionName) {
15919
16065
  if (!isMutation(query)) {
15920
16066
  console.error(
15921
- chalk157.red(
16067
+ chalk156.red(
15922
16068
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
15923
16069
  )
15924
16070
  );
@@ -15928,18 +16074,18 @@ async function sqlMutate(query, connectionName) {
15928
16074
  const pool = await sqlConnect(conn);
15929
16075
  try {
15930
16076
  const result = await pool.request().query(query);
15931
- console.log(chalk157.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
16077
+ console.log(chalk156.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
15932
16078
  } finally {
15933
16079
  await pool.close();
15934
16080
  }
15935
16081
  }
15936
16082
 
15937
16083
  // src/commands/sql/sqlQuery.ts
15938
- import chalk158 from "chalk";
16084
+ import chalk157 from "chalk";
15939
16085
  async function sqlQuery(query, connectionName) {
15940
16086
  if (isMutation(query)) {
15941
16087
  console.error(
15942
- chalk158.red(
16088
+ chalk157.red(
15943
16089
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
15944
16090
  )
15945
16091
  );
@@ -15954,7 +16100,7 @@ async function sqlQuery(query, connectionName) {
15954
16100
  printTable(rows);
15955
16101
  } else {
15956
16102
  console.log(
15957
- chalk158.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
16103
+ chalk157.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
15958
16104
  );
15959
16105
  }
15960
16106
  } finally {
@@ -16534,14 +16680,14 @@ import {
16534
16680
  import { dirname as dirname22, join as join42 } from "path";
16535
16681
 
16536
16682
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
16537
- import chalk159 from "chalk";
16683
+ import chalk158 from "chalk";
16538
16684
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
16539
16685
  function validateStagedContent(filename, content) {
16540
16686
  const firstLine = content.split("\n")[0];
16541
16687
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
16542
16688
  if (!match) {
16543
16689
  console.error(
16544
- chalk159.red(
16690
+ chalk158.red(
16545
16691
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
16546
16692
  )
16547
16693
  );
@@ -16550,7 +16696,7 @@ function validateStagedContent(filename, content) {
16550
16696
  const contentAfterLink = content.slice(firstLine.length).trim();
16551
16697
  if (!contentAfterLink) {
16552
16698
  console.error(
16553
- chalk159.red(
16699
+ chalk158.red(
16554
16700
  `Staged file ${filename} has no summary content after the transcript link.`
16555
16701
  )
16556
16702
  );
@@ -16754,7 +16900,7 @@ import { mkdirSync as mkdirSync18 } from "fs";
16754
16900
  import { join as join47 } from "path";
16755
16901
 
16756
16902
  // src/commands/voice/checkLockFile.ts
16757
- import { execSync as execSync47 } from "child_process";
16903
+ import { execSync as execSync48 } from "child_process";
16758
16904
  import { existsSync as existsSync45, mkdirSync as mkdirSync17, readFileSync as readFileSync35, writeFileSync as writeFileSync29 } from "fs";
16759
16905
  import { join as join46 } from "path";
16760
16906
  function isProcessAlive2(pid) {
@@ -16783,7 +16929,7 @@ function bootstrapVenv() {
16783
16929
  if (existsSync45(getVenvPython())) return;
16784
16930
  console.log("Setting up Python environment...");
16785
16931
  const pythonDir = getPythonDir();
16786
- execSync47(
16932
+ execSync48(
16787
16933
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
16788
16934
  {
16789
16935
  stdio: "inherit",
@@ -16947,7 +17093,7 @@ function registerVoice(program2) {
16947
17093
 
16948
17094
  // src/commands/roam/auth.ts
16949
17095
  import { randomBytes } from "crypto";
16950
- import chalk160 from "chalk";
17096
+ import chalk159 from "chalk";
16951
17097
 
16952
17098
  // src/commands/roam/waitForCallback.ts
16953
17099
  import { createServer as createServer2 } from "http";
@@ -17078,13 +17224,13 @@ async function auth() {
17078
17224
  saveGlobalConfig(config);
17079
17225
  const state = randomBytes(16).toString("hex");
17080
17226
  console.log(
17081
- chalk160.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
17227
+ chalk159.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
17082
17228
  );
17083
- console.log(chalk160.white("http://localhost:14523/callback\n"));
17084
- console.log(chalk160.blue("Opening browser for authorization..."));
17085
- console.log(chalk160.dim("Waiting for authorization callback..."));
17229
+ console.log(chalk159.white("http://localhost:14523/callback\n"));
17230
+ console.log(chalk159.blue("Opening browser for authorization..."));
17231
+ console.log(chalk159.dim("Waiting for authorization callback..."));
17086
17232
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
17087
- console.log(chalk160.dim("Exchanging code for tokens..."));
17233
+ console.log(chalk159.dim("Exchanging code for tokens..."));
17088
17234
  const tokens = await exchangeToken({
17089
17235
  code,
17090
17236
  clientId,
@@ -17100,7 +17246,7 @@ async function auth() {
17100
17246
  };
17101
17247
  saveGlobalConfig(config);
17102
17248
  console.log(
17103
- chalk160.green("Roam credentials and tokens saved to ~/.assist.yml")
17249
+ chalk159.green("Roam credentials and tokens saved to ~/.assist.yml")
17104
17250
  );
17105
17251
  }
17106
17252
 
@@ -17260,11 +17406,11 @@ function resolveParams(params, cliArgs) {
17260
17406
  }
17261
17407
 
17262
17408
  // src/commands/run/runPreCommands.ts
17263
- import { execSync as execSync48 } from "child_process";
17409
+ import { execSync as execSync49 } from "child_process";
17264
17410
  function runPreCommands(pre, cwd) {
17265
17411
  for (const cmd of pre) {
17266
17412
  try {
17267
- execSync48(cmd, { stdio: "inherit", cwd });
17413
+ execSync49(cmd, { stdio: "inherit", cwd });
17268
17414
  } catch (err) {
17269
17415
  const code = err && typeof err === "object" && "status" in err ? err.status : 1;
17270
17416
  process.exit(code);
@@ -17548,11 +17694,11 @@ function registerRun(program2) {
17548
17694
  }
17549
17695
 
17550
17696
  // src/commands/screenshot/index.ts
17551
- import { execSync as execSync49 } from "child_process";
17697
+ import { execSync as execSync50 } from "child_process";
17552
17698
  import { existsSync as existsSync50, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
17553
17699
  import { tmpdir as tmpdir7 } from "os";
17554
17700
  import { join as join53, resolve as resolve13 } from "path";
17555
- import chalk161 from "chalk";
17701
+ import chalk160 from "chalk";
17556
17702
 
17557
17703
  // src/commands/screenshot/captureWindowPs1.ts
17558
17704
  var captureWindowPs1 = `
@@ -17691,7 +17837,7 @@ function runPowerShellScript(processName, outputPath) {
17691
17837
  const scriptPath = join53(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
17692
17838
  writeFileSync32(scriptPath, captureWindowPs1, "utf-8");
17693
17839
  try {
17694
- execSync49(
17840
+ execSync50(
17695
17841
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
17696
17842
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
17697
17843
  );
@@ -17703,13 +17849,13 @@ function screenshot(processName) {
17703
17849
  const config = loadConfig();
17704
17850
  const outputDir = resolve13(config.screenshot.outputDir);
17705
17851
  const outputPath = buildOutputPath(outputDir, processName);
17706
- console.log(chalk161.gray(`Capturing window for process "${processName}" ...`));
17852
+ console.log(chalk160.gray(`Capturing window for process "${processName}" ...`));
17707
17853
  try {
17708
17854
  runPowerShellScript(processName, outputPath);
17709
- console.log(chalk161.green(`Screenshot saved: ${outputPath}`));
17855
+ console.log(chalk160.green(`Screenshot saved: ${outputPath}`));
17710
17856
  } catch (error) {
17711
17857
  const msg = error instanceof Error ? error.message : String(error);
17712
- console.error(chalk161.red(`Failed to capture screenshot: ${msg}`));
17858
+ console.error(chalk160.red(`Failed to capture screenshot: ${msg}`));
17713
17859
  process.exit(1);
17714
17860
  }
17715
17861
  }
@@ -18609,8 +18755,8 @@ var SessionManager = class {
18609
18755
  watchActivity(session, this.notify);
18610
18756
  return session.id;
18611
18757
  }
18612
- spawnWith(create2) {
18613
- return this.add(create2(String(this.nextId++)));
18758
+ spawnWith(create) {
18759
+ return this.add(create(String(this.nextId++)));
18614
18760
  }
18615
18761
  spawn(prompt, cwd) {
18616
18762
  return this.spawnWith((id) => createSession(id, prompt, cwd));
@@ -18989,7 +19135,7 @@ function registerDaemon(program2) {
18989
19135
 
18990
19136
  // src/commands/sessions/summarise/index.ts
18991
19137
  import * as fs31 from "fs";
18992
- import chalk162 from "chalk";
19138
+ import chalk161 from "chalk";
18993
19139
 
18994
19140
  // src/commands/sessions/summarise/shared.ts
18995
19141
  import * as fs29 from "fs";
@@ -19116,22 +19262,22 @@ ${firstMessage}`);
19116
19262
  async function summarise4(options2) {
19117
19263
  const files = await discoverSessionJsonlPaths();
19118
19264
  if (files.length === 0) {
19119
- console.log(chalk162.yellow("No sessions found."));
19265
+ console.log(chalk161.yellow("No sessions found."));
19120
19266
  return;
19121
19267
  }
19122
19268
  const toProcess = selectCandidates(files, options2);
19123
19269
  if (toProcess.length === 0) {
19124
- console.log(chalk162.green("All sessions already summarised."));
19270
+ console.log(chalk161.green("All sessions already summarised."));
19125
19271
  return;
19126
19272
  }
19127
19273
  console.log(
19128
- chalk162.cyan(
19274
+ chalk161.cyan(
19129
19275
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
19130
19276
  )
19131
19277
  );
19132
19278
  const { succeeded, failed: failed2 } = processSessions(toProcess);
19133
19279
  console.log(
19134
- chalk162.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk162.yellow(`, ${failed2} skipped`) : "")
19280
+ chalk161.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk161.yellow(`, ${failed2} skipped`) : "")
19135
19281
  );
19136
19282
  }
19137
19283
  function selectCandidates(files, options2) {
@@ -19151,16 +19297,16 @@ function processSessions(files) {
19151
19297
  let failed2 = 0;
19152
19298
  for (let i = 0; i < files.length; i++) {
19153
19299
  const file = files[i];
19154
- process.stdout.write(chalk162.dim(` [${i + 1}/${files.length}] `));
19300
+ process.stdout.write(chalk161.dim(` [${i + 1}/${files.length}] `));
19155
19301
  const summary = summariseSession(file);
19156
19302
  if (summary) {
19157
19303
  writeSummary(file, summary);
19158
19304
  succeeded++;
19159
- process.stdout.write(`${chalk162.green("\u2713")} ${summary}
19305
+ process.stdout.write(`${chalk161.green("\u2713")} ${summary}
19160
19306
  `);
19161
19307
  } else {
19162
19308
  failed2++;
19163
- process.stdout.write(` ${chalk162.yellow("skip")}
19309
+ process.stdout.write(` ${chalk161.yellow("skip")}
19164
19310
  `);
19165
19311
  }
19166
19312
  }
@@ -19175,10 +19321,10 @@ function registerSessions(program2) {
19175
19321
  }
19176
19322
 
19177
19323
  // src/commands/statusLine.ts
19178
- import chalk164 from "chalk";
19324
+ import chalk163 from "chalk";
19179
19325
 
19180
19326
  // src/commands/buildLimitsSegment.ts
19181
- import chalk163 from "chalk";
19327
+ import chalk162 from "chalk";
19182
19328
  var FIVE_HOUR_SECONDS = 5 * 3600;
19183
19329
  var SEVEN_DAY_SECONDS = 7 * 86400;
19184
19330
  function formatTimeLeft(resetsAt) {
@@ -19201,10 +19347,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
19201
19347
  function colorizeRateLimit(pct, resetsAt, windowSeconds) {
19202
19348
  const label2 = `${Math.round(pct)}%`;
19203
19349
  const projected = projectUsage(pct, resetsAt, windowSeconds);
19204
- if (projected == null) return chalk163.green(label2);
19205
- if (projected > 100) return chalk163.red(label2);
19206
- if (projected > 75) return chalk163.yellow(label2);
19207
- return chalk163.green(label2);
19350
+ if (projected == null) return chalk162.green(label2);
19351
+ if (projected > 100) return chalk162.red(label2);
19352
+ if (projected > 75) return chalk162.yellow(label2);
19353
+ return chalk162.green(label2);
19208
19354
  }
19209
19355
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
19210
19356
  const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
@@ -19230,14 +19376,14 @@ function buildLimitsSegment(rateLimits) {
19230
19376
  }
19231
19377
 
19232
19378
  // src/commands/statusLine.ts
19233
- chalk164.level = 3;
19379
+ chalk163.level = 3;
19234
19380
  function formatNumber(num) {
19235
19381
  return num.toLocaleString("en-US");
19236
19382
  }
19237
19383
  function colorizePercent(pct) {
19238
19384
  const label2 = `${Math.round(pct)}%`;
19239
- if (pct > 80) return chalk164.red(label2);
19240
- if (pct > 40) return chalk164.yellow(label2);
19385
+ if (pct > 80) return chalk163.red(label2);
19386
+ if (pct > 40) return chalk163.yellow(label2);
19241
19387
  return label2;
19242
19388
  }
19243
19389
  async function statusLine() {
@@ -19260,7 +19406,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
19260
19406
  // src/commands/sync/syncClaudeMd.ts
19261
19407
  import * as fs32 from "fs";
19262
19408
  import * as path50 from "path";
19263
- import chalk165 from "chalk";
19409
+ import chalk164 from "chalk";
19264
19410
  async function syncClaudeMd(claudeDir, targetBase, options2) {
19265
19411
  const source = path50.join(claudeDir, "CLAUDE.md");
19266
19412
  const target = path50.join(targetBase, "CLAUDE.md");
@@ -19269,12 +19415,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
19269
19415
  const targetContent = fs32.readFileSync(target, "utf-8");
19270
19416
  if (sourceContent !== targetContent) {
19271
19417
  console.log(
19272
- chalk165.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
19418
+ chalk164.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
19273
19419
  );
19274
19420
  console.log();
19275
19421
  printDiff(targetContent, sourceContent);
19276
19422
  const confirm = options2?.yes || await promptConfirm(
19277
- chalk165.red("Overwrite existing CLAUDE.md?"),
19423
+ chalk164.red("Overwrite existing CLAUDE.md?"),
19278
19424
  false
19279
19425
  );
19280
19426
  if (!confirm) {
@@ -19290,7 +19436,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
19290
19436
  // src/commands/sync/syncSettings.ts
19291
19437
  import * as fs33 from "fs";
19292
19438
  import * as path51 from "path";
19293
- import chalk166 from "chalk";
19439
+ import chalk165 from "chalk";
19294
19440
  async function syncSettings(claudeDir, targetBase, options2) {
19295
19441
  const source = path51.join(claudeDir, "settings.json");
19296
19442
  const target = path51.join(targetBase, "settings.json");
@@ -19306,14 +19452,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
19306
19452
  if (mergedContent !== normalizedTarget) {
19307
19453
  if (!options2?.yes) {
19308
19454
  console.log(
19309
- chalk166.yellow(
19455
+ chalk165.yellow(
19310
19456
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
19311
19457
  )
19312
19458
  );
19313
19459
  console.log();
19314
19460
  printDiff(targetContent, mergedContent);
19315
19461
  const confirm = await promptConfirm(
19316
- chalk166.red("Overwrite existing settings.json?"),
19462
+ chalk165.red("Overwrite existing settings.json?"),
19317
19463
  false
19318
19464
  );
19319
19465
  if (!confirm) {
@@ -19352,7 +19498,7 @@ function syncCommands(claudeDir, targetBase) {
19352
19498
  }
19353
19499
 
19354
19500
  // src/commands/update.ts
19355
- import { execSync as execSync50 } from "child_process";
19501
+ import { execSync as execSync51 } from "child_process";
19356
19502
  import * as path53 from "path";
19357
19503
  function isGlobalNpmInstall(dir) {
19358
19504
  try {
@@ -19360,7 +19506,7 @@ function isGlobalNpmInstall(dir) {
19360
19506
  if (resolved.split(path53.sep).includes("node_modules")) {
19361
19507
  return true;
19362
19508
  }
19363
- const globalPrefix = execSync50("npm prefix -g", { stdio: "pipe" }).toString().trim();
19509
+ const globalPrefix = execSync51("npm prefix -g", { stdio: "pipe" }).toString().trim();
19364
19510
  return resolved.toLowerCase().startsWith(path53.resolve(globalPrefix).toLowerCase());
19365
19511
  } catch {
19366
19512
  return false;
@@ -19371,18 +19517,18 @@ async function update2() {
19371
19517
  console.log(`Assist is installed at: ${installDir}`);
19372
19518
  if (isGitRepo(installDir)) {
19373
19519
  console.log("Detected git repo installation, pulling latest...");
19374
- execSync50("git pull", { cwd: installDir, stdio: "inherit" });
19520
+ execSync51("git pull", { cwd: installDir, stdio: "inherit" });
19375
19521
  console.log("Installing dependencies...");
19376
- execSync50("npm i", { cwd: installDir, stdio: "inherit" });
19522
+ execSync51("npm i", { cwd: installDir, stdio: "inherit" });
19377
19523
  console.log("Building...");
19378
- execSync50("npm run build", { cwd: installDir, stdio: "inherit" });
19524
+ execSync51("npm run build", { cwd: installDir, stdio: "inherit" });
19379
19525
  console.log("Syncing commands...");
19380
- execSync50("assist sync", { stdio: "inherit" });
19526
+ execSync51("assist sync", { stdio: "inherit" });
19381
19527
  } else if (isGlobalNpmInstall(installDir)) {
19382
19528
  console.log("Detected global npm installation, updating...");
19383
- execSync50("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
19529
+ execSync51("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
19384
19530
  console.log("Syncing commands...");
19385
- execSync50("assist sync", { stdio: "inherit" });
19531
+ execSync51("assist sync", { stdio: "inherit" });
19386
19532
  } else {
19387
19533
  console.error(
19388
19534
  "Could not determine installation method. Expected a git repo or global npm install."