@staff0rd/assist 0.373.0 → 0.374.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.373.0",
9
+ version: "0.374.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -27,7 +27,15 @@ var package_default = {
27
27
  build: "tsup",
28
28
  start: "node dist/index.js",
29
29
  "check:types": "tsc --noEmit",
30
- test: "vitest run"
30
+ test: "vitest run",
31
+ "verify:lint": "oxlint --config .oxlintrc.json src",
32
+ "verify:format": "oxfmt .",
33
+ "verify:knip": "knip --no-progress --treat-config-hints-as-errors",
34
+ "verify:duplicate-code": 'jscpd --format typescript,tsx,python --exitCode 1 --ignore "**/*.test.*,**/.venv/**" -r consoleFull src',
35
+ "verify:test": "vitest run --changed --passWithNoTests --reporter dot",
36
+ "verify:config-keys": "tsx src/index.ts verify config-keys",
37
+ "verify:react-build": "esbuild src/commands/sessions/web/ui/App.tsx --bundle --minify --format=iife --target=es2020 --outfile=dist/commands/sessions/web/bundle.verify.js --jsx=automatic --jsx-import-source=react --define:process.env.NODE_ENV='production'",
38
+ "verify:circular-deps": "skott --displayMode=raw --showCircularDependencies --exitCodeOnCircularDependencies=1 src/index.ts"
31
39
  },
32
40
  overrides: {
33
41
  lodash: "^4.18.0",
@@ -107,7 +115,9 @@ var package_default = {
107
115
  "react-dom": "^19.2.4",
108
116
  "react-router": "^7.14.0",
109
117
  "semantic-release": "^25.0.2",
118
+ skott: "^0.35.11",
110
119
  tsup: "^8.5.1",
120
+ tsx: "^4.23.0",
111
121
  vitest: "^4.0.18"
112
122
  }
113
123
  };
@@ -2583,7 +2593,7 @@ function collectHashComments(content, options2) {
2583
2593
  function collectComments(sourceFile) {
2584
2594
  const seen = /* @__PURE__ */ new Set();
2585
2595
  const comments3 = [];
2586
- const collect5 = (node) => {
2596
+ const collect6 = (node) => {
2587
2597
  for (const range of [
2588
2598
  ...node.getLeadingCommentRanges(),
2589
2599
  ...node.getTrailingCommentRanges()
@@ -2594,8 +2604,8 @@ function collectComments(sourceFile) {
2594
2604
  comments3.push({ pos, text: range.getText() });
2595
2605
  }
2596
2606
  };
2597
- collect5(sourceFile);
2598
- sourceFile.forEachDescendant(collect5);
2607
+ collect6(sourceFile);
2608
+ sourceFile.forEachDescendant(collect6);
2599
2609
  return comments3;
2600
2610
  }
2601
2611
 
@@ -2780,6 +2790,104 @@ Total: ${findings.length} comment(s)`);
2780
2790
  process.exit(1);
2781
2791
  }
2782
2792
 
2793
+ // src/shared/configHelp.ts
2794
+ var documentedKeys = /* @__PURE__ */ new Set();
2795
+ function getDocumentedConfigKeys() {
2796
+ return documentedKeys;
2797
+ }
2798
+ function renderConfigHelp(entries, preamble) {
2799
+ const width = Math.max(...entries.map((entry) => entry.setter.length));
2800
+ const lines = entries.map(
2801
+ (entry) => ` ${entry.setter.padEnd(width)} # ${entry.note}`
2802
+ );
2803
+ const body = preamble ? ["", preamble, "", "Config:", ...lines] : ["", "Config:", ...lines];
2804
+ return body.join("\n");
2805
+ }
2806
+ function configHelp(command, entries, preamble) {
2807
+ for (const entry of entries) documentedKeys.add(entry.key);
2808
+ return command.addHelpText(
2809
+ "after",
2810
+ () => renderConfigHelp(entries, preamble)
2811
+ );
2812
+ }
2813
+
2814
+ // src/shared/enumerateConfigLeafKeys.ts
2815
+ var WRAPPER_TYPES = /* @__PURE__ */ new Set([
2816
+ "optional",
2817
+ "default",
2818
+ "nullable",
2819
+ "nullish",
2820
+ "readonly",
2821
+ "catch"
2822
+ ]);
2823
+ function unwrap(node) {
2824
+ let current = node;
2825
+ while (current.def && WRAPPER_TYPES.has(current.def.type ?? "") && current.def.innerType) {
2826
+ current = current.def.innerType;
2827
+ }
2828
+ return current;
2829
+ }
2830
+ function collect(node, prefix2, out) {
2831
+ const unwrapped = unwrap(node);
2832
+ const shape = unwrapped.def?.shape;
2833
+ if (unwrapped.def?.type === "object" && shape) {
2834
+ for (const [key, child] of Object.entries(shape)) {
2835
+ collect(child, prefix2 ? `${prefix2}.${key}` : key, out);
2836
+ }
2837
+ return;
2838
+ }
2839
+ out.push(prefix2);
2840
+ }
2841
+ function enumerateConfigLeafKeys(schema2) {
2842
+ const out = [];
2843
+ collect(schema2, "", out);
2844
+ return out.sort();
2845
+ }
2846
+
2847
+ // src/commands/verify/pendingConfigDocumentation.ts
2848
+ var pendingConfigDocumentation = /* @__PURE__ */ new Set();
2849
+
2850
+ // src/commands/verify/configKeys.ts
2851
+ function section(label2, keys) {
2852
+ if (keys.length === 0) return void 0;
2853
+ const list5 = keys.sort().map((key) => ` ${key}`).join("\n");
2854
+ return `${label2}:
2855
+ ${list5}`;
2856
+ }
2857
+ function configKeys() {
2858
+ const schemaKeys = new Set(enumerateConfigLeafKeys(assistConfigSchema));
2859
+ const documented = getDocumentedConfigKeys();
2860
+ const pending = pendingConfigDocumentation;
2861
+ const problems = [
2862
+ section(
2863
+ "Config keys documented by no command (surface them with configHelp)",
2864
+ [...schemaKeys].filter(
2865
+ (key) => !documented.has(key) && !pending.has(key)
2866
+ )
2867
+ ),
2868
+ section(
2869
+ "Documented config keys not present in assistConfigSchema",
2870
+ [...documented].filter((key) => !schemaKeys.has(key))
2871
+ ),
2872
+ section(
2873
+ "Keys now documented but still in pendingConfigDocumentation (remove them)",
2874
+ [...pending].filter((key) => documented.has(key))
2875
+ ),
2876
+ section(
2877
+ "pendingConfigDocumentation lists keys not in assistConfigSchema (remove them)",
2878
+ [...pending].filter((key) => !schemaKeys.has(key))
2879
+ )
2880
+ ].filter((problem) => problem !== void 0);
2881
+ if (problems.length > 0) {
2882
+ console.log(problems.join("\n\n"));
2883
+ process.exit(1);
2884
+ }
2885
+ console.log(
2886
+ `All ${schemaKeys.size} config keys are surfaced in --help or pending documentation.`
2887
+ );
2888
+ process.exit(0);
2889
+ }
2890
+
2783
2891
  // src/commands/verify/forbiddenStrings/index.ts
2784
2892
  import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
2785
2893
 
@@ -4082,6 +4190,13 @@ function registerBackup(program2) {
4082
4190
  scheduleCommand.command("remove").description(
4083
4191
  "Remove the marked backup schedule block, leaving other crontab lines intact"
4084
4192
  ).action(scheduleRemove);
4193
+ configHelp(backupCommand, [
4194
+ {
4195
+ key: "backup.dir",
4196
+ setter: "assist config set backup.dir ~/.assist/backups",
4197
+ note: "directory dumps are written to (default: ~/.assist/backups)"
4198
+ }
4199
+ ]);
4085
4200
  }
4086
4201
 
4087
4202
  // src/commands/backlog/next.ts
@@ -7855,6 +7970,20 @@ async function web2(options2) {
7855
7970
  });
7856
7971
  }
