@staff0rd/assist 0.657.1 → 0.659.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.657.1",
9
+ version: "0.659.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -561,6 +561,23 @@ function stripLegacyConfigKeys(config) {
561
561
  // src/shared/types.ts
562
562
  import { z as z3 } from "zod";
563
563
 
564
+ // src/shared/adviceFragmentNames.ts
565
+ var adviceFragmentNames = [
566
+ "assist-global",
567
+ "backlog-ids",
568
+ "backlog-prs",
569
+ "code-comments",
570
+ "drafting-messages",
571
+ "editing-files",
572
+ "filename-convention",
573
+ "jira-context",
574
+ "jira-smart-links",
575
+ "markdown",
576
+ "refactor",
577
+ "settings-json",
578
+ "verify"
579
+ ];
580
+
564
581
  // src/shared/runConfigSchema.ts
565
582
  import { z } from "zod";
566
583
  var runParamSchema = z.strictObject({
@@ -619,8 +636,8 @@ var DEFAULT_BACKUP_DIR = "~/.assist/backups";
619
636
  var DEFAULT_CLONE_DIR = "~/git";
620
637
  var assistConfigShape = {
621
638
  advice: z3.strictObject({
622
- include: z3.array(z3.string()).default([]),
623
- exclude: z3.array(z3.string()).default([]),
639
+ include: z3.array(z3.enum(adviceFragmentNames)).default([]),
640
+ exclude: z3.array(z3.enum(adviceFragmentNames)).default([]),
624
641
  extra: z3.string().optional(),
625
642
  verify: z3.string().optional()
626
643
  }).optional(),
@@ -2013,7 +2030,96 @@ function lint(options2 = {}) {
2013
2030
 
2014
2031
  // src/commands/new/registerNew/newCli/index.ts
2015
2032
  import { execSync as execSync12 } from "child_process";
2016
- import { basename as basename3, resolve as resolve6 } from "path";
2033
+ import { basename as basename4, resolve as resolve6 } from "path";
2034
+
2035
+ // src/commands/advise/loadAdviceFragments.ts
2036
+ import { readdirSync, readFileSync as readFileSync10 } from "fs";
2037
+ import { basename as basename2, join as join10 } from "path";
2038
+
2039
+ // src/commands/advise/adviceDir.ts
2040
+ import { existsSync as existsSync13 } from "fs";
2041
+ import { dirname as dirname10, join as join9 } from "path";
2042
+ import { fileURLToPath } from "url";
2043
+ function adviceDir() {
2044
+ let current = dirname10(fileURLToPath(import.meta.url));
2045
+ while (current !== dirname10(current)) {
2046
+ const candidate = join9(current, "claude", "advice");
2047
+ if (existsSync13(candidate)) return candidate;
2048
+ current = dirname10(current);
2049
+ }
2050
+ throw new Error("Could not locate the shipped claude/advice directory");
2051
+ }
2052
+
2053
+ // src/commands/advise/parseAdviceFragment.ts
2054
+ import { parse as parseYaml2 } from "yaml";
2055
+ var frontmatter = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
2056
+ function parseAdviceFragment(name, content) {
2057
+ const match = frontmatter.exec(content);
2058
+ if (!match) throw new Error(`Advice fragment ${name} has no frontmatter`);
2059
+ const meta = parseYaml2(match[1]) ?? {};
2060
+ const title = meta.title;
2061
+ const when = meta.when;
2062
+ if (typeof title !== "string" || typeof when !== "string")
2063
+ throw new Error(
2064
+ `Advice fragment ${name} needs a title and a when condition`
2065
+ );
2066
+ return {
2067
+ name,
2068
+ title,
2069
+ when,
2070
+ body: content.slice(match[0].length).trim()
2071
+ };
2072
+ }
2073
+
2074
+ // src/commands/advise/loadAdviceFragments.ts
2075
+ function loadAdviceFragments(dir = adviceDir()) {
2076
+ return readdirSync(dir).filter((file) => file.endsWith(".md")).sort().map(
2077
+ (file) => parseAdviceFragment(
2078
+ basename2(file, ".md"),
2079
+ readFileSync10(join10(dir, file), "utf8")
2080
+ )
2081
+ );
2082
+ }
2083
+
2084
+ // src/commands/verify/reportVerifyProblems.ts
2085
+ function verifySection(label2, entries) {
2086
+ if (entries.length === 0) return void 0;
2087
+ const list5 = entries.sort().map((entry) => ` ${entry}`).join("\n");
2088
+ return `${label2}:
2089
+ ${list5}`;
2090
+ }
2091
+ function reportVerifyProblems(problems, success) {
2092
+ const found = problems.filter(
2093
+ (problem) => problem !== void 0
2094
+ );
2095
+ if (found.length > 0) {
2096
+ console.log(found.join("\n\n"));
2097
+ process.exit(1);
2098
+ }
2099
+ console.log(success);
2100
+ process.exit(0);
2101
+ }
2102
+
2103
+ // src/commands/verify/adviceFragments.ts
2104
+ function adviceFragments() {
2105
+ const shipped = new Set(
2106
+ loadAdviceFragments().map((fragment) => fragment.name)
2107
+ );
2108
+ const declared = new Set(adviceFragmentNames);
2109
+ reportVerifyProblems(
2110
+ [
2111
+ verifySection(
2112
+ "Shipped in claude/advice but missing from adviceFragmentNames (add them, or advice.include/exclude cannot name them)",
2113
+ [...shipped].filter((name) => !declared.has(name))
2114
+ ),
2115
+ verifySection(
2116
+ "Listed in adviceFragmentNames but no longer shipped in claude/advice (remove them)",
2117
+ [...declared].filter((name) => !shipped.has(name))
2118
+ )
2119
+ ],
2120
+ `All ${shipped.size} advice fragments are named in adviceFragmentNames.`
2121
+ );
2122
+ }
2017
2123
 
2018
2124
  // src/commands/verify/blockCodeComments/findComments.ts
2019
2125
  import { execSync as execSync4 } from "child_process";
@@ -2960,12 +3066,12 @@ var adviceConfigHelp = [
2960
3066
  {
2961
3067
  key: "advice.include",
2962
3068
  setter: 'assist config set advice.include "refactor"',
2963
- note: "fragment names included whatever their condition says"
3069
+ note: "fragment names included whatever their condition says; 'assist advise --explain' lists every name"
2964
3070
  },
2965
3071
  {
2966
3072
  key: "advice.exclude",
2967
3073
  setter: 'assist config set advice.exclude "jira-context"',
2968
- note: "fragment names dropped even when their condition matches"
3074
+ note: "fragment names dropped even when their condition matches; 'assist advise --explain' lists every name"
2969
3075
  },
2970
3076
  {
2971
3077
  key: "advice.extra",
@@ -3573,57 +3679,46 @@ var pendingConfigDocumentation = /* @__PURE__ */ new Set([
3573
3679
  ]);
3574
3680
 
3575
3681
  // src/commands/verify/configKeys.ts
3576
- function section(label2, keys) {
3577
- if (keys.length === 0) return void 0;
3578
- const list5 = keys.sort().map((key) => ` ${key}`).join("\n");
3579
- return `${label2}:
3580
- ${list5}`;
3581
- }
3582
3682
  function configKeys() {
3583
3683
  const schemaKeys = new Set(enumerateConfigLeafKeys(assistConfigSchema));
3584
3684
  const documented = getDocumentedConfigKeys();
3585
3685
  const pending = pendingConfigDocumentation;
3586
3686
  const aggregated = new Set(configHelpEntries.map((entry) => entry.key));
3587
- const problems = [
3588
- section(
3589
- "Config keys documented by no command (surface them with configHelp)",
3590
- [...schemaKeys].filter(
3591
- (key) => !documented.has(key) && !pending.has(key)
3687
+ reportVerifyProblems(
3688
+ [
3689
+ verifySection(
3690
+ "Config keys documented by no command (surface them with configHelp)",
3691
+ [...schemaKeys].filter(
3692
+ (key) => !documented.has(key) && !pending.has(key)
3693
+ )
3694
+ ),
3695
+ verifySection(
3696
+ "Documented config keys not present in assistConfigSchema",
3697
+ [...documented].filter((key) => !schemaKeys.has(key))
3698
+ ),
3699
+ verifySection(
3700
+ "Keys now documented but still in pendingConfigDocumentation (remove them)",
3701
+ [...pending].filter((key) => documented.has(key))
3702
+ ),
3703
+ verifySection(
3704
+ "pendingConfigDocumentation lists keys not in assistConfigSchema (remove them)",
3705
+ [...pending].filter((key) => !schemaKeys.has(key))
3706
+ ),
3707
+ verifySection(
3708
+ "Keys documented by a command but missing from configHelpEntries (add their module to src/commands/configHelpEntries.ts)",
3709
+ [...documented].filter((key) => !aggregated.has(key))
3710
+ ),
3711
+ verifySection(
3712
+ "configHelpEntries lists keys no command documents (remove them)",
3713
+ [...aggregated].filter((key) => !documented.has(key))
3592
3714
  )
3593
- ),
3594
- section(
3595
- "Documented config keys not present in assistConfigSchema",
3596
- [...documented].filter((key) => !schemaKeys.has(key))
3597
- ),
3598
- section(
3599
- "Keys now documented but still in pendingConfigDocumentation (remove them)",
3600
- [...pending].filter((key) => documented.has(key))
3601
- ),
3602
- section(
3603
- "pendingConfigDocumentation lists keys not in assistConfigSchema (remove them)",
3604
- [...pending].filter((key) => !schemaKeys.has(key))
3605
- ),
3606
- section(
3607
- "Keys documented by a command but missing from configHelpEntries (add their module to src/commands/configHelpEntries.ts)",
3608
- [...documented].filter((key) => !aggregated.has(key))
3609
- ),
3610
- section(
3611
- "configHelpEntries lists keys no command documents (remove them)",
3612
- [...aggregated].filter((key) => !documented.has(key))
3613
- )
3614
- ].filter((problem) => problem !== void 0);
3615
- if (problems.length > 0) {
3616
- console.log(problems.join("\n\n"));
3617
- process.exit(1);
3618
- }
3619
- console.log(
3715
+ ],
3620
3716
  `All ${schemaKeys.size} config keys are surfaced in --help or pending documentation.`
3621
3717
  );
3622
- process.exit(0);
3623
3718
  }
3624
3719
 
3625
3720
  // src/commands/verify/forbiddenStrings/index.ts
3626
- import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
3721
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
3627
3722
 
3628
3723
  // src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
3629
3724
  import { minimatch as minimatch2 } from "minimatch";
@@ -3664,13 +3759,13 @@ function forbiddenStrings() {
3664
3759
  const cache5 = /* @__PURE__ */ new Map();
3665
3760
  const readJson = (file) => {
3666
3761
  if (cache5.has(file)) return cache5.get(file);
3667
- if (!existsSync13(file)) {
3762
+ if (!existsSync14(file)) {
3668
3763
  console.log(`Forbidden-strings file not found: ${file}`);
3669
3764
  process.exit(1);
3670
3765
  }
3671
3766
  let parsed;
3672
3767
  try {
3673
- parsed = JSON.parse(readFileSync10(file, "utf8"));
3768
+ parsed = JSON.parse(readFileSync11(file, "utf8"));
3674
3769
  } catch (error) {
3675
3770
  console.log(`Could not parse ${file}: ${error.message}`);
3676
3771
  process.exit(1);
@@ -3743,7 +3838,7 @@ Total: ${lines2.length} hardcoded color(s)`);
3743
3838
  import * as path20 from "path";
3744
3839
 
3745
3840
  // src/shared/resolveRunConfigs.ts
3746
- import { dirname as dirname10, relative, resolve as resolve4 } from "path";
3841
+ import { dirname as dirname11, relative, resolve as resolve4 } from "path";
3747
3842
 
3748
3843
  // src/shared/assertNoDuplicateRunNames.ts
3749
3844
  function findDuplicateNames(configs) {
@@ -3765,14 +3860,14 @@ function assertNoDuplicateRunNames(configs) {
3765
3860
  }
3766
3861
 
3767
3862
  // src/shared/findLinkedConfigPath.ts
3768
- import { existsSync as existsSync14 } from "fs";
3769
- import { join as join9, resolve as resolve2 } from "path";
3863
+ import { existsSync as existsSync15 } from "fs";
3864
+ import { join as join11, resolve as resolve2 } from "path";
3770
3865
  function findLinkedConfigPath(linkPath, fromDir) {
3771
3866
  const resolved = resolve2(fromDir, linkPath);
3772
- const claudePath = join9(resolved, ".claude", "assist.yml");
3773
- if (existsSync14(claudePath)) return claudePath;
3774
- const rootPath = join9(resolved, "assist.yml");
3775
- if (existsSync14(rootPath)) return rootPath;
3867
+ const claudePath = join11(resolved, ".claude", "assist.yml");
3868
+ if (existsSync15(claudePath)) return claudePath;
3869
+ const rootPath = join11(resolved, "assist.yml");
3870
+ if (existsSync15(rootPath)) return rootPath;
3776
3871
  throw new Error(`No assist.yml found in linked project: ${resolved}`);
3777
3872
  }
3778
3873
 
@@ -3814,7 +3909,7 @@ function loadAndResolveLink(linkPath, configDir, ctx) {
3814
3909
  const entries = loadLinkedEntries(configPath, ctx.visited);
3815
3910
  const defaultCwd = relativeToRoot(ctx, resolve4(configDir, linkPath));
3816
3911
  return setDefaultCwd(
3817
- resolveRecursive(entries, dirname10(configPath), ctx),
3912
+ resolveRecursive(entries, dirname11(configPath), ctx),
3818
3913
  defaultCwd
3819
3914
  );
3820
3915
  }
@@ -3841,12 +3936,12 @@ function resolveLocalCwd(config, configDir, ctx) {
3841
3936
  }
3842
3937
 
3843
3938
  // src/shared/findRepoRoot.ts
3844
- import { existsSync as existsSync15 } from "fs";
3939
+ import { existsSync as existsSync16 } from "fs";
3845
3940
  import path19 from "path";
3846
3941
  function findRepoRoot(dir) {
3847
3942
  let current = dir;
3848
3943
  while (current !== path19.dirname(current)) {
3849
- if (existsSync15(path19.join(current, ".git"))) {
3944
+ if (existsSync16(path19.join(current, ".git"))) {
3850
3945
  return current;
3851
3946
  }
3852
3947
  current = path19.dirname(current);
@@ -3917,9 +4012,9 @@ function list() {
3917
4012
  }
3918
4013
 
3919
4014
  // src/commands/verify/migrations/index.ts
3920
- import { readFileSync as readFileSync11 } from "fs";
4015
+ import { readFileSync as readFileSync12 } from "fs";
3921
4016
  import path21 from "path";
3922
- import { fileURLToPath } from "url";
4017
+ import { fileURLToPath as fileURLToPath2 } from "url";
3923
4018
 
3924
4019
  // src/shared/db/migrations/migration0001Baseline.ts
3925
4020
  var sql = `
@@ -4267,15 +4362,15 @@ function checkSequential(migrations3, files) {
4267
4362
  }
4268
4363
 
4269
4364
  // src/commands/verify/migrations/listMigrationFiles.ts
4270
- import { readdirSync } from "fs";
4365
+ import { readdirSync as readdirSync2 } from "fs";
4271
4366
  var MIGRATION_FILE2 = /^migration\d+[A-Za-z0-9]*\.ts$/;
4272
4367
  function listMigrationFiles(dir) {
4273
- return readdirSync(dir).filter((file) => MIGRATION_FILE2.test(file));
4368
+ return readdirSync2(dir).filter((file) => MIGRATION_FILE2.test(file));
4274
4369
  }
4275
4370
 
4276
4371
  // src/commands/verify/migrations/readBaselineMigrations.ts
4277
4372
  import { execSync as execSync6 } from "child_process";
4278
- import { basename as basename2 } from "path";
4373
+ import { basename as basename3 } from "path";
4279
4374
  var MIGRATION_FILE3 = /^migration\d+[A-Za-z0-9]*\.ts$/;
4280
4375
  function readBaselineMigrations(repoRelativeDir, ref) {
4281
4376
  const baseline = /* @__PURE__ */ new Map();
@@ -4288,7 +4383,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
4288
4383
  } catch {
4289
4384
  return baseline;
4290
4385
  }
4291
- const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path91) => MIGRATION_FILE3.test(basename2(path91)));
4386
+ const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path91) => MIGRATION_FILE3.test(basename3(path91)));
4292
4387
  for (const path91 of paths) {
4293
4388
  try {
4294
4389
  const content = execSync6(`git show "${ref}:${path91}"`, {
@@ -4296,7 +4391,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
4296
4391
  maxBuffer: 16 * 1024 * 1024,
4297
4392
  stdio: ["pipe", "pipe", "pipe"]
4298
4393
  });
4299
- baseline.set(basename2(path91), content);
4394
+ baseline.set(basename3(path91), content);
4300
4395
  } catch {
4301
4396
  }
4302
4397
  }
@@ -4338,7 +4433,7 @@ function resolveBaselineRef() {
4338
4433
  var REPO_RELATIVE_DIR = "src/shared/db/migrations";
4339
4434
  function migrationsDir() {
4340
4435
  return path21.resolve(
4341
- path21.dirname(fileURLToPath(import.meta.url)),
4436
+ path21.dirname(fileURLToPath2(import.meta.url)),
4342
4437
  "../../../shared/db/migrations"
4343
4438
  );
4344
4439
  }
@@ -4356,7 +4451,7 @@ function migrations2() {
4356
4451
  if (ref) {
4357
4452
  const baseline = readBaselineMigrations(REPO_RELATIVE_DIR, ref);
4358
4453
  const current = new Map(
4359
- files.map((file) => [file, readFileSync11(path21.join(dir, file), "utf8")])
4454
+ files.map((file) => [file, readFileSync12(path21.join(dir, file), "utf8")])
4360
4455
  );
4361
4456
  for (const finding of checkAppendOnly(baseline, current)) {
4362
4457
  problems.push(
@@ -4415,15 +4510,15 @@ import * as net from "net";
4415
4510
 
4416
4511
  // src/commands/sessions/daemon/daemonPaths.ts
4417
4512
  import { homedir as homedir2 } from "os";
4418
- import { join as join10 } from "path";
4419
- var DAEMON_DIR = join10(homedir2(), ".assist", "daemon");
4513
+ import { join as join12 } from "path";
4514
+ var DAEMON_DIR = join12(homedir2(), ".assist", "daemon");
4420
4515
  var daemonPaths = {
4421
4516
  dir: DAEMON_DIR,
4422
- socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` : join10(DAEMON_DIR, "daemon.sock"),
4423
- log: join10(DAEMON_DIR, "daemon.log"),
4424
- pid: join10(DAEMON_DIR, "daemon.pid"),
4425
- spawnLock: join10(DAEMON_DIR, "spawn.lock"),
4426
- hooksSettings: join10(DAEMON_DIR, "hooks-settings.json")
4517
+ socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` : join12(DAEMON_DIR, "daemon.sock"),
4518
+ log: join12(DAEMON_DIR, "daemon.log"),
4519
+ pid: join12(DAEMON_DIR, "daemon.pid"),
4520
+ spawnLock: join12(DAEMON_DIR, "spawn.lock"),
4521
+ hooksSettings: join12(DAEMON_DIR, "hooks-settings.json")
4427
4522
  };
4428
4523
 
4429
4524
  // src/commands/sessions/daemon/connectToDaemon.ts
@@ -4731,7 +4826,7 @@ program.parse();
4731
4826
 
4732
4827
  // src/commands/new/registerNew/newCli/index.ts
4733
4828
  async function newCli() {
4734
- const name = basename3(resolve6("."));
4829
+ const name = basename4(resolve6("."));
4735
4830
  initGit();
4736
4831
  initPackageJson(name);
4737
4832
  console.log("Installing dependencies...");
@@ -4746,7 +4841,7 @@ async function newCli() {
4746
4841
 
4747
4842
  // src/commands/new/registerNew/newProject.ts
4748
4843
  import { execSync as execSync14 } from "child_process";
4749
- import { existsSync as existsSync17, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
4844
+ import { existsSync as existsSync18, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
4750
4845
 
4751
4846
  // src/commands/deploy/init/index.ts
4752
4847
  import { execSync as execSync13 } from "child_process";
@@ -4754,33 +4849,33 @@ import chalk27 from "chalk";
4754
4849
  import enquirer3 from "enquirer";
4755
4850
 
4756
4851
  // src/commands/deploy/init/updateWorkflow.ts
4757
- import { existsSync as existsSync16, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
4758
- import { dirname as dirname12, join as join11 } from "path";
4759
- import { fileURLToPath as fileURLToPath2 } from "url";
4852
+ import { existsSync as existsSync17, mkdirSync as mkdirSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
4853
+ import { dirname as dirname13, join as join13 } from "path";
4854
+ import { fileURLToPath as fileURLToPath3 } from "url";
4760
4855
  import chalk26 from "chalk";
4761
4856
  var WORKFLOW_PATH = ".github/workflows/build.yml";
4762
- var __dirname2 = dirname12(fileURLToPath2(import.meta.url));
4857
+ var __dirname2 = dirname13(fileURLToPath3(import.meta.url));
4763
4858
  function getExistingSiteId() {
4764
- if (!existsSync16(WORKFLOW_PATH)) {
4859
+ if (!existsSync17(WORKFLOW_PATH)) {
4765
4860
  return null;
4766
4861
  }
4767
- const content = readFileSync12(WORKFLOW_PATH, "utf8");
4862
+ const content = readFileSync13(WORKFLOW_PATH, "utf8");
4768
4863
  const match = content.match(/-s\s+([a-f0-9-]{36})/);
4769
4864
  return match ? match[1] : null;
4770
4865
  }
4771
4866
  function getTemplateContent(siteId) {
4772
- const templatePath = join11(__dirname2, "commands/deploy/build.yml");
4773
- const template = readFileSync12(templatePath, "utf8");
4867
+ const templatePath = join13(__dirname2, "commands/deploy/build.yml");
4868
+ const template = readFileSync13(templatePath, "utf8");
4774
4869
  return template.replace("{{NETLIFY_SITE_ID}}", siteId);
4775
4870
  }
4776
4871
  async function updateWorkflow(siteId) {
4777
4872
  const newContent = getTemplateContent(siteId);
4778
4873
  const workflowDir = ".github/workflows";
4779
- if (!existsSync16(workflowDir)) {
4874
+ if (!existsSync17(workflowDir)) {
4780
4875
  mkdirSync3(workflowDir, { recursive: true });
4781
4876
  }
4782
- if (existsSync16(WORKFLOW_PATH)) {
4783
- const oldContent = readFileSync12(WORKFLOW_PATH, "utf8");
4877
+ if (existsSync17(WORKFLOW_PATH)) {
4878
+ const oldContent = readFileSync13(WORKFLOW_PATH, "utf8");
4784
4879
  if (oldContent === newContent) {
4785
4880
  console.log(chalk26.green("build.yml is already up to date"));
4786
4881
  return;
@@ -4874,11 +4969,11 @@ async function newProject() {
4874
4969
  }
4875
4970
  function addViteBaseConfig() {
4876
4971
  const viteConfigPath = "vite.config.ts";
4877
- if (!existsSync17(viteConfigPath)) {
4972
+ if (!existsSync18(viteConfigPath)) {
4878
4973
  console.log("No vite.config.ts found, skipping base config");
4879
4974
  return;
4880
4975
  }
4881
- const content = readFileSync13(viteConfigPath, "utf8");
4976
+ const content = readFileSync14(viteConfigPath, "utf8");
4882
4977
  if (content.includes("base:")) {
4883
4978
  console.log("vite.config.ts already has base config");
4884
4979
  return;
@@ -5019,28 +5114,45 @@ async function notify() {
5019
5114
  console.log(`Notification sent: ${notification_type} for ${projectName}`);
5020
5115
  }
5021
5116
 
5022
- // src/commands/activity/activityChart.ts
5117
+ // src/lib/renderLineChart.ts
5118
+ import * as fs16 from "fs";
5119
+ import * as tty from "tty";
5023
5120
  import blessed from "blessed";
5024
5121
  import contrib from "blessed-contrib";
5025
- function activityChart(data, range) {
5122
+ var keyboardInput = () => {
5123
+ if (process.stdin.isTTY) return void 0;
5124
+ try {
5125
+ return new tty.ReadStream(fs16.openSync("/dev/tty", "r"));
5126
+ } catch {
5127
+ return void 0;
5128
+ }
5129
+ };
5130
+ function renderLineChart({
5131
+ title,
5132
+ label: label2,
5133
+ seriesTitle,
5134
+ labels,
5135
+ values,
5136
+ wholeNumbersOnly = false
5137
+ }) {
5138
+ const input = keyboardInput();
5026
5139
  const screen = blessed.screen({
5027
5140
  smartCSR: true,
5028
- title: "Commit Activity"
5141
+ title,
5142
+ input
5029
5143
  });
5030
5144
  const grid = new contrib.grid({ rows: 1, cols: 1, screen });
5031
- const labels = data.map((d) => d.date.slice(5));
5032
- const values = data.map((d) => d.count);
5033
5145
  const line = grid.set(0, 0, 1, 1, contrib.line, {
5034
- label: ` Commits per week \xB7 ${range.since} \u2192 ${range.until} (press q to close) `,
5146
+ label: ` ${label2} (press q to close) `,
5035
5147
  showLegend: true,
5036
- legend: { width: 12 },
5148
+ legend: { width: Math.max(12, seriesTitle.length + 2) },
5037
5149
  xLabelPadding: 3,
5038
5150
  xPadding: 5,
5039
- wholeNumbersOnly: true
5151
+ wholeNumbersOnly
5040
5152
  });
5041
5153
  line.setData([
5042
5154
  {
5043
- title: "Commits",
5155
+ title: seriesTitle,
5044
5156
  x: labels,
5045
5157
  y: values,
5046
5158
  style: { line: "green" }
@@ -5048,6 +5160,7 @@ function activityChart(data, range) {
5048
5160
  ]);
5049
5161
  screen.key(["q", "C-c", "escape"], () => {
5050
5162
  screen.destroy();
5163
+ input?.destroy();
5051
5164
  });
5052
5165
  screen.render();
5053
5166
  }
@@ -5107,7 +5220,14 @@ async function activity(options2) {
5107
5220
  }
5108
5221
  const weeklyData = [...weekly.entries()].map(([date, count8]) => ({ date, count: count8 })).sort((a, b) => a.date.localeCompare(b.date));
5109
5222
  const until = data[data.length - 1].date;
5110
- activityChart(weeklyData, { since, until });
5223
+ renderLineChart({
5224
+ title: "Commit Activity",
5225
+ label: `Commits per week \xB7 ${since} \u2192 ${until}`,
5226
+ seriesTitle: "Commits",
5227
+ labels: weeklyData.map((d) => d.date.slice(5)),
5228
+ values: weeklyData.map((d) => d.count),
5229
+ wholeNumbersOnly: true
5230
+ });
5111
5231
  }
5112
5232
 
5113
5233
  // src/commands/registerActivity.ts
@@ -5126,55 +5246,6 @@ function adviceContextFor(cwd) {
5126
5246
  };
5127
5247
  }
5128
5248
 
5129
- // src/commands/advise/loadAdviceFragments.ts
5130
- import { readdirSync as readdirSync2, readFileSync as readFileSync14 } from "fs";
5131
- import { basename as basename4, join as join13 } from "path";
5132
-
5133
- // src/commands/advise/adviceDir.ts
5134
- import { existsSync as existsSync18 } from "fs";
5135
- import { dirname as dirname13, join as join12 } from "path";
5136
- import { fileURLToPath as fileURLToPath3 } from "url";
5137
- function adviceDir() {
5138
- let current = dirname13(fileURLToPath3(import.meta.url));
5139
- while (current !== dirname13(current)) {
5140
- const candidate = join12(current, "claude", "advice");
5141
- if (existsSync18(candidate)) return candidate;
5142
- current = dirname13(current);
5143
- }
5144
- throw new Error("Could not locate the shipped claude/advice directory");
5145
- }
5146
-
5147
- // src/commands/advise/parseAdviceFragment.ts
5148
- import { parse as parseYaml2 } from "yaml";
5149
- var frontmatter = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
5150
- function parseAdviceFragment(name, content) {
5151
- const match = frontmatter.exec(content);
5152
- if (!match) throw new Error(`Advice fragment ${name} has no frontmatter`);
5153
- const meta = parseYaml2(match[1]) ?? {};
5154
- const title = meta.title;
5155
- const when = meta.when;
5156
- if (typeof title !== "string" || typeof when !== "string")
5157
- throw new Error(
5158
- `Advice fragment ${name} needs a title and a when condition`
5159
- );
5160
- return {
5161
- name,
5162
- title,
5163
- when,
5164
- body: content.slice(match[0].length).trim()
5165
- };
5166
- }
5167
-
5168
- // src/commands/advise/loadAdviceFragments.ts
5169
- function loadAdviceFragments(dir = adviceDir()) {
5170
- return readdirSync2(dir).filter((file) => file.endsWith(".md")).sort().map(
5171
- (file) => parseAdviceFragment(
5172
- basename4(file, ".md"),
5173
- readFileSync14(join13(dir, file), "utf8")
5174
- )
5175
- );
5176
- }
5177
-
5178
5249
  // src/commands/advise/verifyRunCommandNames.ts
5179
5250
  function verifyRunCommandNames({
5180
5251
  config,
@@ -5243,9 +5314,11 @@ var adviceConditions = {
5243
5314
  // src/commands/advise/selectAdvice.ts
5244
5315
  function decide(fragment, context) {
5245
5316
  const advice = context.config.advice;
5246
- if (advice?.exclude.includes(fragment.name))
5317
+ const exclude = advice?.exclude ?? [];
5318
+ const include = advice?.include ?? [];
5319
+ if (exclude.includes(fragment.name))
5247
5320
  return { fragment, included: false, reason: "excluded by advice.exclude" };
5248
- if (advice?.include.includes(fragment.name))
5321
+ if (include.includes(fragment.name))
5249
5322
  return { fragment, included: true, reason: "included by advice.include" };
5250
5323
  const condition = adviceConditions[fragment.when];
5251
5324
  if (!condition)
@@ -6337,6 +6410,72 @@ function registerBackup(program2) {
6337
6410
  configHelp(backupCommand, backupConfigHelp);
6338
6411
  }
6339
6412
 
6413
+ // src/commands/chart/parseChartSeries.ts
6414
+ function parseChartSeries(lines2) {
6415
+ const points = [];
6416
+ for (const line of lines2) {
6417
+ const trimmed = line.trim();
6418
+ if (trimmed === "") continue;
6419
+ const parts = trimmed.split(/[,\t ]+/).filter((part) => part !== "");
6420
+ if (parts.length < 2) {
6421
+ throw new Error(`Expected a label and a value, got: ${trimmed}`);
6422
+ }
6423
+ const label2 = parts.slice(0, -1).join(" ");
6424
+ const raw = parts[parts.length - 1];
6425
+ const value = Number(raw);
6426
+ if (!Number.isFinite(value)) {
6427
+ throw new Error(`Value "${raw}" is not numeric, on line: ${trimmed}`);
6428
+ }
6429
+ points.push({ label: label2, value });
6430
+ }
6431
+ return points;
6432
+ }
6433
+
6434
+ // src/commands/chart/readStdinLines.ts
6435
+ import * as readline2 from "readline";
6436
+ async function readStdinLines() {
6437
+ const rl = readline2.createInterface({
6438
+ input: process.stdin,
6439
+ terminal: false
6440
+ });
6441
+ const lines2 = [];
6442
+ for await (const line of rl) {
6443
+ lines2.push(line);
6444
+ }
6445
+ return lines2;
6446
+ }
6447
+
6448
+ // src/commands/chart.ts
6449
+ async function chart(options2) {
6450
+ const lines2 = await readStdinLines();
6451
+ let points;
6452
+ try {
6453
+ points = parseChartSeries(lines2);
6454
+ } catch (error) {
6455
+ console.error(error instanceof Error ? error.message : String(error));
6456
+ process.exit(1);
6457
+ }
6458
+ if (points.length < 2) {
6459
+ console.log("Not enough data points to chart.");
6460
+ return;
6461
+ }
6462
+ const title = options2.title ?? "Chart";
6463
+ renderLineChart({
6464
+ title,
6465
+ label: title,
6466
+ seriesTitle: title,
6467
+ labels: points.map((p) => p.label),
6468
+ values: points.map((p) => p.value)
6469
+ });
6470
+ }
6471
+
6472
+ // src/commands/registerChart.ts
6473
+ function registerChart(program2) {
6474
+ program2.command("chart").description(
6475
+ "Chart a label/value series read from stdin, one pair per line (comma, tab or whitespace separated)"
6476
+ ).option("--title <title>", "Chart title").action(chart);
6477
+ }
6478
+
6340
6479
  // src/commands/backlog/next.ts
6341
6480
  import chalk47 from "chalk";
6342
6481
  import enquirer5 from "enquirer";
@@ -8631,12 +8770,12 @@ import chalk44 from "chalk";
8631
8770
  import * as path29 from "path";
8632
8771
 
8633
8772
  // src/commands/sessions/shared/discoverSessions.ts
8634
- import * as fs20 from "fs";
8773
+ import * as fs21 from "fs";
8635
8774
  import * as os3 from "os";
8636
8775
  import * as path28 from "path";
8637
8776
 
8638
8777
  // src/commands/sessions/shared/codex/discoverCodexRolloutPaths.ts
8639
- import * as fs16 from "fs";
8778
+ import * as fs17 from "fs";
8640
8779
  import * as path25 from "path";
8641
8780
 
8642
8781
  // src/commands/sessions/shared/codex/codexSessionsDir.ts
@@ -8661,7 +8800,7 @@ async function discoverCodexRolloutPaths() {
8661
8800
  async function collect(dir, depth) {
8662
8801
  let entries;
8663
8802
  try {
8664
- entries = await fs16.promises.readdir(dir, { withFileTypes: true });
8803
+ entries = await fs17.promises.readdir(dir, { withFileTypes: true });
8665
8804
  } catch {
8666
8805
  return [];
8667
8806
  }
@@ -8677,7 +8816,7 @@ async function collectEntry(dir, entry, depth) {
8677
8816
  }
8678
8817
 
8679
8818
  // src/commands/sessions/shared/codex/parseCodexSessionFile.ts
8680
- import * as fs18 from "fs";
8819
+ import * as fs19 from "fs";
8681
8820
  import * as path26 from "path";
8682
8821
 
8683
8822
  // src/commands/sessions/shared/backlogRunMarkers.ts
@@ -8769,12 +8908,12 @@ function firstUserMessage(entry) {
8769
8908
  }
8770
8909
 
8771
8910
  // src/commands/sessions/shared/codex/readCodexHeadLines.ts
8772
- import * as fs17 from "fs";
8773
- import * as readline2 from "readline";
8911
+ import * as fs18 from "fs";
8912
+ import * as readline3 from "readline";
8774
8913
  var DEFAULT_MAX_LINES = 80;
8775
8914
  async function readCodexHeadLines(filePath, maxLines = DEFAULT_MAX_LINES) {
8776
- const stream = fs17.createReadStream(filePath, { encoding: "utf8" });
8777
- const reader = readline2.createInterface({ input: stream });
8915
+ const stream = fs18.createReadStream(filePath, { encoding: "utf8" });
8916
+ const reader = readline3.createInterface({ input: stream });
8778
8917
  const lines2 = [];
8779
8918
  try {
8780
8919
  for await (const line of reader) {
@@ -8812,7 +8951,7 @@ async function parseCodexSessionFile(filePath) {
8812
8951
  }
8813
8952
  }
8814
8953
  async function mtime(filePath) {
8815
- return (await fs18.promises.stat(filePath)).mtime.toISOString();
8954
+ return (await fs19.promises.stat(filePath)).mtime.toISOString();
8816
8955
  }
8817
8956
 
8818
8957
  // src/commands/sessions/shared/codex/discoverCodexSessions.ts
@@ -8823,7 +8962,7 @@ async function discoverCodexSessions() {
8823
8962
  }
8824
8963
 
8825
8964
  // src/commands/sessions/shared/parseSessionFile.ts
8826
- import * as fs19 from "fs";
8965
+ import * as fs20 from "fs";
8827
8966
 
8828
8967
  // src/commands/sessions/shared/extractSessionMeta.ts
8829
8968
  function extractSessionMeta(lines2) {
@@ -8894,10 +9033,10 @@ function dirNameToProject(filePath) {
8894
9033
  async function parseSessionFile(filePath, origin = "wsl") {
8895
9034
  let handle;
8896
9035
  try {
8897
- handle = await fs19.promises.open(filePath, "r");
9036
+ handle = await fs20.promises.open(filePath, "r");
8898
9037
  const meta = extractSessionMeta(await readHeadLines(handle));
8899
9038
  if (!meta.sessionId) return null;
8900
- const timestamp6 = meta.timestamp || (await fs19.promises.stat(filePath)).mtime.toISOString();
9039
+ const timestamp6 = meta.timestamp || (await fs20.promises.stat(filePath)).mtime.toISOString();
8901
9040
  return {
8902
9041
  sessionId: meta.sessionId,
8903
9042
  name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
@@ -8934,7 +9073,7 @@ async function discoverSessionJsonlPaths() {
8934
9073
  sessionRoots().map(async ({ dir, origin }) => {
8935
9074
  let projectDirs;
8936
9075
  try {
8937
- projectDirs = await fs20.promises.readdir(dir);
9076
+ projectDirs = await fs21.promises.readdir(dir);
8938
9077
  } catch {
8939
9078
  return;
8940
9079
  }
@@ -8943,7 +9082,7 @@ async function discoverSessionJsonlPaths() {
8943
9082
  const dirPath = path28.join(dir, dirName);
8944
9083
  let entries;
8945
9084
  try {
8946
- entries = await fs20.promises.readdir(dirPath);
9085
+ entries = await fs21.promises.readdir(dirPath);
8947
9086
  } catch {
8948
9087
  return;
8949
9088
  }
@@ -9824,7 +9963,7 @@ import { spawn as spawn4 } from "child_process";
9824
9963
  import {
9825
9964
  closeSync,
9826
9965
  mkdirSync as mkdirSync10,
9827
- openSync,
9966
+ openSync as openSync2,
9828
9967
  statSync as statSync2,
9829
9968
  unlinkSync as unlinkSync5,
9830
9969
  writeSync
@@ -9864,7 +10003,7 @@ function acquireSpawnLock() {
9864
10003
  }
9865
10004
  function tryCreateLock() {
9866
10005
  try {
9867
- const fd = openSync(daemonPaths.spawnLock, "wx");
10006
+ const fd = openSync2(daemonPaths.spawnLock, "wx");
9868
10007
  writeSync(fd, String(process.pid));
9869
10008
  closeSync(fd);
9870
10009
  return true;
@@ -9886,7 +10025,7 @@ function releaseSpawnLock() {
9886
10025
  }
9887
10026
  }
9888
10027
  function spawnDaemon(reason4) {
9889
- const log2 = openSync(daemonPaths.log, "a");
10028
+ const log2 = openSync2(daemonPaths.log, "a");
9890
10029
  const child = spawn4(process.execPath, [process.argv[1], "daemon", "run"], {
9891
10030
  detached: true,
9892
10031
  windowsHide: true,
@@ -13544,7 +13683,7 @@ var handleRequest = createFallbackHandler(
13544
13683
  );
13545
13684
 
13546
13685
  // src/commands/sessions/web/handleSocket.ts
13547
- import { createInterface as createInterface3 } from "readline";
13686
+ import { createInterface as createInterface4 } from "readline";
13548
13687
  var CWD_DEFAULTED_TYPES = /* @__PURE__ */ new Set(["create", "create-run", "create-assist"]);
13549
13688
  function handleSocket(ws, ctx) {
13550
13689
  const connection = openDaemonConnection(ws, ctx);
@@ -13572,7 +13711,7 @@ async function openDaemonConnection(ws, ctx) {
13572
13711
  }
13573
13712
  }
13574
13713
  function relayDaemonLines(conn, ws, repoCwd) {
13575
- const lines2 = createInterface3({ input: conn });
13714
+ const lines2 = createInterface4({ input: conn });
13576
13715
  lines2.on("error", () => {
13577
13716
  });
13578
13717
  lines2.on("line", (line) => {
@@ -13836,7 +13975,7 @@ function installRestartMenu(options2 = {}) {
13836
13975
  }
13837
13976
 
13838
13977
  // src/commands/sessions/web/streamDaemonLogs.ts
13839
- import { createInterface as createInterface4 } from "readline";
13978
+ import { createInterface as createInterface5 } from "readline";
13840
13979
  var RECONNECT_MS = 3e3;
13841
13980
  function streamDaemonLogs() {
13842
13981
  void connect2();
@@ -13855,7 +13994,7 @@ async function connect2() {
13855
13994
  }
13856
13995
  }
13857
13996
  function wire(socket) {
13858
- const lines2 = createInterface4({ input: socket });
13997
+ const lines2 = createInterface5({ input: socket });
13859
13998
  lines2.on("error", () => {
13860
13999
  });
13861
14000
  lines2.on("line", emit);
@@ -13927,20 +14066,20 @@ async function web2(options2) {
13927
14066
  import chalk64 from "chalk";
13928
14067
 
13929
14068
  // src/commands/sessions/shared/resolveSessionTranscript.ts
13930
- import * as fs22 from "fs";
14069
+ import * as fs23 from "fs";
13931
14070
  import * as path35 from "path";
13932
14071
 
13933
14072
  // src/commands/sessions/summarise/readTranscriptHead.ts
13934
- import * as fs21 from "fs";
14073
+ import * as fs22 from "fs";
13935
14074
  function readTranscriptHead(filePath, maxBytes = 65536) {
13936
14075
  try {
13937
- const fd = fs21.openSync(filePath, "r");
14076
+ const fd = fs22.openSync(filePath, "r");
13938
14077
  try {
13939
14078
  const buf = Buffer.alloc(maxBytes);
13940
- const bytesRead = fs21.readSync(fd, buf, 0, buf.length, 0);
14079
+ const bytesRead = fs22.readSync(fd, buf, 0, buf.length, 0);
13941
14080
  return buf.toString("utf8", 0, bytesRead);
13942
14081
  } finally {
13943
- fs21.closeSync(fd);
14082
+ fs22.closeSync(fd);
13944
14083
  }
13945
14084
  } catch {
13946
14085
  return void 0;
@@ -13969,13 +14108,13 @@ function resolveSessionTranscript(sessionId, projectsRoot = claudeProjectsRoot()
13969
14108
  function findTranscriptFile(sessionId, projectsRoot) {
13970
14109
  let projectDirs;
13971
14110
  try {
13972
- projectDirs = fs22.readdirSync(projectsRoot);
14111
+ projectDirs = fs23.readdirSync(projectsRoot);
13973
14112
  } catch {
13974
14113
  return void 0;
13975
14114
  }
13976
14115
  for (const dir of projectDirs) {
13977
14116
  const candidate = path35.join(projectsRoot, dir, `${sessionId}.jsonl`);
13978
- if (fs22.existsSync(candidate)) return candidate;
14117
+ if (fs23.existsSync(candidate)) return candidate;
13979
14118
  }
13980
14119
  return void 0;
13981
14120
  }
@@ -14025,7 +14164,7 @@ async function addActivity(id, kind, ref, options2) {
14025
14164
  import chalk65 from "chalk";
14026
14165
 
14027
14166
  // src/commands/sessions/shared/resolveCurrentSessionId.ts
14028
- import * as fs23 from "fs";
14167
+ import * as fs24 from "fs";
14029
14168
  import * as path36 from "path";
14030
14169
  var SESSION_ID_ENV = "CLAUDE_CODE_SESSION_ID";
14031
14170
  function resolveCurrentSessionId(options2 = {}) {
@@ -14040,7 +14179,7 @@ function resolveCurrentSessionId(options2 = {}) {
14040
14179
  function newestTranscriptId(dir) {
14041
14180
  let entries;
14042
14181
  try {
14043
- entries = fs23.readdirSync(dir);
14182
+ entries = fs24.readdirSync(dir);
14044
14183
  } catch {
14045
14184
  return void 0;
14046
14185
  }
@@ -14056,7 +14195,7 @@ function newestTranscriptId(dir) {
14056
14195
  }
14057
14196
  function modifiedAtOf(filePath) {
14058
14197
  try {
14059
- return fs23.statSync(filePath).mtimeMs;
14198
+ return fs24.statSync(filePath).mtimeMs;
14060
14199
  } catch {
14061
14200
  return void 0;
14062
14201
  }
@@ -16709,13 +16848,13 @@ function phaseNotes(entry, position) {
16709
16848
  }
16710
16849
  function renderDiffPhase(entry, idx) {
16711
16850
  const notes = phaseNotes(entry, idx + 1);
16712
- const section3 = renderPhaseSection(
16851
+ const section2 = renderPhaseSection(
16713
16852
  { ...entry.phase, name: `${entry.phase.name} (${notes.join(", ")})` },
16714
16853
  idx
16715
16854
  );
16716
- if (!entry.previousTasks) return section3;
16855
+ if (!entry.previousTasks) return section2;
16717
16856
  return [
16718
- section3,
16857
+ section2,
16719
16858
  "**Previously:**",
16720
16859
  entry.previousTasks.map((task) => `- ${task}`).join("\n")
16721
16860
  ].join("\n\n");
@@ -19022,13 +19161,13 @@ import chalk133 from "chalk";
19022
19161
  import chalk126 from "chalk";
19023
19162
 
19024
19163
  // src/commands/complexity/shared/index.ts
19025
- import fs25 from "fs";
19164
+ import fs26 from "fs";
19026
19165
  import path38 from "path";
19027
19166
  import chalk125 from "chalk";
19028
19167
  import ts5 from "typescript";
19029
19168
 
19030
19169
  // src/commands/complexity/findSourceFiles.ts
19031
- import fs24 from "fs";
19170
+ import fs25 from "fs";
19032
19171
  import path37 from "path";
19033
19172
  import { minimatch as minimatch5 } from "minimatch";
19034
19173
  function applyIgnoreGlobs(files, extraIgnore = []) {
@@ -19037,11 +19176,11 @@ function applyIgnoreGlobs(files, extraIgnore = []) {
19037
19176
  return files.filter((f) => !ignore3.some((glob) => minimatch5(f, glob)));
19038
19177
  }
19039
19178
  function walk2(dir, results) {
19040
- if (!fs24.existsSync(dir)) {
19179
+ if (!fs25.existsSync(dir)) {
19041
19180
  return;
19042
19181
  }
19043
19182
  const extensions = [".ts", ".tsx"];
19044
- const entries = fs24.readdirSync(dir, { withFileTypes: true });
19183
+ const entries = fs25.readdirSync(dir, { withFileTypes: true });
19045
19184
  for (const entry of entries) {
19046
19185
  const fullPath = path37.join(dir, entry.name);
19047
19186
  if (entry.isDirectory()) {
@@ -19062,10 +19201,10 @@ function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
19062
19201
  extraIgnore
19063
19202
  );
19064
19203
  }
19065
- if (fs24.existsSync(pattern2) && fs24.statSync(pattern2).isFile()) {
19204
+ if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isFile()) {
19066
19205
  return [pattern2];
19067
19206
  }
19068
- if (fs24.existsSync(pattern2) && fs24.statSync(pattern2).isDirectory()) {
19207
+ if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isDirectory()) {
19069
19208
  walk2(pattern2, results);
19070
19209
  return applyIgnoreGlobs(results, extraIgnore);
19071
19210
  }
@@ -19263,7 +19402,7 @@ function countSloc(content) {
19263
19402
 
19264
19403
  // src/commands/complexity/shared/index.ts
19265
19404
  function createSourceFromFile(filePath) {
19266
- const content = fs25.readFileSync(filePath, "utf8");
19405
+ const content = fs26.readFileSync(filePath, "utf8");
19267
19406
  return ts5.createSourceFile(
19268
19407
  path38.basename(filePath),
19269
19408
  content,
@@ -19375,7 +19514,7 @@ function aggregateResults(fileMetrics) {
19375
19514
  }
19376
19515
 
19377
19516
  // src/commands/complexity/maintainability/collectFileMetrics.ts
19378
- import fs26 from "fs";
19517
+ import fs27 from "fs";
19379
19518
 
19380
19519
  // src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
19381
19520
  function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
@@ -19390,7 +19529,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
19390
19529
  function collectFileMetrics(files) {
19391
19530
  const fileMetrics = /* @__PURE__ */ new Map();
19392
19531
  for (const file of files) {
19393
- const content = fs26.readFileSync(file, "utf8");
19532
+ const content = fs27.readFileSync(file, "utf8");
19394
19533
  fileMetrics.set(file, {
19395
19534
  sloc: countSloc(content),
19396
19535
  functions: [],
@@ -19551,14 +19690,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
19551
19690
  }
19552
19691
 
19553
19692
  // src/commands/complexity/sloc.ts
19554
- import fs27 from "fs";
19693
+ import fs28 from "fs";
19555
19694
  import chalk132 from "chalk";
19556
19695
  async function sloc(pattern2 = "**/*.ts", options2 = {}) {
19557
19696
  withSourceFiles(pattern2, (files) => {
19558
19697
  const results = [];
19559
19698
  let hasViolation = false;
19560
19699
  for (const file of files) {
19561
- const content = fs27.readFileSync(file, "utf8");
19700
+ const content = fs28.readFileSync(file, "utf8");
19562
19701
  const lines2 = countSloc(content);
19563
19702
  results.push({ file, lines: lines2 });
19564
19703
  if (options2.threshold !== void 0 && lines2 > options2.threshold) {
@@ -20807,7 +20946,7 @@ function registerDevlog(program2) {
20807
20946
  }
20808
20947
 
20809
20948
  // src/commands/dotnet/checkBuildLocks.ts
20810
- import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync8 } from "fs";
20949
+ import { closeSync as closeSync3, openSync as openSync4, readdirSync as readdirSync8 } from "fs";
20811
20950
  import { join as join56 } from "path";
20812
20951
  import chalk154 from "chalk";
20813
20952
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
@@ -20822,7 +20961,7 @@ function isLockedDll(debugDir) {
20822
20961
  if (!file.toLowerCase().endsWith(".dll")) continue;
20823
20962
  const dllPath = join56(debugDir, file);
20824
20963
  try {
20825
- const fd = openSync3(dllPath, "r+");
20964
+ const fd = openSync4(dllPath, "r+");
20826
20965
  closeSync3(fd);
20827
20966
  } catch {
20828
20967
  return dllPath;
@@ -21417,7 +21556,7 @@ function registerDotnet(program2) {
21417
21556
  }
21418
21557
 
21419
21558
  // src/commands/editHook/index.ts
21420
- import fs28 from "fs";
21559
+ import fs29 from "fs";
21421
21560
 
21422
21561
  // src/commands/editHook/introducedComments.ts
21423
21562
  function introducedComments(added, removed) {
@@ -21664,7 +21803,7 @@ function tryParseInput2(raw) {
21664
21803
  function readExisting(filePath) {
21665
21804
  if (!filePath) return void 0;
21666
21805
  try {
21667
- return fs28.readFileSync(filePath, "utf8");
21806
+ return fs29.readFileSync(filePath, "utf8");
21668
21807
  } catch {
21669
21808
  return void 0;
21670
21809
  }
@@ -26228,9 +26367,9 @@ function parsePrBody(body) {
26228
26367
  return sections;
26229
26368
  }
26230
26369
  function serializePrBody(sections) {
26231
- return sections.map((section3) => `## ${section3.heading}
26370
+ return sections.map((section2) => `## ${section2.heading}
26232
26371
 
26233
- ${section3.content}`).join("\n\n");
26372
+ ${section2.content}`).join("\n\n");
26234
26373
  }
26235
26374
 
26236
26375
  // src/commands/prs/editPrBody.ts
@@ -26279,11 +26418,11 @@ function findWallOfText(body) {
26279
26418
  }
26280
26419
  function splitParagraphs(body) {
26281
26420
  const paragraphs = [];
26282
- let section3 = "(intro)";
26421
+ let section2 = "(intro)";
26283
26422
  let lines2 = [];
26284
26423
  const flush = () => {
26285
26424
  if (lines2.length > 0) {
26286
- paragraphs.push({ section: section3, lines: lines2 });
26425
+ paragraphs.push({ section: section2, lines: lines2 });
26287
26426
  lines2 = [];
26288
26427
  }
26289
26428
  };
@@ -26291,7 +26430,7 @@ function splitParagraphs(body) {
26291
26430
  const heading2 = line.match(/^#{1,6}\s+(.*)$/);
26292
26431
  if (heading2) {
26293
26432
  flush();
26294
- section3 = heading2[1].trim();
26433
+ section2 = heading2[1].trim();
26295
26434
  } else if (line.trim() === "") {
26296
26435
  flush();
26297
26436
  } else {
@@ -28267,17 +28406,17 @@ Refactor check failed:
28267
28406
 
28268
28407
  // src/commands/refactor/check/getViolations/index.ts
28269
28408
  import { execSync as execSync55 } from "child_process";
28270
- import fs30 from "fs";
28409
+ import fs31 from "fs";
28271
28410
  import { minimatch as minimatch6 } from "minimatch";
28272
28411
 
28273
28412
  // src/commands/refactor/check/getViolations/getIgnoredFiles.ts
28274
- import fs29 from "fs";
28413
+ import fs30 from "fs";
28275
28414
  var REFACTOR_YML_PATH = "refactor.yml";
28276
28415
  function parseRefactorYml() {
28277
- if (!fs29.existsSync(REFACTOR_YML_PATH)) {
28416
+ if (!fs30.existsSync(REFACTOR_YML_PATH)) {
28278
28417
  return [];
28279
28418
  }
28280
- const content = fs29.readFileSync(REFACTOR_YML_PATH, "utf8");
28419
+ const content = fs30.readFileSync(REFACTOR_YML_PATH, "utf8");
28281
28420
  const entries = [];
28282
28421
  const lines2 = content.split("\n");
28283
28422
  let currentEntry = {};
@@ -28307,7 +28446,7 @@ function getIgnoredFiles() {
28307
28446
 
28308
28447
  // src/commands/refactor/check/getViolations/index.ts
28309
28448
  function countLines(filePath) {
28310
- const content = fs30.readFileSync(filePath, "utf8");
28449
+ const content = fs31.readFileSync(filePath, "utf8");
28311
28450
  return content.split("\n").length;
28312
28451
  }
28313
28452
  function getGitFiles(options2) {
@@ -29012,13 +29151,13 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
29012
29151
  // src/commands/refactor/extract/displayPlan.ts
29013
29152
  import path50 from "path";
29014
29153
  import chalk199 from "chalk";
29015
- function section2(title) {
29154
+ function section(title) {
29016
29155
  return `
29017
29156
  ${chalk199.cyan(title)}`;
29018
29157
  }
29019
29158
  function displayImporters(plan2, cwd) {
29020
29159
  if (plan2.importersToUpdate.length === 0) return;
29021
- console.log(section2("Update importers:"));
29160
+ console.log(section("Update importers:"));
29022
29161
  for (const imp of plan2.importersToUpdate) {
29023
29162
  const rel = path50.relative(cwd, imp.file.getFilePath());
29024
29163
  console.log(` ${chalk199.dim(rel)}: \u2192 import from "${imp.relPath}"`);
@@ -29032,18 +29171,18 @@ function displayPlan(functionName, relDest, plan2, cwd) {
29032
29171
  console.log(` ${name}`);
29033
29172
  }
29034
29173
  if (plan2.imports.length > 0) {
29035
- console.log(section2("Imports to copy:"));
29174
+ console.log(section("Imports to copy:"));
29036
29175
  for (const imp of plan2.imports) {
29037
29176
  console.log(` ${formatImportLine(imp)}`);
29038
29177
  }
29039
29178
  }
29040
29179
  if (plan2.exportedDeps.length > 0) {
29041
- console.log(section2("New imports from source:"));
29180
+ console.log(section("New imports from source:"));
29042
29181
  console.log(
29043
29182
  ` import { ${plan2.exportedDeps.join(", ")} } from "${plan2.sourceRelPath}";`
29044
29183
  );
29045
29184
  }
29046
- console.log(section2("Source file changes:"));
29185
+ console.log(section("Source file changes:"));
29047
29186
  console.log(` Remove: ${plan2.extractedNames.join(", ")}`);
29048
29187
  if (plan2.sourceNeedsReimport) {
29049
29188
  console.log(
@@ -29052,7 +29191,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
29052
29191
  }
29053
29192
  displayImporters(plan2, cwd);
29054
29193
  if (plan2.barrel) {
29055
- console.log(section2("Barrel export:"));
29194
+ console.log(section("Barrel export:"));
29056
29195
  console.log(
29057
29196
  ` Add: export { ${functionName} } from "${plan2.barrelRelPath}";`
29058
29197
  );
@@ -29065,11 +29204,11 @@ import chalk200 from "chalk";
29065
29204
  import { Project as Project4 } from "ts-morph";
29066
29205
 
29067
29206
  // src/commands/refactor/extract/findTsConfig.ts
29068
- import fs32 from "fs";
29207
+ import fs33 from "fs";
29069
29208
  import path52 from "path";
29070
29209
 
29071
29210
  // src/commands/refactor/extract/findEnclosingTsConfig.ts
29072
- import fs31 from "fs";
29211
+ import fs32 from "fs";
29073
29212
  import path51 from "path";
29074
29213
 
29075
29214
  // src/commands/refactor/extract/projectIncludesFile.ts
@@ -29090,7 +29229,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
29090
29229
  const nested = path51.join(dir, "tsconfig.json");
29091
29230
  if (!tried.has(nested)) {
29092
29231
  tried.add(nested);
29093
- if (fs31.existsSync(nested) && projectIncludesFile(nested, sourcePath)) {
29232
+ if (fs32.existsSync(nested) && projectIncludesFile(nested, sourcePath)) {
29094
29233
  return nested;
29095
29234
  }
29096
29235
  }
@@ -29104,7 +29243,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
29104
29243
  // src/commands/refactor/extract/findTsConfig.ts
29105
29244
  function findTsConfig(sourcePath) {
29106
29245
  const rootConfig = path52.resolve("tsconfig.json");
29107
- if (!fs32.existsSync(rootConfig)) return rootConfig;
29246
+ if (!fs33.existsSync(rootConfig)) return rootConfig;
29108
29247
  const tried = /* @__PURE__ */ new Set();
29109
29248
  const candidates = [rootConfig, ...readReferences(rootConfig)];
29110
29249
  for (const candidate of candidates) {
@@ -29112,7 +29251,7 @@ function findTsConfig(sourcePath) {
29112
29251
  tried.add(candidate);
29113
29252
  if (projectIncludesFile(candidate, sourcePath)) return candidate;
29114
29253
  }
29115
- const siblings = fs32.readdirSync(path52.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path52.resolve(path52.dirname(rootConfig), f));
29254
+ const siblings = fs33.readdirSync(path52.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path52.resolve(path52.dirname(rootConfig), f));
29116
29255
  for (const sibling of siblings) {
29117
29256
  if (tried.has(sibling)) continue;
29118
29257
  tried.add(sibling);
@@ -29127,8 +29266,8 @@ function findTsConfig(sourcePath) {
29127
29266
  return rootConfig;
29128
29267
  }
29129
29268
  function readReferences(configPath) {
29130
- if (!fs32.existsSync(configPath)) return [];
29131
- const raw = fs32.readFileSync(configPath, "utf8");
29269
+ if (!fs33.existsSync(configPath)) return [];
29270
+ const raw = fs33.readFileSync(configPath, "utf8");
29132
29271
  const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
29133
29272
  let parsed;
29134
29273
  try {
@@ -29140,8 +29279,8 @@ function readReferences(configPath) {
29140
29279
  const cwd = path52.dirname(configPath);
29141
29280
  return parsed.references.map((ref) => {
29142
29281
  const refPath = path52.resolve(cwd, ref.path);
29143
- return fs32.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path52.join(refPath, "tsconfig.json") : refPath;
29144
- }).filter((p) => fs32.existsSync(p));
29282
+ return fs33.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path52.join(refPath, "tsconfig.json") : refPath;
29283
+ }).filter((p) => fs33.existsSync(p));
29145
29284
  }
29146
29285
 
29147
29286
  // src/commands/refactor/extract/loadProjectFile.ts
@@ -29183,25 +29322,25 @@ async function extract(file, functionName, destination, options2 = {}) {
29183
29322
  }
29184
29323
 
29185
29324
  // src/commands/refactor/ignore.ts
29186
- import fs33 from "fs";
29325
+ import fs34 from "fs";
29187
29326
  import chalk202 from "chalk";
29188
29327
  var REFACTOR_YML_PATH2 = "refactor.yml";
29189
29328
  function ignore2(file) {
29190
- if (!fs33.existsSync(file)) {
29329
+ if (!fs34.existsSync(file)) {
29191
29330
  console.error(chalk202.red(`Error: File does not exist: ${file}`));
29192
29331
  process.exit(1);
29193
29332
  }
29194
- const content = fs33.readFileSync(file, "utf8");
29333
+ const content = fs34.readFileSync(file, "utf8");
29195
29334
  const lineCount = content.split("\n").length;
29196
29335
  const maxLines = lineCount + 10;
29197
29336
  const entry = `- file: ${file}
29198
29337
  maxLines: ${maxLines}
29199
29338
  `;
29200
- if (fs33.existsSync(REFACTOR_YML_PATH2)) {
29201
- const existing = fs33.readFileSync(REFACTOR_YML_PATH2, "utf8");
29202
- fs33.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
29339
+ if (fs34.existsSync(REFACTOR_YML_PATH2)) {
29340
+ const existing = fs34.readFileSync(REFACTOR_YML_PATH2, "utf8");
29341
+ fs34.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
29203
29342
  } else {
29204
- fs33.writeFileSync(REFACTOR_YML_PATH2, entry);
29343
+ fs34.writeFileSync(REFACTOR_YML_PATH2, entry);
29205
29344
  }
29206
29345
  console.log(
29207
29346
  chalk202.green(
@@ -29211,12 +29350,12 @@ function ignore2(file) {
29211
29350
  }
29212
29351
 
29213
29352
  // src/commands/refactor/rename/index.ts
29214
- import fs36 from "fs";
29353
+ import fs37 from "fs";
29215
29354
  import path59 from "path";
29216
29355
  import chalk205 from "chalk";
29217
29356
 
29218
29357
  // src/commands/refactor/rename/applyRename.ts
29219
- import fs35 from "fs";
29358
+ import fs36 from "fs";
29220
29359
  import path56 from "path";
29221
29360
  import chalk203 from "chalk";
29222
29361
 
@@ -29224,7 +29363,7 @@ import chalk203 from "chalk";
29224
29363
  import path55 from "path";
29225
29364
 
29226
29365
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
29227
- import fs34 from "fs";
29366
+ import fs35 from "fs";
29228
29367
  function getOrCreateList(map, key) {
29229
29368
  const list5 = map.get(key) ?? [];
29230
29369
  if (!map.has(key)) map.set(key, list5);
@@ -29243,7 +29382,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
29243
29382
  return content.replace(pattern2, `$1${newSpecifier}$2`);
29244
29383
  }
29245
29384
  function applyFileRewrites(file, fileRewrites) {
29246
- let content = fs34.readFileSync(file, "utf8");
29385
+ let content = fs35.readFileSync(file, "utf8");
29247
29386
  for (const { oldSpecifier, newSpecifier } of fileRewrites) {
29248
29387
  content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
29249
29388
  }
@@ -29322,12 +29461,12 @@ function computeRewrites(moves, edges, allProjectFiles) {
29322
29461
  function applyRename(rewrites, sourcePath, destPath, cwd) {
29323
29462
  const updatedContents = applyRewrites(rewrites);
29324
29463
  for (const [file, content] of updatedContents) {
29325
- fs35.writeFileSync(file, content, "utf8");
29464
+ fs36.writeFileSync(file, content, "utf8");
29326
29465
  console.log(chalk203.cyan(` Updated imports in ${path56.relative(cwd, file)}`));
29327
29466
  }
29328
29467
  const destDir = path56.dirname(destPath);
29329
- if (!fs35.existsSync(destDir)) fs35.mkdirSync(destDir, { recursive: true });
29330
- fs35.renameSync(sourcePath, destPath);
29468
+ if (!fs36.existsSync(destDir)) fs36.mkdirSync(destDir, { recursive: true });
29469
+ fs36.renameSync(sourcePath, destPath);
29331
29470
  console.log(
29332
29471
  chalk203.white(
29333
29472
  ` Moved ${path56.relative(cwd, sourcePath)} \u2192 ${path56.relative(cwd, destPath)}`
@@ -29435,11 +29574,11 @@ async function rename(source, destination, options2 = {}) {
29435
29574
  const cwd = process.cwd();
29436
29575
  const relSource = path59.relative(cwd, sourcePath);
29437
29576
  const relDest = path59.relative(cwd, destPath);
29438
- if (!fs36.existsSync(sourcePath)) {
29577
+ if (!fs37.existsSync(sourcePath)) {
29439
29578
  console.log(chalk205.red(`File not found: ${source}`));
29440
29579
  process.exit(1);
29441
29580
  }
29442
- if (destPath !== sourcePath && fs36.existsSync(destPath)) {
29581
+ if (destPath !== sourcePath && fs37.existsSync(destPath)) {
29443
29582
  console.log(chalk205.red(`Destination already exists: ${destination}`));
29444
29583
  process.exit(1);
29445
29584
  }
@@ -29664,27 +29803,27 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
29664
29803
  }
29665
29804
 
29666
29805
  // src/commands/refactor/restructure/executePlan.ts
29667
- import fs37 from "fs";
29806
+ import fs38 from "fs";
29668
29807
  import path64 from "path";
29669
29808
  import chalk208 from "chalk";
29670
29809
  function executePlan(plan2) {
29671
29810
  const updatedContents = applyRewrites(plan2.rewrites);
29672
29811
  for (const [file, content] of updatedContents) {
29673
- fs37.writeFileSync(file, content, "utf8");
29812
+ fs38.writeFileSync(file, content, "utf8");
29674
29813
  console.log(
29675
29814
  chalk208.cyan(` Rewrote imports in ${path64.relative(process.cwd(), file)}`)
29676
29815
  );
29677
29816
  }
29678
29817
  for (const dir of plan2.newDirectories) {
29679
- fs37.mkdirSync(dir, { recursive: true });
29818
+ fs38.mkdirSync(dir, { recursive: true });
29680
29819
  console.log(chalk208.green(` Created ${path64.relative(process.cwd(), dir)}/`));
29681
29820
  }
29682
29821
  for (const move2 of plan2.moves) {
29683
29822
  const targetDir = path64.dirname(move2.to);
29684
- if (!fs37.existsSync(targetDir)) {
29685
- fs37.mkdirSync(targetDir, { recursive: true });
29823
+ if (!fs38.existsSync(targetDir)) {
29824
+ fs38.mkdirSync(targetDir, { recursive: true });
29686
29825
  }
29687
- fs37.renameSync(move2.from, move2.to);
29826
+ fs38.renameSync(move2.from, move2.to);
29688
29827
  console.log(
29689
29828
  chalk208.white(
29690
29829
  ` Moved ${path64.relative(process.cwd(), move2.from)} \u2192 ${path64.relative(process.cwd(), move2.to)}`
@@ -29696,10 +29835,10 @@ function executePlan(plan2) {
29696
29835
  function removeEmptyDirectories(dirs) {
29697
29836
  const unique = [...new Set(dirs)];
29698
29837
  for (const dir of unique) {
29699
- if (!fs37.existsSync(dir)) continue;
29700
- const entries = fs37.readdirSync(dir);
29838
+ if (!fs38.existsSync(dir)) continue;
29839
+ const entries = fs38.readdirSync(dir);
29701
29840
  if (entries.length === 0) {
29702
- fs37.rmdirSync(dir);
29841
+ fs38.rmdirSync(dir);
29703
29842
  console.log(
29704
29843
  chalk208.dim(
29705
29844
  ` Removed empty directory ${path64.relative(process.cwd(), dir)}`
@@ -29713,18 +29852,18 @@ function removeEmptyDirectories(dirs) {
29713
29852
  import path66 from "path";
29714
29853
 
29715
29854
  // src/commands/refactor/restructure/planFileMoves/shared.ts
29716
- import fs38 from "fs";
29855
+ import fs39 from "fs";
29717
29856
  function emptyResult() {
29718
29857
  return { moves: [], directories: [], warnings: [] };
29719
29858
  }
29720
29859
  function checkDirConflict(result, label2, dir) {
29721
- if (!fs38.existsSync(dir)) return false;
29860
+ if (!fs39.existsSync(dir)) return false;
29722
29861
  result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
29723
29862
  return true;
29724
29863
  }
29725
29864
 
29726
29865
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
29727
- import fs39 from "fs";
29866
+ import fs40 from "fs";
29728
29867
  import path65 from "path";
29729
29868
  function collectEntry2(results, dir, entry) {
29730
29869
  const full = path65.join(dir, entry.name);
@@ -29732,9 +29871,9 @@ function collectEntry2(results, dir, entry) {
29732
29871
  results.push(...items2);
29733
29872
  }
29734
29873
  function listFilesRecursive(dir) {
29735
- if (!fs39.existsSync(dir)) return [];
29874
+ if (!fs40.existsSync(dir)) return [];
29736
29875
  const results = [];
29737
- for (const entry of fs39.readdirSync(dir, { withFileTypes: true })) {
29876
+ for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
29738
29877
  collectEntry2(results, dir, entry);
29739
29878
  }
29740
29879
  return results;
@@ -32893,7 +33032,7 @@ function registerSql(program2) {
32893
33032
  }
32894
33033
 
32895
33034
  // src/commands/sync.ts
32896
- import * as fs48 from "fs";
33035
+ import * as fs49 from "fs";
32897
33036
  import * as os5 from "os";
32898
33037
  import * as path85 from "path";
32899
33038
  import { fileURLToPath as fileURLToPath9 } from "url";
@@ -32902,7 +33041,7 @@ import { fileURLToPath as fileURLToPath9 } from "url";
32902
33041
  import * as path76 from "path";
32903
33042
 
32904
33043
  // src/commands/sync/pruneTarget.ts
32905
- import * as fs40 from "fs";
33044
+ import * as fs41 from "fs";
32906
33045
  import * as path75 from "path";
32907
33046
  function pruneTarget(targetDir, keepNames, shape, options2) {
32908
33047
  const result = {
@@ -32911,9 +33050,9 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
32911
33050
  skipped: [],
32912
33051
  unmanaged: []
32913
33052
  };
32914
- if (!fs40.existsSync(targetDir)) return result;
33053
+ if (!fs41.existsSync(targetDir)) return result;
32915
33054
  const keep = new Set(keepNames);
32916
- for (const entry of fs40.readdirSync(targetDir, { withFileTypes: true })) {
33055
+ for (const entry of fs41.readdirSync(targetDir, { withFileTypes: true })) {
32917
33056
  const name = shape.nameOf(entry);
32918
33057
  if (name === void 0) {
32919
33058
  result.unmanaged.push(entry.name);
@@ -32928,7 +33067,7 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
32928
33067
  continue;
32929
33068
  }
32930
33069
  if (options2.force) {
32931
- fs40.rmSync(entryPath, { recursive: true });
33070
+ fs41.rmSync(entryPath, { recursive: true });
32932
33071
  result.removed.push(entry.name);
32933
33072
  }
32934
33073
  }
@@ -32975,7 +33114,7 @@ function reportPrune(label2, result, force) {
32975
33114
  }
32976
33115
 
32977
33116
  // src/commands/sync/reportRetiredAgentsFiles.ts
32978
- import * as fs41 from "fs";
33117
+ import * as fs42 from "fs";
32979
33118
  import * as path77 from "path";
32980
33119
  var retired = [
32981
33120
  path77.join(harnesses.claude.homeDir, "CLAUDE.md"),
@@ -32983,7 +33122,7 @@ var retired = [
32983
33122
  path77.join(harnesses.pi.homeDir, "AGENTS.md")
32984
33123
  ];
32985
33124
  function reportRetiredAgentsFiles() {
32986
- const leftovers = retired.filter((file) => fs41.existsSync(file));
33125
+ const leftovers = retired.filter((file) => fs42.existsSync(file));
32987
33126
  if (leftovers.length === 0) return;
32988
33127
  console.log(
32989
33128
  "No longer written by sync \u2014 each harness now composes its own advice at session start:"
@@ -32998,28 +33137,28 @@ function reportRetiredAgentsFiles() {
32998
33137
  import * as path80 from "path";
32999
33138
 
33000
33139
  // src/commands/sync/installHarnessCommands.ts
33001
- import * as fs42 from "fs";
33140
+ import * as fs43 from "fs";
33002
33141
  import * as path78 from "path";
33003
33142
  function installHarnessCommands(claudeDir, harness, transform) {
33004
33143
  const commandsSource = path78.join(claudeDir, "commands");
33005
- const files = fs42.readdirSync(commandsSource);
33144
+ const files = fs43.readdirSync(commandsSource);
33006
33145
  const names = [];
33007
33146
  let synced = 0;
33008
33147
  for (const file of files) {
33009
33148
  if (!file.endsWith(".md")) continue;
33010
33149
  const name = file.replace(/\.md$/, "");
33011
33150
  names.push(name);
33012
- const content = fs42.readFileSync(path78.join(commandsSource, file), "utf8");
33151
+ const content = fs43.readFileSync(path78.join(commandsSource, file), "utf8");
33013
33152
  const target = path78.join(harness.homeDir, harness.sync.commandDest(name));
33014
- fs42.mkdirSync(path78.dirname(target), { recursive: true });
33015
- fs42.writeFileSync(target, transform(name, content));
33153
+ fs43.mkdirSync(path78.dirname(target), { recursive: true });
33154
+ fs43.writeFileSync(target, transform(name, content));
33016
33155
  synced++;
33017
33156
  }
33018
33157
  return { total: files.length, synced, names };
33019
33158
  }
33020
33159
 
33021
33160
  // src/commands/sync/pruneSkills.ts
33022
- import * as fs43 from "fs";
33161
+ import * as fs44 from "fs";
33023
33162
  function pruneSkills(targetDir, skillNames, options2) {
33024
33163
  return pruneTarget(
33025
33164
  targetDir,
@@ -33032,14 +33171,14 @@ function pruneSkills(targetDir, skillNames, options2) {
33032
33171
  );
33033
33172
  }
33034
33173
  function unexpectedContent(skillDir) {
33035
- const entries = fs43.readdirSync(skillDir);
33174
+ const entries = fs44.readdirSync(skillDir);
33036
33175
  const others = entries.filter((entry) => entry !== "SKILL.md");
33037
33176
  if (others.length > 0) return `contains ${others.sort().join(", ")}`;
33038
33177
  return entries.length === 0 ? "no SKILL.md" : void 0;
33039
33178
  }
33040
33179
 
33041
33180
  // src/commands/sync/syncCodexHooks.ts
33042
- import * as fs44 from "fs";
33181
+ import * as fs45 from "fs";
33043
33182
  import * as path79 from "path";
33044
33183
  var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
33045
33184
  var END = "# <<< assist codex hooks (managed) <<<";
@@ -33070,11 +33209,11 @@ ${rest}
33070
33209
  `;
33071
33210
  }
33072
33211
  function syncCodexHooks(sourcePath) {
33073
- const body = fs44.readFileSync(sourcePath, "utf8");
33212
+ const body = fs45.readFileSync(sourcePath, "utf8");
33074
33213
  const configPath = path79.join(harnesses.codex.homeDir, "config.toml");
33075
- const existing = fs44.existsSync(configPath) ? fs44.readFileSync(configPath, "utf8") : "";
33076
- fs44.mkdirSync(path79.dirname(configPath), { recursive: true });
33077
- fs44.writeFileSync(configPath, upsertManagedBlock(existing, body));
33214
+ const existing = fs45.existsSync(configPath) ? fs45.readFileSync(configPath, "utf8") : "";
33215
+ fs45.mkdirSync(path79.dirname(configPath), { recursive: true });
33216
+ fs45.writeFileSync(configPath, upsertManagedBlock(existing, body));
33078
33217
  console.log(
33079
33218
  "Registered assist codex-hook in ~/.codex/config.toml (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, Stop)"
33080
33219
  );
@@ -33117,21 +33256,21 @@ function syncCodex(claudeDir, options2) {
33117
33256
  }
33118
33257
 
33119
33258
  // src/commands/sync/syncDesign.ts
33120
- import * as fs45 from "fs";
33259
+ import * as fs46 from "fs";
33121
33260
  import * as path81 from "path";
33122
33261
  function syncDesign(claudeDir, targetBase) {
33123
33262
  const systemPromptSource = path81.join(claudeDir, "design-system-prompt.md");
33124
33263
  const systemPromptTarget = path81.join(targetBase, "design-system-prompt.md");
33125
- fs45.copyFileSync(systemPromptSource, systemPromptTarget);
33264
+ fs46.copyFileSync(systemPromptSource, systemPromptTarget);
33126
33265
  console.log(
33127
33266
  "Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
33128
33267
  );
33129
33268
  const skillsSource = path81.join(claudeDir, "skills");
33130
33269
  const skillsTarget = path81.join(targetBase, "skills");
33131
- fs45.mkdirSync(skillsTarget, { recursive: true });
33132
- const files = fs45.readdirSync(skillsSource);
33270
+ fs46.mkdirSync(skillsTarget, { recursive: true });
33271
+ const files = fs46.readdirSync(skillsSource);
33133
33272
  for (const file of files) {
33134
- fs45.copyFileSync(
33273
+ fs46.copyFileSync(
33135
33274
  path81.join(skillsSource, file),
33136
33275
  path81.join(skillsTarget, file)
33137
33276
  );
@@ -33143,17 +33282,17 @@ function syncDesign(claudeDir, targetBase) {
33143
33282
  import * as path83 from "path";
33144
33283
 
33145
33284
  // src/commands/sync/syncPiHooks.ts
33146
- import * as fs46 from "fs";
33285
+ import * as fs47 from "fs";
33147
33286
  import * as path82 from "path";
33148
33287
  function piExtensionsDir() {
33149
33288
  return path82.join(harnesses.pi.homeDir, "extensions");
33150
33289
  }
33151
33290
  function syncPiHooks(sourceDir) {
33152
33291
  const target = piExtensionsDir();
33153
- fs46.mkdirSync(target, { recursive: true });
33154
- const files = fs46.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
33292
+ fs47.mkdirSync(target, { recursive: true });
33293
+ const files = fs47.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
33155
33294
  for (const file of files) {
33156
- fs46.copyFileSync(
33295
+ fs47.copyFileSync(
33157
33296
  path82.join(sourceDir, file),
33158
33297
  path82.join(target, `assist-${file}`)
33159
33298
  );
@@ -33204,16 +33343,16 @@ function syncPi(claudeDir, options2) {
33204
33343
  }
33205
33344
 
33206
33345
  // src/commands/sync/syncSettings.ts
33207
- import * as fs47 from "fs";
33346
+ import * as fs48 from "fs";
33208
33347
  import * as path84 from "path";
33209
33348
  import chalk227 from "chalk";
33210
33349
  async function syncSettings(claudeDir, targetBase, options2) {
33211
33350
  const source = path84.join(claudeDir, "settings.json");
33212
33351
  const target = path84.join(targetBase, "settings.json");
33213
- const sourceContent = fs47.readFileSync(source, "utf8");
33352
+ const sourceContent = fs48.readFileSync(source, "utf8");
33214
33353
  const sourceSettings = JSON.parse(sourceContent);
33215
- const targetExists = fs47.existsSync(target);
33216
- const targetContent = targetExists ? fs47.readFileSync(target, "utf8") : "";
33354
+ const targetExists = fs48.existsSync(target);
33355
+ const targetContent = targetExists ? fs48.readFileSync(target, "utf8") : "";
33217
33356
  const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
33218
33357
  const mergedContent = JSON.stringify(
33219
33358
  { ...preservedUserSettings, ...sourceSettings },
@@ -33243,7 +33382,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
33243
33382
  }
33244
33383
  }
33245
33384
  }
33246
- fs47.writeFileSync(target, mergedContent);
33385
+ fs48.writeFileSync(target, mergedContent);
33247
33386
  console.log("Copied settings.json to ~/.claude/settings.json");
33248
33387
  }
33249
33388
 
@@ -33274,10 +33413,10 @@ async function sync(options2) {
33274
33413
  function syncCommands(claudeDir, targetBase) {
33275
33414
  const sourceDir = path85.join(claudeDir, "commands");
33276
33415
  const targetDir = path85.join(targetBase, "commands");
33277
- fs48.mkdirSync(targetDir, { recursive: true });
33278
- const files = fs48.readdirSync(sourceDir);
33416
+ fs49.mkdirSync(targetDir, { recursive: true });
33417
+ const files = fs49.readdirSync(sourceDir);
33279
33418
  for (const file of files) {
33280
- fs48.copyFileSync(path85.join(sourceDir, file), path85.join(targetDir, file));
33419
+ fs49.copyFileSync(path85.join(sourceDir, file), path85.join(targetDir, file));
33281
33420
  console.log(`Copied ${file} to ${targetDir}`);
33282
33421
  }
33283
33422
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -33596,9 +33735,9 @@ function clean(file, options2 = {}) {
33596
33735
  }
33597
33736
 
33598
33737
  // src/commands/transcript/shared.ts
33599
- import * as readline3 from "readline";
33738
+ import * as readline4 from "readline";
33600
33739
  function createReadlineInterface() {
33601
- return readline3.createInterface({
33740
+ return readline4.createInterface({
33602
33741
  input: process.stdin,
33603
33742
  output: process.stdout
33604
33743
  });
@@ -33989,6 +34128,11 @@ var checks = [
33989
34128
  description: "Check every assistConfigSchema key is surfaced in some command's --help via configHelp",
33990
34129
  action: configKeys
33991
34130
  },
34131
+ {
34132
+ name: "advice-fragments",
34133
+ description: "Check ADVICE_FRAGMENT_NAMES matches the fragments shipped in claude/advice, so advice.include/exclude can name every one",
34134
+ action: adviceFragments
34135
+ },
33992
34136
  {
33993
34137
  name: "migrations",
33994
34138
  description: "Check DB migrations are sequentially numbered, append-only, and gate destructive DDL behind an acknowledgement marker",
@@ -35659,7 +35803,7 @@ function listDaemonPids() {
35659
35803
  }
35660
35804
 
35661
35805
  // src/commands/sessions/daemon/queryDaemon.ts
35662
- import { createInterface as createInterface6 } from "readline";
35806
+ import { createInterface as createInterface7 } from "readline";
35663
35807
  var STATUS_TIMEOUT_MS = 5e3;
35664
35808
  function queryDaemon(socket) {
35665
35809
  socket.write(`${JSON.stringify({ type: "ping" })}
@@ -35668,7 +35812,7 @@ function queryDaemon(socket) {
35668
35812
  const result = { sessions: [] };
35669
35813
  const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
35670
35814
  const timer = setTimeout(() => resolve25(result), STATUS_TIMEOUT_MS);
35671
- const lines2 = createInterface6({ input: socket });
35815
+ const lines2 = createInterface7({ input: socket });
35672
35816
  lines2.on("error", () => {
35673
35817
  });
35674
35818
  lines2.on("line", (line) => {
@@ -35758,7 +35902,7 @@ function reportStrays(pids) {
35758
35902
  }
35759
35903
 
35760
35904
  // src/commands/sessions/daemon/drainDaemon.ts
35761
- import { createInterface as createInterface7 } from "readline";
35905
+ import { createInterface as createInterface8 } from "readline";
35762
35906
 
35763
35907
  // src/commands/sessions/daemon/clearPersistedSessionsOnDrain.ts
35764
35908
  function clearPersistedSessionsOnDrain() {
@@ -35800,7 +35944,7 @@ async function drainDaemon(options2 = {}) {
35800
35944
  clearPersistedSessionsOnDrain();
35801
35945
  return;
35802
35946
  }
35803
- const lines2 = createInterface7({ input: socket });
35947
+ const lines2 = createInterface8({ input: socket });
35804
35948
  lines2.on("error", () => {
35805
35949
  });
35806
35950
  const live = await liveSessions(lines2);
@@ -36264,7 +36408,7 @@ function serverRunMeta(runName, cwd) {
36264
36408
  }
36265
36409
 
36266
36410
  // src/commands/sessions/daemon/readDesignSystemPrompt.ts
36267
- import * as fs49 from "fs";
36411
+ import * as fs50 from "fs";
36268
36412
  import * as path87 from "path";
36269
36413
  import { fileURLToPath as fileURLToPath11 } from "url";
36270
36414
  var __filename5 = fileURLToPath11(import.meta.url);
@@ -36276,7 +36420,7 @@ function readDesignSystemPrompt() {
36276
36420
  "claude",
36277
36421
  "design-system-prompt.md"
36278
36422
  );
36279
- return fs49.readFileSync(promptPath, "utf8");
36423
+ return fs50.readFileSync(promptPath, "utf8");
36280
36424
  }
36281
36425
 
36282
36426
  // src/commands/sessions/daemon/spawnClaude.ts
@@ -37365,7 +37509,7 @@ function reportSilentFailure(session, clients) {
37365
37509
  }
37366
37510
 
37367
37511
  // src/commands/sessions/shared/codex/resolveCodexSessionId.ts
37368
- import * as fs50 from "fs";
37512
+ import * as fs51 from "fs";
37369
37513
  var META_LINES = 5;
37370
37514
  async function resolveCodexSessionId(cwd, sinceMs) {
37371
37515
  if (!cwd) return null;
@@ -37394,7 +37538,7 @@ async function startedIn(file, cwd, sinceMs) {
37394
37538
  }
37395
37539
  async function touchedSince(file, sinceMs) {
37396
37540
  try {
37397
- return (await fs50.promises.stat(file)).mtimeMs >= sinceMs;
37541
+ return (await fs51.promises.stat(file)).mtimeMs >= sinceMs;
37398
37542
  } catch {
37399
37543
  return false;
37400
37544
  }
@@ -37428,7 +37572,7 @@ function bindCodexSession(session, notify2) {
37428
37572
  import { watch as watch3 } from "fs";
37429
37573
 
37430
37574
  // src/commands/sessions/shared/findTranscriptPathSync.ts
37431
- import * as fs51 from "fs";
37575
+ import * as fs52 from "fs";
37432
37576
  import * as path88 from "path";
37433
37577
  function projectDirForCwd(cwd) {
37434
37578
  return path88.join(claudeProjectsRoot(), projectSlug(cwd));
@@ -37438,11 +37582,11 @@ function transcriptPathFor(cwd, claudeSessionId) {
37438
37582
  }
37439
37583
  function findTranscriptPathSync(cwd, claudeSessionId) {
37440
37584
  const direct = transcriptPathFor(cwd, claudeSessionId);
37441
- if (fs51.existsSync(direct)) return direct;
37585
+ if (fs52.existsSync(direct)) return direct;
37442
37586
  const dir = projectDirForCwd(cwd);
37443
37587
  let files;
37444
37588
  try {
37445
- files = fs51.readdirSync(dir);
37589
+ files = fs52.readdirSync(dir);
37446
37590
  } catch {
37447
37591
  return null;
37448
37592
  }
@@ -37456,14 +37600,14 @@ function findTranscriptPathSync(cwd, claudeSessionId) {
37456
37600
  function headContainsSessionId(filePath, claudeSessionId) {
37457
37601
  let fd;
37458
37602
  try {
37459
- fd = fs51.openSync(filePath, "r");
37603
+ fd = fs52.openSync(filePath, "r");
37460
37604
  const buf = Buffer.alloc(16384);
37461
- const bytesRead = fs51.readSync(fd, buf, 0, buf.length, 0);
37605
+ const bytesRead = fs52.readSync(fd, buf, 0, buf.length, 0);
37462
37606
  return buf.toString("utf8", 0, bytesRead).includes(claudeSessionId);
37463
37607
  } catch {
37464
37608
  return false;
37465
37609
  } finally {
37466
- if (fd !== void 0) fs51.closeSync(fd);
37610
+ if (fd !== void 0) fs52.closeSync(fd);
37467
37611
  }
37468
37612
  }
37469
37613
 
@@ -37633,7 +37777,7 @@ function asRecord3(value) {
37633
37777
  }
37634
37778
 
37635
37779
  // src/commands/sessions/shared/readTranscriptTail.ts
37636
- import * as fs52 from "fs";
37780
+ import * as fs53 from "fs";
37637
37781
  var DEFAULT_MAX_BYTES = 256 * 1024;
37638
37782
  function parseTailEntries(raw) {
37639
37783
  const entries = [];
@@ -37657,7 +37801,7 @@ function dropPartialFirstLine(raw, sliced) {
37657
37801
  async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37658
37802
  let handle;
37659
37803
  try {
37660
- handle = await fs52.promises.open(filePath, "r");
37804
+ handle = await fs53.promises.open(filePath, "r");
37661
37805
  const { size } = await handle.stat();
37662
37806
  const start3 = Math.max(0, size - maxBytes);
37663
37807
  const length = size - start3;
@@ -37676,20 +37820,20 @@ async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37676
37820
  function readTranscriptTailSync(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37677
37821
  let fd;
37678
37822
  try {
37679
- fd = fs52.openSync(filePath, "r");
37680
- const { size } = fs52.fstatSync(fd);
37823
+ fd = fs53.openSync(filePath, "r");
37824
+ const { size } = fs53.fstatSync(fd);
37681
37825
  const start3 = Math.max(0, size - maxBytes);
37682
37826
  const length = size - start3;
37683
37827
  if (length === 0) return [];
37684
37828
  const buf = Buffer.alloc(length);
37685
- fs52.readSync(fd, buf, 0, length, start3);
37829
+ fs53.readSync(fd, buf, 0, length, start3);
37686
37830
  return parseTailEntries(
37687
37831
  dropPartialFirstLine(buf.toString("utf8"), start3 > 0)
37688
37832
  );
37689
37833
  } catch {
37690
37834
  return [];
37691
37835
  } finally {
37692
- if (fd !== void 0) fs52.closeSync(fd);
37836
+ if (fd !== void 0) fs53.closeSync(fd);
37693
37837
  }
37694
37838
  }
37695
37839
 
@@ -38068,7 +38212,7 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
38068
38212
  }
38069
38213
 
38070
38214
  // src/commands/sessions/shared/transcriptUsage.ts
38071
- import * as fs53 from "fs";
38215
+ import * as fs54 from "fs";
38072
38216
  function transcriptUsage(lines2) {
38073
38217
  const byId = /* @__PURE__ */ new Map();
38074
38218
  for (const line of lines2) {
@@ -38092,7 +38236,7 @@ function transcriptUsage(lines2) {
38092
38236
  return [...byId.values()];
38093
38237
  }
38094
38238
  async function readTranscriptUsage(transcriptPath2) {
38095
- const content = await fs53.promises.readFile(transcriptPath2, "utf8");
38239
+ const content = await fs54.promises.readFile(transcriptPath2, "utf8");
38096
38240
  return transcriptUsage(content.split("\n"));
38097
38241
  }
38098
38242
 
@@ -39785,10 +39929,10 @@ async function isWindowsDaemonRunning() {
39785
39929
  import { spawn as spawn11 } from "child_process";
39786
39930
 
39787
39931
  // src/commands/sessions/daemon/logChildStream.ts
39788
- import { createInterface as createInterface8 } from "readline";
39932
+ import { createInterface as createInterface9 } from "readline";
39789
39933
  function logChildStream(stream, label2, onLine) {
39790
39934
  if (!stream) return;
39791
- const lines2 = createInterface8({ input: stream });
39935
+ const lines2 = createInterface9({ input: stream });
39792
39936
  lines2.on("line", (line) => {
39793
39937
  daemonLog(`[${label2}] ${line}`);
39794
39938
  onLine?.(line);
@@ -40218,7 +40362,7 @@ function isWindowsIo(data) {
40218
40362
  }
40219
40363
 
40220
40364
  // src/commands/sessions/daemon/WindowsConnection.ts
40221
- import { createInterface as createInterface9 } from "readline";
40365
+ import { createInterface as createInterface10 } from "readline";
40222
40366
 
40223
40367
  // src/commands/sessions/daemon/LaunchCircuitBreaker.ts
40224
40368
  var MAX_FAILURES = 3;
@@ -40305,7 +40449,7 @@ var WindowsConnection = class {
40305
40449
  return socket;
40306
40450
  }
40307
40451
  wire(socket) {
40308
- const lines2 = createInterface9({ input: socket });
40452
+ const lines2 = createInterface10({ input: socket });
40309
40453
  lines2.on("error", () => {
40310
40454
  });
40311
40455
  lines2.on("line", (line) => this.deps.onLine(line));
@@ -40914,7 +41058,7 @@ function exitAfterFlush(code) {
40914
41058
  }
40915
41059
 
40916
41060
  // src/commands/sessions/daemon/handleConnection.ts
40917
- import { createInterface as createInterface10 } from "readline";
41061
+ import { createInterface as createInterface11 } from "readline";
40918
41062
 
40919
41063
  // src/commands/sessions/daemon/creator.ts
40920
41064
  function creator(isNew, spawn13) {
@@ -40989,7 +41133,7 @@ function handleSetStatus(client, m, d) {
40989
41133
  }
40990
41134
 
40991
41135
  // src/commands/sessions/shared/parseTranscript.ts
40992
- import * as fs54 from "fs";
41136
+ import * as fs55 from "fs";
40993
41137
 
40994
41138
  // src/commands/sessions/shared/codex/findCodexRolloutPath.ts
40995
41139
  import * as path89 from "path";
@@ -41072,7 +41216,7 @@ async function parseTranscript(sessionId) {
41072
41216
  }
41073
41217
  async function readMessages(filePath, parse4) {
41074
41218
  try {
41075
- const raw = await fs54.promises.readFile(filePath, "utf8");
41219
+ const raw = await fs55.promises.readFile(filePath, "utf8");
41076
41220
  return parse4(raw.split("\n"));
41077
41221
  } catch {
41078
41222
  return [];
@@ -41278,7 +41422,7 @@ function handleConnection(socket, manager) {
41278
41422
  };
41279
41423
  manager.addClient(client);
41280
41424
  manager.clients.greet(client);
41281
- const lines2 = createInterface10({ input: socket });
41425
+ const lines2 = createInterface11({ input: socket });
41282
41426
  lines2.on("error", () => {
41283
41427
  });
41284
41428
  lines2.on("line", (line) => {
@@ -41600,17 +41744,17 @@ async function renameSession(title) {
41600
41744
  }
41601
41745
 
41602
41746
  // src/commands/sessions/summarise/index.ts
41603
- import * as fs56 from "fs";
41747
+ import * as fs57 from "fs";
41604
41748
  import chalk230 from "chalk";
41605
41749
 
41606
41750
  // src/commands/sessions/summarise/shared.ts
41607
- import * as fs55 from "fs";
41751
+ import * as fs56 from "fs";
41608
41752
  function writeSummary(jsonlPath2, summary) {
41609
- fs55.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
41753
+ fs56.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
41610
41754
  `, "utf8");
41611
41755
  }
41612
41756
  function hasSummary(jsonlPath2) {
41613
- return fs55.existsSync(summaryPathFor(jsonlPath2));
41757
+ return fs56.existsSync(summaryPathFor(jsonlPath2));
41614
41758
  }
41615
41759
  function summaryPathFor(jsonlPath2) {
41616
41760
  return jsonlPath2.replace(/\.jsonl$/, ".summary");
@@ -41682,7 +41826,7 @@ function selectCandidates(files, options2) {
41682
41826
  const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
41683
41827
  candidates.sort((a, b) => {
41684
41828
  try {
41685
- return fs56.statSync(b).mtimeMs - fs56.statSync(a).mtimeMs;
41829
+ return fs57.statSync(b).mtimeMs - fs57.statSync(a).mtimeMs;
41686
41830
  } catch {
41687
41831
  return 0;
41688
41832
  }
@@ -42005,6 +42149,7 @@ configHelp(screenshotCommand, rootConfigHelp.screenshot);
42005
42149
  registerActivity(program);
42006
42150
  registerAdvise(program);
42007
42151
  registerBackup(program);
42152
+ registerChart(program);
42008
42153
  registerDb(program);
42009
42154
  registerDbMigration(program);
42010
42155
  registerCliHook(program);