@staff0rd/assist 0.124.0 → 0.126.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.124.0",
9
+ version: "0.126.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -179,6 +179,16 @@ var assistConfigSchema = z.strictObject({
179
179
  ).default([]),
180
180
  defaultConnection: z.string().optional()
181
181
  }).optional(),
182
+ seq: z.strictObject({
183
+ connections: z.array(
184
+ z.strictObject({
185
+ name: z.string(),
186
+ url: z.string(),
187
+ apiToken: z.string()
188
+ })
189
+ ).default([]),
190
+ defaultConnection: z.string().optional()
191
+ }).optional(),
182
192
  voice: z.strictObject({
183
193
  wakeWords: z.array(z.string()).default(DEFAULT_WAKE_WORDS),
184
194
  mic: z.string().optional(),
@@ -4710,9 +4720,7 @@ async function inSln(csprojPath) {
4710
4720
  }
4711
4721
 
4712
4722
  // src/commands/dotnet/inspect.ts
4713
- import { existsSync as existsSync23 } from "fs";
4714
- import path26 from "path";
4715
- import chalk55 from "chalk";
4723
+ import chalk57 from "chalk";
4716
4724
 
4717
4725
  // src/shared/formatElapsed.ts
4718
4726
  function formatElapsed(ms) {
@@ -4759,6 +4767,7 @@ ${issues.length} issue(s) found`));
4759
4767
 
4760
4768
  // src/commands/dotnet/deadCodeRules.ts
4761
4769
  var deadCodeRules = /* @__PURE__ */ new Set([
4770
+ // JetBrains ReSharper rules
4762
4771
  "UnusedMember.Local",
4763
4772
  "UnusedType.Local",
4764
4773
  "UnusedParameter.Global",
@@ -4773,7 +4782,27 @@ var deadCodeRules = /* @__PURE__ */ new Set([
4773
4782
  "UnusedMethodReturnValue.Global",
4774
4783
  "UnusedMethodReturnValue.Local",
4775
4784
  "UnusedVariable.Compiler",
4776
- "RedundantUsingDirective"
4785
+ "RedundantUsingDirective",
4786
+ // Roslyn compiler diagnostics
4787
+ "CS0168",
4788
+ // Variable declared but never used
4789
+ "CS0169",
4790
+ // Field is never used
4791
+ "CS0219",
4792
+ // Variable assigned but never used
4793
+ "CS0414",
4794
+ // Field assigned but never read
4795
+ "CS8321",
4796
+ // Local function declared but never used
4797
+ // Roslyn IDE analyzers
4798
+ "IDE0051",
4799
+ // Private member is unused
4800
+ "IDE0052",
4801
+ // Private member can be removed (value never read)
4802
+ "IDE0059",
4803
+ // Unnecessary assignment
4804
+ "IDE0060"
4805
+ // Remove unused parameter
4777
4806
  ]);
4778
4807
 
4779
4808
  // src/commands/dotnet/filterIssues.ts
@@ -4784,6 +4813,27 @@ function filterIssues(issues, all) {
4784
4813
  );
4785
4814
  }
4786
4815
 
4816
+ // src/commands/dotnet/getChangedCsFiles.ts
4817
+ import { execSync as execSync20 } from "child_process";
4818
+ function getChangedCsFiles(ref, base) {
4819
+ let cmd;
4820
+ if (base) {
4821
+ cmd = `git diff --name-only ${base}...HEAD`;
4822
+ } else if (ref) {
4823
+ cmd = `git diff --name-only ${ref}~1 ${ref}`;
4824
+ } else {
4825
+ cmd = "git diff --name-only HEAD";
4826
+ }
4827
+ const output = execSync20(cmd, { encoding: "utf-8" }).trim();
4828
+ if (output === "") return [];
4829
+ return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
4830
+ }
4831
+
4832
+ // src/commands/dotnet/resolveSolution.ts
4833
+ import { existsSync as existsSync22 } from "fs";
4834
+ import path25 from "path";
4835
+ import chalk54 from "chalk";
4836
+
4787
4837
  // src/commands/dotnet/findSolution.ts
4788
4838
  import { readdirSync as readdirSync4 } from "fs";
4789
4839
  import { dirname as dirname16, join as join17 } from "path";
@@ -4817,20 +4867,27 @@ function findSolution() {
4817
4867
  process.exit(1);
4818
4868
  }
4819
4869
 
4820
- // src/commands/dotnet/getChangedCsFiles.ts
4821
- import { execSync as execSync20 } from "child_process";
4822
- function getChangedCsFiles(ref, base) {
4823
- let cmd;
4824
- if (base) {
4825
- cmd = `git diff --name-only ${base}...HEAD`;
4826
- } else if (ref) {
4827
- cmd = `git diff --name-only ${ref}~1 ${ref}`;
4828
- } else {
4829
- cmd = "git diff --name-only HEAD";
4870
+ // src/commands/dotnet/resolveSolution.ts
4871
+ function resolveSolution(sln) {
4872
+ if (sln) {
4873
+ const resolved = path25.resolve(sln);
4874
+ if (!existsSync22(resolved)) {
4875
+ console.error(chalk54.red(`Solution file not found: ${resolved}`));
4876
+ process.exit(1);
4877
+ }
4878
+ return resolved;
4830
4879
  }
4831
- const output = execSync20(cmd, { encoding: "utf-8" }).trim();
4832
- if (output === "") return [];
4833
- return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
4880
+ return findSolution();
4881
+ }
4882
+
4883
+ // src/commands/dotnet/filterToChangedFiles.ts
4884
+ function filterToChangedFiles(issues, changedFiles) {
4885
+ const normalize = (f) => f.replace(/\\/g, "/").replace(/^file:\/\/\//, "");
4886
+ const changed = changedFiles.map(normalize);
4887
+ return issues.filter((i) => {
4888
+ const file = normalize(i.file);
4889
+ return changed.some((c) => file === c || file.endsWith(`/${c}`));
4890
+ });
4834
4891
  }
4835
4892
 
4836
4893
  // src/commands/dotnet/parseInspectReport.ts
@@ -4854,23 +4911,23 @@ function parseInspectReport(json) {
4854
4911
 
4855
4912
  // src/commands/dotnet/runInspectCode.ts
4856
4913
  import { execSync as execSync21 } from "child_process";
4857
- import { existsSync as existsSync22, readFileSync as readFileSync20, unlinkSync as unlinkSync3 } from "fs";
4914
+ import { existsSync as existsSync23, readFileSync as readFileSync20, unlinkSync as unlinkSync3 } from "fs";
4858
4915
  import { tmpdir as tmpdir2 } from "os";
4859
- import path25 from "path";
4860
- import chalk54 from "chalk";
4916
+ import path26 from "path";
4917
+ import chalk55 from "chalk";
4861
4918
  function assertJbInstalled() {
4862
4919
  try {
4863
4920
  execSync21("jb inspectcode --version", { stdio: "pipe" });
4864
4921
  } catch {
4865
- console.error(chalk54.red("jb is not installed. Install with:"));
4922
+ console.error(chalk55.red("jb is not installed. Install with:"));
4866
4923
  console.error(
4867
- chalk54.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
4924
+ chalk55.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
4868
4925
  );
4869
4926
  process.exit(1);
4870
4927
  }
4871
4928
  }
4872
4929
  function runInspectCode(slnPath, include, swea) {
4873
- const reportPath = path25.join(tmpdir2(), `inspect-${Date.now()}.xml`);
4930
+ const reportPath = path26.join(tmpdir2(), `inspect-${Date.now()}.xml`);
4874
4931
  const sweaFlag = swea ? " --swea" : "";
4875
4932
  try {
4876
4933
  execSync21(
@@ -4881,11 +4938,11 @@ function runInspectCode(slnPath, include, swea) {
4881
4938
  if (err && typeof err === "object" && "stderr" in err) {
4882
4939
  process.stderr.write(err.stderr);
4883
4940
  }
4884
- console.error(chalk54.red("jb inspectcode failed"));
4941
+ console.error(chalk55.red("jb inspectcode failed"));
4885
4942
  process.exit(1);
4886
4943
  }
4887
- if (!existsSync22(reportPath)) {
4888
- console.error(chalk54.red("Report file not generated"));
4944
+ if (!existsSync23(reportPath)) {
4945
+ console.error(chalk55.red("Report file not generated"));
4889
4946
  process.exit(1);
4890
4947
  }
4891
4948
  const xml = readFileSync20(reportPath, "utf-8");
@@ -4893,45 +4950,88 @@ function runInspectCode(slnPath, include, swea) {
4893
4950
  return xml;
4894
4951
  }
4895
4952
 
4896
- // src/commands/dotnet/inspect.ts
4897
- function resolveSolution(sln) {
4898
- if (sln) {
4899
- const resolved = path26.resolve(sln);
4900
- if (!existsSync23(resolved)) {
4901
- console.error(chalk55.red(`Solution file not found: ${resolved}`));
4902
- process.exit(1);
4903
- }
4904
- return resolved;
4953
+ // src/commands/dotnet/runRoslynInspect.ts
4954
+ import { execSync as execSync22 } from "child_process";
4955
+ import chalk56 from "chalk";
4956
+ function resolveMsbuildPath() {
4957
+ const config = loadConfig();
4958
+ const buildConfig = config.run?.find((r) => r.name === "build");
4959
+ return buildConfig?.command ?? "msbuild";
4960
+ }
4961
+ function assertMsbuildInstalled() {
4962
+ const msbuild = resolveMsbuildPath();
4963
+ try {
4964
+ execSync22(`"${msbuild}" -version`, { stdio: "pipe" });
4965
+ } catch {
4966
+ console.error(chalk56.red(`msbuild not found at: ${msbuild}`));
4967
+ console.error(
4968
+ chalk56.yellow(
4969
+ "Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
4970
+ )
4971
+ );
4972
+ process.exit(1);
4905
4973
  }
4906
- return findSolution();
4907
4974
  }
4975
+ var DIAG_PATTERN = /^(.+?)\((\d+),\d+\):\s+(error|warning)\s+(\S+):\s+(.+?)(?:\s+\[.+\])?$/gm;
4976
+ function parseMsbuildOutput(output) {
4977
+ const normalized = output.replace(/\r\n/g, "\n");
4978
+ return [...normalized.matchAll(DIAG_PATTERN)].map((m) => ({
4979
+ file: m[1].replace(/\\/g, "/"),
4980
+ line: Number.parseInt(m[2], 10),
4981
+ severity: m[3] === "error" ? "ERROR" : "WARNING",
4982
+ typeId: m[4],
4983
+ message: m[5].trim()
4984
+ }));
4985
+ }
4986
+ function runRoslynInspect(slnPath) {
4987
+ const msbuild = resolveMsbuildPath();
4988
+ let output;
4989
+ try {
4990
+ output = execSync22(
4991
+ `"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
4992
+ { encoding: "utf-8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
4993
+ );
4994
+ } catch (err) {
4995
+ const e = err;
4996
+ output = e.stdout ?? "";
4997
+ }
4998
+ return parseMsbuildOutput(output);
4999
+ }
5000
+
5001
+ // src/commands/dotnet/runEngine.ts
5002
+ function runEngine(resolved, changedFiles, options2) {
5003
+ if (options2.roslyn) {
5004
+ return filterToChangedFiles(runRoslynInspect(resolved), changedFiles);
5005
+ }
5006
+ return parseInspectReport(
5007
+ runInspectCode(resolved, changedFiles.join(";"), !!options2.swea)
5008
+ );
5009
+ }
5010
+
5011
+ // src/commands/dotnet/inspect.ts
4908
5012
  function reportResults(issues, elapsed) {
4909
5013
  if (issues.length > 0) displayIssues(issues);
4910
- else console.log(chalk55.green("No issues found"));
4911
- console.log(chalk55.dim(`Completed in ${formatElapsed(elapsed)}`));
5014
+ else console.log(chalk57.green("No issues found"));
5015
+ console.log(chalk57.dim(`Completed in ${formatElapsed(elapsed)}`));
4912
5016
  if (issues.length > 0) process.exit(1);
4913
5017
  }
4914
5018
  async function inspect(sln, options2) {
4915
5019
  const resolved = resolveSolution(sln);
4916
5020
  checkBuildLocks();
4917
- assertJbInstalled();
5021
+ if (options2.roslyn) assertMsbuildInstalled();
5022
+ else assertJbInstalled();
4918
5023
  const changedFiles = getChangedCsFiles(options2.ref, options2.base);
4919
5024
  if (changedFiles.length === 0) {
4920
- console.log(chalk55.green("No changed .cs files found"));
5025
+ console.log(chalk57.green("No changed .cs files found"));
4921
5026
  return;
4922
5027
  }
4923
5028
  console.log(
4924
- chalk55.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
5029
+ chalk57.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
4925
5030
  );
4926
5031
  const start3 = Date.now();
4927
- const report = runInspectCode(
4928
- resolved,
4929
- changedFiles.join(";"),
4930
- !!options2.swea
4931
- );
5032
+ const issues = runEngine(resolved, changedFiles, options2);
4932
5033
  const elapsed = Date.now() - start3;
4933
- const issues = filterIssues(parseInspectReport(report), !!options2.all);
4934
- reportResults(issues, elapsed);
5034
+ reportResults(filterIssues(issues, !!options2.all), elapsed);
4935
5035
  }
4936
5036
 
4937
5037
  // src/commands/registerDotnet.ts
@@ -4942,14 +5042,14 @@ function registerDotnet(program2) {
4942
5042
  ).argument("[sln]", "Path to a .sln file (auto-detected if omitted)").option("--ref <ref>", "Git commit to inspect (default: working copy)").option(
4943
5043
  "--base <ref>",
4944
5044
  "Compare against a base ref using merge-base (e.g. main); inspects all PR changes"
4945
- ).option("--all", "Show all issues, not just dead code").option("--swea", "Enable solution-wide error analysis").action(inspect);
5045
+ ).option("--all", "Show all issues, not just dead code").option("--swea", "Enable solution-wide error analysis").option("--roslyn", "Use Roslyn analyzers via msbuild instead of JetBrains").action(inspect);
4946
5046
  cmd.command("check-locks").description("Check if build output files are locked by a debugger").action(checkBuildLocksCommand);