7857
7972
 
7973
+ // src/commands/backlog/backlogConfigHelp.ts
7974
+ var backlogConfigHelp = [
7975
+ {
7976
+ key: "database.url",
7977
+ setter: "assist config set database.url postgresql://...",
7978
+ note: "Postgres connection string for backlog storage (or ASSIST_DATABASE_URL)"
7979
+ },
7980
+ {
7981
+ key: "subtasks",
7982
+ setter: 'assist config set subtasks.0.title "Review"',
7983
+ note: "default sub-tasks seeded onto every new backlog item"
7984
+ }
7985
+ ];
7986
+
7858
7987
  // src/commands/backlog/addActivity.ts
7859
7988
  import chalk60 from "chalk";
7860
7989
  async function addActivity(id, kind, ref, options2) {
@@ -8114,7 +8243,7 @@ function parseDump(dump) {
8114
8243
  function validateDump({ header, sections }) {
8115
8244
  const tables = header.tables ?? [];
8116
8245
  const missing = tables.find(({ name }) => !sections.has(name))?.name;
8117
- const checks = [
8246
+ const checks2 = [
8118
8247
  [
8119
8248
  header.format === DUMP_FORMAT,
8120
8249
  `Unrecognised dump format "${header.format}" (expected "${DUMP_FORMAT}").`
@@ -8126,7 +8255,7 @@ function validateDump({ header, sections }) {
8126
8255
  [tables.length > 0, "Dump header lists no tables; cannot restore."],
8127
8256
  [!missing, `Invalid dump: missing data section for "${missing}".`]
8128
8257
  ];
8129
- const failure = checks.find(([ok]) => !ok);
8258
+ const failure = checks2.find(([ok]) => !ok);
8130
8259
  if (failure) throw new Error(failure[1]);
8131
8260
  }
8132
8261
 
@@ -9598,11 +9727,11 @@ function resolveChecks(o, current) {
9598
9727
  CHECK_FLAGS
9599
9728
  );
9600
9729
  }
9601
- function buildFields(name, tasks, checks) {
9730
+ function buildFields(name, tasks, checks2) {
9602
9731
  const fields = {
9603
9732
  name,
9604
9733
  task: tasks.items,
9605
- manualCheck: checks.items
9734
+ manualCheck: checks2.items
9606
9735
  };
9607
9736
  if (!fields.name && !fields.task && !fields.manualCheck) {
9608
9737
  return {
@@ -9615,9 +9744,9 @@ function buildFields(name, tasks, checks) {
9615
9744
  function resolvePhaseFields(options2, current) {
9616
9745
  const tasks = resolveTasks(options2, current);
9617
9746
  if (!tasks.ok) return tasks;
9618
- const checks = resolveChecks(options2, current);
9619
- if (!checks.ok) return checks;
9620
- return buildFields(options2.name, tasks, checks);
9747
+ const checks2 = resolveChecks(options2, current);
9748
+ if (!checks2.ok) return checks2;
9749
+ return buildFields(options2.name, tasks, checks2);
9621
9750
  }
9622
9751
 
9623
9752
  // src/commands/backlog/updatePhase.ts
@@ -9646,14 +9775,14 @@ async function updatePhase(id, phase, options2) {
9646
9775
  }
9647
9776
 
9648
9777
  // src/commands/backlog/registerUpdatePhaseCommand.ts
9649
- function collect(value, previous) {
9778
+ function collect2(value, previous) {
9650
9779
  return [...previous, value];
9651
9780
  }
9652
9781
  function registerUpdatePhaseCommand(cmd) {
9653
- cmd.command("update-phase <id> <phase>").description("Modify a plan phase on a backlog item").option("--name <name>", "New phase name").option("--task <task...>", "Replace tasks (repeatable)").option("--manual-check <check...>", "Replace manual checks (repeatable)").option("--add-task <text>", "Append one task (repeatable)", collect, []).option("--edit-task <n> <text...>", "Replace task n (1-based) in place").option("--remove-task <n>", "Remove task n (1-based)").option(
9782
+ cmd.command("update-phase <id> <phase>").description("Modify a plan phase on a backlog item").option("--name <name>", "New phase name").option("--task <task...>", "Replace tasks (repeatable)").option("--manual-check <check...>", "Replace manual checks (repeatable)").option("--add-task <text>", "Append one task (repeatable)", collect2, []).option("--edit-task <n> <text...>", "Replace task n (1-based) in place").option("--remove-task <n>", "Remove task n (1-based)").option(
9654
9783
  "--add-check <text>",
9655
9784
  "Append one manual check (repeatable)",
9656
- collect,
9785
+ collect2,
9657
9786
  []
9658
9787
  ).option(
9659
9788
  "--edit-check <n> <text...>",
@@ -9772,7 +9901,7 @@ async function update(id, options2) {
9772
9901
  }
9773
9902
 
9774
9903
  // src/commands/backlog/registerUpdateCommands.ts
9775
- function collect2(value, previous) {
9904
+ function collect3(value, previous) {
9776
9905
  return [...previous, value];
9777
9906
  }
9778
9907
  function registerUpdateCommands(cmd) {
@@ -9782,7 +9911,7 @@ function registerUpdateCommands(cmd) {
9782
9911
  ).option("--type <type>", "New type (story or bug)").option("--ac <criterion...>", "Replace acceptance criteria (repeatable)").option(
9783
9912
  "--add-ac <text>",
9784
9913
  "Append one acceptance criterion (repeatable)",
9785
- collect2,
9914
+ collect3,
9786
9915
  []
9787
9916
  ).option(
9788
9917
  "--edit-ac <n> <text...>",
@@ -9830,6 +9959,7 @@ function registerBacklog(program2) {
9830
9959
  for (const register of registrars) {
9831
9960
  register(cmd);
9832
9961
  }
9962
+ configHelp(cmd, backlogConfigHelp);
9833
9963
  }
9834
9964
 
9835
9965
  // src/commands/branch/validateSlug.ts
@@ -9878,19 +10008,27 @@ async function branch(slug, options2) {
9878
10008
 
9879
10009
  // src/commands/registerBranch.ts
9880
10010
  function registerBranch(program2) {
9881
- program2.command("branch <slug>").description(
10011
+ const branchCommand = program2.command("branch <slug>").description(
9882
10012
  "Create and switch to a branch off the fresh remote default branch"
9883
- ).option("--jira <key>", "Jira issue key to include in the branch name").addHelpText(
9884
- "after",
9885
- `
9886
- Branch name is assembled as [<prefix>/][<JIRA>-]<slug>, e.g. sw/BAD-671-add-login-form.
9887
-
9888
- Config:
9889
- assist config set branch.prefix sw # optional; prepends "<prefix>/" (omitted when unset)
9890
- assist config set branch.defaultBranch main # optional; overrides the live remote default branch`
9891
- ).action(
10013
+ ).option("--jira <key>", "Jira issue key to include in the branch name").action(
9892
10014
  (slug, options2) => branch(slug, options2)
9893
10015
  );
10016
+ configHelp(
10017
+ branchCommand,
10018
+ [
10019
+ {
10020
+ key: "branch.prefix",
10021
+ setter: "assist config set branch.prefix sw",
10022
+ note: 'optional; prepends "<prefix>/" (omitted when unset)'
10023
+ },
10024
+ {
10025
+ key: "branch.defaultBranch",
10026
+ setter: "assist config set branch.defaultBranch main",
10027
+ note: "optional; overrides the live remote default branch"
10028
+ }
10029
+ ],
10030
+ "Branch name is assembled as [<prefix>/][<JIRA>-]<slug>, e.g. sw/BAD-671-add-login-form."
10031
+ );
9894
10032
  }
9895
10033
 
9896
10034
  // src/commands/cliHook/index.ts
@@ -10943,6 +11081,13 @@ function denyRemove(pattern2, options2) {
10943
11081
  // src/commands/registerDeny.ts
10944
11082
  function registerDeny(parent) {
10945
11083
  const denyCommand = parent.command("deny").description("Manage command deny rules").action(denyList);
11084
+ configHelp(denyCommand, [
11085
+ {
11086
+ key: "deny",
11087
+ setter: "assist deny add <pattern> <message>",
11088
+ note: "command patterns blocked with a correction message"
11089
+ }
11090
+ ]);
10946
11091
  denyCommand.command("add").description("Add a deny rule for a command pattern").argument("<pattern>", "Command prefix to deny").argument("<message>", "Correction message shown to the agent").option("-g, --global", "Write to global ~/.assist.yml").action(denyAdd);
10947
11092
  denyCommand.command("remove").description("Remove a deny rule by pattern").argument("<pattern>", "Command prefix to remove").option("-g, --global", "Remove from global ~/.assist.yml").action(denyRemove);
10948
11093
  denyCommand.command("list").description("List all deny rules").action(denyList);
@@ -10953,6 +11098,13 @@ function registerCliHook(program2) {
10953
11098
  const cmd = program2.command("cli-hook").description("PreToolUse hook for auto-approving read-only CLI commands").action(() => {
10954
11099
  cliHook();
10955
11100
  });
11101
+ configHelp(cmd, [
11102
+ {
11103
+ key: "cliReadVerbs",
11104
+ setter: 'assist config set cliReadVerbs.git "status"',
11105
+ note: "extra per-CLI verbs treated as read-only for auto-approval"
11106
+ }
11107
+ ]);
10956
11108
  cmd.command("check <command>").description("Check whether a command would be auto-approved").option("--tool <tool>", "Tool name to check against", "Bash").action((command, options2) => {
10957
11109
  cliHookCheck(command, options2.tool);
10958
11110
  });
@@ -11698,6 +11850,15 @@ async function analyze(pattern2) {
11698
11850
  await maintainability(searchPattern);
11699
11851
  }
11700
11852
 
11853
+ // src/commands/complexity/complexityConfigHelp.ts
11854
+ var complexityConfigHelp = [
11855
+ {
11856
+ key: "complexity.ignore",
11857
+ setter: 'assist config set complexity.ignore "**/*test.ts*"',
11858
+ note: "globs excluded from maintainability (default: **/*test.ts*)"
11859
+ }
11860
+ ];
11861
+
11701
11862
  // src/commands/registerComplexity.ts
11702
11863
  function registerComplexity(program2) {
11703
11864
  const complexityCommand = program2.command("complexity").description("Analyze TypeScript code complexity metrics").argument("[pattern]").action((pattern2) => {
@@ -11720,6 +11881,7 @@ function registerComplexity(program2) {
11720
11881
  []
11721
11882
  ).action(maintainability);
11722
11883
  complexityCommand.command("sloc [pattern]").description("Count source lines of code per file").option("--threshold <number>", "Max lines threshold", Number.parseInt).action(sloc);
11884
+ configHelp(complexityCommand, complexityConfigHelp);
11723
11885
  }
11724
11886
 
11725
11887
  // src/commands/config/index.ts
@@ -12421,6 +12583,25 @@ function version() {
12421
12583
  console.log(`${chalk127.bold("next:")} ${nextVersion ?? chalk127.dim("none")}`);
12422
12584
  }
12423
12585
 
12586
+ // src/commands/devlog/devlogConfigHelp.ts
12587
+ var devlogConfigHelp = [
12588
+ {
12589
+ key: "devlog.name",
12590
+ setter: "assist config set devlog.name my-repo",
12591
+ note: "override the repo name reported in devlog entries"
12592
+ },
12593
+ {
12594
+ key: "devlog.ignore",
12595
+ setter: 'assist config set devlog.ignore "**/*.lock"',
12596
+ note: "globs excluded when grouping commits"
12597
+ },
12598
+ {
12599
+ key: "devlog.skip",
12600
+ setter: "assist devlog skip 2026-07-10",
12601
+ note: "dates (per repo) omitted from devlog output"
12602
+ }
12603
+ ];
12604
+
12424
12605
  // src/commands/registerDevlog.ts
12425
12606
  function registerDevlog(program2) {
12426
12607
  const devlogCommand = program2.command("devlog").description("Development log utilities");
@@ -12437,6 +12618,7 @@ function registerDevlog(program2) {
12437
12618
  "Only show repos pushed within N days (default: 30)",
12438
12619
  Number.parseInt
12439
12620
  ).option("--all", "Show all non-archived repos regardless of push date").action(repos);
12621
+ configHelp(devlogCommand, devlogConfigHelp);
12440
12622
  }
12441
12623
 
12442
12624
  // src/commands/dotnet/checkBuildLocks.ts
@@ -13062,6 +13244,13 @@ function registerDotnet(program2) {
13062
13244
  cmd.command("check-locks").description("Check if build output files are locked by a debugger").action(checkBuildLocksCommand);
13063
13245
  cmd.command("deps").description("Show .csproj project dependency tree and solution membership").argument("<csproj>", "Path to a .csproj file").option("--json", "Output as JSON").action(deps);
13064
13246
  cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
13247
+ configHelp(cmd, [
13248
+ {
13249
+ key: "dotnet.inspect.suppress",
13250
+ setter: "assist config set dotnet.inspect.suppress CSharpWarnings::CS0168",
13251
+ note: "inspection issue-type IDs suppressed by default"
13252
+ }
13253
+ ]);
13065
13254
  }
13066
13255
 
13067
13256
  // src/commands/editHook/index.ts
@@ -13879,6 +14068,13 @@ function registerJira(program2) {
13879
14068
  jiraCommand.command("auth").description("Authenticate with Jira via API token").action(() => jiraAuth());
13880
14069
  jiraCommand.command("ac <issue-key>").description("Print acceptance criteria for a Jira issue").action((issueKey) => acceptanceCriteria(issueKey));
13881
14070
  jiraCommand.command("view <issue-key>").description("Print the title and description of a Jira issue").action((issueKey) => viewIssue(issueKey));
14071
+ configHelp(jiraCommand, [
14072
+ {
14073
+ key: "jira.acField",
14074
+ setter: "assist config set jira.acField customfield_11937",
14075
+ note: "custom field holding acceptance criteria (default: customfield_11937)"
14076
+ }
14077
+ ]);
13882
14078
  }
13883
14079
 
13884
14080
  // src/commands/reviewComments.ts
@@ -14066,6 +14262,13 @@ function registerMermaid(program2) {
14066
14262
  ).action(
14067
14263
  (file, options2) => mermaidExport(file, options2)
14068
14264
  );
14265
+ configHelp(cmd, [
14266
+ {
14267
+ key: "mermaid.krokiUrl",
14268
+ setter: "assist config set mermaid.krokiUrl https://kroki.io",
14269
+ note: "Kroki server used to render diagrams (default: https://kroki.io)"
14270
+ }
14271
+ ]);
14069
14272
  }
14070
14273
 
14071
14274
  // src/commands/netcap/netcap.ts
@@ -15026,9 +15229,9 @@ function parsePrBody(body) {
15026
15229
  return sections;
15027
15230
  }
15028
15231
  function serializePrBody(sections) {
15029
- return sections.map((section2) => `## ${section2.heading}
15232
+ return sections.map((section3) => `## ${section3.heading}
15030
15233
 
15031
- ${section2.content}`).join("\n\n");
15234
+ ${section3.content}`).join("\n\n");
15032
15235
  }
15033
15236
 
15034
15237
  // src/commands/prs/editPrBody.ts
@@ -15076,11 +15279,11 @@ function countSentences(paragraph) {
15076
15279
  }
15077
15280
  function splitParagraphs(body) {
15078
15281
  const paragraphs = [];
15079
- let section2 = "(intro)";
15282
+ let section3 = "(intro)";
15080
15283
  let lines = [];
15081
15284
  const flush = () => {
15082
15285
  if (lines.length > 0) {
15083
- paragraphs.push({ section: section2, lines });
15286
+ paragraphs.push({ section: section3, lines });
15084
15287
  lines = [];
15085
15288
  }
15086
15289
  };
@@ -15088,7 +15291,7 @@ function splitParagraphs(body) {
15088
15291
  const heading = line.match(/^#{1,6}\s+(.*)$/);
15089
15292
  if (heading) {
15090
15293
  flush();
15091
- section2 = heading[1].trim();
15294
+ section3 = heading[1].trim();
15092
15295
  } else if (line.trim() === "") {
15093
15296
  flush();
15094
15297
  } else {
@@ -15748,8 +15951,22 @@ function wontfix(commentId, reason) {
15748
15951
  }
15749
15952
  }
15750
15953
 
15954
+ // src/commands/prs/prsConfigHelp.ts
15955
+ var prsConfigHelp = [
15956
+ {
15957
+ key: "prs.slack",
15958
+ setter: 'assist config set prs.slack "#pull-requests"',
15959
+ note: "Slack channel PRs are announced to (used by /prs-slack)"
15960
+ },
15961
+ {
15962
+ key: "prs.required",
15963
+ setter: "assist config set prs.required true",
15964
+ note: "require a branch when running a backlog item"
15965
+ }
15966
+ ];
15967
+
15751
15968
  // src/commands/registerPrsEdit.ts
15752
- function collect3(value, previous) {
15969
+ function collect4(value, previous) {
15753
15970
  return previous.concat([value]);
15754
15971
  }
15755
15972
  function registerPrsEdit(prsCommand) {
@@ -15758,13 +15975,13 @@ function registerPrsEdit(prsCommand) {
15758
15975
  ).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(
15759
15976
  "--resolves <key>",
15760
15977
  "Jira issue key resolved by this PR, appended to ## Why (repeatable)",
15761
- collect3,
15978
+ collect4,
15762
15979
  []
15763
15980
  ).action(edit);
15764
15981
  }
15765
15982
 
15766
15983
  // src/commands/registerPrsRaise.ts
15767
- function collect4(value, previous) {
15984
+ function collect5(value, previous) {
15768
15985
  return previous.concat([value]);
15769
15986
  }
15770
15987
  function registerPrsRaise(prsCommand) {
@@ -15773,20 +15990,20 @@ function registerPrsRaise(prsCommand) {
15773
15990
  ).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(
15774
15991
  "--resolves <key>",
15775
15992
  "Jira issue key resolved by this PR, appended to ## Why (repeatable)",
15776
- collect4,
15993
+ collect5,
15777
15994
  []
15778
15995
  ).option(
15779
15996
  "--force",
15780
15997
  "Overwrite the title and body of an existing pull request"
15781
- ).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)", collect4, []).option(
15998
+ ).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)", collect5, []).option(
15782
15999
  "-a, --assignee <login>",
15783
16000
  "Assign a person by login (repeatable)",
15784
- collect4,
16001
+ collect5,
15785
16002
  []
15786
16003
  ).option(
15787
16004
  "-r, --reviewer <handle>",
15788
16005
  "Request a review (repeatable)",
15789
- collect4,
16006
+ collect5,
15790
16007
  []
15791
16008
  ).option("-m, --milestone <name>", "Add the pull request to a milestone").action(raise);
15792
16009
  }
@@ -15811,6 +16028,7 @@ function registerPrs(program2) {
15811
16028
  prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path58, line, body) => {
15812
16029
  comment2(path58, Number.parseInt(line, 10), body);
15813
16030
  });
16031
+ configHelp(prsCommand, prsConfigHelp);
15814
16032
  }
15815
16033
 
15816
16034
  // src/commands/ravendb/ravendbAuth.ts
@@ -16145,6 +16363,20 @@ async function ravendbCollections(connectionName) {
16145
16363
  }
16146
16364
  }
16147
16365
 
16366
+ // src/commands/ravendb/ravendbConfigHelp.ts
16367
+ var ravendbConfigHelp = [
16368
+ {
16369
+ key: "ravendb.connections",
16370
+ setter: "assist ravendb auth add",
16371
+ note: "named RavenDB connections (add/list/remove via ravendb auth)"
16372
+ },
16373
+ {
16374
+ key: "ravendb.defaultConnection",
16375
+ setter: "assist ravendb set-connection <name>",
16376
+ note: "connection used when none is passed"
16377
+ }
16378
+ ];
16379
+
16148
16380
  // src/commands/ravendb/ravendbQuery.ts
16149
16381
  import chalk164 from "chalk";
16150
16382
 
@@ -16233,6 +16465,7 @@ function registerRavendb(program2) {
16233
16465
  (connection, collection, options2) => ravendbQuery(connection, collection, options2)
16234
16466
  );
16235
16467
  cmd.command("collections [connection]").description("List collections in a RavenDB database").action((connection) => ravendbCollections(connection));
16468
+ configHelp(cmd, ravendbConfigHelp);
16236
16469
  }
16237
16470
 
16238
16471
  // src/commands/refactor/check/index.ts
@@ -17017,13 +17250,13 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
17017
17250
  // src/commands/refactor/extract/displayPlan.ts
17018
17251
  import path33 from "path";
17019
17252
  import chalk166 from "chalk";
17020
- function section(title) {
17253
+ function section2(title) {
17021
17254
  return `
17022
17255
  ${chalk166.cyan(title)}`;
17023
17256
  }
17024
17257
  function displayImporters(plan2, cwd) {
17025
17258
  if (plan2.importersToUpdate.length === 0) return;
17026
- console.log(section("Update importers:"));
17259
+ console.log(section2("Update importers:"));
17027
17260
  for (const imp of plan2.importersToUpdate) {
17028
17261
  const rel = path33.relative(cwd, imp.file.getFilePath());
17029
17262
  console.log(` ${chalk166.dim(rel)}: \u2192 import from "${imp.relPath}"`);
@@ -17037,18 +17270,18 @@ function displayPlan(functionName, relDest, plan2, cwd) {
17037
17270
  console.log(` ${name}`);
17038
17271
  }
17039
17272
  if (plan2.imports.length > 0) {
17040
- console.log(section("Imports to copy:"));
17273
+ console.log(section2("Imports to copy:"));
17041
17274
  for (const imp of plan2.imports) {
17042
17275
  console.log(` ${formatImportLine(imp)}`);
17043
17276
  }
17044
17277
  }
17045
17278
  if (plan2.exportedDeps.length > 0) {
17046
- console.log(section("New imports from source:"));
17279
+ console.log(section2("New imports from source:"));
17047
17280
  console.log(
17048
17281
  ` import { ${plan2.exportedDeps.join(", ")} } from "${plan2.sourceRelPath}";`
17049
17282
  );
17050
17283
  }
17051
- console.log(section("Source file changes:"));
17284
+ console.log(section2("Source file changes:"));
17052
17285
  console.log(` Remove: ${plan2.extractedNames.join(", ")}`);
17053
17286
  if (plan2.sourceNeedsReimport) {
17054
17287
  console.log(
@@ -17057,7 +17290,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
17057
17290
  }
17058
17291
  displayImporters(plan2, cwd);
17059
17292
  if (plan2.barrel) {
17060
- console.log(section("Barrel export:"));
17293
+ console.log(section2("Barrel export:"));
17061
17294
  console.log(
17062
17295
  ` Add: export { ${functionName} } from "${plan2.barrelRelPath}";`
17063
17296
  );
@@ -17826,6 +18059,15 @@ async function restructure(pattern2, options2 = {}) {
17826
18059
  }
17827
18060
  }
17828
18061
 
18062
+ // src/commands/refactor/refactorConfigHelp.ts
18063
+ var refactorConfigHelp = [
18064
+ {
18065
+ key: "restructure.ignore",
18066
+ setter: 'assist config set restructure.ignore "src/generated/**"',
18067
+ note: "globs excluded from restructure coupling analysis"
18068
+ }
18069
+ ];
18070
+
17829
18071
  // src/commands/registerRefactor.ts
17830
18072
  function registerCheck(parent) {
17831
18073
  parent.command("check [pattern]").description("Check for files that exceed the maximum line count").option("--modified", "Check only staged and unstaged files").option("--staged", "Check only staged files").option("--unstaged", "Check only unstaged files").option(
@@ -17842,13 +18084,14 @@ function registerRename(parent) {
17842
18084
  ).option("--apply", "Execute the rename (default: dry-run)").action(renameSymbol);
17843
18085
  }
17844
18086
  function registerRestructure(parent) {
17845
- parent.command("restructure [pattern]").description(
18087
+ const restructureCommand = parent.command("restructure [pattern]").description(
17846
18088
  "Analyze import graph and restructure tightly-coupled files into nested directories"
17847
18089
  ).option("--apply", "Execute the restructuring (default: dry-run)").option(
17848
18090
  "--max-depth <number>",
17849
18091
  "Maximum nesting iterations (default: 3)",
17850
18092
  Number.parseInt
17851
18093
  ).action(restructure);
18094
+ configHelp(restructureCommand, refactorConfigHelp);
17852
18095
  }
17853
18096
  function registerRefactor(program2) {
17854
18097
  const refactorCommand = program2.command("refactor").description("Run refactoring checks for code quality");
@@ -19663,6 +19906,20 @@ var seqAuth = createConnectionAuth({
19663
19906
  onFirst: (c) => setDefaultConnection(c.name)
19664
19907
  });
19665
19908
 
19909
+ // src/commands/seq/seqConfigHelp.ts
19910
+ var seqConfigHelp = [
19911
+ {
19912
+ key: "seq.connections",
19913
+ setter: "assist seq auth add",
19914
+ note: "named Seq connections (add/list/remove via seq auth)"
19915
+ },
19916
+ {
19917
+ key: "seq.defaultConnection",
19918
+ setter: "assist seq set-connection <name>",
19919
+ note: "connection used when none is passed"
19920
+ }
19921
+ ];
19922
+
19666
19923
  // src/commands/seq/seqQuery.ts
19667
19924
  import chalk184 from "chalk";
19668
19925
 
@@ -19932,6 +20189,7 @@ function registerSeq(program2) {
19932
20189
  "--to <date>",
19933
20190
  "End of query window (UTC date or relative e.g. 5m, 1h, 2d)"
19934
20191
  ).option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
20192
+ configHelp(cmd, seqConfigHelp);
19935
20193
  }
19936
20194
 
19937
20195
  // src/commands/registerSignal.ts
@@ -20086,6 +20344,20 @@ async function sqlColumns(table, connectionName) {
20086
20344
  }
20087
20345
  }
20088
20346
 
20347
+ // src/commands/sql/sqlConfigHelp.ts
20348
+ var sqlConfigHelp = [
20349
+ {
20350
+ key: "sql.connections",
20351
+ setter: "assist sql auth add",
20352
+ note: "named MSSQL connections (add/list/remove via sql auth)"
20353
+ },
20354
+ {
20355
+ key: "sql.defaultConnection",
20356
+ setter: "assist sql set-connection <name>",
20357
+ note: "connection used when none is passed"
20358
+ }
20359
+ ];
20360
+
20089
20361
  // src/commands/sql/sqlMutate.ts
20090
20362
  import chalk189 from "chalk";
20091
20363
 
@@ -20214,6 +20486,7 @@ function registerSql(program2) {
20214
20486
  ).action(
20215
20487
  (table, connection) => sqlColumns(table, connection)
20216
20488
  );
20489
+ configHelp(cmd, sqlConfigHelp);
20217
20490
  }
20218
20491
 
20219
20492
  // src/commands/transcript/shared.ts
@@ -20549,9 +20822,29 @@ function move(file, options2) {
20549
20822
  console.log(`Summary target: ${summaryPath}`);
20550
20823
  }
20551
20824
 
20825
+ // src/commands/transcript/transcriptConfigHelp.ts
20826
+ var transcriptConfigHelp = [
20827
+ {
20828
+ key: "transcript.vttDir",
20829
+ setter: "assist transcript configure",
20830
+ note: "pick-up directory scanned for raw .vtt files"
20831
+ },
20832
+ {
20833
+ key: "transcript.transcriptsDir",
20834
+ setter: "assist transcript configure",
20835
+ note: "directory dated markdown transcripts are written to"
20836
+ },
20837
+ {
20838
+ key: "transcript.summaryDir",
20839
+ setter: "assist transcript configure",
20840
+ note: "directory generated transcript summaries are written to"
20841
+ }
20842
+ ];
20843
+
20552
20844
  // src/commands/registerTranscript.ts
20553
20845
  function registerTranscript(program2) {
20554
20846
  const transcriptCommand = program2.command("transcript").description("Meeting transcript utilities");
20847
+ configHelp(transcriptCommand, transcriptConfigHelp);
20555
20848
  transcriptCommand.command("configure").description("Configure transcript directories").action(configure);
20556
20849
  transcriptCommand.command("list").description("List raw .vtt filenames waiting in the pick-up directory").action(list4);
20557
20850
  transcriptCommand.command("move <file>").description(
@@ -20559,6 +20852,59 @@ function registerTranscript(program2) {
20559
20852
  ).requiredOption("--date <YYYY-MM-DD>", "meeting date").requiredOption("--client <name>", "client name").action(move);
20560
20853
  }
20561
20854
 
20855
+ // src/commands/registerVerifyChecks.ts
20856
+ var checks = [
20857
+ {
20858
+ name: "hardcoded-colors",
20859
+ description: "Check for hardcoded hex colors in src/",
20860
+ action: hardcodedColors
20861
+ },
20862
+ {
20863
+ name: "block-comments",
20864
+ description: "Fail on any comment on a changed line, whether added or edited",
20865
+ action: blockComments
20866
+ },
20867
+ {
20868
+ name: "no-venv",
20869
+ description: "Check that no venv folders exist in the repo",
20870
+ action: noVenv
20871
+ },
20872
+ {
20873
+ name: "forbidden-strings",
20874
+ description: "Check configured JSON files for values matching forbiddenStrings rules",
20875
+ action: forbiddenStrings
20876
+ },
20877
+ {
20878
+ name: "config-keys",
20879
+ description: "Check every assistConfigSchema key is surfaced in some command's --help via configHelp",
20880
+ action: configKeys
20881
+ }
20882
+ ];
20883
+ function registerVerifyChecks(verifyCommand) {
20884
+ for (const check2 of checks) {
20885
+ verifyCommand.command(check2.name).description(check2.description).action(check2.action);
20886
+ }
20887
+ }
20888
+
20889
+ // src/commands/verify/verifyConfigHelp.ts
20890
+ var verifyConfigHelp = [
20891
+ {
20892
+ key: "blockComments.ignore",
20893
+ setter: 'assist config set blockComments.ignore "**/*.test.ts"',
20894
+ note: "globs exempt from the block-comments check"
20895
+ },
20896
+ {
20897
+ key: "hardcodedColors.ignore",
20898
+ setter: 'assist config set hardcodedColors.ignore "**/theme.ts"',
20899
+ note: "globs exempt from the hardcoded-colors check"
20900
+ },
20901
+ {
20902
+ key: "forbiddenStrings",
20903
+ setter: 'assist config set forbiddenStrings.0.disallowed "secret"',
20904
+ note: "per-file value rules enforced by the forbidden-strings check"
20905
+ }
20906
+ ];
20907
+
20562
20908
  // src/commands/registerVerify.ts
20563
20909
  function runScope(scope, options2) {
20564
20910
  if (scope && scope !== "all") {
@@ -20580,14 +20926,8 @@ function registerVerify(program2) {
20580
20926
  "--package-json",
20581
20927
  "Write scripts to package.json instead of assist.yml"
20582
20928
  ).action(init3);
20583
- verifyCommand.command("hardcoded-colors").description("Check for hardcoded hex colors in src/").action(hardcodedColors);
20584
- verifyCommand.command("block-comments").description(
20585
- "Fail on any comment on a changed line, whether added or edited"
20586
- ).action(blockComments);
20587
- verifyCommand.command("no-venv").description("Check that no venv folders exist in the repo").action(noVenv);
20588
- verifyCommand.command("forbidden-strings").description(
20589
- "Check configured JSON files for values matching forbiddenStrings rules"
20590
- ).action(forbiddenStrings);
20929
+ registerVerifyChecks(verifyCommand);
20930
+ configHelp(verifyCommand, verifyConfigHelp);
20591
20931
  }
20592
20932
 
20593
20933
  // src/commands/voice/devices.ts
@@ -20841,6 +21181,50 @@ function stop2() {
20841
21181
  console.log("Voice daemon stopped");
20842
21182
  }
20843
21183
 
21184
+ // src/commands/voice/voiceConfigHelp.ts
21185
+ var voiceConfigHelp = [
21186
+ {
21187
+ key: "voice.wakeWords",
21188
+ setter: 'assist config set voice.wakeWords "computer"',
21189
+ note: "wake words that activate the daemon (default: computer)"
21190
+ },
21191
+ {
21192
+ key: "voice.mic",
21193
+ setter: "assist config set voice.mic <device>",
21194
+ note: "audio input device (defaults to the system default)"
21195
+ },
21196
+ {
21197
+ key: "voice.cwd",
21198
+ setter: "assist config set voice.cwd <path>",
21199
+ note: "working directory commands are dispatched from"
21200
+ },
21201
+ {
21202
+ key: "voice.modelsDir",
21203
+ setter: "assist config set voice.modelsDir ~/.assist/voice/models",
21204
+ note: "directory VAD/STT models download to"
21205
+ },
21206
+ {
21207
+ key: "voice.lockDir",
21208
+ setter: "assist config set voice.lockDir <path>",
21209
+ note: "directory holding the daemon lock file"
21210
+ },
21211
+ {
21212
+ key: "voice.submitWindows",
21213
+ setter: 'assist config set voice.submitWindows "Code"',
21214
+ note: "window titles where transcriptions auto-submit"
21215
+ },
21216
+ {
21217
+ key: "voice.models.vad",
21218
+ setter: "assist config set voice.models.vad <path>",
21219
+ note: "override the voice-activity-detection model path"
21220
+ },
21221
+ {
21222
+ key: "voice.models.smartTurn",
21223
+ setter: "assist config set voice.models.smartTurn <path>",
21224
+ note: "override the smart-turn model path"
21225
+ }
21226
+ ];
21227
+
20844
21228
  // src/commands/registerVoice.ts
20845
21229
  function registerVoice(program2) {
20846
21230
  const voiceCommand = program2.command("voice").description("Voice interaction daemon for hands-free Claude commands");
@@ -20850,6 +21234,7 @@ function registerVoice(program2) {
20850
21234
  voiceCommand.command("status").description("Check voice daemon status").action(status);
20851
21235
  voiceCommand.command("devices").description("List available audio input devices").action(devices);
20852
21236
  voiceCommand.command("logs").description("Tail voice daemon logs").option("-n, --lines <count>", "Number of lines to show", "20").action((options2) => logs(options2));
21237
+ configHelp(voiceCommand, voiceConfigHelp);
20853
21238
  }
20854
21239
 
20855
21240
  // src/commands/roam/auth.ts
@@ -21080,8 +21465,82 @@ function registerRoam(program2) {
21080
21465
  roamCommand.command("stop-claude-code-icon").description("Signal Claude Code session stop to Roam local API").action(stopClaudeCodeIcon);
21081
21466
  roamCommand.command("show-codex-icon").description("Forward Codex hook activity to Roam local API").action(showCodexIcon);
21082
21467
  roamCommand.command("stop-codex-icon").description("Signal Codex session stop to Roam local API").action(stopCodexIcon);
21468
+ configHelp(roamCommand, [
21469
+ {
21470
+ key: "roam.clientId",
21471
+ setter: "assist roam auth",
21472
+ note: "OAuth client ID (written by the auth flow)"
21473
+ },
21474
+ {
21475
+ key: "roam.clientSecret",
21476
+ setter: "assist roam auth",
21477
+ note: "OAuth client secret (written by the auth flow)"
21478
+ },
21479
+ {
21480
+ key: "roam.accessToken",
21481
+ setter: "assist roam auth",
21482
+ note: "OAuth access token (managed by the auth flow)"
21483
+ },
21484
+ {
21485
+ key: "roam.refreshToken",
21486
+ setter: "assist roam auth",
21487
+ note: "OAuth refresh token (managed by the auth flow)"
21488
+ },
21489
+ {
21490
+ key: "roam.tokenExpiresAt",
21491
+ setter: "assist roam auth",
21492
+ note: "access-token expiry epoch (managed by the auth flow)"
21493
+ }
21494
+ ]);
21083
21495
  }
21084
21496
 
21497
+ // src/commands/rootConfigHelp.ts
21498
+ var rootConfigHelp = {
21499
+ sync: [
21500
+ {
21501
+ key: "sync.autoConfirm",
21502
+ setter: "assist config set sync.autoConfirm true",
21503
+ note: "skip the settings.json overwrite prompt"
21504
+ }
21505
+ ],
21506
+ commit: [
21507
+ {
21508
+ key: "commit.conventional",
21509
+ setter: "assist config set commit.conventional true",
21510
+ note: "enforce conventional commit message format"
21511
+ },
21512
+ {
21513
+ key: "commit.pull",
21514
+ setter: "assist config set commit.pull true",
21515
+ note: "pull before committing"
21516
+ },
21517
+ {
21518
+ key: "commit.push",
21519
+ setter: "assist config set commit.push true",
21520
+ note: "push after committing"
21521
+ },
21522
+ {
21523
+ key: "commit.expectedBranch",
21524
+ setter: "assist config set commit.expectedBranch main",
21525
+ note: "warn when committing off this branch"
21526
+ }
21527
+ ],
21528
+ notify: [
21529
+ {
21530
+ key: "notify.enabled",
21531
+ setter: "assist config set notify.enabled false",
21532
+ note: "enable or disable desktop notifications (default: enabled)"
21533
+ }
21534
+ ],
21535
+ screenshot: [
21536
+ {
21537
+ key: "screenshot.outputDir",
21538
+ setter: "assist config set screenshot.outputDir ./screenshots",
21539
+ note: "directory screenshots are written to (default: ./screenshots)"
21540
+ }
21541
+ ]
21542
+ };
21543
+
21085
21544
  // src/commands/run/index.ts
21086
21545
  import { resolve as resolve14 } from "path";
21087
21546
 
@@ -21438,12 +21897,8 @@ function remove() {
21438
21897
  console.log(`Removed run configuration: ${name}`);
21439
21898
  }
21440
21899
 
21441
- // src/commands/run/registerRun.ts
21442
- function registerRun(program2) {
21443
- const runCommand = program2.command("run").description("Run a configured command from assist.yml").argument("[name]", "Name of the configured command").argument("[args...]", "Arguments to pass to the command").allowUnknownOption().addHelpText(
21444
- "after",
21445
- "\nAn a-prefixed item id (e.g. a555) with no matching command is an alias for\n'assist backlog run <id>' (forwards --write/--no-write/-w)."
21446
- ).addHelpText("after", () => formatConfiguredCommands()).action((name, args) => run3(name, args));
21900
+ // src/commands/run/registerRunSubcommands.ts
21901
+ function registerRunSubcommands(runCommand) {
21447
21902
  runCommand.command("list").description("List configured run commands").option("-v, --verbose", "Show full command details").action((opts) => listRunConfigs(!!opts.verbose));
21448
21903
  runCommand.command("add").description("Add a new run configuration to assist.yml").argument("<name>", "Name for the run configuration").argument("<command>", "Command to execute").argument("[args...]", "Static args to pass to the command").option(
21449
21904
  "--cwd <dir>",
@@ -21456,6 +21911,25 @@ function registerRun(program2) {
21456
21911
  runCommand.command("remove").description("Remove a run configuration from assist.yml").argument("<name>", "Name of the run configuration to remove").action(() => remove());
21457
21912
  }
21458
21913
 
21914
+ // src/commands/run/runConfigHelp.ts
21915
+ var runConfigHelp = [
21916
+ {
21917
+ key: "run",
21918
+ setter: "assist run add <name> <command>",
21919
+ note: "configured commands runnable via assist run <name>"
21920
+ }
21921
+ ];
21922
+
21923
+ // src/commands/run/registerRun.ts
21924
+ function registerRun(program2) {
21925
+ const runCommand = program2.command("run").description("Run a configured command from assist.yml").argument("[name]", "Name of the configured command").argument("[args...]", "Arguments to pass to the command").allowUnknownOption().addHelpText(
21926
+ "after",
21927
+ "\nAn a-prefixed item id (e.g. a555) with no matching command is an alias for\n'assist backlog run <id>' (forwards --write/--no-write/-w)."
21928
+ ).addHelpText("after", () => formatConfiguredCommands()).action((name, args) => run3(name, args));
21929
+ configHelp(runCommand, runConfigHelp);
21930
+ registerRunSubcommands(runCommand);
21931
+ }
21932
+
21459
21933
  // src/commands/screenshot/index.ts
21460
21934
  import { execSync as execSync54 } from "child_process";
21461
21935
  import { existsSync as existsSync51, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
@@ -24492,6 +24966,28 @@ function registerSessions(program2) {
24492
24966
  cmd.command("set-status <status>").description(
24493
24967
  "Report the current session's status to the sessions daemon (used by Claude Code hooks)"
24494
24968
  ).action(setSessionStatus);
24969
+ configHelp(cmd, [
24970
+ {
24971
+ key: "sessions.windowsProjectsRoot",
24972
+ setter: "assist config set sessions.windowsProjectsRoot /mnt/c/Users/you/.claude/projects",
24973
+ note: "WSL path to the Windows .claude/projects root to discover"
24974
+ },
24975
+ {
24976
+ key: "sessions.windowsDaemonHost",
24977
+ setter: "assist config set sessions.windowsDaemonHost 127.0.0.1",
24978
+ note: "host the WSL daemon dials to reach the Windows daemon (default: 127.0.0.1)"
24979
+ },
24980
+ {
24981
+ key: "sessions.windowsDaemonPort",
24982
+ setter: "assist config set sessions.windowsDaemonPort 51764",
24983
+ note: "TCP port the Windows daemon listens on (default: 51764)"
24984
+ },
24985
+ {
24986
+ key: "sessions.windowsVersionCheck",
24987
+ setter: "assist config set sessions.windowsVersionCheck block",
24988
+ note: "Windows daemon version mismatch handling: block | warn | off"
24989
+ }
24990
+ ]);
24495
24991
  }
24496
24992
 
24497
24993
  // src/commands/statusLine.ts
@@ -24822,9 +25318,11 @@ function reportCliError(error) {
24822
25318
  // src/index.ts
24823
25319
  var program = new Command();
24824
25320
  program.name("assist").description("CLI application").version(package_default.version).option("--no-open", "Do not open a browser on startup").action((options2) => web({ port: "3100", open: options2.open }));
24825
- program.command("sync").description("Copy command files to ~/.claude/commands").option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
25321
+ var syncCommand = program.command("sync").description("Copy command files to ~/.claude/commands").option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
25322
+ configHelp(syncCommand, rootConfigHelp.sync);
24826
25323
  program.command("init").description("Initialize VS Code and verify configurations").action(init5);
24827
- program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);
25324
+ var commitCommand = program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);
25325
+ configHelp(commitCommand, rootConfigHelp.commit);
24828
25326
  registerConfig(program);
24829
25327
  registerRun(program);
24830
25328
  registerNew(program);
@@ -24833,12 +25331,14 @@ lintCommand.command("init").description("Initialize oxlint with baseline linter
24833
25331
  var vscodeCommand = program.command("vscode").description("VS Code configuration utilities");
24834
25332
  vscodeCommand.command("init").description("Add VS Code configuration files").action(init4);
24835
25333
  program.command("status-line").description("Format Claude Code status line from JSON stdin").action(statusLine);
24836
- program.command("notify").description(
25334
+ var notifyCommand = program.command("notify").description(
24837
25335
  "Show notification from Claude Code hook (reads JSON from stdin)"
24838
25336
  ).action(notify);
25337
+ configHelp(notifyCommand, rootConfigHelp.notify);
24839
25338
  program.command("update").description("Update assist to the latest version and sync commands").action(update2);
24840
25339
  program.command("coverage").description("Print global statement coverage percentage").action(coverage);
24841
- program.command("screenshot").description("Capture a screenshot of a running application window").argument("<process>", "Name of the running process (e.g. notepad, code)").action(screenshot);
25340
+ var screenshotCommand = program.command("screenshot").description("Capture a screenshot of a running application window").argument("<process>", "Name of the running process (e.g. notepad, code)").action(screenshot);
25341
+ configHelp(screenshotCommand, rootConfigHelp.screenshot);
24842
25342
  registerActivity(program);
24843
25343
  registerBackup(program);
24844
25344
  registerCliHook(program);