@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/README.md +13 -3
- package/claude/commands/seq.md +29 -0
- package/claude/settings.json +5 -1
- package/dist/index.js +602 -284
- package/package.json +1 -1
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.
|
|
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
|
|
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/
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
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
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
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
|
|
4914
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20, unlinkSync as unlinkSync3 } from "fs";
|
|
4858
4915
|
import { tmpdir as tmpdir2 } from "os";
|
|
4859
|
-
import
|
|
4860
|
-
import
|
|
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(
|
|
4922
|
+
console.error(chalk55.red("jb is not installed. Install with:"));
|
|
4866
4923
|
console.error(
|
|
4867
|
-
|
|
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 =
|
|
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(
|
|
4941
|
+
console.error(chalk55.red("jb inspectcode failed"));
|
|
4885
4942
|
process.exit(1);
|
|
4886
4943
|
}
|
|
4887
|
-
if (!
|
|
4888
|
-
console.error(
|
|
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/
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
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(
|
|
4911
|
-
console.log(
|
|
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
|
-
|
|
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(
|
|
5025
|
+
console.log(chalk57.green("No changed .cs files found"));
|
|
4921
5026
|
return;
|
|
4922
5027
|
}
|
|
4923
5028
|
console.log(
|
|
4924
|
-
|
|
5029
|
+
chalk57.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
4925
5030
|
);
|
|
4926
5031
|
const start3 = Date.now();
|
|
4927
|
-
const
|
|
4928
|
-
resolved,
|
|
4929
|
-
changedFiles.join(";"),
|
|
4930
|
-
!!options2.swea
|
|
4931
|
-
);
|
|
5032
|
+
const issues = runEngine(resolved, changedFiles, options2);
|
|
4932
5033
|
const elapsed = Date.now() - start3;
|
|
4933
|
-
|
|
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
|
|
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
|
|
5013
|
-
import
|
|
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 =
|
|
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
|
-
|
|
5126
|
+
chalk58.red("Jira authentication expired."),
|
|
5027
5127
|
"Run",
|
|
5028
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
const
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
5307
|
+
console.log(chalk61.green(`Added feed: ${url}`));
|
|
5204
5308
|
}
|
|
5205
5309
|
|
|
5206
5310
|
// src/commands/news/web/handleRequest.ts
|
|
5207
|
-
import
|
|
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(
|
|
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${
|
|
5453
|
+
`\r${chalk62.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
5350
5454
|
);
|
|
5351
5455
|
}).then((items) => {
|
|
5352
5456
|
process.stdout.write(
|
|
5353
|
-
`\r${
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5616
|
+
import { execSync as execSync27 } from "child_process";
|
|
5513
5617
|
|
|
5514
5618
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
5515
|
-
import { execSync as
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
5774
|
+
import { execSync as execSync29 } from "child_process";
|
|
5671
5775
|
function fetchJson(endpoint) {
|
|
5672
|
-
const result =
|
|
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
|
|
5818
|
+
import chalk63 from "chalk";
|
|
5715
5819
|
function formatForHuman(comment2) {
|
|
5716
5820
|
if (comment2.type === "review") {
|
|
5717
|
-
const stateColor = comment2.state === "APPROVED" ?
|
|
5821
|
+
const stateColor = comment2.state === "APPROVED" ? chalk63.green : comment2.state === "CHANGES_REQUESTED" ? chalk63.red : chalk63.yellow;
|
|
5718
5822
|
return [
|
|
5719
|
-
`${
|
|
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
|
-
`${
|
|
5727
|
-
|
|
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
|
|
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
|
|
5921
|
+
import chalk64 from "chalk";
|
|
5818
5922
|
var STATUS_MAP = {
|
|
5819
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
5820
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
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:
|
|
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 `${
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
6020
|
-
import Enquirer3 from "enquirer";
|
|
6168
|
+
import chalk68 from "chalk";
|
|
6021
6169
|
|
|
6022
6170
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6023
|
-
import
|
|
6171
|
+
import chalk67 from "chalk";
|
|
6024
6172
|
import Enquirer2 from "enquirer";
|
|
6025
6173
|
|
|
6026
6174
|
// src/commands/ravendb/searchItems.ts
|
|
6027
|
-
import { execSync as
|
|
6028
|
-
import
|
|
6175
|
+
import { execSync as execSync32 } from "child_process";
|
|
6176
|
+
import chalk66 from "chalk";
|
|
6029
6177
|
function opExec(args) {
|
|
6030
|
-
return
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
6245
|
+
console.error(chalk68.red(`Connection "${name}" already exists.`));
|
|
6102
6246
|
process.exit(1);
|
|
6103
6247
|
}
|
|
6104
|
-
const url = await
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
const database = await
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
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
|
|
6291
|
+
import chalk74 from "chalk";
|
|
6177
6292
|
|
|
6178
6293
|
// src/commands/ravendb/ravenFetch.ts
|
|
6179
|
-
import
|
|
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
|
|
6216
|
-
import
|
|
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(
|
|
6334
|
+
console.error(chalk71.red(`Invalid secret reference: must start with op://`));
|
|
6220
6335
|
process.exit(1);
|
|
6221
6336
|
}
|
|
6222
6337
|
try {
|
|
6223
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(`${
|
|
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
|
|
6438
|
+
import chalk76 from "chalk";
|
|
6324
6439
|
|
|
6325
6440
|
// src/commands/ravendb/fetchAllPages.ts
|
|
6326
|
-
import
|
|
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${
|
|
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(
|
|
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")
|
|
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
|
|
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(
|
|
6541
|
+
console.error(chalk77.red(`
|
|
6424
6542
|
Refactor check failed:
|
|
6425
6543
|
`));
|
|
6426
|
-
console.error(
|
|
6544
|
+
console.error(chalk77.red(` The following files exceed ${maxLines} lines:
|
|
6427
6545
|
`));
|
|
6428
6546
|
for (const violation of violations) {
|
|
6429
|
-
console.error(
|
|
6547
|
+
console.error(chalk77.red(` ${violation.file} (${violation.lines} lines)`));
|
|
6430
6548
|
}
|
|
6431
6549
|
console.error(
|
|
6432
|
-
|
|
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(
|
|
6557
|
+
console.error(chalk77.gray(` assist refactor ignore <file>
|
|
6440
6558
|
`));
|
|
6441
6559
|
if (process.env.CLAUDECODE) {
|
|
6442
|
-
console.error(
|
|
6560
|
+
console.error(chalk77.cyan(`
|
|
6443
6561
|
## Extracting Code to New Files
|
|
6444
6562
|
`));
|
|
6445
6563
|
console.error(
|
|
6446
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
6774
|
+
console.log(chalk79.red(`File not found in project: ${source}`));
|
|
6657
6775
|
process.exit(1);
|
|
6658
6776
|
}
|
|
6659
|
-
console.log(
|
|
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(
|
|
6781
|
+
console.log(chalk79.green("Done"));
|
|
6664
6782
|
} else {
|
|
6665
|
-
console.log(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
` ${
|
|
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(
|
|
6860
|
+
console.log(chalk80.green(`
|
|
6743
6861
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
6744
6862
|
} else {
|
|
6745
|
-
console.log(
|
|
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
|
|
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
|
|
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(
|
|
7118
|
+
console.log(chalk81.bold("\nFile moves:"));
|
|
7001
7119
|
for (const move of plan.moves) {
|
|
7002
7120
|
console.log(
|
|
7003
|
-
` ${
|
|
7121
|
+
` ${chalk81.red(relPath(move.from))} \u2192 ${chalk81.green(relPath(move.to))}`
|
|
7004
7122
|
);
|
|
7005
|
-
console.log(
|
|
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(
|
|
7129
|
+
console.log(chalk81.bold(`
|
|
7012
7130
|
Import rewrites (${affectedFiles.size} files):`));
|
|
7013
7131
|
for (const file of affectedFiles) {
|
|
7014
|
-
console.log(` ${
|
|
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
|
-
` ${
|
|
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(
|
|
7027
|
-
for (const w of plan.warnings) console.log(
|
|
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(
|
|
7148
|
+
console.log(chalk81.bold("\nNew directories:"));
|
|
7031
7149
|
for (const dir of plan.newDirectories)
|
|
7032
|
-
console.log(
|
|
7150
|
+
console.log(chalk81.green(` ${dir}/`));
|
|
7033
7151
|
}
|
|
7034
7152
|
displayMoves(plan);
|
|
7035
7153
|
displayRewrites(plan.rewrites);
|
|
7036
7154
|
console.log(
|
|
7037
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
7344
|
+
console.log(chalk83.bold("\nApplying changes..."));
|
|
7227
7345
|
executePlan(plan);
|
|
7228
|
-
console.log(
|
|
7346
|
+
console.log(chalk83.green("\nRestructuring complete"));
|
|
7229
7347
|
} else {
|
|
7230
|
-
console.log(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
8504
|
+
import chalk91 from "chalk";
|
|
8188
8505
|
|
|
8189
8506
|
// src/lib/openBrowser.ts
|
|
8190
|
-
import { execSync as
|
|
8507
|
+
import { execSync as execSync36 } from "child_process";
|
|
8191
8508
|
function tryExec(commands) {
|
|
8192
8509
|
for (const cmd of commands) {
|
|
8193
8510
|
try {
|
|
8194
|
-
|
|
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
|
-
|
|
8679
|
+
chalk91.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
8363
8680
|
);
|
|
8364
|
-
console.log(
|
|
8365
|
-
console.log(
|
|
8366
|
-
console.log(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
8893
|
+
import chalk93 from "chalk";
|
|
8577
8894
|
|
|
8578
8895
|
// src/commands/buildLimitsSegment.ts
|
|
8579
|
-
import
|
|
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
|
|
8603
|
-
if (projected > 100) return
|
|
8604
|
-
if (projected > 75) return
|
|
8605
|
-
return
|
|
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
|
-
|
|
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
|
|
8638
|
-
if (pct > 40) return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
9087
|
+
execSync38("git pull", { cwd: installDir, stdio: "inherit" });
|
|
8771
9088
|
console.log("Installing dependencies...");
|
|
8772
|
-
|
|
9089
|
+
execSync38("npm i", { cwd: installDir, stdio: "inherit" });
|
|
8773
9090
|
console.log("Building...");
|
|
8774
|
-
|
|
9091
|
+
execSync38("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
8775
9092
|
console.log("Syncing commands...");
|
|
8776
|
-
|
|
9093
|
+
execSync38("assist sync", { stdio: "inherit" });
|
|
8777
9094
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
8778
9095
|
console.log("Detected global npm installation, updating...");
|
|
8779
|
-
|
|
9096
|
+
execSync38("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
8780
9097
|
console.log("Syncing commands...");
|
|
8781
|
-
|
|
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();
|