@staff0rd/assist 0.206.2 → 0.207.1
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 +1 -0
- package/claude/settings.json +0 -1
- package/dist/index.js +438 -320
- 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.207.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -983,8 +983,8 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
983
983
|
const child = spawn("claude", args, {
|
|
984
984
|
stdio: "inherit"
|
|
985
985
|
});
|
|
986
|
-
const done2 = new Promise((
|
|
987
|
-
child.on("close", (code) =>
|
|
986
|
+
const done2 = new Promise((resolve15, reject) => {
|
|
987
|
+
child.on("close", (code) => resolve15(code ?? 0));
|
|
988
988
|
child.on("error", reject);
|
|
989
989
|
});
|
|
990
990
|
return { child, done: done2 };
|
|
@@ -1447,12 +1447,12 @@ function createFallbackHandler(routes3, htmlHandler2, extra) {
|
|
|
1447
1447
|
|
|
1448
1448
|
// src/commands/backlog/web/parseItemBody.ts
|
|
1449
1449
|
function readBody(req) {
|
|
1450
|
-
return new Promise((
|
|
1450
|
+
return new Promise((resolve15, reject) => {
|
|
1451
1451
|
let body = "";
|
|
1452
1452
|
req.on("data", (chunk) => {
|
|
1453
1453
|
body += chunk.toString();
|
|
1454
1454
|
});
|
|
1455
|
-
req.on("end", () =>
|
|
1455
|
+
req.on("end", () => resolve15(body));
|
|
1456
1456
|
req.on("error", reject);
|
|
1457
1457
|
});
|
|
1458
1458
|
}
|
|
@@ -1689,6 +1689,9 @@ function mergeRawConfigs(globalRaw, projectRaw) {
|
|
|
1689
1689
|
}
|
|
1690
1690
|
|
|
1691
1691
|
// src/shared/types.ts
|
|
1692
|
+
import { z as z3 } from "zod";
|
|
1693
|
+
|
|
1694
|
+
// src/shared/runConfigSchema.ts
|
|
1692
1695
|
import { z as z2 } from "zod";
|
|
1693
1696
|
var runParamSchema = z2.strictObject({
|
|
1694
1697
|
name: z2.string(),
|
|
@@ -1710,103 +1713,108 @@ var runLinkSchema = z2.strictObject({
|
|
|
1710
1713
|
link: z2.string(),
|
|
1711
1714
|
prefix: z2.string()
|
|
1712
1715
|
});
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1716
|
+
|
|
1717
|
+
// src/shared/types.ts
|
|
1718
|
+
var transcriptConfigSchema = z3.strictObject({
|
|
1719
|
+
vttDir: z3.string(),
|
|
1720
|
+
transcriptsDir: z3.string(),
|
|
1721
|
+
summaryDir: z3.string()
|
|
1717
1722
|
});
|
|
1718
1723
|
var DEFAULT_WAKE_WORDS = ["computer"];
|
|
1719
1724
|
var DEFAULT_MODELS_DIR = "~/.assist/voice/models";
|
|
1720
|
-
var assistConfigSchema =
|
|
1721
|
-
commit:
|
|
1722
|
-
conventional:
|
|
1723
|
-
pull:
|
|
1724
|
-
push:
|
|
1725
|
+
var assistConfigSchema = z3.strictObject({
|
|
1726
|
+
commit: z3.strictObject({
|
|
1727
|
+
conventional: z3.boolean().default(false),
|
|
1728
|
+
pull: z3.boolean().default(false),
|
|
1729
|
+
push: z3.boolean().default(false)
|
|
1725
1730
|
}).default({ conventional: false, pull: false, push: false }),
|
|
1726
|
-
devlog:
|
|
1727
|
-
name:
|
|
1728
|
-
ignore:
|
|
1729
|
-
skip:
|
|
1731
|
+
devlog: z3.strictObject({
|
|
1732
|
+
name: z3.string().optional(),
|
|
1733
|
+
ignore: z3.array(z3.string()).optional(),
|
|
1734
|
+
skip: z3.record(z3.string(), z3.array(z3.string())).optional()
|
|
1730
1735
|
}).optional(),
|
|
1731
|
-
notify:
|
|
1732
|
-
enabled:
|
|
1736
|
+
notify: z3.strictObject({
|
|
1737
|
+
enabled: z3.boolean().default(true)
|
|
1733
1738
|
}).default({ enabled: true }),
|
|
1734
|
-
complexity:
|
|
1735
|
-
ignore:
|
|
1739
|
+
complexity: z3.strictObject({
|
|
1740
|
+
ignore: z3.array(z3.string()).default(["**/*test.ts*"])
|
|
1736
1741
|
}).default({ ignore: ["**/*test.ts*"] }),
|
|
1737
|
-
hardcodedColors:
|
|
1738
|
-
ignore:
|
|
1742
|
+
hardcodedColors: z3.strictObject({
|
|
1743
|
+
ignore: z3.array(z3.string()).default([])
|
|
1739
1744
|
}).optional(),
|
|
1740
|
-
restructure:
|
|
1741
|
-
ignore:
|
|
1745
|
+
restructure: z3.strictObject({
|
|
1746
|
+
ignore: z3.array(z3.string()).default([])
|
|
1742
1747
|
}).optional(),
|
|
1743
|
-
jira:
|
|
1744
|
-
acField:
|
|
1748
|
+
jira: z3.strictObject({
|
|
1749
|
+
acField: z3.string().default("customfield_11937")
|
|
1745
1750
|
}).optional(),
|
|
1746
|
-
roam:
|
|
1747
|
-
clientId:
|
|
1748
|
-
clientSecret:
|
|
1749
|
-
accessToken:
|
|
1750
|
-
refreshToken:
|
|
1751
|
-
tokenExpiresAt:
|
|
1751
|
+
roam: z3.strictObject({
|
|
1752
|
+
clientId: z3.string(),
|
|
1753
|
+
clientSecret: z3.string(),
|
|
1754
|
+
accessToken: z3.string().optional(),
|
|
1755
|
+
refreshToken: z3.string().optional(),
|
|
1756
|
+
tokenExpiresAt: z3.number().optional()
|
|
1752
1757
|
}).optional(),
|
|
1753
|
-
run:
|
|
1758
|
+
run: z3.array(z3.union([runConfigSchema, runLinkSchema])).optional(),
|
|
1754
1759
|
transcript: transcriptConfigSchema.optional(),
|
|
1755
|
-
cliReadVerbs:
|
|
1756
|
-
news:
|
|
1757
|
-
feeds:
|
|
1760
|
+
cliReadVerbs: z3.record(z3.string(), z3.array(z3.string())).optional(),
|
|
1761
|
+
news: z3.strictObject({
|
|
1762
|
+
feeds: z3.array(z3.string()).default([])
|
|
1758
1763
|
}).default({ feeds: [] }),
|
|
1759
|
-
dotnet:
|
|
1760
|
-
inspect:
|
|
1761
|
-
suppress:
|
|
1764
|
+
dotnet: z3.strictObject({
|
|
1765
|
+
inspect: z3.strictObject({
|
|
1766
|
+
suppress: z3.array(z3.string()).default([])
|
|
1762
1767
|
}).default({ suppress: [] })
|
|
1763
1768
|
}).optional(),
|
|
1764
|
-
ravendb:
|
|
1765
|
-
connections:
|
|
1766
|
-
|
|
1767
|
-
name:
|
|
1768
|
-
url:
|
|
1769
|
-
database:
|
|
1770
|
-
apiKeyRef:
|
|
1769
|
+
ravendb: z3.strictObject({
|
|
1770
|
+
connections: z3.array(
|
|
1771
|
+
z3.strictObject({
|
|
1772
|
+
name: z3.string(),
|
|
1773
|
+
url: z3.string(),
|
|
1774
|
+
database: z3.string(),
|
|
1775
|
+
apiKeyRef: z3.string()
|
|
1771
1776
|
})
|
|
1772
1777
|
).default([]),
|
|
1773
|
-
defaultConnection:
|
|
1778
|
+
defaultConnection: z3.string().optional()
|
|
1774
1779
|
}).optional(),
|
|
1775
|
-
seq:
|
|
1776
|
-
connections:
|
|
1777
|
-
|
|
1778
|
-
name:
|
|
1779
|
-
url:
|
|
1780
|
-
apiToken:
|
|
1780
|
+
seq: z3.strictObject({
|
|
1781
|
+
connections: z3.array(
|
|
1782
|
+
z3.strictObject({
|
|
1783
|
+
name: z3.string(),
|
|
1784
|
+
url: z3.string(),
|
|
1785
|
+
apiToken: z3.string()
|
|
1781
1786
|
})
|
|
1782
1787
|
).default([]),
|
|
1783
|
-
defaultConnection:
|
|
1788
|
+
defaultConnection: z3.string().optional()
|
|
1784
1789
|
}).optional(),
|
|
1785
|
-
screenshot:
|
|
1786
|
-
outputDir:
|
|
1790
|
+
screenshot: z3.strictObject({
|
|
1791
|
+
outputDir: z3.string().default("./screenshots")
|
|
1787
1792
|
}).default({ outputDir: "./screenshots" }),
|
|
1788
|
-
backlog:
|
|
1789
|
-
autoCommit:
|
|
1793
|
+
backlog: z3.strictObject({
|
|
1794
|
+
autoCommit: z3.boolean().default(false)
|
|
1790
1795
|
}).default({ autoCommit: false }),
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1796
|
+
mermaid: z3.strictObject({
|
|
1797
|
+
krokiUrl: z3.string().default("https://kroki.io")
|
|
1798
|
+
}).default({ krokiUrl: "https://kroki.io" }),
|
|
1799
|
+
deny: z3.array(
|
|
1800
|
+
z3.strictObject({
|
|
1801
|
+
pattern: z3.string(),
|
|
1802
|
+
message: z3.string()
|
|
1795
1803
|
})
|
|
1796
1804
|
).optional(),
|
|
1797
|
-
sync:
|
|
1798
|
-
autoConfirm:
|
|
1805
|
+
sync: z3.strictObject({
|
|
1806
|
+
autoConfirm: z3.boolean().default(false)
|
|
1799
1807
|
}).default({ autoConfirm: false }),
|
|
1800
|
-
voice:
|
|
1801
|
-
wakeWords:
|
|
1802
|
-
mic:
|
|
1803
|
-
cwd:
|
|
1804
|
-
modelsDir:
|
|
1805
|
-
lockDir:
|
|
1806
|
-
submitWindows:
|
|
1807
|
-
models:
|
|
1808
|
-
vad:
|
|
1809
|
-
smartTurn:
|
|
1808
|
+
voice: z3.strictObject({
|
|
1809
|
+
wakeWords: z3.array(z3.string()).default(DEFAULT_WAKE_WORDS),
|
|
1810
|
+
mic: z3.string().optional(),
|
|
1811
|
+
cwd: z3.string().optional(),
|
|
1812
|
+
modelsDir: z3.string().default(DEFAULT_MODELS_DIR),
|
|
1813
|
+
lockDir: z3.string().optional(),
|
|
1814
|
+
submitWindows: z3.array(z3.string()).optional(),
|
|
1815
|
+
models: z3.strictObject({
|
|
1816
|
+
vad: z3.string().optional(),
|
|
1817
|
+
smartTurn: z3.string().optional()
|
|
1810
1818
|
}).default({})
|
|
1811
1819
|
}).default({
|
|
1812
1820
|
wakeWords: DEFAULT_WAKE_WORDS,
|
|
@@ -4042,14 +4050,14 @@ function flushIfFailed(exitCode, chunks) {
|
|
|
4042
4050
|
|
|
4043
4051
|
// src/commands/verify/run/runAllEntries.ts
|
|
4044
4052
|
function runEntry(entry, onComplete) {
|
|
4045
|
-
return new Promise((
|
|
4053
|
+
return new Promise((resolve15) => {
|
|
4046
4054
|
const child = spawnCommand(entry.fullCommand, entry.cwd, entry.env);
|
|
4047
4055
|
const chunks = collectOutput(child);
|
|
4048
4056
|
child.on("close", (code) => {
|
|
4049
4057
|
const exitCode = code ?? 1;
|
|
4050
4058
|
flushIfFailed(exitCode, chunks);
|
|
4051
4059
|
onComplete?.(exitCode);
|
|
4052
|
-
|
|
4060
|
+
resolve15({ script: entry.name, code: exitCode });
|
|
4053
4061
|
});
|
|
4054
4062
|
});
|
|
4055
4063
|
}
|
|
@@ -6125,12 +6133,12 @@ function hasSubcommands(helpText) {
|
|
|
6125
6133
|
// src/commands/permitCliReads/runHelp.ts
|
|
6126
6134
|
import { exec as exec2 } from "child_process";
|
|
6127
6135
|
function runHelp(args) {
|
|
6128
|
-
return new Promise((
|
|
6136
|
+
return new Promise((resolve15) => {
|
|
6129
6137
|
exec2(
|
|
6130
6138
|
`${args.join(" ")} --help`,
|
|
6131
6139
|
{ encoding: "utf-8", timeout: 3e4 },
|
|
6132
6140
|
(_err, stdout, stderr) => {
|
|
6133
|
-
|
|
6141
|
+
resolve15(stdout || stderr || "");
|
|
6134
6142
|
}
|
|
6135
6143
|
);
|
|
6136
6144
|
});
|
|
@@ -8493,8 +8501,115 @@ function registerJira(program2) {
|
|
|
8493
8501
|
jiraCommand.command("view <issue-key>").description("Print the title and description of a Jira issue").action((issueKey) => viewIssue(issueKey));
|
|
8494
8502
|
}
|
|
8495
8503
|
|
|
8496
|
-
// src/commands/
|
|
8504
|
+
// src/commands/mermaid/index.ts
|
|
8505
|
+
import { mkdirSync as mkdirSync8, readdirSync as readdirSync5 } from "fs";
|
|
8506
|
+
import { resolve as resolve10 } from "path";
|
|
8507
|
+
import chalk99 from "chalk";
|
|
8508
|
+
|
|
8509
|
+
// src/commands/mermaid/exportFile.ts
|
|
8510
|
+
import { readFileSync as readFileSync27, writeFileSync as writeFileSync21 } from "fs";
|
|
8511
|
+
import { basename as basename7, extname, resolve as resolve9 } from "path";
|
|
8512
|
+
import chalk98 from "chalk";
|
|
8513
|
+
|
|
8514
|
+
// src/commands/mermaid/renderBlock.ts
|
|
8497
8515
|
import chalk97 from "chalk";
|
|
8516
|
+
async function renderBlock(krokiUrl, source) {
|
|
8517
|
+
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
8518
|
+
method: "POST",
|
|
8519
|
+
headers: { "Content-Type": "text/plain" },
|
|
8520
|
+
body: source
|
|
8521
|
+
});
|
|
8522
|
+
if (!response.ok) {
|
|
8523
|
+
console.error(
|
|
8524
|
+
chalk97.red(
|
|
8525
|
+
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
8526
|
+
)
|
|
8527
|
+
);
|
|
8528
|
+
console.error(await response.text());
|
|
8529
|
+
process.exit(1);
|
|
8530
|
+
}
|
|
8531
|
+
return await response.text();
|
|
8532
|
+
}
|
|
8533
|
+
|
|
8534
|
+
// src/commands/mermaid/exportFile.ts
|
|
8535
|
+
async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
8536
|
+
const content = readFileSync27(file, "utf8");
|
|
8537
|
+
const blocks = extractMermaidBlocks(content);
|
|
8538
|
+
const stem = basename7(file, extname(file));
|
|
8539
|
+
if (onlyIndex !== void 0) {
|
|
8540
|
+
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
8541
|
+
console.error(
|
|
8542
|
+
chalk98.red(
|
|
8543
|
+
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
8544
|
+
)
|
|
8545
|
+
);
|
|
8546
|
+
process.exit(1);
|
|
8547
|
+
}
|
|
8548
|
+
console.log(
|
|
8549
|
+
chalk98.gray(
|
|
8550
|
+
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
8551
|
+
)
|
|
8552
|
+
);
|
|
8553
|
+
} else {
|
|
8554
|
+
console.log(chalk98.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
8555
|
+
}
|
|
8556
|
+
for (const [i, source] of blocks.entries()) {
|
|
8557
|
+
const idx = i + 1;
|
|
8558
|
+
if (onlyIndex !== void 0 && idx !== onlyIndex) continue;
|
|
8559
|
+
const outPath = resolve9(outDir, `${stem}-${idx}.svg`);
|
|
8560
|
+
const svg = await renderBlock(krokiUrl, source);
|
|
8561
|
+
writeFileSync21(outPath, svg, "utf8");
|
|
8562
|
+
console.log(chalk98.green(` \u2192 ${outPath}`));
|
|
8563
|
+
}
|
|
8564
|
+
}
|
|
8565
|
+
function extractMermaidBlocks(markdown) {
|
|
8566
|
+
const matches = [...markdown.matchAll(/```mermaid\n([\s\S]*?)\n```/g)];
|
|
8567
|
+
return matches.map(([, src]) => src);
|
|
8568
|
+
}
|
|
8569
|
+
|
|
8570
|
+
// src/commands/mermaid/index.ts
|
|
8571
|
+
async function mermaidExport(file, options2 = {}) {
|
|
8572
|
+
const { mermaid } = loadConfig();
|
|
8573
|
+
const outDir = resolve10(process.cwd(), options2.out ?? ".");
|
|
8574
|
+
mkdirSync8(outDir, { recursive: true });
|
|
8575
|
+
if (options2.index !== void 0) {
|
|
8576
|
+
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
8577
|
+
console.error(
|
|
8578
|
+
chalk99.red(`--index must be a positive integer (got ${options2.index})`)
|
|
8579
|
+
);
|
|
8580
|
+
process.exit(1);
|
|
8581
|
+
}
|
|
8582
|
+
if (!file) {
|
|
8583
|
+
console.error(chalk99.red("--index requires a file argument"));
|
|
8584
|
+
process.exit(1);
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
const files = file ? [file] : readdirSync5(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
8588
|
+
if (files.length === 0) {
|
|
8589
|
+
console.log(chalk99.gray("No markdown files found in current directory."));
|
|
8590
|
+
return;
|
|
8591
|
+
}
|
|
8592
|
+
for (const f of files) {
|
|
8593
|
+
await exportFile(f, outDir, mermaid.krokiUrl, options2.index);
|
|
8594
|
+
}
|
|
8595
|
+
}
|
|
8596
|
+
|
|
8597
|
+
// src/commands/registerMermaid.ts
|
|
8598
|
+
function registerMermaid(program2) {
|
|
8599
|
+
const cmd = program2.command("mermaid").description("Render mermaid diagrams from markdown files");
|
|
8600
|
+
cmd.command("export [file]").description(
|
|
8601
|
+
"Render fenced mermaid blocks as SVG via Kroki. With no file, scans *.md in cwd."
|
|
8602
|
+
).option("--out <dir>", "Output directory (default: cwd)").option(
|
|
8603
|
+
"--index <n>",
|
|
8604
|
+
"Render only the nth mermaid block (1-based)",
|
|
8605
|
+
(value) => Number.parseInt(value, 10)
|
|
8606
|
+
).action(
|
|
8607
|
+
(file, options2) => mermaidExport(file, options2)
|
|
8608
|
+
);
|
|
8609
|
+
}
|
|
8610
|
+
|
|
8611
|
+
// src/commands/news/add/index.ts
|
|
8612
|
+
import chalk100 from "chalk";
|
|
8498
8613
|
import enquirer8 from "enquirer";
|
|
8499
8614
|
async function add2(url) {
|
|
8500
8615
|
if (!url) {
|
|
@@ -8517,17 +8632,17 @@ async function add2(url) {
|
|
|
8517
8632
|
const news = config.news ?? {};
|
|
8518
8633
|
const feeds = news.feeds ?? [];
|
|
8519
8634
|
if (feeds.includes(url)) {
|
|
8520
|
-
console.log(
|
|
8635
|
+
console.log(chalk100.yellow("Feed already exists in config"));
|
|
8521
8636
|
return;
|
|
8522
8637
|
}
|
|
8523
8638
|
feeds.push(url);
|
|
8524
8639
|
config.news = { ...news, feeds };
|
|
8525
8640
|
saveGlobalConfig(config);
|
|
8526
|
-
console.log(
|
|
8641
|
+
console.log(chalk100.green(`Added feed: ${url}`));
|
|
8527
8642
|
}
|
|
8528
8643
|
|
|
8529
8644
|
// src/commands/news/web/handleRequest.ts
|
|
8530
|
-
import
|
|
8645
|
+
import chalk101 from "chalk";
|
|
8531
8646
|
|
|
8532
8647
|
// src/commands/news/web/shared.ts
|
|
8533
8648
|
import { decodeHTML } from "entities";
|
|
@@ -8663,17 +8778,17 @@ function prefetch() {
|
|
|
8663
8778
|
const config = loadConfig();
|
|
8664
8779
|
const total = config.news.feeds.length;
|
|
8665
8780
|
if (total === 0) return;
|
|
8666
|
-
process.stdout.write(
|
|
8781
|
+
process.stdout.write(chalk101.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
8667
8782
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
8668
8783
|
const width = 20;
|
|
8669
8784
|
const filled = Math.round(done2 / t * width);
|
|
8670
8785
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
8671
8786
|
process.stdout.write(
|
|
8672
|
-
`\r${
|
|
8787
|
+
`\r${chalk101.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
8673
8788
|
);
|
|
8674
8789
|
}).then((items) => {
|
|
8675
8790
|
process.stdout.write(
|
|
8676
|
-
`\r${
|
|
8791
|
+
`\r${chalk101.green(`Fetched ${items.length} items from ${total} feed(s)`)}
|
|
8677
8792
|
`
|
|
8678
8793
|
);
|
|
8679
8794
|
cachedItems = items;
|
|
@@ -8718,7 +8833,7 @@ function registerNews(program2) {
|
|
|
8718
8833
|
}
|
|
8719
8834
|
|
|
8720
8835
|
// src/commands/prompts/printPromptsTable.ts
|
|
8721
|
-
import
|
|
8836
|
+
import chalk102 from "chalk";
|
|
8722
8837
|
function truncate(str, max) {
|
|
8723
8838
|
if (str.length <= max) return str;
|
|
8724
8839
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -8736,14 +8851,14 @@ function printPromptsTable(rows) {
|
|
|
8736
8851
|
"Command".padEnd(commandWidth),
|
|
8737
8852
|
"Repos"
|
|
8738
8853
|
].join(" ");
|
|
8739
|
-
console.log(
|
|
8740
|
-
console.log(
|
|
8854
|
+
console.log(chalk102.dim(header));
|
|
8855
|
+
console.log(chalk102.dim("-".repeat(header.length)));
|
|
8741
8856
|
for (const row of rows) {
|
|
8742
8857
|
const count = String(row.count).padStart(countWidth);
|
|
8743
8858
|
const tool = row.tool.padEnd(toolWidth);
|
|
8744
8859
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
8745
8860
|
console.log(
|
|
8746
|
-
`${
|
|
8861
|
+
`${chalk102.yellow(count)} ${tool} ${command} ${chalk102.dim(row.repos)}`
|
|
8747
8862
|
);
|
|
8748
8863
|
}
|
|
8749
8864
|
}
|
|
@@ -8773,7 +8888,7 @@ function registerPrompts(program2) {
|
|
|
8773
8888
|
|
|
8774
8889
|
// src/commands/prs/comment.ts
|
|
8775
8890
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
8776
|
-
import { unlinkSync as unlinkSync6, writeFileSync as
|
|
8891
|
+
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync22 } from "fs";
|
|
8777
8892
|
import { tmpdir as tmpdir4 } from "os";
|
|
8778
8893
|
import { join as join29 } from "path";
|
|
8779
8894
|
|
|
@@ -8848,7 +8963,7 @@ function comment2(path53, line, body) {
|
|
|
8848
8963
|
try {
|
|
8849
8964
|
const prId = getCurrentPrNodeId();
|
|
8850
8965
|
const queryFile = join29(tmpdir4(), `gh-query-${Date.now()}.graphql`);
|
|
8851
|
-
|
|
8966
|
+
writeFileSync22(queryFile, MUTATION);
|
|
8852
8967
|
try {
|
|
8853
8968
|
const result = spawnSync2(
|
|
8854
8969
|
"gh",
|
|
@@ -8890,12 +9005,12 @@ import { execSync as execSync28 } from "child_process";
|
|
|
8890
9005
|
|
|
8891
9006
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
8892
9007
|
import { execSync as execSync27 } from "child_process";
|
|
8893
|
-
import { unlinkSync as unlinkSync8, writeFileSync as
|
|
9008
|
+
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync23 } from "fs";
|
|
8894
9009
|
import { tmpdir as tmpdir5 } from "os";
|
|
8895
9010
|
import { join as join31 } from "path";
|
|
8896
9011
|
|
|
8897
9012
|
// src/commands/prs/loadCommentsCache.ts
|
|
8898
|
-
import { existsSync as existsSync30, readFileSync as
|
|
9013
|
+
import { existsSync as existsSync30, readFileSync as readFileSync28, unlinkSync as unlinkSync7 } from "fs";
|
|
8899
9014
|
import { join as join30 } from "path";
|
|
8900
9015
|
import { parse as parse2 } from "yaml";
|
|
8901
9016
|
function getCachePath(prNumber) {
|
|
@@ -8906,7 +9021,7 @@ function loadCommentsCache(prNumber) {
|
|
|
8906
9021
|
if (!existsSync30(cachePath)) {
|
|
8907
9022
|
return null;
|
|
8908
9023
|
}
|
|
8909
|
-
const content =
|
|
9024
|
+
const content = readFileSync28(cachePath, "utf-8");
|
|
8910
9025
|
return parse2(content);
|
|
8911
9026
|
}
|
|
8912
9027
|
function deleteCommentsCache(prNumber) {
|
|
@@ -8927,7 +9042,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
8927
9042
|
function resolveThread(threadId) {
|
|
8928
9043
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
8929
9044
|
const queryFile = join31(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
8930
|
-
|
|
9045
|
+
writeFileSync23(queryFile, mutation);
|
|
8931
9046
|
try {
|
|
8932
9047
|
execSync27(
|
|
8933
9048
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
@@ -9008,19 +9123,19 @@ function fixed(commentId, sha) {
|
|
|
9008
9123
|
}
|
|
9009
9124
|
|
|
9010
9125
|
// src/commands/prs/listComments/index.ts
|
|
9011
|
-
import { existsSync as existsSync31, mkdirSync as
|
|
9126
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync9, writeFileSync as writeFileSync25 } from "fs";
|
|
9012
9127
|
import { join as join33 } from "path";
|
|
9013
9128
|
import { stringify } from "yaml";
|
|
9014
9129
|
|
|
9015
9130
|
// src/commands/prs/fetchThreadIds.ts
|
|
9016
9131
|
import { execSync as execSync29 } from "child_process";
|
|
9017
|
-
import { unlinkSync as unlinkSync9, writeFileSync as
|
|
9132
|
+
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync24 } from "fs";
|
|
9018
9133
|
import { tmpdir as tmpdir6 } from "os";
|
|
9019
9134
|
import { join as join32 } from "path";
|
|
9020
9135
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
9021
9136
|
function fetchThreadIds(org, repo, prNumber) {
|
|
9022
9137
|
const queryFile = join32(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
9023
|
-
|
|
9138
|
+
writeFileSync24(queryFile, THREAD_QUERY);
|
|
9024
9139
|
try {
|
|
9025
9140
|
const result = execSync29(
|
|
9026
9141
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
@@ -9088,20 +9203,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
9088
9203
|
}
|
|
9089
9204
|
|
|
9090
9205
|
// src/commands/prs/listComments/printComments.ts
|
|
9091
|
-
import
|
|
9206
|
+
import chalk103 from "chalk";
|
|
9092
9207
|
function formatForHuman(comment3) {
|
|
9093
9208
|
if (comment3.type === "review") {
|
|
9094
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
9209
|
+
const stateColor = comment3.state === "APPROVED" ? chalk103.green : comment3.state === "CHANGES_REQUESTED" ? chalk103.red : chalk103.yellow;
|
|
9095
9210
|
return [
|
|
9096
|
-
`${
|
|
9211
|
+
`${chalk103.cyan("Review")} by ${chalk103.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
9097
9212
|
comment3.body,
|
|
9098
9213
|
""
|
|
9099
9214
|
].join("\n");
|
|
9100
9215
|
}
|
|
9101
9216
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
9102
9217
|
return [
|
|
9103
|
-
`${
|
|
9104
|
-
|
|
9218
|
+
`${chalk103.cyan("Line comment")} by ${chalk103.bold(comment3.user)} on ${chalk103.dim(`${comment3.path}${location}`)}`,
|
|
9219
|
+
chalk103.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
9105
9220
|
comment3.body,
|
|
9106
9221
|
""
|
|
9107
9222
|
].join("\n");
|
|
@@ -9135,7 +9250,7 @@ function printComments2(result) {
|
|
|
9135
9250
|
function writeCommentsCache(prNumber, comments2) {
|
|
9136
9251
|
const assistDir = join33(process.cwd(), ".assist");
|
|
9137
9252
|
if (!existsSync31(assistDir)) {
|
|
9138
|
-
|
|
9253
|
+
mkdirSync9(assistDir, { recursive: true });
|
|
9139
9254
|
}
|
|
9140
9255
|
const cacheData = {
|
|
9141
9256
|
prNumber,
|
|
@@ -9143,7 +9258,7 @@ function writeCommentsCache(prNumber, comments2) {
|
|
|
9143
9258
|
comments: comments2
|
|
9144
9259
|
};
|
|
9145
9260
|
const cachePath = join33(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
9146
|
-
|
|
9261
|
+
writeFileSync25(cachePath, stringify(cacheData));
|
|
9147
9262
|
}
|
|
9148
9263
|
function handleKnownErrors(error) {
|
|
9149
9264
|
if (isGhNotInstalled(error)) {
|
|
@@ -9191,13 +9306,13 @@ import { execSync as execSync31 } from "child_process";
|
|
|
9191
9306
|
import enquirer9 from "enquirer";
|
|
9192
9307
|
|
|
9193
9308
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
9194
|
-
import
|
|
9309
|
+
import chalk104 from "chalk";
|
|
9195
9310
|
var STATUS_MAP = {
|
|
9196
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
9197
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
9311
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk104.magenta("merged"), date: pr.mergedAt } : null,
|
|
9312
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk104.red("closed"), date: pr.closedAt } : null
|
|
9198
9313
|
};
|
|
9199
9314
|
function defaultStatus(pr) {
|
|
9200
|
-
return { label:
|
|
9315
|
+
return { label: chalk104.green("opened"), date: pr.createdAt };
|
|
9201
9316
|
}
|
|
9202
9317
|
function getStatus2(pr) {
|
|
9203
9318
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -9206,11 +9321,11 @@ function formatDate(dateStr) {
|
|
|
9206
9321
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
9207
9322
|
}
|
|
9208
9323
|
function formatPrHeader(pr, status2) {
|
|
9209
|
-
return `${
|
|
9324
|
+
return `${chalk104.cyan(`#${pr.number}`)} ${pr.title} ${chalk104.dim(`(${pr.author.login},`)} ${status2.label} ${chalk104.dim(`${formatDate(status2.date)})`)}`;
|
|
9210
9325
|
}
|
|
9211
9326
|
function logPrDetails(pr) {
|
|
9212
9327
|
console.log(
|
|
9213
|
-
|
|
9328
|
+
chalk104.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
9214
9329
|
);
|
|
9215
9330
|
console.log();
|
|
9216
9331
|
}
|
|
@@ -9376,10 +9491,10 @@ function registerPrs(program2) {
|
|
|
9376
9491
|
}
|
|
9377
9492
|
|
|
9378
9493
|
// src/commands/ravendb/ravendbAuth.ts
|
|
9379
|
-
import
|
|
9494
|
+
import chalk110 from "chalk";
|
|
9380
9495
|
|
|
9381
9496
|
// src/shared/createConnectionAuth.ts
|
|
9382
|
-
import
|
|
9497
|
+
import chalk105 from "chalk";
|
|
9383
9498
|
function listConnections(connections, format2) {
|
|
9384
9499
|
if (connections.length === 0) {
|
|
9385
9500
|
console.log("No connections configured.");
|
|
@@ -9392,7 +9507,7 @@ function listConnections(connections, format2) {
|
|
|
9392
9507
|
function removeConnection(connections, name, save) {
|
|
9393
9508
|
const filtered = connections.filter((c) => c.name !== name);
|
|
9394
9509
|
if (filtered.length === connections.length) {
|
|
9395
|
-
console.error(
|
|
9510
|
+
console.error(chalk105.red(`Connection "${name}" not found.`));
|
|
9396
9511
|
process.exit(1);
|
|
9397
9512
|
}
|
|
9398
9513
|
save(filtered);
|
|
@@ -9438,15 +9553,15 @@ function saveConnections(connections) {
|
|
|
9438
9553
|
}
|
|
9439
9554
|
|
|
9440
9555
|
// src/commands/ravendb/promptConnection.ts
|
|
9441
|
-
import
|
|
9556
|
+
import chalk108 from "chalk";
|
|
9442
9557
|
|
|
9443
9558
|
// src/commands/ravendb/selectOpSecret.ts
|
|
9444
|
-
import
|
|
9559
|
+
import chalk107 from "chalk";
|
|
9445
9560
|
import Enquirer2 from "enquirer";
|
|
9446
9561
|
|
|
9447
9562
|
// src/commands/ravendb/searchItems.ts
|
|
9448
9563
|
import { execSync as execSync33 } from "child_process";
|
|
9449
|
-
import
|
|
9564
|
+
import chalk106 from "chalk";
|
|
9450
9565
|
function opExec(args) {
|
|
9451
9566
|
return execSync33(`op ${args}`, {
|
|
9452
9567
|
encoding: "utf-8",
|
|
@@ -9459,7 +9574,7 @@ function searchItems(search2) {
|
|
|
9459
9574
|
items = JSON.parse(opExec("item list --format=json"));
|
|
9460
9575
|
} catch {
|
|
9461
9576
|
console.error(
|
|
9462
|
-
|
|
9577
|
+
chalk106.red(
|
|
9463
9578
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
9464
9579
|
)
|
|
9465
9580
|
);
|
|
@@ -9473,7 +9588,7 @@ function getItemFields(itemId) {
|
|
|
9473
9588
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
9474
9589
|
return item.fields.filter((f) => f.reference && f.label);
|
|
9475
9590
|
} catch {
|
|
9476
|
-
console.error(
|
|
9591
|
+
console.error(chalk106.red("Failed to get item details from 1Password."));
|
|
9477
9592
|
process.exit(1);
|
|
9478
9593
|
}
|
|
9479
9594
|
}
|
|
@@ -9492,7 +9607,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
9492
9607
|
}).run();
|
|
9493
9608
|
const items = searchItems(search2);
|
|
9494
9609
|
if (items.length === 0) {
|
|
9495
|
-
console.error(
|
|
9610
|
+
console.error(chalk107.red(`No items found matching "${search2}".`));
|
|
9496
9611
|
process.exit(1);
|
|
9497
9612
|
}
|
|
9498
9613
|
const itemId = await selectOne(
|
|
@@ -9501,7 +9616,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
9501
9616
|
);
|
|
9502
9617
|
const fields = getItemFields(itemId);
|
|
9503
9618
|
if (fields.length === 0) {
|
|
9504
|
-
console.error(
|
|
9619
|
+
console.error(chalk107.red("No fields with references found on this item."));
|
|
9505
9620
|
process.exit(1);
|
|
9506
9621
|
}
|
|
9507
9622
|
const ref = await selectOne(
|
|
@@ -9515,7 +9630,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
9515
9630
|
async function promptConnection(existingNames) {
|
|
9516
9631
|
const name = await promptInput("name", "Connection name:");
|
|
9517
9632
|
if (existingNames.includes(name)) {
|
|
9518
|
-
console.error(
|
|
9633
|
+
console.error(chalk108.red(`Connection "${name}" already exists.`));
|
|
9519
9634
|
process.exit(1);
|
|
9520
9635
|
}
|
|
9521
9636
|
const url = await promptInput(
|
|
@@ -9524,22 +9639,22 @@ async function promptConnection(existingNames) {
|
|
|
9524
9639
|
);
|
|
9525
9640
|
const database = await promptInput("database", "Database name:");
|
|
9526
9641
|
if (!name || !url || !database) {
|
|
9527
|
-
console.error(
|
|
9642
|
+
console.error(chalk108.red("All fields are required."));
|
|
9528
9643
|
process.exit(1);
|
|
9529
9644
|
}
|
|
9530
9645
|
const apiKeyRef = await selectOpSecret();
|
|
9531
|
-
console.log(
|
|
9646
|
+
console.log(chalk108.dim(`Using: ${apiKeyRef}`));
|
|
9532
9647
|
return { name, url, database, apiKeyRef };
|
|
9533
9648
|
}
|
|
9534
9649
|
|
|
9535
9650
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
9536
|
-
import
|
|
9651
|
+
import chalk109 from "chalk";
|
|
9537
9652
|
function ravendbSetConnection(name) {
|
|
9538
9653
|
const raw = loadGlobalConfigRaw();
|
|
9539
9654
|
const ravendb = raw.ravendb ?? {};
|
|
9540
9655
|
const connections = ravendb.connections ?? [];
|
|
9541
9656
|
if (!connections.some((c) => c.name === name)) {
|
|
9542
|
-
console.error(
|
|
9657
|
+
console.error(chalk109.red(`Connection "${name}" not found.`));
|
|
9543
9658
|
console.error(
|
|
9544
9659
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
9545
9660
|
);
|
|
@@ -9555,16 +9670,16 @@ function ravendbSetConnection(name) {
|
|
|
9555
9670
|
var ravendbAuth = createConnectionAuth({
|
|
9556
9671
|
load: loadConnections,
|
|
9557
9672
|
save: saveConnections,
|
|
9558
|
-
format: (c) => `${
|
|
9673
|
+
format: (c) => `${chalk110.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
9559
9674
|
promptNew: promptConnection,
|
|
9560
9675
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
9561
9676
|
});
|
|
9562
9677
|
|
|
9563
9678
|
// src/commands/ravendb/ravendbCollections.ts
|
|
9564
|
-
import
|
|
9679
|
+
import chalk114 from "chalk";
|
|
9565
9680
|
|
|
9566
9681
|
// src/commands/ravendb/ravenFetch.ts
|
|
9567
|
-
import
|
|
9682
|
+
import chalk112 from "chalk";
|
|
9568
9683
|
|
|
9569
9684
|
// src/commands/ravendb/getAccessToken.ts
|
|
9570
9685
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -9601,10 +9716,10 @@ ${errorText}`
|
|
|
9601
9716
|
|
|
9602
9717
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
9603
9718
|
import { execSync as execSync34 } from "child_process";
|
|
9604
|
-
import
|
|
9719
|
+
import chalk111 from "chalk";
|
|
9605
9720
|
function resolveOpSecret(reference) {
|
|
9606
9721
|
if (!reference.startsWith("op://")) {
|
|
9607
|
-
console.error(
|
|
9722
|
+
console.error(chalk111.red(`Invalid secret reference: must start with op://`));
|
|
9608
9723
|
process.exit(1);
|
|
9609
9724
|
}
|
|
9610
9725
|
try {
|
|
@@ -9614,7 +9729,7 @@ function resolveOpSecret(reference) {
|
|
|
9614
9729
|
}).trim();
|
|
9615
9730
|
} catch {
|
|
9616
9731
|
console.error(
|
|
9617
|
-
|
|
9732
|
+
chalk111.red(
|
|
9618
9733
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
9619
9734
|
)
|
|
9620
9735
|
);
|
|
@@ -9641,7 +9756,7 @@ async function ravenFetch(connection, path53) {
|
|
|
9641
9756
|
if (!response.ok) {
|
|
9642
9757
|
const body = await response.text();
|
|
9643
9758
|
console.error(
|
|
9644
|
-
|
|
9759
|
+
chalk112.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
9645
9760
|
);
|
|
9646
9761
|
console.error(body.substring(0, 500));
|
|
9647
9762
|
process.exit(1);
|
|
@@ -9650,7 +9765,7 @@ async function ravenFetch(connection, path53) {
|
|
|
9650
9765
|
}
|
|
9651
9766
|
|
|
9652
9767
|
// src/commands/ravendb/resolveConnection.ts
|
|
9653
|
-
import
|
|
9768
|
+
import chalk113 from "chalk";
|
|
9654
9769
|
function loadRavendb() {
|
|
9655
9770
|
const raw = loadGlobalConfigRaw();
|
|
9656
9771
|
const ravendb = raw.ravendb;
|
|
@@ -9664,7 +9779,7 @@ function resolveConnection(name) {
|
|
|
9664
9779
|
const connectionName = name ?? defaultConnection;
|
|
9665
9780
|
if (!connectionName) {
|
|
9666
9781
|
console.error(
|
|
9667
|
-
|
|
9782
|
+
chalk113.red(
|
|
9668
9783
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
9669
9784
|
)
|
|
9670
9785
|
);
|
|
@@ -9672,7 +9787,7 @@ function resolveConnection(name) {
|
|
|
9672
9787
|
}
|
|
9673
9788
|
const connection = connections.find((c) => c.name === connectionName);
|
|
9674
9789
|
if (!connection) {
|
|
9675
|
-
console.error(
|
|
9790
|
+
console.error(chalk113.red(`Connection "${connectionName}" not found.`));
|
|
9676
9791
|
console.error(
|
|
9677
9792
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
9678
9793
|
);
|
|
@@ -9703,15 +9818,15 @@ async function ravendbCollections(connectionName) {
|
|
|
9703
9818
|
return;
|
|
9704
9819
|
}
|
|
9705
9820
|
for (const c of collections) {
|
|
9706
|
-
console.log(`${
|
|
9821
|
+
console.log(`${chalk114.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
9707
9822
|
}
|
|
9708
9823
|
}
|
|
9709
9824
|
|
|
9710
9825
|
// src/commands/ravendb/ravendbQuery.ts
|
|
9711
|
-
import
|
|
9826
|
+
import chalk116 from "chalk";
|
|
9712
9827
|
|
|
9713
9828
|
// src/commands/ravendb/fetchAllPages.ts
|
|
9714
|
-
import
|
|
9829
|
+
import chalk115 from "chalk";
|
|
9715
9830
|
|
|
9716
9831
|
// src/commands/ravendb/buildQueryPath.ts
|
|
9717
9832
|
function buildQueryPath(opts) {
|
|
@@ -9749,7 +9864,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
9749
9864
|
allResults.push(...results);
|
|
9750
9865
|
start3 += results.length;
|
|
9751
9866
|
process.stderr.write(
|
|
9752
|
-
`\r${
|
|
9867
|
+
`\r${chalk115.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
9753
9868
|
);
|
|
9754
9869
|
if (start3 >= totalResults) break;
|
|
9755
9870
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -9764,7 +9879,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
9764
9879
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
9765
9880
|
const resolved = resolveArgs(connectionName, collection);
|
|
9766
9881
|
if (!resolved.collection && !options2.query) {
|
|
9767
|
-
console.error(
|
|
9882
|
+
console.error(chalk116.red("Provide a collection name or --query filter."));
|
|
9768
9883
|
process.exit(1);
|
|
9769
9884
|
}
|
|
9770
9885
|
const { collection: col } = resolved;
|
|
@@ -9802,7 +9917,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
9802
9917
|
import * as path30 from "path";
|
|
9803
9918
|
|
|
9804
9919
|
// src/commands/refactor/logViolations.ts
|
|
9805
|
-
import
|
|
9920
|
+
import chalk117 from "chalk";
|
|
9806
9921
|
var DEFAULT_MAX_LINES = 100;
|
|
9807
9922
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
9808
9923
|
if (violations.length === 0) {
|
|
@@ -9811,43 +9926,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
9811
9926
|
}
|
|
9812
9927
|
return;
|
|
9813
9928
|
}
|
|
9814
|
-
console.error(
|
|
9929
|
+
console.error(chalk117.red(`
|
|
9815
9930
|
Refactor check failed:
|
|
9816
9931
|
`));
|
|
9817
|
-
console.error(
|
|
9932
|
+
console.error(chalk117.red(` The following files exceed ${maxLines} lines:
|
|
9818
9933
|
`));
|
|
9819
9934
|
for (const violation of violations) {
|
|
9820
|
-
console.error(
|
|
9935
|
+
console.error(chalk117.red(` ${violation.file} (${violation.lines} lines)`));
|
|
9821
9936
|
}
|
|
9822
9937
|
console.error(
|
|
9823
|
-
|
|
9938
|
+
chalk117.yellow(
|
|
9824
9939
|
`
|
|
9825
9940
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
9826
9941
|
way to refactor it, ignore it with:
|
|
9827
9942
|
`
|
|
9828
9943
|
)
|
|
9829
9944
|
);
|
|
9830
|
-
console.error(
|
|
9945
|
+
console.error(chalk117.gray(` assist refactor ignore <file>
|
|
9831
9946
|
`));
|
|
9832
9947
|
if (process.env.CLAUDECODE) {
|
|
9833
|
-
console.error(
|
|
9948
|
+
console.error(chalk117.cyan(`
|
|
9834
9949
|
## Extracting Code to New Files
|
|
9835
9950
|
`));
|
|
9836
9951
|
console.error(
|
|
9837
|
-
|
|
9952
|
+
chalk117.cyan(
|
|
9838
9953
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
9839
9954
|
`
|
|
9840
9955
|
)
|
|
9841
9956
|
);
|
|
9842
9957
|
console.error(
|
|
9843
|
-
|
|
9958
|
+
chalk117.cyan(
|
|
9844
9959
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
9845
9960
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
9846
9961
|
`
|
|
9847
9962
|
)
|
|
9848
9963
|
);
|
|
9849
9964
|
console.error(
|
|
9850
|
-
|
|
9965
|
+
chalk117.cyan(
|
|
9851
9966
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
9852
9967
|
domains, move it to a common/shared folder.
|
|
9853
9968
|
`
|
|
@@ -9945,7 +10060,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
9945
10060
|
|
|
9946
10061
|
// src/commands/refactor/check/index.ts
|
|
9947
10062
|
function runScript(script, cwd) {
|
|
9948
|
-
return new Promise((
|
|
10063
|
+
return new Promise((resolve15) => {
|
|
9949
10064
|
const child = spawn5("npm", ["run", script], {
|
|
9950
10065
|
stdio: "pipe",
|
|
9951
10066
|
shell: true,
|
|
@@ -9959,7 +10074,7 @@ function runScript(script, cwd) {
|
|
|
9959
10074
|
output += data.toString();
|
|
9960
10075
|
});
|
|
9961
10076
|
child.on("close", (code) => {
|
|
9962
|
-
|
|
10077
|
+
resolve15({ script, code: code ?? 1, output });
|
|
9963
10078
|
});
|
|
9964
10079
|
});
|
|
9965
10080
|
}
|
|
@@ -10003,7 +10118,7 @@ async function check(pattern2, options2) {
|
|
|
10003
10118
|
|
|
10004
10119
|
// src/commands/refactor/extract/index.ts
|
|
10005
10120
|
import path36 from "path";
|
|
10006
|
-
import
|
|
10121
|
+
import chalk120 from "chalk";
|
|
10007
10122
|
|
|
10008
10123
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
10009
10124
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -10550,23 +10665,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
10550
10665
|
|
|
10551
10666
|
// src/commands/refactor/extract/displayPlan.ts
|
|
10552
10667
|
import path34 from "path";
|
|
10553
|
-
import
|
|
10668
|
+
import chalk118 from "chalk";
|
|
10554
10669
|
function section(title) {
|
|
10555
10670
|
return `
|
|
10556
|
-
${
|
|
10671
|
+
${chalk118.cyan(title)}`;
|
|
10557
10672
|
}
|
|
10558
10673
|
function displayImporters(plan2, cwd) {
|
|
10559
10674
|
if (plan2.importersToUpdate.length === 0) return;
|
|
10560
10675
|
console.log(section("Update importers:"));
|
|
10561
10676
|
for (const imp of plan2.importersToUpdate) {
|
|
10562
10677
|
const rel = path34.relative(cwd, imp.file.getFilePath());
|
|
10563
|
-
console.log(` ${
|
|
10678
|
+
console.log(` ${chalk118.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
10564
10679
|
}
|
|
10565
10680
|
}
|
|
10566
10681
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
10567
|
-
console.log(
|
|
10682
|
+
console.log(chalk118.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
10568
10683
|
`));
|
|
10569
|
-
console.log(` ${
|
|
10684
|
+
console.log(` ${chalk118.cyan("Functions to move:")}`);
|
|
10570
10685
|
for (const name of plan2.extractedNames) {
|
|
10571
10686
|
console.log(` ${name}`);
|
|
10572
10687
|
}
|
|
@@ -10601,7 +10716,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
10601
10716
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
10602
10717
|
import fs19 from "fs";
|
|
10603
10718
|
import path35 from "path";
|
|
10604
|
-
import
|
|
10719
|
+
import chalk119 from "chalk";
|
|
10605
10720
|
import { Project as Project2 } from "ts-morph";
|
|
10606
10721
|
function findTsConfig(sourcePath) {
|
|
10607
10722
|
const rootConfig = path35.resolve("tsconfig.json");
|
|
@@ -10632,7 +10747,7 @@ function loadProjectFile(file) {
|
|
|
10632
10747
|
});
|
|
10633
10748
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
10634
10749
|
if (!sourceFile) {
|
|
10635
|
-
console.log(
|
|
10750
|
+
console.log(chalk119.red(`File not found in project: ${file}`));
|
|
10636
10751
|
process.exit(1);
|
|
10637
10752
|
}
|
|
10638
10753
|
return { project, sourceFile };
|
|
@@ -10655,19 +10770,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
10655
10770
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
10656
10771
|
if (options2.apply) {
|
|
10657
10772
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
10658
|
-
console.log(
|
|
10773
|
+
console.log(chalk120.green("\nExtraction complete"));
|
|
10659
10774
|
} else {
|
|
10660
|
-
console.log(
|
|
10775
|
+
console.log(chalk120.dim("\nDry run. Use --apply to execute."));
|
|
10661
10776
|
}
|
|
10662
10777
|
}
|
|
10663
10778
|
|
|
10664
10779
|
// src/commands/refactor/ignore.ts
|
|
10665
10780
|
import fs20 from "fs";
|
|
10666
|
-
import
|
|
10781
|
+
import chalk121 from "chalk";
|
|
10667
10782
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
10668
10783
|
function ignore(file) {
|
|
10669
10784
|
if (!fs20.existsSync(file)) {
|
|
10670
|
-
console.error(
|
|
10785
|
+
console.error(chalk121.red(`Error: File does not exist: ${file}`));
|
|
10671
10786
|
process.exit(1);
|
|
10672
10787
|
}
|
|
10673
10788
|
const content = fs20.readFileSync(file, "utf-8");
|
|
@@ -10683,7 +10798,7 @@ function ignore(file) {
|
|
|
10683
10798
|
fs20.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
10684
10799
|
}
|
|
10685
10800
|
console.log(
|
|
10686
|
-
|
|
10801
|
+
chalk121.green(
|
|
10687
10802
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
10688
10803
|
)
|
|
10689
10804
|
);
|
|
@@ -10691,26 +10806,26 @@ function ignore(file) {
|
|
|
10691
10806
|
|
|
10692
10807
|
// src/commands/refactor/rename/index.ts
|
|
10693
10808
|
import path37 from "path";
|
|
10694
|
-
import
|
|
10809
|
+
import chalk122 from "chalk";
|
|
10695
10810
|
async function rename(source, destination, options2 = {}) {
|
|
10696
10811
|
const destPath = path37.resolve(destination);
|
|
10697
10812
|
const cwd = process.cwd();
|
|
10698
10813
|
const relSource = path37.relative(cwd, path37.resolve(source));
|
|
10699
10814
|
const relDest = path37.relative(cwd, destPath);
|
|
10700
10815
|
const { project, sourceFile } = loadProjectFile(source);
|
|
10701
|
-
console.log(
|
|
10816
|
+
console.log(chalk122.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
10702
10817
|
if (options2.apply) {
|
|
10703
10818
|
sourceFile.move(destPath);
|
|
10704
10819
|
await project.save();
|
|
10705
|
-
console.log(
|
|
10820
|
+
console.log(chalk122.green("Done"));
|
|
10706
10821
|
} else {
|
|
10707
|
-
console.log(
|
|
10822
|
+
console.log(chalk122.dim("Dry run. Use --apply to execute."));
|
|
10708
10823
|
}
|
|
10709
10824
|
}
|
|
10710
10825
|
|
|
10711
10826
|
// src/commands/refactor/renameSymbol/index.ts
|
|
10712
10827
|
import path39 from "path";
|
|
10713
|
-
import
|
|
10828
|
+
import chalk123 from "chalk";
|
|
10714
10829
|
import { Project as Project3 } from "ts-morph";
|
|
10715
10830
|
|
|
10716
10831
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -10759,38 +10874,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
10759
10874
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
10760
10875
|
const sourceFile = project.getSourceFile(filePath);
|
|
10761
10876
|
if (!sourceFile) {
|
|
10762
|
-
console.log(
|
|
10877
|
+
console.log(chalk123.red(`File not found in project: ${file}`));
|
|
10763
10878
|
process.exit(1);
|
|
10764
10879
|
}
|
|
10765
10880
|
const symbol = findSymbol(sourceFile, oldName);
|
|
10766
10881
|
if (!symbol) {
|
|
10767
|
-
console.log(
|
|
10882
|
+
console.log(chalk123.red(`Symbol "${oldName}" not found in ${file}`));
|
|
10768
10883
|
process.exit(1);
|
|
10769
10884
|
}
|
|
10770
10885
|
const grouped = groupReferences(symbol, cwd);
|
|
10771
10886
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
10772
10887
|
console.log(
|
|
10773
|
-
|
|
10888
|
+
chalk123.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
10774
10889
|
`)
|
|
10775
10890
|
);
|
|
10776
10891
|
for (const [refFile, lines] of grouped) {
|
|
10777
10892
|
console.log(
|
|
10778
|
-
` ${
|
|
10893
|
+
` ${chalk123.dim(refFile)}: lines ${chalk123.cyan(lines.join(", "))}`
|
|
10779
10894
|
);
|
|
10780
10895
|
}
|
|
10781
10896
|
if (options2.apply) {
|
|
10782
10897
|
symbol.rename(newName);
|
|
10783
10898
|
await project.save();
|
|
10784
|
-
console.log(
|
|
10899
|
+
console.log(chalk123.green(`
|
|
10785
10900
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
10786
10901
|
} else {
|
|
10787
|
-
console.log(
|
|
10902
|
+
console.log(chalk123.dim("\nDry run. Use --apply to execute."));
|
|
10788
10903
|
}
|
|
10789
10904
|
}
|
|
10790
10905
|
|
|
10791
10906
|
// src/commands/refactor/restructure/index.ts
|
|
10792
10907
|
import path48 from "path";
|
|
10793
|
-
import
|
|
10908
|
+
import chalk126 from "chalk";
|
|
10794
10909
|
|
|
10795
10910
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
10796
10911
|
import path40 from "path";
|
|
@@ -10913,8 +11028,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
10913
11028
|
function clusterFiles(graph) {
|
|
10914
11029
|
const clusters = /* @__PURE__ */ new Map();
|
|
10915
11030
|
for (const file of graph.files) {
|
|
10916
|
-
const
|
|
10917
|
-
if (
|
|
11031
|
+
const basename11 = path42.basename(file, path42.extname(file));
|
|
11032
|
+
if (basename11 === "index") continue;
|
|
10918
11033
|
const importers = graph.importedBy.get(file);
|
|
10919
11034
|
if (!importers || importers.size !== 1) continue;
|
|
10920
11035
|
const parent = [...importers][0];
|
|
@@ -11033,50 +11148,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
11033
11148
|
|
|
11034
11149
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
11035
11150
|
import path44 from "path";
|
|
11036
|
-
import
|
|
11151
|
+
import chalk124 from "chalk";
|
|
11037
11152
|
function relPath(filePath) {
|
|
11038
11153
|
return path44.relative(process.cwd(), filePath);
|
|
11039
11154
|
}
|
|
11040
11155
|
function displayMoves(plan2) {
|
|
11041
11156
|
if (plan2.moves.length === 0) return;
|
|
11042
|
-
console.log(
|
|
11157
|
+
console.log(chalk124.bold("\nFile moves:"));
|
|
11043
11158
|
for (const move of plan2.moves) {
|
|
11044
11159
|
console.log(
|
|
11045
|
-
` ${
|
|
11160
|
+
` ${chalk124.red(relPath(move.from))} \u2192 ${chalk124.green(relPath(move.to))}`
|
|
11046
11161
|
);
|
|
11047
|
-
console.log(
|
|
11162
|
+
console.log(chalk124.dim(` ${move.reason}`));
|
|
11048
11163
|
}
|
|
11049
11164
|
}
|
|
11050
11165
|
function displayRewrites(rewrites) {
|
|
11051
11166
|
if (rewrites.length === 0) return;
|
|
11052
11167
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
11053
|
-
console.log(
|
|
11168
|
+
console.log(chalk124.bold(`
|
|
11054
11169
|
Import rewrites (${affectedFiles.size} files):`));
|
|
11055
11170
|
for (const file of affectedFiles) {
|
|
11056
|
-
console.log(` ${
|
|
11171
|
+
console.log(` ${chalk124.cyan(relPath(file))}:`);
|
|
11057
11172
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
11058
11173
|
(r) => r.file === file
|
|
11059
11174
|
)) {
|
|
11060
11175
|
console.log(
|
|
11061
|
-
` ${
|
|
11176
|
+
` ${chalk124.red(`"${oldSpecifier}"`)} \u2192 ${chalk124.green(`"${newSpecifier}"`)}`
|
|
11062
11177
|
);
|
|
11063
11178
|
}
|
|
11064
11179
|
}
|
|
11065
11180
|
}
|
|
11066
11181
|
function displayPlan2(plan2) {
|
|
11067
11182
|
if (plan2.warnings.length > 0) {
|
|
11068
|
-
console.log(
|
|
11069
|
-
for (const w of plan2.warnings) console.log(
|
|
11183
|
+
console.log(chalk124.yellow("\nWarnings:"));
|
|
11184
|
+
for (const w of plan2.warnings) console.log(chalk124.yellow(` ${w}`));
|
|
11070
11185
|
}
|
|
11071
11186
|
if (plan2.newDirectories.length > 0) {
|
|
11072
|
-
console.log(
|
|
11187
|
+
console.log(chalk124.bold("\nNew directories:"));
|
|
11073
11188
|
for (const dir of plan2.newDirectories)
|
|
11074
|
-
console.log(
|
|
11189
|
+
console.log(chalk124.green(` ${dir}/`));
|
|
11075
11190
|
}
|
|
11076
11191
|
displayMoves(plan2);
|
|
11077
11192
|
displayRewrites(plan2.rewrites);
|
|
11078
11193
|
console.log(
|
|
11079
|
-
|
|
11194
|
+
chalk124.dim(
|
|
11080
11195
|
`
|
|
11081
11196
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
11082
11197
|
)
|
|
@@ -11086,18 +11201,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
11086
11201
|
// src/commands/refactor/restructure/executePlan.ts
|
|
11087
11202
|
import fs22 from "fs";
|
|
11088
11203
|
import path45 from "path";
|
|
11089
|
-
import
|
|
11204
|
+
import chalk125 from "chalk";
|
|
11090
11205
|
function executePlan(plan2) {
|
|
11091
11206
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
11092
11207
|
for (const [file, content] of updatedContents) {
|
|
11093
11208
|
fs22.writeFileSync(file, content, "utf-8");
|
|
11094
11209
|
console.log(
|
|
11095
|
-
|
|
11210
|
+
chalk125.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
11096
11211
|
);
|
|
11097
11212
|
}
|
|
11098
11213
|
for (const dir of plan2.newDirectories) {
|
|
11099
11214
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11100
|
-
console.log(
|
|
11215
|
+
console.log(chalk125.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
11101
11216
|
}
|
|
11102
11217
|
for (const move of plan2.moves) {
|
|
11103
11218
|
const targetDir = path45.dirname(move.to);
|
|
@@ -11106,7 +11221,7 @@ function executePlan(plan2) {
|
|
|
11106
11221
|
}
|
|
11107
11222
|
fs22.renameSync(move.from, move.to);
|
|
11108
11223
|
console.log(
|
|
11109
|
-
|
|
11224
|
+
chalk125.white(
|
|
11110
11225
|
` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
|
|
11111
11226
|
)
|
|
11112
11227
|
);
|
|
@@ -11121,7 +11236,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
11121
11236
|
if (entries.length === 0) {
|
|
11122
11237
|
fs22.rmdirSync(dir);
|
|
11123
11238
|
console.log(
|
|
11124
|
-
|
|
11239
|
+
chalk125.dim(
|
|
11125
11240
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
11126
11241
|
)
|
|
11127
11242
|
);
|
|
@@ -11254,22 +11369,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
11254
11369
|
const targetPattern = pattern2 ?? "src";
|
|
11255
11370
|
const files = findSourceFiles2(targetPattern);
|
|
11256
11371
|
if (files.length === 0) {
|
|
11257
|
-
console.log(
|
|
11372
|
+
console.log(chalk126.yellow("No files found matching pattern"));
|
|
11258
11373
|
return;
|
|
11259
11374
|
}
|
|
11260
11375
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
11261
11376
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
11262
11377
|
if (plan2.moves.length === 0) {
|
|
11263
|
-
console.log(
|
|
11378
|
+
console.log(chalk126.green("No restructuring needed"));
|
|
11264
11379
|
return;
|
|
11265
11380
|
}
|
|
11266
11381
|
displayPlan2(plan2);
|
|
11267
11382
|
if (options2.apply) {
|
|
11268
|
-
console.log(
|
|
11383
|
+
console.log(chalk126.bold("\nApplying changes..."));
|
|
11269
11384
|
executePlan(plan2);
|
|
11270
|
-
console.log(
|
|
11385
|
+
console.log(chalk126.green("\nRestructuring complete"));
|
|
11271
11386
|
} else {
|
|
11272
|
-
console.log(
|
|
11387
|
+
console.log(chalk126.dim("\nDry run. Use --apply to execute."));
|
|
11273
11388
|
}
|
|
11274
11389
|
}
|
|
11275
11390
|
|
|
@@ -11309,7 +11424,7 @@ function registerRefactor(program2) {
|
|
|
11309
11424
|
}
|
|
11310
11425
|
|
|
11311
11426
|
// src/commands/seq/seqAuth.ts
|
|
11312
|
-
import
|
|
11427
|
+
import chalk128 from "chalk";
|
|
11313
11428
|
|
|
11314
11429
|
// src/commands/seq/loadConnections.ts
|
|
11315
11430
|
function loadConnections2() {
|
|
@@ -11338,11 +11453,11 @@ function setDefaultConnection(name) {
|
|
|
11338
11453
|
}
|
|
11339
11454
|
|
|
11340
11455
|
// src/commands/seq/promptConnection.ts
|
|
11341
|
-
import
|
|
11456
|
+
import chalk127 from "chalk";
|
|
11342
11457
|
async function promptConnection2(existingNames) {
|
|
11343
11458
|
const name = await promptInput("name", "Connection name:", "default");
|
|
11344
11459
|
if (existingNames.includes(name)) {
|
|
11345
|
-
console.error(
|
|
11460
|
+
console.error(chalk127.red(`Connection "${name}" already exists.`));
|
|
11346
11461
|
process.exit(1);
|
|
11347
11462
|
}
|
|
11348
11463
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -11354,16 +11469,16 @@ async function promptConnection2(existingNames) {
|
|
|
11354
11469
|
var seqAuth = createConnectionAuth({
|
|
11355
11470
|
load: loadConnections2,
|
|
11356
11471
|
save: saveConnections2,
|
|
11357
|
-
format: (c) => `${
|
|
11472
|
+
format: (c) => `${chalk128.bold(c.name)} ${c.url}`,
|
|
11358
11473
|
promptNew: promptConnection2,
|
|
11359
11474
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
11360
11475
|
});
|
|
11361
11476
|
|
|
11362
11477
|
// src/commands/seq/seqQuery.ts
|
|
11363
|
-
import
|
|
11478
|
+
import chalk132 from "chalk";
|
|
11364
11479
|
|
|
11365
11480
|
// src/commands/seq/fetchSeq.ts
|
|
11366
|
-
import
|
|
11481
|
+
import chalk129 from "chalk";
|
|
11367
11482
|
async function fetchSeq(conn, path53, params) {
|
|
11368
11483
|
const url = `${conn.url}${path53}?${params}`;
|
|
11369
11484
|
const response = await fetch(url, {
|
|
@@ -11374,7 +11489,7 @@ async function fetchSeq(conn, path53, params) {
|
|
|
11374
11489
|
});
|
|
11375
11490
|
if (!response.ok) {
|
|
11376
11491
|
const body = await response.text();
|
|
11377
|
-
console.error(
|
|
11492
|
+
console.error(chalk129.red(`Seq returned ${response.status}: ${body}`));
|
|
11378
11493
|
process.exit(1);
|
|
11379
11494
|
}
|
|
11380
11495
|
return response;
|
|
@@ -11429,23 +11544,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
11429
11544
|
}
|
|
11430
11545
|
|
|
11431
11546
|
// src/commands/seq/formatEvent.ts
|
|
11432
|
-
import
|
|
11547
|
+
import chalk130 from "chalk";
|
|
11433
11548
|
function levelColor(level) {
|
|
11434
11549
|
switch (level) {
|
|
11435
11550
|
case "Fatal":
|
|
11436
|
-
return
|
|
11551
|
+
return chalk130.bgRed.white;
|
|
11437
11552
|
case "Error":
|
|
11438
|
-
return
|
|
11553
|
+
return chalk130.red;
|
|
11439
11554
|
case "Warning":
|
|
11440
|
-
return
|
|
11555
|
+
return chalk130.yellow;
|
|
11441
11556
|
case "Information":
|
|
11442
|
-
return
|
|
11557
|
+
return chalk130.cyan;
|
|
11443
11558
|
case "Debug":
|
|
11444
|
-
return
|
|
11559
|
+
return chalk130.gray;
|
|
11445
11560
|
case "Verbose":
|
|
11446
|
-
return
|
|
11561
|
+
return chalk130.dim;
|
|
11447
11562
|
default:
|
|
11448
|
-
return
|
|
11563
|
+
return chalk130.white;
|
|
11449
11564
|
}
|
|
11450
11565
|
}
|
|
11451
11566
|
function levelAbbrev(level) {
|
|
@@ -11486,12 +11601,12 @@ function formatTimestamp(iso) {
|
|
|
11486
11601
|
function formatEvent(event) {
|
|
11487
11602
|
const color = levelColor(event.Level);
|
|
11488
11603
|
const abbrev = levelAbbrev(event.Level);
|
|
11489
|
-
const ts8 =
|
|
11604
|
+
const ts8 = chalk130.dim(formatTimestamp(event.Timestamp));
|
|
11490
11605
|
const msg = renderMessage(event);
|
|
11491
11606
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
11492
11607
|
if (event.Exception) {
|
|
11493
11608
|
for (const line of event.Exception.split("\n")) {
|
|
11494
|
-
lines.push(
|
|
11609
|
+
lines.push(chalk130.red(` ${line}`));
|
|
11495
11610
|
}
|
|
11496
11611
|
}
|
|
11497
11612
|
return lines.join("\n");
|
|
@@ -11524,19 +11639,19 @@ function rejectTimestampFilter(filter) {
|
|
|
11524
11639
|
}
|
|
11525
11640
|
|
|
11526
11641
|
// src/commands/seq/resolveConnection.ts
|
|
11527
|
-
import
|
|
11642
|
+
import chalk131 from "chalk";
|
|
11528
11643
|
function resolveConnection2(name) {
|
|
11529
11644
|
const connections = loadConnections2();
|
|
11530
11645
|
if (connections.length === 0) {
|
|
11531
11646
|
console.error(
|
|
11532
|
-
|
|
11647
|
+
chalk131.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
11533
11648
|
);
|
|
11534
11649
|
process.exit(1);
|
|
11535
11650
|
}
|
|
11536
11651
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
11537
11652
|
const connection = connections.find((c) => c.name === target);
|
|
11538
11653
|
if (!connection) {
|
|
11539
|
-
console.error(
|
|
11654
|
+
console.error(chalk131.red(`Seq connection "${target}" not found.`));
|
|
11540
11655
|
process.exit(1);
|
|
11541
11656
|
}
|
|
11542
11657
|
return connection;
|
|
@@ -11554,7 +11669,7 @@ async function seqQuery(filter, options2) {
|
|
|
11554
11669
|
new URLSearchParams({ filter, count: String(count) })
|
|
11555
11670
|
);
|
|
11556
11671
|
if (events.length === 0) {
|
|
11557
|
-
console.log(
|
|
11672
|
+
console.log(chalk132.yellow("No events found."));
|
|
11558
11673
|
return;
|
|
11559
11674
|
}
|
|
11560
11675
|
if (options2.json) {
|
|
@@ -11565,11 +11680,11 @@ async function seqQuery(filter, options2) {
|
|
|
11565
11680
|
for (const event of chronological) {
|
|
11566
11681
|
console.log(formatEvent(event));
|
|
11567
11682
|
}
|
|
11568
|
-
console.log(
|
|
11683
|
+
console.log(chalk132.dim(`
|
|
11569
11684
|
${events.length} events`));
|
|
11570
11685
|
if (events.length >= count) {
|
|
11571
11686
|
console.log(
|
|
11572
|
-
|
|
11687
|
+
chalk132.yellow(
|
|
11573
11688
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
11574
11689
|
)
|
|
11575
11690
|
);
|
|
@@ -11577,11 +11692,11 @@ ${events.length} events`));
|
|
|
11577
11692
|
}
|
|
11578
11693
|
|
|
11579
11694
|
// src/commands/seq/seqSetConnection.ts
|
|
11580
|
-
import
|
|
11695
|
+
import chalk133 from "chalk";
|
|
11581
11696
|
function seqSetConnection(name) {
|
|
11582
11697
|
const connections = loadConnections2();
|
|
11583
11698
|
if (!connections.find((c) => c.name === name)) {
|
|
11584
|
-
console.error(
|
|
11699
|
+
console.error(chalk133.red(`Connection "${name}" not found.`));
|
|
11585
11700
|
process.exit(1);
|
|
11586
11701
|
}
|
|
11587
11702
|
setDefaultConnection(name);
|
|
@@ -11606,8 +11721,8 @@ function registerSeq(program2) {
|
|
|
11606
11721
|
}
|
|
11607
11722
|
|
|
11608
11723
|
// src/commands/transcript/shared.ts
|
|
11609
|
-
import { existsSync as existsSync32, readdirSync as
|
|
11610
|
-
import { basename as
|
|
11724
|
+
import { existsSync as existsSync32, readdirSync as readdirSync6, statSync as statSync4 } from "fs";
|
|
11725
|
+
import { basename as basename8, join as join34, relative as relative2 } from "path";
|
|
11611
11726
|
import * as readline2 from "readline";
|
|
11612
11727
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
11613
11728
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -11624,7 +11739,7 @@ function isValidDatePrefix(filename) {
|
|
|
11624
11739
|
function collectFiles(dir, extension) {
|
|
11625
11740
|
if (!existsSync32(dir)) return [];
|
|
11626
11741
|
const results = [];
|
|
11627
|
-
for (const entry of
|
|
11742
|
+
for (const entry of readdirSync6(dir)) {
|
|
11628
11743
|
const fullPath = join34(dir, entry);
|
|
11629
11744
|
if (statSync4(fullPath).isDirectory()) {
|
|
11630
11745
|
results.push(...collectFiles(fullPath, extension));
|
|
@@ -11638,7 +11753,7 @@ function toFileInfo(baseDir, fullPath) {
|
|
|
11638
11753
|
return {
|
|
11639
11754
|
absolutePath: fullPath,
|
|
11640
11755
|
relativePath: relative2(baseDir, fullPath),
|
|
11641
|
-
filename:
|
|
11756
|
+
filename: basename8(fullPath)
|
|
11642
11757
|
};
|
|
11643
11758
|
}
|
|
11644
11759
|
function findVttFilesRecursive(dir, baseDir = dir) {
|
|
@@ -11648,7 +11763,7 @@ function findMdFilesRecursive(dir, baseDir = dir) {
|
|
|
11648
11763
|
return collectFiles(dir, ".md").map((f) => toFileInfo(baseDir, f));
|
|
11649
11764
|
}
|
|
11650
11765
|
function getTranscriptBaseName(transcriptFile) {
|
|
11651
|
-
return
|
|
11766
|
+
return basename8(transcriptFile, ".md").replace(/ Transcription$/, "");
|
|
11652
11767
|
}
|
|
11653
11768
|
function createReadlineInterface() {
|
|
11654
11769
|
return readline2.createInterface({
|
|
@@ -11657,9 +11772,9 @@ function createReadlineInterface() {
|
|
|
11657
11772
|
});
|
|
11658
11773
|
}
|
|
11659
11774
|
function askQuestion(rl, question) {
|
|
11660
|
-
return new Promise((
|
|
11775
|
+
return new Promise((resolve15) => {
|
|
11661
11776
|
rl.question(question, (answer) => {
|
|
11662
|
-
|
|
11777
|
+
resolve15(answer.trim());
|
|
11663
11778
|
});
|
|
11664
11779
|
});
|
|
11665
11780
|
}
|
|
@@ -11793,8 +11908,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
11793
11908
|
}
|
|
11794
11909
|
|
|
11795
11910
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
11796
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
11797
|
-
import { basename as
|
|
11911
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync10, readFileSync as readFileSync29, writeFileSync as writeFileSync26 } from "fs";
|
|
11912
|
+
import { basename as basename9, dirname as dirname21, join as join37 } from "path";
|
|
11798
11913
|
|
|
11799
11914
|
// src/commands/transcript/cleanText.ts
|
|
11800
11915
|
function cleanText(text) {
|
|
@@ -12001,7 +12116,7 @@ function formatChatLog(messages) {
|
|
|
12001
12116
|
|
|
12002
12117
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
12003
12118
|
function toMdFilename(vttFilename) {
|
|
12004
|
-
return `${
|
|
12119
|
+
return `${basename9(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
12005
12120
|
}
|
|
12006
12121
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
12007
12122
|
return relativeDir === "." ? transcriptsDir : join37(transcriptsDir, relativeDir);
|
|
@@ -12019,7 +12134,7 @@ function logSkipped(relativeDir, mdFile) {
|
|
|
12019
12134
|
}
|
|
12020
12135
|
function ensureDirectory(dir, label2) {
|
|
12021
12136
|
if (!existsSync33(dir)) {
|
|
12022
|
-
|
|
12137
|
+
mkdirSync10(dir, { recursive: true });
|
|
12023
12138
|
console.log(`Created ${label2}: ${dir}`);
|
|
12024
12139
|
}
|
|
12025
12140
|
}
|
|
@@ -12041,10 +12156,10 @@ function logReduction(cueCount, messageCount) {
|
|
|
12041
12156
|
}
|
|
12042
12157
|
function readAndParseCues(inputPath) {
|
|
12043
12158
|
console.log(`Reading: ${inputPath}`);
|
|
12044
|
-
return processCues(
|
|
12159
|
+
return processCues(readFileSync29(inputPath, "utf-8"));
|
|
12045
12160
|
}
|
|
12046
12161
|
function writeFormatted(outputPath, content) {
|
|
12047
|
-
|
|
12162
|
+
writeFileSync26(outputPath, content, "utf-8");
|
|
12048
12163
|
console.log(`Written: ${outputPath}`);
|
|
12049
12164
|
}
|
|
12050
12165
|
function convertVttToMarkdown(inputPath, outputPath) {
|
|
@@ -12113,27 +12228,27 @@ async function format() {
|
|
|
12113
12228
|
|
|
12114
12229
|
// src/commands/transcript/summarise/index.ts
|
|
12115
12230
|
import { existsSync as existsSync36 } from "fs";
|
|
12116
|
-
import { basename as
|
|
12231
|
+
import { basename as basename10, dirname as dirname23, join as join39, relative as relative3 } from "path";
|
|
12117
12232
|
|
|
12118
12233
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
12119
12234
|
import {
|
|
12120
12235
|
existsSync as existsSync35,
|
|
12121
|
-
mkdirSync as
|
|
12122
|
-
readFileSync as
|
|
12236
|
+
mkdirSync as mkdirSync11,
|
|
12237
|
+
readFileSync as readFileSync30,
|
|
12123
12238
|
renameSync as renameSync3,
|
|
12124
12239
|
rmSync
|
|
12125
12240
|
} from "fs";
|
|
12126
12241
|
import { dirname as dirname22, join as join38 } from "path";
|
|
12127
12242
|
|
|
12128
12243
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
12129
|
-
import
|
|
12244
|
+
import chalk134 from "chalk";
|
|
12130
12245
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
12131
12246
|
function validateStagedContent(filename, content) {
|
|
12132
12247
|
const firstLine = content.split("\n")[0];
|
|
12133
12248
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
12134
12249
|
if (!match) {
|
|
12135
12250
|
console.error(
|
|
12136
|
-
|
|
12251
|
+
chalk134.red(
|
|
12137
12252
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
12138
12253
|
)
|
|
12139
12254
|
);
|
|
@@ -12142,7 +12257,7 @@ function validateStagedContent(filename, content) {
|
|
|
12142
12257
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
12143
12258
|
if (!contentAfterLink) {
|
|
12144
12259
|
console.error(
|
|
12145
|
-
|
|
12260
|
+
chalk134.red(
|
|
12146
12261
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
12147
12262
|
)
|
|
12148
12263
|
);
|
|
@@ -12163,7 +12278,7 @@ function processStagedFile() {
|
|
|
12163
12278
|
}
|
|
12164
12279
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
12165
12280
|
const stagedFile = stagedFiles[0];
|
|
12166
|
-
const content =
|
|
12281
|
+
const content = readFileSync30(stagedFile.absolutePath, "utf-8");
|
|
12167
12282
|
validateStagedContent(stagedFile.filename, content);
|
|
12168
12283
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
12169
12284
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -12179,7 +12294,7 @@ function processStagedFile() {
|
|
|
12179
12294
|
const destPath = join38(summaryDir, matchingTranscript.relativePath);
|
|
12180
12295
|
const destDir = dirname22(destPath);
|
|
12181
12296
|
if (!existsSync35(destDir)) {
|
|
12182
|
-
|
|
12297
|
+
mkdirSync11(destDir, { recursive: true });
|
|
12183
12298
|
}
|
|
12184
12299
|
renameSync3(stagedFile.absolutePath, destPath);
|
|
12185
12300
|
const remaining = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -12198,7 +12313,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
12198
12313
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
12199
12314
|
return new Set(
|
|
12200
12315
|
summaryFiles.map(
|
|
12201
|
-
(f) => buildRelativeKey(f.relativePath,
|
|
12316
|
+
(f) => buildRelativeKey(f.relativePath, basename10(f.filename, ".md"))
|
|
12202
12317
|
)
|
|
12203
12318
|
);
|
|
12204
12319
|
}
|
|
@@ -12312,14 +12427,14 @@ function devices() {
|
|
|
12312
12427
|
}
|
|
12313
12428
|
|
|
12314
12429
|
// src/commands/voice/logs.ts
|
|
12315
|
-
import { existsSync as existsSync37, readFileSync as
|
|
12430
|
+
import { existsSync as existsSync37, readFileSync as readFileSync31 } from "fs";
|
|
12316
12431
|
function logs(options2) {
|
|
12317
12432
|
if (!existsSync37(voicePaths.log)) {
|
|
12318
12433
|
console.log("No voice log file found");
|
|
12319
12434
|
return;
|
|
12320
12435
|
}
|
|
12321
12436
|
const count = Number.parseInt(options2.lines ?? "150", 10);
|
|
12322
|
-
const content =
|
|
12437
|
+
const content = readFileSync31(voicePaths.log, "utf-8").trim();
|
|
12323
12438
|
if (!content) {
|
|
12324
12439
|
console.log("Voice log is empty");
|
|
12325
12440
|
return;
|
|
@@ -12341,12 +12456,12 @@ function logs(options2) {
|
|
|
12341
12456
|
|
|
12342
12457
|
// src/commands/voice/setup.ts
|
|
12343
12458
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
12344
|
-
import { mkdirSync as
|
|
12459
|
+
import { mkdirSync as mkdirSync13 } from "fs";
|
|
12345
12460
|
import { join as join43 } from "path";
|
|
12346
12461
|
|
|
12347
12462
|
// src/commands/voice/checkLockFile.ts
|
|
12348
12463
|
import { execSync as execSync36 } from "child_process";
|
|
12349
|
-
import { existsSync as existsSync38, mkdirSync as
|
|
12464
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync12, readFileSync as readFileSync32, writeFileSync as writeFileSync27 } from "fs";
|
|
12350
12465
|
import { join as join42 } from "path";
|
|
12351
12466
|
function isProcessAlive2(pid) {
|
|
12352
12467
|
try {
|
|
@@ -12360,7 +12475,7 @@ function checkLockFile() {
|
|
|
12360
12475
|
const lockFile = getLockFile();
|
|
12361
12476
|
if (!existsSync38(lockFile)) return;
|
|
12362
12477
|
try {
|
|
12363
|
-
const lock = JSON.parse(
|
|
12478
|
+
const lock = JSON.parse(readFileSync32(lockFile, "utf-8"));
|
|
12364
12479
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
12365
12480
|
console.error(
|
|
12366
12481
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -12384,8 +12499,8 @@ function bootstrapVenv() {
|
|
|
12384
12499
|
}
|
|
12385
12500
|
function writeLockFile(pid) {
|
|
12386
12501
|
const lockFile = getLockFile();
|
|
12387
|
-
|
|
12388
|
-
|
|
12502
|
+
mkdirSync12(join42(lockFile, ".."), { recursive: true });
|
|
12503
|
+
writeFileSync27(
|
|
12389
12504
|
lockFile,
|
|
12390
12505
|
JSON.stringify({
|
|
12391
12506
|
pid,
|
|
@@ -12397,7 +12512,7 @@ function writeLockFile(pid) {
|
|
|
12397
12512
|
|
|
12398
12513
|
// src/commands/voice/setup.ts
|
|
12399
12514
|
function setup() {
|
|
12400
|
-
|
|
12515
|
+
mkdirSync13(voicePaths.dir, { recursive: true });
|
|
12401
12516
|
bootstrapVenv();
|
|
12402
12517
|
console.log("\nDownloading models...\n");
|
|
12403
12518
|
const script = join43(getPythonDir(), "setup_models.py");
|
|
@@ -12413,7 +12528,7 @@ function setup() {
|
|
|
12413
12528
|
|
|
12414
12529
|
// src/commands/voice/start.ts
|
|
12415
12530
|
import { spawn as spawn6 } from "child_process";
|
|
12416
|
-
import { mkdirSync as
|
|
12531
|
+
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync28 } from "fs";
|
|
12417
12532
|
import { join as join44 } from "path";
|
|
12418
12533
|
|
|
12419
12534
|
// src/commands/voice/buildDaemonEnv.ts
|
|
@@ -12442,12 +12557,12 @@ function spawnBackground(python, script, env) {
|
|
|
12442
12557
|
console.error("Failed to start voice daemon");
|
|
12443
12558
|
process.exit(1);
|
|
12444
12559
|
}
|
|
12445
|
-
|
|
12560
|
+
writeFileSync28(voicePaths.pid, String(pid));
|
|
12446
12561
|
writeLockFile(pid);
|
|
12447
12562
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
12448
12563
|
}
|
|
12449
12564
|
function start2(options2) {
|
|
12450
|
-
|
|
12565
|
+
mkdirSync14(voicePaths.dir, { recursive: true });
|
|
12451
12566
|
checkLockFile();
|
|
12452
12567
|
bootstrapVenv();
|
|
12453
12568
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
@@ -12462,7 +12577,7 @@ function start2(options2) {
|
|
|
12462
12577
|
}
|
|
12463
12578
|
|
|
12464
12579
|
// src/commands/voice/status.ts
|
|
12465
|
-
import { existsSync as existsSync39, readFileSync as
|
|
12580
|
+
import { existsSync as existsSync39, readFileSync as readFileSync33 } from "fs";
|
|
12466
12581
|
function isProcessAlive3(pid) {
|
|
12467
12582
|
try {
|
|
12468
12583
|
process.kill(pid, 0);
|
|
@@ -12473,7 +12588,7 @@ function isProcessAlive3(pid) {
|
|
|
12473
12588
|
}
|
|
12474
12589
|
function readRecentLogs(count) {
|
|
12475
12590
|
if (!existsSync39(voicePaths.log)) return [];
|
|
12476
|
-
const lines =
|
|
12591
|
+
const lines = readFileSync33(voicePaths.log, "utf-8").trim().split("\n");
|
|
12477
12592
|
return lines.slice(-count);
|
|
12478
12593
|
}
|
|
12479
12594
|
function status() {
|
|
@@ -12481,7 +12596,7 @@ function status() {
|
|
|
12481
12596
|
console.log("Voice daemon: not running (no PID file)");
|
|
12482
12597
|
return;
|
|
12483
12598
|
}
|
|
12484
|
-
const pid = Number.parseInt(
|
|
12599
|
+
const pid = Number.parseInt(readFileSync33(voicePaths.pid, "utf-8").trim(), 10);
|
|
12485
12600
|
const alive = isProcessAlive3(pid);
|
|
12486
12601
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
12487
12602
|
const recent = readRecentLogs(5);
|
|
@@ -12500,13 +12615,13 @@ function status() {
|
|
|
12500
12615
|
}
|
|
12501
12616
|
|
|
12502
12617
|
// src/commands/voice/stop.ts
|
|
12503
|
-
import { existsSync as existsSync40, readFileSync as
|
|
12618
|
+
import { existsSync as existsSync40, readFileSync as readFileSync34, unlinkSync as unlinkSync10 } from "fs";
|
|
12504
12619
|
function stop() {
|
|
12505
12620
|
if (!existsSync40(voicePaths.pid)) {
|
|
12506
12621
|
console.log("Voice daemon is not running (no PID file)");
|
|
12507
12622
|
return;
|
|
12508
12623
|
}
|
|
12509
|
-
const pid = Number.parseInt(
|
|
12624
|
+
const pid = Number.parseInt(readFileSync34(voicePaths.pid, "utf-8").trim(), 10);
|
|
12510
12625
|
try {
|
|
12511
12626
|
process.kill(pid, "SIGTERM");
|
|
12512
12627
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -12538,7 +12653,7 @@ function registerVoice(program2) {
|
|
|
12538
12653
|
|
|
12539
12654
|
// src/commands/roam/auth.ts
|
|
12540
12655
|
import { randomBytes } from "crypto";
|
|
12541
|
-
import
|
|
12656
|
+
import chalk135 from "chalk";
|
|
12542
12657
|
|
|
12543
12658
|
// src/lib/openBrowser.ts
|
|
12544
12659
|
import { execSync as execSync37 } from "child_process";
|
|
@@ -12603,7 +12718,7 @@ function extractCode(url, expectedState) {
|
|
|
12603
12718
|
return code;
|
|
12604
12719
|
}
|
|
12605
12720
|
function waitForCallback(port, expectedState) {
|
|
12606
|
-
return new Promise((
|
|
12721
|
+
return new Promise((resolve15, reject) => {
|
|
12607
12722
|
const timeout = setTimeout(() => {
|
|
12608
12723
|
server.close();
|
|
12609
12724
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -12620,7 +12735,7 @@ function waitForCallback(port, expectedState) {
|
|
|
12620
12735
|
const code = extractCode(url, expectedState);
|
|
12621
12736
|
respondHtml(res, 200, "Authorization successful!");
|
|
12622
12737
|
server.close();
|
|
12623
|
-
|
|
12738
|
+
resolve15(code);
|
|
12624
12739
|
} catch (err) {
|
|
12625
12740
|
respondHtml(res, 400, err.message);
|
|
12626
12741
|
server.close();
|
|
@@ -12713,13 +12828,13 @@ async function auth() {
|
|
|
12713
12828
|
saveGlobalConfig(config);
|
|
12714
12829
|
const state = randomBytes(16).toString("hex");
|
|
12715
12830
|
console.log(
|
|
12716
|
-
|
|
12831
|
+
chalk135.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
12717
12832
|
);
|
|
12718
|
-
console.log(
|
|
12719
|
-
console.log(
|
|
12720
|
-
console.log(
|
|
12833
|
+
console.log(chalk135.white("http://localhost:14523/callback\n"));
|
|
12834
|
+
console.log(chalk135.blue("Opening browser for authorization..."));
|
|
12835
|
+
console.log(chalk135.dim("Waiting for authorization callback..."));
|
|
12721
12836
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
12722
|
-
console.log(
|
|
12837
|
+
console.log(chalk135.dim("Exchanging code for tokens..."));
|
|
12723
12838
|
const tokens = await exchangeToken({
|
|
12724
12839
|
code,
|
|
12725
12840
|
clientId,
|
|
@@ -12735,18 +12850,18 @@ async function auth() {
|
|
|
12735
12850
|
};
|
|
12736
12851
|
saveGlobalConfig(config);
|
|
12737
12852
|
console.log(
|
|
12738
|
-
|
|
12853
|
+
chalk135.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
12739
12854
|
);
|
|
12740
12855
|
}
|
|
12741
12856
|
|
|
12742
12857
|
// src/commands/roam/postRoamActivity.ts
|
|
12743
12858
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
12744
|
-
import { readdirSync as
|
|
12859
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync35, statSync as statSync5 } from "fs";
|
|
12745
12860
|
import { join as join45 } from "path";
|
|
12746
12861
|
function findPortFile(roamDir) {
|
|
12747
12862
|
let entries;
|
|
12748
12863
|
try {
|
|
12749
|
-
entries =
|
|
12864
|
+
entries = readdirSync7(roamDir);
|
|
12750
12865
|
} catch {
|
|
12751
12866
|
return void 0;
|
|
12752
12867
|
}
|
|
@@ -12767,7 +12882,7 @@ function postRoamActivity(app, event) {
|
|
|
12767
12882
|
if (!portFile) return;
|
|
12768
12883
|
let port;
|
|
12769
12884
|
try {
|
|
12770
|
-
port =
|
|
12885
|
+
port = readFileSync35(portFile, "utf-8").trim();
|
|
12771
12886
|
} catch {
|
|
12772
12887
|
return;
|
|
12773
12888
|
}
|
|
@@ -12811,7 +12926,7 @@ function registerRoam(program2) {
|
|
|
12811
12926
|
}
|
|
12812
12927
|
|
|
12813
12928
|
// src/commands/run/index.ts
|
|
12814
|
-
import { resolve as
|
|
12929
|
+
import { resolve as resolve12 } from "path";
|
|
12815
12930
|
|
|
12816
12931
|
// src/commands/run/findRunConfig.ts
|
|
12817
12932
|
function exitNoRunConfigs() {
|
|
@@ -12902,12 +13017,12 @@ function runPreCommands(pre, cwd) {
|
|
|
12902
13017
|
// src/commands/run/spawnRunCommand.ts
|
|
12903
13018
|
import { execFileSync as execFileSync5, spawn as spawn7 } from "child_process";
|
|
12904
13019
|
import { existsSync as existsSync41 } from "fs";
|
|
12905
|
-
import { dirname as dirname25, join as join46, resolve as
|
|
13020
|
+
import { dirname as dirname25, join as join46, resolve as resolve11 } from "path";
|
|
12906
13021
|
function resolveCommand2(command) {
|
|
12907
13022
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
12908
13023
|
try {
|
|
12909
13024
|
const gitPath = execFileSync5("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
12910
|
-
const gitRoot =
|
|
13025
|
+
const gitRoot = resolve11(dirname25(gitPath), "..");
|
|
12911
13026
|
const gitBash = join46(gitRoot, "bin", "bash.exe");
|
|
12912
13027
|
if (existsSync41(gitBash)) return gitBash;
|
|
12913
13028
|
} catch {
|
|
@@ -12946,7 +13061,7 @@ function listRunConfigs(verbose) {
|
|
|
12946
13061
|
}
|
|
12947
13062
|
}
|
|
12948
13063
|
function execRunConfig(config, args) {
|
|
12949
|
-
const cwd = config.cwd ?
|
|
13064
|
+
const cwd = config.cwd ? resolve12(getConfigDir(), config.cwd) : void 0;
|
|
12950
13065
|
if (config.pre) runPreCommands(config.pre, cwd);
|
|
12951
13066
|
const resolved = resolveParams(config.params, args);
|
|
12952
13067
|
spawnRunCommand(
|
|
@@ -12966,7 +13081,7 @@ function run3(name, args) {
|
|
|
12966
13081
|
}
|
|
12967
13082
|
|
|
12968
13083
|
// src/commands/run/add.ts
|
|
12969
|
-
import { mkdirSync as
|
|
13084
|
+
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync29 } from "fs";
|
|
12970
13085
|
import { join as join47 } from "path";
|
|
12971
13086
|
|
|
12972
13087
|
// src/commands/run/extractOption.ts
|
|
@@ -13029,7 +13144,7 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
13029
13144
|
}
|
|
13030
13145
|
function createCommandFile(name) {
|
|
13031
13146
|
const dir = join47(".claude", "commands");
|
|
13032
|
-
|
|
13147
|
+
mkdirSync15(dir, { recursive: true });
|
|
13033
13148
|
const content = `---
|
|
13034
13149
|
description: Run ${name}
|
|
13035
13150
|
---
|
|
@@ -13037,13 +13152,15 @@ description: Run ${name}
|
|
|
13037
13152
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
13038
13153
|
`;
|
|
13039
13154
|
const filePath = join47(dir, `${name}.md`);
|
|
13040
|
-
|
|
13155
|
+
writeFileSync29(filePath, content);
|
|
13041
13156
|
console.log(`Created command file: ${filePath}`);
|
|
13042
13157
|
}
|
|
13043
13158
|
function add3() {
|
|
13044
13159
|
const { name, command, args, cwd } = requireParsedArgs();
|
|
13045
13160
|
saveNewRunConfig(name, command, args, cwd);
|
|
13046
|
-
|
|
13161
|
+
if (!name.startsWith("verify:")) {
|
|
13162
|
+
createCommandFile(name);
|
|
13163
|
+
}
|
|
13047
13164
|
console.log(
|
|
13048
13165
|
`Added run configuration: ${name} -> ${formatDisplay(command, args)}`
|
|
13049
13166
|
);
|
|
@@ -13143,10 +13260,10 @@ function registerRun(program2) {
|
|
|
13143
13260
|
|
|
13144
13261
|
// src/commands/screenshot/index.ts
|
|
13145
13262
|
import { execSync as execSync39 } from "child_process";
|
|
13146
|
-
import { existsSync as existsSync43, mkdirSync as
|
|
13263
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync16, unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
13147
13264
|
import { tmpdir as tmpdir7 } from "os";
|
|
13148
|
-
import { join as join49, resolve as
|
|
13149
|
-
import
|
|
13265
|
+
import { join as join49, resolve as resolve13 } from "path";
|
|
13266
|
+
import chalk136 from "chalk";
|
|
13150
13267
|
|
|
13151
13268
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
13152
13269
|
var captureWindowPs1 = `
|
|
@@ -13276,14 +13393,14 @@ Write-Output $OutputPath
|
|
|
13276
13393
|
// src/commands/screenshot/index.ts
|
|
13277
13394
|
function buildOutputPath(outputDir, processName) {
|
|
13278
13395
|
if (!existsSync43(outputDir)) {
|
|
13279
|
-
|
|
13396
|
+
mkdirSync16(outputDir, { recursive: true });
|
|
13280
13397
|
}
|
|
13281
13398
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13282
|
-
return
|
|
13399
|
+
return resolve13(outputDir, `${processName}-${timestamp}.png`);
|
|
13283
13400
|
}
|
|
13284
13401
|
function runPowerShellScript(processName, outputPath) {
|
|
13285
13402
|
const scriptPath = join49(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
13286
|
-
|
|
13403
|
+
writeFileSync30(scriptPath, captureWindowPs1, "utf-8");
|
|
13287
13404
|
try {
|
|
13288
13405
|
execSync39(
|
|
13289
13406
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
@@ -13295,22 +13412,22 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
13295
13412
|
}
|
|
13296
13413
|
function screenshot(processName) {
|
|
13297
13414
|
const config = loadConfig();
|
|
13298
|
-
const outputDir =
|
|
13415
|
+
const outputDir = resolve13(config.screenshot.outputDir);
|
|
13299
13416
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
13300
|
-
console.log(
|
|
13417
|
+
console.log(chalk136.gray(`Capturing window for process "${processName}" ...`));
|
|
13301
13418
|
try {
|
|
13302
13419
|
runPowerShellScript(processName, outputPath);
|
|
13303
|
-
console.log(
|
|
13420
|
+
console.log(chalk136.green(`Screenshot saved: ${outputPath}`));
|
|
13304
13421
|
} catch (error) {
|
|
13305
13422
|
const msg = error instanceof Error ? error.message : String(error);
|
|
13306
|
-
console.error(
|
|
13423
|
+
console.error(chalk136.red(`Failed to capture screenshot: ${msg}`));
|
|
13307
13424
|
process.exit(1);
|
|
13308
13425
|
}
|
|
13309
13426
|
}
|
|
13310
13427
|
|
|
13311
13428
|
// src/commands/sessions/summarise/index.ts
|
|
13312
13429
|
import * as fs27 from "fs";
|
|
13313
|
-
import
|
|
13430
|
+
import chalk137 from "chalk";
|
|
13314
13431
|
|
|
13315
13432
|
// src/commands/sessions/summarise/shared.ts
|
|
13316
13433
|
import * as fs25 from "fs";
|
|
@@ -13450,22 +13567,22 @@ ${firstMessage}`);
|
|
|
13450
13567
|
async function summarise3(options2) {
|
|
13451
13568
|
const files = await discoverSessionJsonlPaths();
|
|
13452
13569
|
if (files.length === 0) {
|
|
13453
|
-
console.log(
|
|
13570
|
+
console.log(chalk137.yellow("No sessions found."));
|
|
13454
13571
|
return;
|
|
13455
13572
|
}
|
|
13456
13573
|
const toProcess = selectCandidates(files, options2);
|
|
13457
13574
|
if (toProcess.length === 0) {
|
|
13458
|
-
console.log(
|
|
13575
|
+
console.log(chalk137.green("All sessions already summarised."));
|
|
13459
13576
|
return;
|
|
13460
13577
|
}
|
|
13461
13578
|
console.log(
|
|
13462
|
-
|
|
13579
|
+
chalk137.cyan(
|
|
13463
13580
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
13464
13581
|
)
|
|
13465
13582
|
);
|
|
13466
13583
|
const { succeeded, failed } = processSessions(toProcess);
|
|
13467
13584
|
console.log(
|
|
13468
|
-
|
|
13585
|
+
chalk137.green(`Done: ${succeeded} summarised`) + (failed > 0 ? chalk137.yellow(`, ${failed} skipped`) : "")
|
|
13469
13586
|
);
|
|
13470
13587
|
}
|
|
13471
13588
|
function selectCandidates(files, options2) {
|
|
@@ -13485,16 +13602,16 @@ function processSessions(files) {
|
|
|
13485
13602
|
let failed = 0;
|
|
13486
13603
|
for (let i = 0; i < files.length; i++) {
|
|
13487
13604
|
const file = files[i];
|
|
13488
|
-
process.stdout.write(
|
|
13605
|
+
process.stdout.write(chalk137.dim(` [${i + 1}/${files.length}] `));
|
|
13489
13606
|
const summary = summariseSession(file);
|
|
13490
13607
|
if (summary) {
|
|
13491
13608
|
writeSummary(file, summary);
|
|
13492
13609
|
succeeded++;
|
|
13493
|
-
process.stdout.write(`${
|
|
13610
|
+
process.stdout.write(`${chalk137.green("\u2713")} ${summary}
|
|
13494
13611
|
`);
|
|
13495
13612
|
} else {
|
|
13496
13613
|
failed++;
|
|
13497
|
-
process.stdout.write(` ${
|
|
13614
|
+
process.stdout.write(` ${chalk137.yellow("skip")}
|
|
13498
13615
|
`);
|
|
13499
13616
|
}
|
|
13500
13617
|
}
|
|
@@ -13509,10 +13626,10 @@ function registerSessions(program2) {
|
|
|
13509
13626
|
}
|
|
13510
13627
|
|
|
13511
13628
|
// src/commands/statusLine.ts
|
|
13512
|
-
import
|
|
13629
|
+
import chalk139 from "chalk";
|
|
13513
13630
|
|
|
13514
13631
|
// src/commands/buildLimitsSegment.ts
|
|
13515
|
-
import
|
|
13632
|
+
import chalk138 from "chalk";
|
|
13516
13633
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
13517
13634
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
13518
13635
|
function formatTimeLeft(resetsAt) {
|
|
@@ -13535,10 +13652,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
13535
13652
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
13536
13653
|
const label2 = `${Math.round(pct)}%`;
|
|
13537
13654
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
13538
|
-
if (projected == null) return
|
|
13539
|
-
if (projected > 100) return
|
|
13540
|
-
if (projected > 75) return
|
|
13541
|
-
return
|
|
13655
|
+
if (projected == null) return chalk138.green(label2);
|
|
13656
|
+
if (projected > 100) return chalk138.red(label2);
|
|
13657
|
+
if (projected > 75) return chalk138.yellow(label2);
|
|
13658
|
+
return chalk138.green(label2);
|
|
13542
13659
|
}
|
|
13543
13660
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
13544
13661
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -13564,14 +13681,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
13564
13681
|
}
|
|
13565
13682
|
|
|
13566
13683
|
// src/commands/statusLine.ts
|
|
13567
|
-
|
|
13684
|
+
chalk139.level = 3;
|
|
13568
13685
|
function formatNumber(num) {
|
|
13569
13686
|
return num.toLocaleString("en-US");
|
|
13570
13687
|
}
|
|
13571
13688
|
function colorizePercent(pct) {
|
|
13572
13689
|
const label2 = `${Math.round(pct)}%`;
|
|
13573
|
-
if (pct > 80) return
|
|
13574
|
-
if (pct > 40) return
|
|
13690
|
+
if (pct > 80) return chalk139.red(label2);
|
|
13691
|
+
if (pct > 40) return chalk139.yellow(label2);
|
|
13575
13692
|
return label2;
|
|
13576
13693
|
}
|
|
13577
13694
|
async function statusLine() {
|
|
@@ -13594,7 +13711,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
13594
13711
|
// src/commands/sync/syncClaudeMd.ts
|
|
13595
13712
|
import * as fs28 from "fs";
|
|
13596
13713
|
import * as path49 from "path";
|
|
13597
|
-
import
|
|
13714
|
+
import chalk140 from "chalk";
|
|
13598
13715
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
13599
13716
|
const source = path49.join(claudeDir, "CLAUDE.md");
|
|
13600
13717
|
const target = path49.join(targetBase, "CLAUDE.md");
|
|
@@ -13603,12 +13720,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
13603
13720
|
const targetContent = fs28.readFileSync(target, "utf-8");
|
|
13604
13721
|
if (sourceContent !== targetContent) {
|
|
13605
13722
|
console.log(
|
|
13606
|
-
|
|
13723
|
+
chalk140.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
13607
13724
|
);
|
|
13608
13725
|
console.log();
|
|
13609
13726
|
printDiff(targetContent, sourceContent);
|
|
13610
13727
|
const confirm = options2?.yes || await promptConfirm(
|
|
13611
|
-
|
|
13728
|
+
chalk140.red("Overwrite existing CLAUDE.md?"),
|
|
13612
13729
|
false
|
|
13613
13730
|
);
|
|
13614
13731
|
if (!confirm) {
|
|
@@ -13624,7 +13741,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
13624
13741
|
// src/commands/sync/syncSettings.ts
|
|
13625
13742
|
import * as fs29 from "fs";
|
|
13626
13743
|
import * as path50 from "path";
|
|
13627
|
-
import
|
|
13744
|
+
import chalk141 from "chalk";
|
|
13628
13745
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
13629
13746
|
const source = path50.join(claudeDir, "settings.json");
|
|
13630
13747
|
const target = path50.join(targetBase, "settings.json");
|
|
@@ -13640,14 +13757,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
13640
13757
|
if (mergedContent !== normalizedTarget) {
|
|
13641
13758
|
if (!options2?.yes) {
|
|
13642
13759
|
console.log(
|
|
13643
|
-
|
|
13760
|
+
chalk141.yellow(
|
|
13644
13761
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
13645
13762
|
)
|
|
13646
13763
|
);
|
|
13647
13764
|
console.log();
|
|
13648
13765
|
printDiff(targetContent, mergedContent);
|
|
13649
13766
|
const confirm = await promptConfirm(
|
|
13650
|
-
|
|
13767
|
+
chalk141.red("Overwrite existing settings.json?"),
|
|
13651
13768
|
false
|
|
13652
13769
|
);
|
|
13653
13770
|
if (!confirm) {
|
|
@@ -13748,6 +13865,7 @@ program.command("screenshot").description("Capture a screenshot of a running app
|
|
|
13748
13865
|
registerActivity(program);
|
|
13749
13866
|
registerCliHook(program);
|
|
13750
13867
|
registerJira(program);
|
|
13868
|
+
registerMermaid(program);
|
|
13751
13869
|
registerPrs(program);
|
|
13752
13870
|
registerRoam(program);
|
|
13753
13871
|
registerBacklog(program);
|