4947
5047
  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);
4948
5048
  cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
4949
5049
  }
4950
5050
 
4951
5051
  // src/commands/jira/acceptanceCriteria.ts
4952
- import chalk57 from "chalk";
5052
+ import chalk59 from "chalk";
4953
5053
 
4954
5054
  // src/commands/jira/adfToText.ts
4955
5055
  function renderInline(node) {
@@ -5009,12 +5109,12 @@ function adfToText(doc) {
5009
5109
  }
5010
5110
 
5011
5111
  // src/commands/jira/fetchIssue.ts
5012
- import { execSync as execSync22 } from "child_process";
5013
- import chalk56 from "chalk";
5112
+ import { execSync as execSync23 } from "child_process";
5113
+ import chalk58 from "chalk";
5014
5114
  function fetchIssue(issueKey, fields) {
5015
5115
  let result;
5016
5116
  try {
5017
- result = execSync22(
5117
+ result = execSync23(
5018
5118
  `acli jira workitem view ${issueKey} -f ${fields} --json`,
5019
5119
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
5020
5120
  );
@@ -5023,15 +5123,15 @@ function fetchIssue(issueKey, fields) {
5023
5123
  const stderr = error.stderr;
5024
5124
  if (stderr.includes("unauthorized")) {
5025
5125
  console.error(
5026
- chalk56.red("Jira authentication expired."),
5126
+ chalk58.red("Jira authentication expired."),
5027
5127
  "Run",
5028
- chalk56.cyan("assist jira auth"),
5128
+ chalk58.cyan("assist jira auth"),
5029
5129
  "to re-authenticate."
5030
5130
  );
5031
5131
  process.exit(1);
5032
5132
  }
5033
5133
  }
5034
- console.error(chalk56.red(`Failed to fetch ${issueKey}.`));
5134
+ console.error(chalk58.red(`Failed to fetch ${issueKey}.`));
5035
5135
  process.exit(1);
5036
5136
  }
5037
5137
  return JSON.parse(result);
@@ -5045,7 +5145,7 @@ function acceptanceCriteria(issueKey) {
5045
5145
  const parsed = fetchIssue(issueKey, field);
5046
5146
  const acValue = parsed?.fields?.[field];
5047
5147
  if (!acValue) {
5048
- console.log(chalk57.yellow(`No acceptance criteria found on ${issueKey}.`));
5148
+ console.log(chalk59.yellow(`No acceptance criteria found on ${issueKey}.`));
5049
5149
  return;
5050
5150
  }
5051
5151
  if (typeof acValue === "string") {
@@ -5060,8 +5160,7 @@ function acceptanceCriteria(issueKey) {
5060
5160
  }
5061
5161
 
5062
5162
  // src/commands/jira/jiraAuth.ts
5063
- import { execSync as execSync23 } from "child_process";
5064
- import Enquirer from "enquirer";
5163
+ import { execSync as execSync24 } from "child_process";
5065
5164
 
5066
5165
  // src/shared/loadJson.ts
5067
5166
  import { existsSync as existsSync24, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "fs";
@@ -5092,24 +5191,29 @@ function saveJson(filename, data) {
5092
5191
  writeFileSync17(getStorePath(filename), JSON.stringify(data, null, 2));
5093
5192
  }
5094
5193
 
5194
+ // src/shared/promptInput.ts
5195
+ import Enquirer from "enquirer";
5196
+ var prompts = Enquirer;
5197
+ async function promptInput(name, message, initial) {
5198
+ return new prompts.Input({ name, message, initial }).run();
5199
+ }
5200
+ async function promptPassword(name, message) {
5201
+ return new prompts.Password({ name, message }).run();
5202
+ }
5203
+
5095
5204
  // src/commands/jira/jiraAuth.ts
5096
5205
  var CONFIG_FILE = "jira.json";
5097
5206
  async function promptCredentials(config) {
5098
- const { Input: Input2, Password } = Enquirer;
5099
- const site = await new Input2({
5100
- name: "site",
5101
- message: "Jira site (e.g., mycompany.atlassian.net):",
5102
- initial: config.site
5103
- }).run();
5104
- const email = await new Input2({
5105
- name: "email",
5106
- message: "Email:",
5107
- initial: config.email
5108
- }).run();
5109
- const token = await new Password({
5110
- name: "token",
5111
- message: "API token (https://id.atlassian.com/manage-profile/security/api-tokens):"
5112
- }).run();
5207
+ const site = await promptInput(
5208
+ "site",
5209
+ "Jira site (e.g., mycompany.atlassian.net):",
5210
+ config.site
5211
+ );
5212
+ const email = await promptInput("email", "Email:", config.email);
5213
+ const token = await promptPassword(
5214
+ "token",
5215
+ "API token (https://id.atlassian.com/manage-profile/security/api-tokens):"
5216
+ );
5113
5217
  return { site, email, token };
5114
5218
  }
5115
5219
  async function jiraAuth() {
@@ -5120,7 +5224,7 @@ async function jiraAuth() {
5120
5224
  console.error("All fields are required.");
5121
5225
  process.exit(1);
5122
5226
  }
5123
- execSync23(`acli jira auth login --site ${site} --email "${email}" --token`, {
5227
+ execSync24(`acli jira auth login --site ${site} --email "${email}" --token`, {
5124
5228
  encoding: "utf-8",
5125
5229
  input: token,
5126
5230
  stdio: ["pipe", "inherit", "inherit"]
@@ -5136,14 +5240,14 @@ async function jiraAuth() {
5136
5240
  }
5137
5241
 
5138
5242
  // src/commands/jira/viewIssue.ts
5139
- import chalk58 from "chalk";
5243
+ import chalk60 from "chalk";
5140
5244
  function viewIssue(issueKey) {
5141
5245
  const parsed = fetchIssue(issueKey, "summary,description");
5142
5246
  const fields = parsed?.fields;
5143
5247
  const summary = fields?.summary;
5144
5248
  const description = fields?.description;
5145
5249
  if (summary) {
5146
- console.log(chalk58.bold(summary));
5250
+ console.log(chalk60.bold(summary));
5147
5251
  }
5148
5252
  if (description) {
5149
5253
  if (summary) console.log();
@@ -5157,7 +5261,7 @@ function viewIssue(issueKey) {
5157
5261
  }
5158
5262
  if (!summary && !description) {
5159
5263
  console.log(
5160
- chalk58.yellow(`No summary or description found on ${issueKey}.`)
5264
+ chalk60.yellow(`No summary or description found on ${issueKey}.`)
5161
5265
  );
5162
5266
  }
5163
5267
  }
@@ -5171,7 +5275,7 @@ function registerJira(program2) {
5171
5275
  }
5172
5276
 
5173
5277
  // src/commands/news/add/index.ts
5174
- import chalk59 from "chalk";
5278
+ import chalk61 from "chalk";
5175
5279
  import enquirer5 from "enquirer";
5176
5280
  async function add2(url) {
5177
5281
  if (!url) {
@@ -5194,17 +5298,17 @@ async function add2(url) {
5194
5298
  const news = config.news ?? {};
5195
5299
  const feeds = news.feeds ?? [];
5196
5300
  if (feeds.includes(url)) {
5197
- console.log(chalk59.yellow("Feed already exists in config"));
5301
+ console.log(chalk61.yellow("Feed already exists in config"));
5198
5302
  return;
5199
5303
  }
5200
5304
  feeds.push(url);
5201
5305
  config.news = { ...news, feeds };
5202
5306
  saveGlobalConfig(config);
5203
- console.log(chalk59.green(`Added feed: ${url}`));
5307
+ console.log(chalk61.green(`Added feed: ${url}`));
5204
5308
  }
5205
5309
 
5206
5310
  // src/commands/news/web/handleRequest.ts
5207
- import chalk60 from "chalk";
5311
+ import chalk62 from "chalk";
5208
5312
 
5209
5313
  // src/commands/news/web/shared.ts
5210
5314
  import { decodeHTML } from "entities";
@@ -5340,17 +5444,17 @@ function prefetch() {
5340
5444
  const config = loadConfig();
5341
5445
  const total = config.news.feeds.length;
5342
5446
  if (total === 0) return;
5343
- process.stdout.write(chalk60.dim(`Fetching ${total} feed(s)\u2026 `));
5447
+ process.stdout.write(chalk62.dim(`Fetching ${total} feed(s)\u2026 `));
5344
5448
  prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
5345
5449
  const width = 20;
5346
5450
  const filled = Math.round(done2 / t * width);
5347
5451
  const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
5348
5452
  process.stdout.write(
5349
- `\r${chalk60.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
5453
+ `\r${chalk62.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
5350
5454
  );
5351
5455
  }).then((items) => {
5352
5456
  process.stdout.write(
5353
- `\r${chalk60.green(`Fetched ${items.length} items from ${total} feed(s)`)}
5457
+ `\r${chalk62.green(`Fetched ${items.length} items from ${total} feed(s)`)}
5354
5458
  `
5355
5459
  );
5356
5460
  cachedItems = items;
@@ -5401,7 +5505,7 @@ import { tmpdir as tmpdir3 } from "os";
5401
5505
  import { join as join19 } from "path";
5402
5506
 
5403
5507
  // src/commands/prs/shared.ts
5404
- import { execSync as execSync24 } from "child_process";
5508
+ import { execSync as execSync25 } from "child_process";
5405
5509
  function isGhNotInstalled(error) {
5406
5510
  if (error instanceof Error) {
5407
5511
  const msg = error.message.toLowerCase();
@@ -5417,14 +5521,14 @@ function isNotFound(error) {
5417
5521
  }
5418
5522
  function getRepoInfo() {
5419
5523
  const repoInfo = JSON.parse(
5420
- execSync24("gh repo view --json owner,name", { encoding: "utf-8" })
5524
+ execSync25("gh repo view --json owner,name", { encoding: "utf-8" })
5421
5525
  );
5422
5526
  return { org: repoInfo.owner.login, repo: repoInfo.name };
5423
5527
  }
5424
5528
  function getCurrentPrNumber() {
5425
5529
  try {
5426
5530
  const prInfo = JSON.parse(
5427
- execSync24("gh pr view --json number", { encoding: "utf-8" })
5531
+ execSync25("gh pr view --json number", { encoding: "utf-8" })
5428
5532
  );
5429
5533
  return prInfo.number;
5430
5534
  } catch (error) {
@@ -5438,7 +5542,7 @@ function getCurrentPrNumber() {
5438
5542
  function getCurrentPrNodeId() {
5439
5543
  try {
5440
5544
  const prInfo = JSON.parse(
5441
- execSync24("gh pr view --json id", { encoding: "utf-8" })
5545
+ execSync25("gh pr view --json id", { encoding: "utf-8" })
5442
5546
  );
5443
5547
  return prInfo.id;
5444
5548
  } catch (error) {
@@ -5509,10 +5613,10 @@ function comment(path44, line, body) {
5509
5613
  }
5510
5614
 
5511
5615
  // src/commands/prs/fixed.ts
5512
- import { execSync as execSync26 } from "child_process";
5616
+ import { execSync as execSync27 } from "child_process";
5513
5617
 
5514
5618
  // src/commands/prs/resolveCommentWithReply.ts
5515
- import { execSync as execSync25 } from "child_process";
5619
+ import { execSync as execSync26 } from "child_process";
5516
5620
  import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync19 } from "fs";
5517
5621
  import { tmpdir as tmpdir4 } from "os";
5518
5622
  import { join as join21 } from "path";
@@ -5542,7 +5646,7 @@ function deleteCommentsCache(prNumber) {
5542
5646
 
5543
5647
  // src/commands/prs/resolveCommentWithReply.ts
5544
5648
  function replyToComment(org, repo, prNumber, commentId, message) {
5545
- execSync25(
5649
+ execSync26(
5546
5650
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
5547
5651
  { stdio: ["inherit", "pipe", "inherit"] }
5548
5652
  );
@@ -5552,7 +5656,7 @@ function resolveThread(threadId) {
5552
5656
  const queryFile = join21(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
5553
5657
  writeFileSync19(queryFile, mutation);
5554
5658
  try {
5555
- execSync25(
5659
+ execSync26(
5556
5660
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
5557
5661
  { stdio: ["inherit", "pipe", "inherit"] }
5558
5662
  );
@@ -5604,7 +5708,7 @@ function resolveCommentWithReply(commentId, message) {
5604
5708
  // src/commands/prs/fixed.ts
5605
5709
  function verifySha(sha) {
5606
5710
  try {
5607
- return execSync26(`git rev-parse --verify ${sha}`, {
5711
+ return execSync27(`git rev-parse --verify ${sha}`, {
5608
5712
  encoding: "utf-8"
5609
5713
  }).trim();
5610
5714
  } catch {
@@ -5618,7 +5722,7 @@ function fixed(commentId, sha) {
5618
5722
  const { org, repo } = getRepoInfo();
5619
5723
  const repoUrl = `https://github.com/${org}/${repo}`;
5620
5724
  const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
5621
- execSync26("git push", { stdio: "inherit" });
5725
+ execSync27("git push", { stdio: "inherit" });
5622
5726
  resolveCommentWithReply(commentId, message);
5623
5727
  } catch (error) {
5624
5728
  if (isGhNotInstalled(error)) {
@@ -5636,7 +5740,7 @@ import { join as join23 } from "path";
5636
5740
  import { stringify } from "yaml";
5637
5741
 
5638
5742
  // src/commands/prs/fetchThreadIds.ts
5639
- import { execSync as execSync27 } from "child_process";
5743
+ import { execSync as execSync28 } from "child_process";
5640
5744
  import { unlinkSync as unlinkSync7, writeFileSync as writeFileSync20 } from "fs";
5641
5745
  import { tmpdir as tmpdir5 } from "os";
5642
5746
  import { join as join22 } from "path";
@@ -5645,7 +5749,7 @@ function fetchThreadIds(org, repo, prNumber) {
5645
5749
  const queryFile = join22(tmpdir5(), `gh-query-${Date.now()}.graphql`);
5646
5750
  writeFileSync20(queryFile, THREAD_QUERY);
5647
5751
  try {
5648
- const result = execSync27(
5752
+ const result = execSync28(
5649
5753
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
5650
5754
  { encoding: "utf-8" }
5651
5755
  );
@@ -5667,9 +5771,9 @@ function fetchThreadIds(org, repo, prNumber) {
5667
5771
  }
5668
5772
 
5669
5773
  // src/commands/prs/listComments/fetchReviewComments.ts
5670
- import { execSync as execSync28 } from "child_process";
5774
+ import { execSync as execSync29 } from "child_process";
5671
5775
  function fetchJson(endpoint) {
5672
- const result = execSync28(`gh api --paginate ${endpoint}`, {
5776
+ const result = execSync29(`gh api --paginate ${endpoint}`, {
5673
5777
  encoding: "utf-8"
5674
5778
  });
5675
5779
  if (!result.trim()) return [];
@@ -5711,20 +5815,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
5711
5815
  }
5712
5816
 
5713
5817
  // src/commands/prs/listComments/printComments.ts
5714
- import chalk61 from "chalk";
5818
+ import chalk63 from "chalk";
5715
5819
  function formatForHuman(comment2) {
5716
5820
  if (comment2.type === "review") {
5717
- const stateColor = comment2.state === "APPROVED" ? chalk61.green : comment2.state === "CHANGES_REQUESTED" ? chalk61.red : chalk61.yellow;
5821
+ const stateColor = comment2.state === "APPROVED" ? chalk63.green : comment2.state === "CHANGES_REQUESTED" ? chalk63.red : chalk63.yellow;
5718
5822
  return [
5719
- `${chalk61.cyan("Review")} by ${chalk61.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
5823
+ `${chalk63.cyan("Review")} by ${chalk63.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
5720
5824
  comment2.body,
5721
5825
  ""
5722
5826
  ].join("\n");
5723
5827
  }
5724
5828
  const location = comment2.line ? `:${comment2.line}` : "";
5725
5829
  return [
5726
- `${chalk61.cyan("Line comment")} by ${chalk61.bold(comment2.user)} on ${chalk61.dim(`${comment2.path}${location}`)}`,
5727
- chalk61.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
5830
+ `${chalk63.cyan("Line comment")} by ${chalk63.bold(comment2.user)} on ${chalk63.dim(`${comment2.path}${location}`)}`,
5831
+ chalk63.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
5728
5832
  comment2.body,
5729
5833
  ""
5730
5834
  ].join("\n");
@@ -5808,19 +5912,19 @@ async function listComments() {
5808
5912
  }
5809
5913
 
5810
5914
  // src/commands/prs/prs/index.ts
5811
- import { execSync as execSync29 } from "child_process";
5915
+ import { execSync as execSync30 } from "child_process";
5812
5916
 
5813
5917
  // src/commands/prs/prs/displayPaginated/index.ts
5814
5918
  import enquirer6 from "enquirer";
5815
5919
 
5816
5920
  // src/commands/prs/prs/displayPaginated/printPr.ts
5817
- import chalk62 from "chalk";
5921
+ import chalk64 from "chalk";
5818
5922
  var STATUS_MAP = {
5819
- MERGED: (pr) => pr.mergedAt ? { label: chalk62.magenta("merged"), date: pr.mergedAt } : null,
5820
- CLOSED: (pr) => pr.closedAt ? { label: chalk62.red("closed"), date: pr.closedAt } : null
5923
+ MERGED: (pr) => pr.mergedAt ? { label: chalk64.magenta("merged"), date: pr.mergedAt } : null,
5924
+ CLOSED: (pr) => pr.closedAt ? { label: chalk64.red("closed"), date: pr.closedAt } : null
5821
5925
  };
5822
5926
  function defaultStatus(pr) {
5823
- return { label: chalk62.green("opened"), date: pr.createdAt };
5927
+ return { label: chalk64.green("opened"), date: pr.createdAt };
5824
5928
  }
5825
5929
  function getStatus2(pr) {
5826
5930
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -5829,11 +5933,11 @@ function formatDate(dateStr) {
5829
5933
  return new Date(dateStr).toISOString().split("T")[0];
5830
5934
  }
5831
5935
  function formatPrHeader(pr, status2) {
5832
- return `${chalk62.cyan(`#${pr.number}`)} ${pr.title} ${chalk62.dim(`(${pr.author.login},`)} ${status2.label} ${chalk62.dim(`${formatDate(status2.date)})`)}`;
5936
+ return `${chalk64.cyan(`#${pr.number}`)} ${pr.title} ${chalk64.dim(`(${pr.author.login},`)} ${status2.label} ${chalk64.dim(`${formatDate(status2.date)})`)}`;
5833
5937
  }
5834
5938
  function logPrDetails(pr) {
5835
5939
  console.log(
5836
- chalk62.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
5940
+ chalk64.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
5837
5941
  );
5838
5942
  console.log();
5839
5943
  }
@@ -5914,7 +6018,7 @@ async function displayPaginated(pullRequests) {
5914
6018
  async function prs(options2) {
5915
6019
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
5916
6020
  try {
5917
- const result = execSync29(
6021
+ const result = execSync30(
5918
6022
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
5919
6023
  { encoding: "utf-8" }
5920
6024
  );
@@ -5937,7 +6041,7 @@ async function prs(options2) {
5937
6041
  }
5938
6042
 
5939
6043
  // src/commands/prs/wontfix.ts
5940
- import { execSync as execSync30 } from "child_process";
6044
+ import { execSync as execSync31 } from "child_process";
5941
6045
  function validateReason(reason) {
5942
6046
  const lowerReason = reason.toLowerCase();
5943
6047
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -5954,7 +6058,7 @@ function validateShaReferences(reason) {
5954
6058
  const invalidShas = [];
5955
6059
  for (const sha of shas) {
5956
6060
  try {
5957
- execSync30(`git cat-file -t ${sha}`, { stdio: "pipe" });
6061
+ execSync31(`git cat-file -t ${sha}`, { stdio: "pipe" });
5958
6062
  } catch {
5959
6063
  invalidShas.push(sha);
5960
6064
  }
@@ -5999,7 +6103,52 @@ function registerPrs(program2) {
5999
6103
  }
6000
6104
 
6001
6105
  // src/commands/ravendb/ravendbAuth.ts
6002
- import chalk67 from "chalk";
6106
+ import chalk70 from "chalk";
6107
+
6108
+ // src/shared/createConnectionAuth.ts
6109
+ import chalk65 from "chalk";
6110
+ function listConnections(connections, format2) {
6111
+ if (connections.length === 0) {
6112
+ console.log("No connections configured.");
6113
+ } else {
6114
+ for (const c of connections) {
6115
+ console.log(format2(c));
6116
+ }
6117
+ }
6118
+ }
6119
+ function removeConnection(connections, name, save) {
6120
+ const filtered = connections.filter((c) => c.name !== name);
6121
+ if (filtered.length === connections.length) {
6122
+ console.error(chalk65.red(`Connection "${name}" not found.`));
6123
+ process.exit(1);
6124
+ }
6125
+ save(filtered);
6126
+ console.log(`Removed connection "${name}".`);
6127
+ }
6128
+ async function addConnection(connections, config) {
6129
+ const isFirst = connections.length === 0;
6130
+ const conn = await config.promptNew(connections.map((c) => c.name));
6131
+ connections.push(conn);
6132
+ config.save(connections);
6133
+ if (isFirst && config.onFirst) {
6134
+ config.onFirst(conn);
6135
+ }
6136
+ console.log(`Connection "${conn.name}" saved.`);
6137
+ }
6138
+ function createConnectionAuth(config) {
6139
+ return {
6140
+ async add() {
6141
+ const connections = config.load();
6142
+ await addConnection(connections, config);
6143
+ },
6144
+ list() {
6145
+ listConnections(config.load(), config.format);
6146
+ },
6147
+ remove(name) {
6148
+ removeConnection(config.load(), name, config.save);
6149
+ }
6150
+ };
6151
+ }
6003
6152
 
6004
6153
  // src/commands/ravendb/loadConnections.ts
6005
6154
  function loadConnections() {
@@ -6016,18 +6165,17 @@ function saveConnections(connections) {
6016
6165
  }
6017
6166
 
6018
6167
  // src/commands/ravendb/promptConnection.ts
6019
- import chalk65 from "chalk";
6020
- import Enquirer3 from "enquirer";
6168
+ import chalk68 from "chalk";
6021
6169
 
6022
6170
  // src/commands/ravendb/selectOpSecret.ts
6023
- import chalk64 from "chalk";
6171
+ import chalk67 from "chalk";
6024
6172
  import Enquirer2 from "enquirer";
6025
6173
 
6026
6174
  // src/commands/ravendb/searchItems.ts
6027
- import { execSync as execSync31 } from "child_process";
6028
- import chalk63 from "chalk";
6175
+ import { execSync as execSync32 } from "child_process";
6176
+ import chalk66 from "chalk";
6029
6177
  function opExec(args) {
6030
- return execSync31(`op ${args}`, {
6178
+ return execSync32(`op ${args}`, {
6031
6179
  encoding: "utf-8",
6032
6180
  stdio: ["pipe", "pipe", "pipe"]
6033
6181
  }).trim();
@@ -6038,7 +6186,7 @@ function searchItems(search) {
6038
6186
  items = JSON.parse(opExec("item list --format=json"));
6039
6187
  } catch {
6040
6188
  console.error(
6041
- chalk63.red(
6189
+ chalk66.red(
6042
6190
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
6043
6191
  )
6044
6192
  );
@@ -6052,7 +6200,7 @@ function getItemFields(itemId) {
6052
6200
  const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
6053
6201
  return item.fields.filter((f) => f.reference && f.label);
6054
6202
  } catch {
6055
- console.error(chalk63.red("Failed to get item details from 1Password."));
6203
+ console.error(chalk66.red("Failed to get item details from 1Password."));
6056
6204
  process.exit(1);
6057
6205
  }
6058
6206
  }
@@ -6071,7 +6219,7 @@ async function selectOpSecret(searchTerm) {
6071
6219
  }).run();
6072
6220
  const items = searchItems(search);
6073
6221
  if (items.length === 0) {
6074
- console.error(chalk64.red(`No items found matching "${search}".`));
6222
+ console.error(chalk67.red(`No items found matching "${search}".`));
6075
6223
  process.exit(1);
6076
6224
  }
6077
6225
  const itemId = await selectOne(
@@ -6080,7 +6228,7 @@ async function selectOpSecret(searchTerm) {
6080
6228
  );
6081
6229
  const fields = getItemFields(itemId);
6082
6230
  if (fields.length === 0) {
6083
- console.error(chalk64.red("No fields with references found on this item."));
6231
+ console.error(chalk67.red("No fields with references found on this item."));
6084
6232
  process.exit(1);
6085
6233
  }
6086
6234
  const ref = await selectOne(
@@ -6092,40 +6240,33 @@ async function selectOpSecret(searchTerm) {
6092
6240
 
6093
6241
  // src/commands/ravendb/promptConnection.ts
6094
6242
  async function promptConnection(existingNames) {
6095
- const { Input: Input2 } = Enquirer3;
6096
- const name = await new Input2({
6097
- name: "name",
6098
- message: "Connection name:"
6099
- }).run();
6243
+ const name = await promptInput("name", "Connection name:");
6100
6244
  if (existingNames.includes(name)) {
6101
- console.error(chalk65.red(`Connection "${name}" already exists.`));
6245
+ console.error(chalk68.red(`Connection "${name}" already exists.`));
6102
6246
  process.exit(1);
6103
6247
  }
6104
- const url = await new Input2({
6105
- name: "url",
6106
- message: "RavenDB base URL (e.g. https://host.ravenhq.com):"
6107
- }).run();
6108
- const database = await new Input2({
6109
- name: "database",
6110
- message: "Database name:"
6111
- }).run();
6248
+ const url = await promptInput(
6249
+ "url",
6250
+ "RavenDB base URL (e.g. https://host.ravenhq.com):"
6251
+ );
6252
+ const database = await promptInput("database", "Database name:");
6112
6253
  if (!name || !url || !database) {
6113
- console.error(chalk65.red("All fields are required."));
6254
+ console.error(chalk68.red("All fields are required."));
6114
6255
  process.exit(1);
6115
6256
  }
6116
6257
  const apiKeyRef = await selectOpSecret();
6117
- console.log(chalk65.dim(`Using: ${apiKeyRef}`));
6258
+ console.log(chalk68.dim(`Using: ${apiKeyRef}`));
6118
6259
  return { name, url, database, apiKeyRef };
6119
6260
  }
6120
6261
 
6121
6262
  // src/commands/ravendb/ravendbSetConnection.ts
6122
- import chalk66 from "chalk";
6263
+ import chalk69 from "chalk";
6123
6264
  function ravendbSetConnection(name) {
6124
6265
  const raw = loadGlobalConfigRaw();
6125
6266
  const ravendb = raw.ravendb ?? {};
6126
6267
  const connections = ravendb.connections ?? [];
6127
6268
  if (!connections.some((c) => c.name === name)) {
6128
- console.error(chalk66.red(`Connection "${name}" not found.`));
6269
+ console.error(chalk69.red(`Connection "${name}" not found.`));
6129
6270
  console.error(
6130
6271
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
6131
6272
  );
@@ -6138,45 +6279,19 @@ function ravendbSetConnection(name) {
6138
6279
  }
6139
6280
 
6140
6281
  // src/commands/ravendb/ravendbAuth.ts
6141
- async function ravendbAuth(options2) {
6142
- const connections = loadConnections();
6143
- if (options2.list) {
6144
- if (connections.length === 0) {
6145
- console.log("No RavenDB connections configured.");
6146
- return;
6147
- }
6148
- for (const c of connections) {
6149
- console.log(
6150
- `${chalk67.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`
6151
- );
6152
- }
6153
- return;
6154
- }
6155
- if (options2.remove) {
6156
- const filtered = connections.filter((c) => c.name !== options2.remove);
6157
- if (filtered.length === connections.length) {
6158
- console.error(chalk67.red(`Connection "${options2.remove}" not found.`));
6159
- process.exit(1);
6160
- }
6161
- saveConnections(filtered);
6162
- console.log(`Removed connection "${options2.remove}".`);
6163
- return;
6164
- }
6165
- const isFirst = connections.length === 0;
6166
- const newConnection = await promptConnection(connections.map((c) => c.name));
6167
- connections.push(newConnection);
6168
- saveConnections(connections);
6169
- if (isFirst) {
6170
- ravendbSetConnection(newConnection.name);
6171
- }
6172
- console.log(`Connection "${newConnection.name}" saved.`);
6173
- }
6282
+ var ravendbAuth = createConnectionAuth({
6283
+ load: loadConnections,
6284
+ save: saveConnections,
6285
+ format: (c) => `${chalk70.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
6286
+ promptNew: promptConnection,
6287
+ onFirst: (c) => ravendbSetConnection(c.name)
6288
+ });
6174
6289
 
6175
6290
  // src/commands/ravendb/ravendbCollections.ts
6176
- import chalk71 from "chalk";
6291
+ import chalk74 from "chalk";
6177
6292
 
6178
6293
  // src/commands/ravendb/ravenFetch.ts
6179
- import chalk69 from "chalk";
6294
+ import chalk72 from "chalk";
6180
6295
 
6181
6296
  // src/commands/ravendb/getAccessToken.ts
6182
6297
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -6212,21 +6327,21 @@ ${errorText}`
6212
6327
  }
6213
6328
 
6214
6329
  // src/commands/ravendb/resolveOpSecret.ts
6215
- import { execSync as execSync32 } from "child_process";
6216
- import chalk68 from "chalk";
6330
+ import { execSync as execSync33 } from "child_process";
6331
+ import chalk71 from "chalk";
6217
6332
  function resolveOpSecret(reference) {
6218
6333
  if (!reference.startsWith("op://")) {
6219
- console.error(chalk68.red(`Invalid secret reference: must start with op://`));
6334
+ console.error(chalk71.red(`Invalid secret reference: must start with op://`));
6220
6335
  process.exit(1);
6221
6336
  }
6222
6337
  try {
6223
- return execSync32(`op read "${reference}"`, {
6338
+ return execSync33(`op read "${reference}"`, {
6224
6339
  encoding: "utf-8",
6225
6340
  stdio: ["pipe", "pipe", "pipe"]
6226
6341
  }).trim();
6227
6342
  } catch {
6228
6343
  console.error(
6229
- chalk68.red(
6344
+ chalk71.red(
6230
6345
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
6231
6346
  )
6232
6347
  );
@@ -6253,7 +6368,7 @@ async function ravenFetch(connection, path44) {
6253
6368
  if (!response.ok) {
6254
6369
  const body = await response.text();
6255
6370
  console.error(
6256
- chalk69.red(`RavenDB error: ${response.status} ${response.statusText}`)
6371
+ chalk72.red(`RavenDB error: ${response.status} ${response.statusText}`)
6257
6372
  );
6258
6373
  console.error(body.substring(0, 500));
6259
6374
  process.exit(1);
@@ -6262,7 +6377,7 @@ async function ravenFetch(connection, path44) {
6262
6377
  }
6263
6378
 
6264
6379
  // src/commands/ravendb/resolveConnection.ts
6265
- import chalk70 from "chalk";
6380
+ import chalk73 from "chalk";
6266
6381
  function loadRavendb() {
6267
6382
  const raw = loadGlobalConfigRaw();
6268
6383
  const ravendb = raw.ravendb;
@@ -6276,7 +6391,7 @@ function resolveConnection(name) {
6276
6391
  const connectionName = name ?? defaultConnection;
6277
6392
  if (!connectionName) {
6278
6393
  console.error(
6279
- chalk70.red(
6394
+ chalk73.red(
6280
6395
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
6281
6396
  )
6282
6397
  );
@@ -6284,7 +6399,7 @@ function resolveConnection(name) {
6284
6399
  }
6285
6400
  const connection = connections.find((c) => c.name === connectionName);
6286
6401
  if (!connection) {
6287
- console.error(chalk70.red(`Connection "${connectionName}" not found.`));
6402
+ console.error(chalk73.red(`Connection "${connectionName}" not found.`));
6288
6403
  console.error(
6289
6404
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
6290
6405
  );
@@ -6315,15 +6430,15 @@ async function ravendbCollections(connectionName) {
6315
6430
  return;
6316
6431
  }
6317
6432
  for (const c of collections) {
6318
- console.log(`${chalk71.bold(c.Name)} ${c.CountOfDocuments} docs`);
6433
+ console.log(`${chalk74.bold(c.Name)} ${c.CountOfDocuments} docs`);
6319
6434
  }
6320
6435
  }
6321
6436
 
6322
6437
  // src/commands/ravendb/ravendbQuery.ts
6323
- import chalk73 from "chalk";
6438
+ import chalk76 from "chalk";
6324
6439
 
6325
6440
  // src/commands/ravendb/fetchAllPages.ts
6326
- import chalk72 from "chalk";
6441
+ import chalk75 from "chalk";
6327
6442
 
6328
6443
  // src/commands/ravendb/buildQueryPath.ts
6329
6444
  function buildQueryPath(opts) {
@@ -6361,7 +6476,7 @@ async function fetchAllPages(connection, opts) {
6361
6476
  allResults.push(...results);
6362
6477
  start3 += results.length;
6363
6478
  process.stderr.write(
6364
- `\r${chalk72.dim(`Fetched ${allResults.length}/${totalResults}`)}`
6479
+ `\r${chalk75.dim(`Fetched ${allResults.length}/${totalResults}`)}`
6365
6480
  );
6366
6481
  if (start3 >= totalResults) break;
6367
6482
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -6376,7 +6491,7 @@ async function fetchAllPages(connection, opts) {
6376
6491
  async function ravendbQuery(connectionName, collection, options2) {
6377
6492
  const resolved = resolveArgs(connectionName, collection);
6378
6493
  if (!resolved.collection && !options2.query) {
6379
- console.error(chalk73.red("Provide a collection name or --query filter."));
6494
+ console.error(chalk76.red("Provide a collection name or --query filter."));
6380
6495
  process.exit(1);
6381
6496
  }
6382
6497
  const { collection: col } = resolved;
@@ -6394,7 +6509,10 @@ async function ravendbQuery(connectionName, collection, options2) {
6394
6509
  // src/commands/registerRavendb.ts
6395
6510
  function registerRavendb(program2) {
6396
6511
  const cmd = program2.command("ravendb").description("RavenDB query utilities");
6397
- cmd.command("auth").description("Configure a named RavenDB connection").option("--list", "List configured connections").option("--remove <name>", "Remove a configured connection").action((options2) => ravendbAuth(options2));
6512
+ const auth2 = cmd.command("auth").description("Configure a named RavenDB connection");
6513
+ auth2.command("add").description("Add a new connection").action(() => ravendbAuth.add());
6514
+ auth2.command("list").description("List configured connections").action(() => ravendbAuth.list());
6515
+ auth2.command("remove <name>").description("Remove a configured connection").action((name) => ravendbAuth.remove(name));
6398
6516
  cmd.command("set-connection <name>").description("Set the default connection").action((name) => ravendbSetConnection(name));
6399
6517
  cmd.command("query [connection] [collection]").description("Query a RavenDB collection").option("--page-size <n>", "Documents per page", "25").option(
6400
6518
  "--sort <field>",
@@ -6411,7 +6529,7 @@ import { spawn as spawn3 } from "child_process";
6411
6529
  import * as path27 from "path";
6412
6530
 
6413
6531
  // src/commands/refactor/logViolations.ts
6414
- import chalk74 from "chalk";
6532
+ import chalk77 from "chalk";
6415
6533
  var DEFAULT_MAX_LINES = 100;
6416
6534
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
6417
6535
  if (violations.length === 0) {
@@ -6420,43 +6538,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
6420
6538
  }
6421
6539
  return;
6422
6540
  }
6423
- console.error(chalk74.red(`
6541
+ console.error(chalk77.red(`
6424
6542
  Refactor check failed:
6425
6543
  `));
6426
- console.error(chalk74.red(` The following files exceed ${maxLines} lines:
6544
+ console.error(chalk77.red(` The following files exceed ${maxLines} lines:
6427
6545
  `));
6428
6546
  for (const violation of violations) {
6429
- console.error(chalk74.red(` ${violation.file} (${violation.lines} lines)`));
6547
+ console.error(chalk77.red(` ${violation.file} (${violation.lines} lines)`));
6430
6548
  }
6431
6549
  console.error(
6432
- chalk74.yellow(
6550
+ chalk77.yellow(
6433
6551
  `
6434
6552
  Each file needs to be sensibly refactored, or if there is no sensible
6435
6553
  way to refactor it, ignore it with:
6436
6554
  `
6437
6555
  )
6438
6556
  );
6439
- console.error(chalk74.gray(` assist refactor ignore <file>
6557
+ console.error(chalk77.gray(` assist refactor ignore <file>
6440
6558
  `));
6441
6559
  if (process.env.CLAUDECODE) {
6442
- console.error(chalk74.cyan(`
6560
+ console.error(chalk77.cyan(`
6443
6561
  ## Extracting Code to New Files
6444
6562
  `));
6445
6563
  console.error(
6446
- chalk74.cyan(
6564
+ chalk77.cyan(
6447
6565
  ` When extracting logic from one file to another, consider where the extracted code belongs:
6448
6566
  `
6449
6567
  )
6450
6568
  );
6451
6569
  console.error(
6452
- chalk74.cyan(
6570
+ chalk77.cyan(
6453
6571
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
6454
6572
  original file's domain, create a new folder containing both the original and extracted files.
6455
6573
  `
6456
6574
  )
6457
6575
  );
6458
6576
  console.error(
6459
- chalk74.cyan(
6577
+ chalk77.cyan(
6460
6578
  ` 2. Share common utilities: If the extracted code can be reused across multiple
6461
6579
  domains, move it to a common/shared folder.
6462
6580
  `
@@ -6466,7 +6584,7 @@ Refactor check failed:
6466
6584
  }
6467
6585
 
6468
6586
  // src/commands/refactor/check/getViolations/index.ts
6469
- import { execSync as execSync33 } from "child_process";
6587
+ import { execSync as execSync34 } from "child_process";
6470
6588
  import fs16 from "fs";
6471
6589
  import { minimatch as minimatch4 } from "minimatch";
6472
6590
 
@@ -6516,7 +6634,7 @@ function getGitFiles(options2) {
6516
6634
  }
6517
6635
  const files = /* @__PURE__ */ new Set();
6518
6636
  if (options2.staged || options2.modified) {
6519
- const staged = execSync33("git diff --cached --name-only", {
6637
+ const staged = execSync34("git diff --cached --name-only", {
6520
6638
  encoding: "utf-8"
6521
6639
  });
6522
6640
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -6524,7 +6642,7 @@ function getGitFiles(options2) {
6524
6642
  }
6525
6643
  }
6526
6644
  if (options2.unstaged || options2.modified) {
6527
- const unstaged = execSync33("git diff --name-only", { encoding: "utf-8" });
6645
+ const unstaged = execSync34("git diff --name-only", { encoding: "utf-8" });
6528
6646
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
6529
6647
  files.add(file);
6530
6648
  }
@@ -6612,11 +6730,11 @@ async function check(pattern2, options2) {
6612
6730
 
6613
6731
  // src/commands/refactor/ignore.ts
6614
6732
  import fs17 from "fs";
6615
- import chalk75 from "chalk";
6733
+ import chalk78 from "chalk";
6616
6734
  var REFACTOR_YML_PATH2 = "refactor.yml";
6617
6735
  function ignore(file) {
6618
6736
  if (!fs17.existsSync(file)) {
6619
- console.error(chalk75.red(`Error: File does not exist: ${file}`));
6737
+ console.error(chalk78.red(`Error: File does not exist: ${file}`));
6620
6738
  process.exit(1);
6621
6739
  }
6622
6740
  const content = fs17.readFileSync(file, "utf-8");
@@ -6632,7 +6750,7 @@ function ignore(file) {
6632
6750
  fs17.writeFileSync(REFACTOR_YML_PATH2, entry);
6633
6751
  }
6634
6752
  console.log(
6635
- chalk75.green(
6753
+ chalk78.green(
6636
6754
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
6637
6755
  )
6638
6756
  );
@@ -6640,7 +6758,7 @@ function ignore(file) {
6640
6758
 
6641
6759
  // src/commands/refactor/rename/index.ts
6642
6760
  import path28 from "path";
6643
- import chalk76 from "chalk";
6761
+ import chalk79 from "chalk";
6644
6762
  import { Project as Project2 } from "ts-morph";
6645
6763
  async function rename(source, destination, options2 = {}) {
6646
6764
  const sourcePath = path28.resolve(source);
@@ -6653,22 +6771,22 @@ async function rename(source, destination, options2 = {}) {
6653
6771
  });
6654
6772
  const sourceFile = project.getSourceFile(sourcePath);
6655
6773
  if (!sourceFile) {
6656
- console.log(chalk76.red(`File not found in project: ${source}`));
6774
+ console.log(chalk79.red(`File not found in project: ${source}`));
6657
6775
  process.exit(1);
6658
6776
  }
6659
- console.log(chalk76.bold(`Rename: ${relSource} \u2192 ${relDest}`));
6777
+ console.log(chalk79.bold(`Rename: ${relSource} \u2192 ${relDest}`));
6660
6778
  if (options2.apply) {
6661
6779
  sourceFile.move(destPath);
6662
6780
  await project.save();
6663
- console.log(chalk76.green("Done"));
6781
+ console.log(chalk79.green("Done"));
6664
6782
  } else {
6665
- console.log(chalk76.dim("Dry run. Use --apply to execute."));
6783
+ console.log(chalk79.dim("Dry run. Use --apply to execute."));
6666
6784
  }
6667
6785
  }
6668
6786
 
6669
6787
  // src/commands/refactor/renameSymbol/index.ts
6670
6788
  import path30 from "path";
6671
- import chalk77 from "chalk";
6789
+ import chalk80 from "chalk";
6672
6790
  import { Project as Project3 } from "ts-morph";
6673
6791
 
6674
6792
  // src/commands/refactor/renameSymbol/findSymbol.ts
@@ -6717,38 +6835,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
6717
6835
  const project = new Project3({ tsConfigFilePath: tsConfigPath });
6718
6836
  const sourceFile = project.getSourceFile(filePath);
6719
6837
  if (!sourceFile) {
6720
- console.log(chalk77.red(`File not found in project: ${file}`));
6838
+ console.log(chalk80.red(`File not found in project: ${file}`));
6721
6839
  process.exit(1);
6722
6840
  }
6723
6841
  const symbol = findSymbol(sourceFile, oldName);
6724
6842
  if (!symbol) {
6725
- console.log(chalk77.red(`Symbol "${oldName}" not found in ${file}`));
6843
+ console.log(chalk80.red(`Symbol "${oldName}" not found in ${file}`));
6726
6844
  process.exit(1);
6727
6845
  }
6728
6846
  const grouped = groupReferences(symbol, cwd);
6729
6847
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
6730
6848
  console.log(
6731
- chalk77.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
6849
+ chalk80.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
6732
6850
  `)
6733
6851
  );
6734
6852
  for (const [refFile, lines] of grouped) {
6735
6853
  console.log(
6736
- ` ${chalk77.dim(refFile)}: lines ${chalk77.cyan(lines.join(", "))}`
6854
+ ` ${chalk80.dim(refFile)}: lines ${chalk80.cyan(lines.join(", "))}`
6737
6855
  );
6738
6856
  }
6739
6857
  if (options2.apply) {
6740
6858
  symbol.rename(newName);
6741
6859
  await project.save();
6742
- console.log(chalk77.green(`
6860
+ console.log(chalk80.green(`
6743
6861
  Renamed ${oldName} \u2192 ${newName}`));
6744
6862
  } else {
6745
- console.log(chalk77.dim("\nDry run. Use --apply to execute."));
6863
+ console.log(chalk80.dim("\nDry run. Use --apply to execute."));
6746
6864
  }
6747
6865
  }
6748
6866
 
6749
6867
  // src/commands/refactor/restructure/index.ts
6750
6868
  import path39 from "path";
6751
- import chalk80 from "chalk";
6869
+ import chalk83 from "chalk";
6752
6870
 
6753
6871
  // src/commands/refactor/restructure/buildImportGraph/index.ts
6754
6872
  import path31 from "path";
@@ -6991,50 +7109,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
6991
7109
 
6992
7110
  // src/commands/refactor/restructure/displayPlan.ts
6993
7111
  import path35 from "path";
6994
- import chalk78 from "chalk";
7112
+ import chalk81 from "chalk";
6995
7113
  function relPath(filePath) {
6996
7114
  return path35.relative(process.cwd(), filePath);
6997
7115
  }
6998
7116
  function displayMoves(plan) {
6999
7117
  if (plan.moves.length === 0) return;
7000
- console.log(chalk78.bold("\nFile moves:"));
7118
+ console.log(chalk81.bold("\nFile moves:"));
7001
7119
  for (const move of plan.moves) {
7002
7120
  console.log(
7003
- ` ${chalk78.red(relPath(move.from))} \u2192 ${chalk78.green(relPath(move.to))}`
7121
+ ` ${chalk81.red(relPath(move.from))} \u2192 ${chalk81.green(relPath(move.to))}`
7004
7122
  );
7005
- console.log(chalk78.dim(` ${move.reason}`));
7123
+ console.log(chalk81.dim(` ${move.reason}`));
7006
7124
  }
7007
7125
  }
7008
7126
  function displayRewrites(rewrites) {
7009
7127
  if (rewrites.length === 0) return;
7010
7128
  const affectedFiles = new Set(rewrites.map((r) => r.file));
7011
- console.log(chalk78.bold(`
7129
+ console.log(chalk81.bold(`
7012
7130
  Import rewrites (${affectedFiles.size} files):`));
7013
7131
  for (const file of affectedFiles) {
7014
- console.log(` ${chalk78.cyan(relPath(file))}:`);
7132
+ console.log(` ${chalk81.cyan(relPath(file))}:`);
7015
7133
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
7016
7134
  (r) => r.file === file
7017
7135
  )) {
7018
7136
  console.log(
7019
- ` ${chalk78.red(`"${oldSpecifier}"`)} \u2192 ${chalk78.green(`"${newSpecifier}"`)}`
7137
+ ` ${chalk81.red(`"${oldSpecifier}"`)} \u2192 ${chalk81.green(`"${newSpecifier}"`)}`
7020
7138
  );
7021
7139
  }
7022
7140
  }
7023
7141
  }
7024
7142
  function displayPlan(plan) {
7025
7143
  if (plan.warnings.length > 0) {
7026
- console.log(chalk78.yellow("\nWarnings:"));
7027
- for (const w of plan.warnings) console.log(chalk78.yellow(` ${w}`));
7144
+ console.log(chalk81.yellow("\nWarnings:"));
7145
+ for (const w of plan.warnings) console.log(chalk81.yellow(` ${w}`));
7028
7146
  }
7029
7147
  if (plan.newDirectories.length > 0) {
7030
- console.log(chalk78.bold("\nNew directories:"));
7148
+ console.log(chalk81.bold("\nNew directories:"));
7031
7149
  for (const dir of plan.newDirectories)
7032
- console.log(chalk78.green(` ${dir}/`));
7150
+ console.log(chalk81.green(` ${dir}/`));
7033
7151
  }
7034
7152
  displayMoves(plan);
7035
7153
  displayRewrites(plan.rewrites);
7036
7154
  console.log(
7037
- chalk78.dim(
7155
+ chalk81.dim(
7038
7156
  `
7039
7157
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
7040
7158
  )
@@ -7044,18 +7162,18 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
7044
7162
  // src/commands/refactor/restructure/executePlan.ts
7045
7163
  import fs19 from "fs";
7046
7164
  import path36 from "path";
7047
- import chalk79 from "chalk";
7165
+ import chalk82 from "chalk";
7048
7166
  function executePlan(plan) {
7049
7167
  const updatedContents = applyRewrites(plan.rewrites);
7050
7168
  for (const [file, content] of updatedContents) {
7051
7169
  fs19.writeFileSync(file, content, "utf-8");
7052
7170
  console.log(
7053
- chalk79.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
7171
+ chalk82.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
7054
7172
  );
7055
7173
  }
7056
7174
  for (const dir of plan.newDirectories) {
7057
7175
  fs19.mkdirSync(dir, { recursive: true });
7058
- console.log(chalk79.green(` Created ${path36.relative(process.cwd(), dir)}/`));
7176
+ console.log(chalk82.green(` Created ${path36.relative(process.cwd(), dir)}/`));
7059
7177
  }
7060
7178
  for (const move of plan.moves) {
7061
7179
  const targetDir = path36.dirname(move.to);
@@ -7064,7 +7182,7 @@ function executePlan(plan) {
7064
7182
  }
7065
7183
  fs19.renameSync(move.from, move.to);
7066
7184
  console.log(
7067
- chalk79.white(
7185
+ chalk82.white(
7068
7186
  ` Moved ${path36.relative(process.cwd(), move.from)} \u2192 ${path36.relative(process.cwd(), move.to)}`
7069
7187
  )
7070
7188
  );
@@ -7079,7 +7197,7 @@ function removeEmptyDirectories(dirs) {
7079
7197
  if (entries.length === 0) {
7080
7198
  fs19.rmdirSync(dir);
7081
7199
  console.log(
7082
- chalk79.dim(
7200
+ chalk82.dim(
7083
7201
  ` Removed empty directory ${path36.relative(process.cwd(), dir)}`
7084
7202
  )
7085
7203
  );
@@ -7212,22 +7330,22 @@ async function restructure(pattern2, options2 = {}) {
7212
7330
  const targetPattern = pattern2 ?? "src";
7213
7331
  const files = findSourceFiles2(targetPattern);
7214
7332
  if (files.length === 0) {
7215
- console.log(chalk80.yellow("No files found matching pattern"));
7333
+ console.log(chalk83.yellow("No files found matching pattern"));
7216
7334
  return;
7217
7335
  }
7218
7336
  const tsConfigPath = path39.resolve("tsconfig.json");
7219
7337
  const plan = buildPlan(files, tsConfigPath);
7220
7338
  if (plan.moves.length === 0) {
7221
- console.log(chalk80.green("No restructuring needed"));
7339
+ console.log(chalk83.green("No restructuring needed"));
7222
7340
  return;
7223
7341
  }
7224
7342
  displayPlan(plan);
7225
7343
  if (options2.apply) {
7226
- console.log(chalk80.bold("\nApplying changes..."));
7344
+ console.log(chalk83.bold("\nApplying changes..."));
7227
7345
  executePlan(plan);
7228
- console.log(chalk80.green("\nRestructuring complete"));
7346
+ console.log(chalk83.green("\nRestructuring complete"));
7229
7347
  } else {
7230
- console.log(chalk80.dim("\nDry run. Use --apply to execute."));
7348
+ console.log(chalk83.dim("\nDry run. Use --apply to execute."));
7231
7349
  }
7232
7350
  }
7233
7351
 
@@ -7254,6 +7372,205 @@ function registerRefactor(program2) {
7254
7372
  ).action(restructure);
7255
7373
  }
7256
7374
 
7375
+ // src/commands/seq/seqAuth.ts
7376
+ import chalk85 from "chalk";
7377
+
7378
+ // src/commands/seq/loadConnections.ts
7379
+ function loadConnections2() {
7380
+ const raw = loadGlobalConfigRaw();
7381
+ const seq = raw.seq;
7382
+ return seq?.connections ?? [];
7383
+ }
7384
+ function saveConnections2(connections) {
7385
+ const raw = loadGlobalConfigRaw();
7386
+ const seq = raw.seq ?? {};
7387
+ seq.connections = connections;
7388
+ raw.seq = seq;
7389
+ saveGlobalConfig(raw);
7390
+ }
7391
+ function getDefaultConnection() {
7392
+ const raw = loadGlobalConfigRaw();
7393
+ const seq = raw.seq;
7394
+ return seq?.defaultConnection;
7395
+ }
7396
+ function setDefaultConnection(name) {
7397
+ const raw = loadGlobalConfigRaw();
7398
+ const seq = raw.seq ?? {};
7399
+ seq.defaultConnection = name;
7400
+ raw.seq = seq;
7401
+ saveGlobalConfig(raw);
7402
+ }
7403
+
7404
+ // src/commands/seq/promptConnection.ts
7405
+ import chalk84 from "chalk";
7406
+ async function promptConnection2(existingNames) {
7407
+ const name = await promptInput("name", "Connection name:", "default");
7408
+ if (existingNames.includes(name)) {
7409
+ console.error(chalk84.red(`Connection "${name}" already exists.`));
7410
+ process.exit(1);
7411
+ }
7412
+ const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
7413
+ const apiToken = await promptPassword("apiToken", "API token:");
7414
+ return { name, url, apiToken };
7415
+ }
7416
+
7417
+ // src/commands/seq/seqAuth.ts
7418
+ var seqAuth = createConnectionAuth({
7419
+ load: loadConnections2,
7420
+ save: saveConnections2,
7421
+ format: (c) => `${chalk85.bold(c.name)} ${c.url}`,
7422
+ promptNew: promptConnection2,
7423
+ onFirst: (c) => setDefaultConnection(c.name)
7424
+ });
7425
+
7426
+ // src/commands/seq/seqQuery.ts
7427
+ import chalk88 from "chalk";
7428
+
7429
+ // src/commands/seq/formatEvent.ts
7430
+ import chalk86 from "chalk";
7431
+ function levelColor(level) {
7432
+ switch (level) {
7433
+ case "Fatal":
7434
+ return chalk86.bgRed.white;
7435
+ case "Error":
7436
+ return chalk86.red;
7437
+ case "Warning":
7438
+ return chalk86.yellow;
7439
+ case "Information":
7440
+ return chalk86.cyan;
7441
+ case "Debug":
7442
+ return chalk86.gray;
7443
+ case "Verbose":
7444
+ return chalk86.dim;
7445
+ default:
7446
+ return chalk86.white;
7447
+ }
7448
+ }
7449
+ function levelAbbrev(level) {
7450
+ switch (level) {
7451
+ case "Fatal":
7452
+ return "FTL";
7453
+ case "Error":
7454
+ return "ERR";
7455
+ case "Warning":
7456
+ return "WRN";
7457
+ case "Information":
7458
+ return "INF";
7459
+ case "Debug":
7460
+ return "DBG";
7461
+ case "Verbose":
7462
+ return "VRB";
7463
+ default:
7464
+ return level.slice(0, 3).toUpperCase();
7465
+ }
7466
+ }
7467
+ function renderMessage(event) {
7468
+ const props = Object.fromEntries(
7469
+ event.Properties.map((p) => [p.Name, p.Value])
7470
+ );
7471
+ return event.MessageTemplateTokens.map((t) => {
7472
+ if ("Text" in t) return t.Text;
7473
+ const val = props[t.PropertyName];
7474
+ return val !== void 0 ? String(val) : `{${t.PropertyName}}`;
7475
+ }).join("");
7476
+ }
7477
+ function formatTimestamp(iso) {
7478
+ const d = new Date(iso);
7479
+ return d.toLocaleTimeString("en-AU", {
7480
+ hour12: false,
7481
+ fractionalSecondDigits: 3
7482
+ });
7483
+ }
7484
+ function formatEvent(event) {
7485
+ const color = levelColor(event.Level);
7486
+ const abbrev = levelAbbrev(event.Level);
7487
+ const ts8 = chalk86.dim(formatTimestamp(event.Timestamp));
7488
+ const msg = renderMessage(event);
7489
+ const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
7490
+ if (event.Exception) {
7491
+ for (const line of event.Exception.split("\n")) {
7492
+ lines.push(chalk86.red(` ${line}`));
7493
+ }
7494
+ }
7495
+ return lines.join("\n");
7496
+ }
7497
+
7498
+ // src/commands/seq/resolveConnection.ts
7499
+ import chalk87 from "chalk";
7500
+ function resolveConnection2(name) {
7501
+ const connections = loadConnections2();
7502
+ if (connections.length === 0) {
7503
+ console.error(
7504
+ chalk87.red("No Seq connections configured. Run 'assist seq auth' first.")
7505
+ );
7506
+ process.exit(1);
7507
+ }
7508
+ const target = name ?? getDefaultConnection() ?? connections[0].name;
7509
+ const connection = connections.find((c) => c.name === target);
7510
+ if (!connection) {
7511
+ console.error(chalk87.red(`Seq connection "${target}" not found.`));
7512
+ process.exit(1);
7513
+ }
7514
+ return connection;
7515
+ }
7516
+
7517
+ // src/commands/seq/seqQuery.ts
7518
+ async function seqQuery(filter, options2) {
7519
+ const conn = resolveConnection2(options2.connection);
7520
+ const count = Number.parseInt(options2.count ?? "50", 10);
7521
+ const params = new URLSearchParams({ filter, count: String(count) });
7522
+ const url = `${conn.url}/api/events?${params}`;
7523
+ const response = await fetch(url, {
7524
+ headers: {
7525
+ Accept: "application/json",
7526
+ "X-Seq-ApiKey": conn.apiToken
7527
+ }
7528
+ });
7529
+ if (!response.ok) {
7530
+ const body = await response.text();
7531
+ console.error(chalk88.red(`Seq returned ${response.status}: ${body}`));
7532
+ process.exit(1);
7533
+ }
7534
+ const events = await response.json();
7535
+ if (events.length === 0) {
7536
+ console.log(chalk88.yellow("No events found."));
7537
+ return;
7538
+ }
7539
+ if (options2.json) {
7540
+ console.log(JSON.stringify(events, null, 2));
7541
+ return;
7542
+ }
7543
+ const chronological = [...events].reverse();
7544
+ for (const event of chronological) {
7545
+ console.log(formatEvent(event));
7546
+ }
7547
+ console.log(chalk88.dim(`
7548
+ ${events.length} events`));
7549
+ }
7550
+
7551
+ // src/commands/seq/seqSetConnection.ts
7552
+ import chalk89 from "chalk";
7553
+ function seqSetConnection(name) {
7554
+ const connections = loadConnections2();
7555
+ if (!connections.find((c) => c.name === name)) {
7556
+ console.error(chalk89.red(`Connection "${name}" not found.`));
7557
+ process.exit(1);
7558
+ }
7559
+ setDefaultConnection(name);
7560
+ console.log(`Default Seq connection set to "${name}".`);
7561
+ }
7562
+
7563
+ // src/commands/registerSeq.ts
7564
+ function registerSeq(program2) {
7565
+ const cmd = program2.command("seq").description("Seq log query utilities");
7566
+ const auth2 = cmd.command("auth").description("Configure a Seq connection");
7567
+ auth2.command("add").description("Add a new connection").action(() => seqAuth.add());
7568
+ auth2.command("list").description("List configured connections").action(() => seqAuth.list());
7569
+ auth2.command("remove <name>").description("Remove a configured connection").action((name) => seqAuth.remove(name));
7570
+ cmd.command("set-connection <name>").description("Set the default Seq connection").action((name) => seqSetConnection(name));
7571
+ cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
7572
+ }
7573
+
7257
7574
  // src/commands/transcript/shared.ts
7258
7575
  import { existsSync as existsSync27, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
7259
7576
  import { basename as basename4, join as join24, relative } from "path";
@@ -7775,14 +8092,14 @@ import {
7775
8092
  import { dirname as dirname20, join as join28 } from "path";
7776
8093
 
7777
8094
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
7778
- import chalk81 from "chalk";
8095
+ import chalk90 from "chalk";
7779
8096
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
7780
8097
  function validateStagedContent(filename, content) {
7781
8098
  const firstLine = content.split("\n")[0];
7782
8099
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
7783
8100
  if (!match) {
7784
8101
  console.error(
7785
- chalk81.red(
8102
+ chalk90.red(
7786
8103
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
7787
8104
  )
7788
8105
  );
@@ -7791,7 +8108,7 @@ function validateStagedContent(filename, content) {
7791
8108
  const contentAfterLink = content.slice(firstLine.length).trim();
7792
8109
  if (!contentAfterLink) {
7793
8110
  console.error(
7794
- chalk81.red(
8111
+ chalk90.red(
7795
8112
  `Staged file ${filename} has no summary content after the transcript link.`
7796
8113
  )
7797
8114
  );
@@ -7991,7 +8308,7 @@ import { mkdirSync as mkdirSync10 } from "fs";
7991
8308
  import { join as join33 } from "path";
7992
8309
 
7993
8310
  // src/commands/voice/checkLockFile.ts
7994
- import { execSync as execSync34 } from "child_process";
8311
+ import { execSync as execSync35 } from "child_process";
7995
8312
  import { existsSync as existsSync33, mkdirSync as mkdirSync9, readFileSync as readFileSync26, writeFileSync as writeFileSync23 } from "fs";
7996
8313
  import { join as join32 } from "path";
7997
8314
  function isProcessAlive(pid) {
@@ -8020,7 +8337,7 @@ function bootstrapVenv() {
8020
8337
  if (existsSync33(getVenvPython())) return;
8021
8338
  console.log("Setting up Python environment...");
8022
8339
  const pythonDir = getPythonDir();
8023
- execSync34(
8340
+ execSync35(
8024
8341
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
8025
8342
  {
8026
8343
  stdio: "inherit",
@@ -8184,14 +8501,14 @@ function registerVoice(program2) {
8184
8501
 
8185
8502
  // src/commands/roam/auth.ts
8186
8503
  import { randomBytes } from "crypto";
8187
- import chalk82 from "chalk";
8504
+ import chalk91 from "chalk";
8188
8505
 
8189
8506
  // src/lib/openBrowser.ts
8190
- import { execSync as execSync35 } from "child_process";
8507
+ import { execSync as execSync36 } from "child_process";
8191
8508
  function tryExec(commands) {
8192
8509
  for (const cmd of commands) {
8193
8510
  try {
8194
- execSync35(cmd);
8511
+ execSync36(cmd);
8195
8512
  return true;
8196
8513
  } catch {
8197
8514
  }
@@ -8359,13 +8676,13 @@ async function auth() {
8359
8676
  saveGlobalConfig(config);
8360
8677
  const state = randomBytes(16).toString("hex");
8361
8678
  console.log(
8362
- chalk82.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
8679
+ chalk91.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
8363
8680
  );
8364
- console.log(chalk82.white("http://localhost:14523/callback\n"));
8365
- console.log(chalk82.blue("Opening browser for authorization..."));
8366
- console.log(chalk82.dim("Waiting for authorization callback..."));
8681
+ console.log(chalk91.white("http://localhost:14523/callback\n"));
8682
+ console.log(chalk91.blue("Opening browser for authorization..."));
8683
+ console.log(chalk91.dim("Waiting for authorization callback..."));
8367
8684
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
8368
- console.log(chalk82.dim("Exchanging code for tokens..."));
8685
+ console.log(chalk91.dim("Exchanging code for tokens..."));
8369
8686
  const tokens = await exchangeToken({
8370
8687
  code,
8371
8688
  clientId,
@@ -8381,7 +8698,7 @@ async function auth() {
8381
8698
  };
8382
8699
  saveGlobalConfig(config);
8383
8700
  console.log(
8384
- chalk82.green("Roam credentials and tokens saved to ~/.assist.yml")
8701
+ chalk91.green("Roam credentials and tokens saved to ~/.assist.yml")
8385
8702
  );
8386
8703
  }
8387
8704
 
@@ -8392,7 +8709,7 @@ function registerRoam(program2) {
8392
8709
  }
8393
8710
 
8394
8711
  // src/commands/run/index.ts
8395
- import { execSync as execSync36 } from "child_process";
8712
+ import { execSync as execSync37 } from "child_process";
8396
8713
 
8397
8714
  // src/commands/run/resolveParams.ts
8398
8715
  function resolveParams(params, cliArgs) {
@@ -8555,7 +8872,7 @@ function listRunConfigs() {
8555
8872
  function runPreCommands(pre) {
8556
8873
  for (const cmd of pre) {
8557
8874
  try {
8558
- execSync36(cmd, { stdio: "inherit" });
8875
+ execSync37(cmd, { stdio: "inherit" });
8559
8876
  } catch (err) {
8560
8877
  const code = err && typeof err === "object" && "status" in err ? err.status : 1;
8561
8878
  process.exit(code);
@@ -8573,10 +8890,10 @@ function run2(name, args) {
8573
8890
  }
8574
8891
 
8575
8892
  // src/commands/statusLine.ts
8576
- import chalk84 from "chalk";
8893
+ import chalk93 from "chalk";
8577
8894
 
8578
8895
  // src/commands/buildLimitsSegment.ts
8579
- import chalk83 from "chalk";
8896
+ import chalk92 from "chalk";
8580
8897
  var FIVE_HOUR_SECONDS = 5 * 3600;
8581
8898
  var SEVEN_DAY_SECONDS = 7 * 86400;
8582
8899
  function formatTimeLeft(resetsAt) {
@@ -8599,10 +8916,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
8599
8916
  function colorizeRateLimit(pct, resetsAt, windowSeconds) {
8600
8917
  const label2 = `${Math.round(pct)}%`;
8601
8918
  const projected = projectUsage(pct, resetsAt, windowSeconds);
8602
- if (projected == null) return chalk83.green(label2);
8603
- if (projected > 100) return chalk83.red(label2);
8604
- if (projected > 75) return chalk83.yellow(label2);
8605
- return chalk83.green(label2);
8919
+ if (projected == null) return chalk92.green(label2);
8920
+ if (projected > 100) return chalk92.red(label2);
8921
+ if (projected > 75) return chalk92.yellow(label2);
8922
+ return chalk92.green(label2);
8606
8923
  }
8607
8924
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
8608
8925
  const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
@@ -8628,14 +8945,14 @@ function buildLimitsSegment(rateLimits) {
8628
8945
  }
8629
8946
 
8630
8947
  // src/commands/statusLine.ts
8631
- chalk84.level = 3;
8948
+ chalk93.level = 3;
8632
8949
  function formatNumber(num) {
8633
8950
  return num.toLocaleString("en-US");
8634
8951
  }
8635
8952
  function colorizePercent(pct) {
8636
8953
  const label2 = `${Math.round(pct)}%`;
8637
- if (pct > 80) return chalk84.red(label2);
8638
- if (pct > 40) return chalk84.yellow(label2);
8954
+ if (pct > 80) return chalk93.red(label2);
8955
+ if (pct > 40) return chalk93.yellow(label2);
8639
8956
  return label2;
8640
8957
  }
8641
8958
  async function statusLine() {
@@ -8658,7 +8975,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
8658
8975
  // src/commands/sync/syncClaudeMd.ts
8659
8976
  import * as fs22 from "fs";
8660
8977
  import * as path40 from "path";
8661
- import chalk85 from "chalk";
8978
+ import chalk94 from "chalk";
8662
8979
  async function syncClaudeMd(claudeDir, targetBase) {
8663
8980
  const source = path40.join(claudeDir, "CLAUDE.md");
8664
8981
  const target = path40.join(targetBase, "CLAUDE.md");
@@ -8667,12 +8984,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
8667
8984
  const targetContent = fs22.readFileSync(target, "utf-8");
8668
8985
  if (sourceContent !== targetContent) {
8669
8986
  console.log(
8670
- chalk85.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
8987
+ chalk94.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
8671
8988
  );
8672
8989
  console.log();
8673
8990
  printDiff(targetContent, sourceContent);
8674
8991
  const confirm = await promptConfirm(
8675
- chalk85.red("Overwrite existing CLAUDE.md?"),
8992
+ chalk94.red("Overwrite existing CLAUDE.md?"),
8676
8993
  false
8677
8994
  );
8678
8995
  if (!confirm) {
@@ -8688,7 +9005,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
8688
9005
  // src/commands/sync/syncSettings.ts
8689
9006
  import * as fs23 from "fs";
8690
9007
  import * as path41 from "path";
8691
- import chalk86 from "chalk";
9008
+ import chalk95 from "chalk";
8692
9009
  async function syncSettings(claudeDir, targetBase, options2) {
8693
9010
  const source = path41.join(claudeDir, "settings.json");
8694
9011
  const target = path41.join(targetBase, "settings.json");
@@ -8704,14 +9021,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
8704
9021
  if (mergedContent !== normalizedTarget) {
8705
9022
  if (!options2?.yes) {
8706
9023
  console.log(
8707
- chalk86.yellow(
9024
+ chalk95.yellow(
8708
9025
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
8709
9026
  )
8710
9027
  );
8711
9028
  console.log();
8712
9029
  printDiff(targetContent, mergedContent);
8713
9030
  const confirm = await promptConfirm(
8714
- chalk86.red("Overwrite existing settings.json?"),
9031
+ chalk95.red("Overwrite existing settings.json?"),
8715
9032
  false
8716
9033
  );
8717
9034
  if (!confirm) {
@@ -8748,7 +9065,7 @@ function syncCommands(claudeDir, targetBase) {
8748
9065
  }
8749
9066
 
8750
9067
  // src/commands/update.ts
8751
- import { execSync as execSync37 } from "child_process";
9068
+ import { execSync as execSync38 } from "child_process";
8752
9069
  import * as path43 from "path";
8753
9070
  function isGlobalNpmInstall(dir) {
8754
9071
  try {
@@ -8756,7 +9073,7 @@ function isGlobalNpmInstall(dir) {
8756
9073
  if (resolved.split(path43.sep).includes("node_modules")) {
8757
9074
  return true;
8758
9075
  }
8759
- const globalPrefix = execSync37("npm prefix -g", { stdio: "pipe" }).toString().trim();
9076
+ const globalPrefix = execSync38("npm prefix -g", { stdio: "pipe" }).toString().trim();
8760
9077
  return resolved.toLowerCase().startsWith(path43.resolve(globalPrefix).toLowerCase());
8761
9078
  } catch {
8762
9079
  return false;
@@ -8767,18 +9084,18 @@ async function update() {
8767
9084
  console.log(`Assist is installed at: ${installDir}`);
8768
9085
  if (isGitRepo(installDir)) {
8769
9086
  console.log("Detected git repo installation, pulling latest...");
8770
- execSync37("git pull", { cwd: installDir, stdio: "inherit" });
9087
+ execSync38("git pull", { cwd: installDir, stdio: "inherit" });
8771
9088
  console.log("Installing dependencies...");
8772
- execSync37("npm i", { cwd: installDir, stdio: "inherit" });
9089
+ execSync38("npm i", { cwd: installDir, stdio: "inherit" });
8773
9090
  console.log("Building...");
8774
- execSync37("npm run build", { cwd: installDir, stdio: "inherit" });
9091
+ execSync38("npm run build", { cwd: installDir, stdio: "inherit" });
8775
9092
  console.log("Syncing commands...");
8776
- execSync37("assist sync", { stdio: "inherit" });
9093
+ execSync38("assist sync", { stdio: "inherit" });
8777
9094
  } else if (isGlobalNpmInstall(installDir)) {
8778
9095
  console.log("Detected global npm installation, updating...");
8779
- execSync37("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
9096
+ execSync38("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
8780
9097
  console.log("Syncing commands...");
8781
- execSync37("assist sync", { stdio: "inherit" });
9098
+ execSync38("assist sync", { stdio: "inherit" });
8782
9099
  } else {
8783
9100
  console.error(
8784
9101
  "Could not determine installation method. Expected a git repo or global npm install."
@@ -8828,6 +9145,7 @@ registerComplexity(program);
8828
9145
  registerDotnet(program);
8829
9146
  registerNews(program);
8830
9147
  registerRavendb(program);
9148
+ registerSeq(program);
8831
9149
  registerTranscript(program);
8832
9150
  registerVoice(program);
8833
9151
  program.parse();