@staff0rd/assist 0.297.0 → 0.297.2
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 -1
- package/dist/commands/deploy/init/updateWorkflow.ts +3 -3
- package/dist/commands/deploy/redirect.ts +4 -6
- package/dist/commands/lint/init.ts +2 -2
- package/dist/commands/lint/lint/checkFileNames.ts +1 -1
- package/dist/commands/lint/lint/index.ts +0 -1
- package/dist/commands/lint/lint/runImportExtensionCheck.ts +1 -1
- package/dist/commands/lint/lint/runStaticImportCheck.ts +1 -1
- package/dist/commands/voice/python/pyproject.toml +7 -11
- package/dist/index.js +830 -716
- package/package.json +3 -2
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.297.
|
|
9
|
+
version: "0.297.2",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -69,7 +69,6 @@ var package_default = {
|
|
|
69
69
|
zod: "^4.3.6"
|
|
70
70
|
},
|
|
71
71
|
devDependencies: {
|
|
72
|
-
"@biomejs/biome": "^2.3.8",
|
|
73
72
|
"@electric-sql/pglite": "^0.4.6",
|
|
74
73
|
"@emotion/react": "^11.14.0",
|
|
75
74
|
"@emotion/styled": "^11.14.1",
|
|
@@ -101,6 +100,8 @@ var package_default = {
|
|
|
101
100
|
jsdom: "^29.1.1",
|
|
102
101
|
knip: "^5.71.0",
|
|
103
102
|
marked: "^15.0.12",
|
|
103
|
+
oxfmt: "^0.54.0",
|
|
104
|
+
oxlint: "^1.69.0",
|
|
104
105
|
react: "^19.2.4",
|
|
105
106
|
"react-dom": "^19.2.4",
|
|
106
107
|
"react-router": "^7.14.0",
|
|
@@ -126,7 +127,7 @@ import { parse as parseYaml } from "yaml";
|
|
|
126
127
|
function loadRawYaml(path56) {
|
|
127
128
|
if (!existsSync(path56)) return {};
|
|
128
129
|
try {
|
|
129
|
-
const content = readFileSync(path56, "
|
|
130
|
+
const content = readFileSync(path56, "utf8");
|
|
130
131
|
return parseYaml(content) || {};
|
|
131
132
|
} catch {
|
|
132
133
|
return {};
|
|
@@ -380,9 +381,9 @@ function getTranscriptConfig() {
|
|
|
380
381
|
function shellQuote(arg) {
|
|
381
382
|
if (/[^a-zA-Z0-9_./:=@%^+,-]/.test(arg)) {
|
|
382
383
|
if (process.platform === "win32") {
|
|
383
|
-
return `"${arg.replace(/"/g,
|
|
384
|
+
return `"${arg.replace(/"/g, String.raw`\"`)}"`;
|
|
384
385
|
}
|
|
385
|
-
return `'${arg.replace(/'/g,
|
|
386
|
+
return `'${arg.replace(/'/g, String.raw`'\''`)}'`;
|
|
386
387
|
}
|
|
387
388
|
return arg;
|
|
388
389
|
}
|
|
@@ -413,7 +414,7 @@ function validateMessage(message, config) {
|
|
|
413
414
|
function commitStaged(message) {
|
|
414
415
|
execSync(`git commit -m ${shellQuote(message)}`, { stdio: "inherit" });
|
|
415
416
|
return execSync("git rev-parse --short=7 HEAD", {
|
|
416
|
-
encoding: "
|
|
417
|
+
encoding: "utf8"
|
|
417
418
|
}).trim();
|
|
418
419
|
}
|
|
419
420
|
function stageAndCommit(files, message) {
|
|
@@ -433,7 +434,7 @@ function execCommit(files, message, config) {
|
|
|
433
434
|
console.log("Pushed to remote");
|
|
434
435
|
}
|
|
435
436
|
process.exit(0);
|
|
436
|
-
} catch
|
|
437
|
+
} catch {
|
|
437
438
|
process.exit(1);
|
|
438
439
|
}
|
|
439
440
|
}
|
|
@@ -460,7 +461,7 @@ import { execSync as execSync2 } from "child_process";
|
|
|
460
461
|
function coverage() {
|
|
461
462
|
const output = execSync2(
|
|
462
463
|
"npx vitest run --coverage --coverage.include='src/**/*.ts' --coverage.all --coverage.reporter=text 2>&1",
|
|
463
|
-
{ encoding: "
|
|
464
|
+
{ encoding: "utf8", timeout: 12e4 }
|
|
464
465
|
);
|
|
465
466
|
const match = output.match(/All files\s*\|\s*([\d.]+)/);
|
|
466
467
|
if (!match) {
|
|
@@ -481,11 +482,11 @@ import enquirer from "enquirer";
|
|
|
481
482
|
async function exitOnCancel(promise) {
|
|
482
483
|
try {
|
|
483
484
|
return await promise;
|
|
484
|
-
} catch (
|
|
485
|
-
if (
|
|
485
|
+
} catch (error) {
|
|
486
|
+
if (error === "" || error === void 0) {
|
|
486
487
|
process.exit(0);
|
|
487
488
|
}
|
|
488
|
-
throw
|
|
489
|
+
throw error;
|
|
489
490
|
}
|
|
490
491
|
}
|
|
491
492
|
|
|
@@ -524,7 +525,7 @@ function findPackageJson() {
|
|
|
524
525
|
return null;
|
|
525
526
|
}
|
|
526
527
|
function readPackageJson(filePath) {
|
|
527
|
-
return JSON.parse(fs.readFileSync(filePath, "
|
|
528
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
528
529
|
}
|
|
529
530
|
function requirePackageJson() {
|
|
530
531
|
const packageJsonPath = findPackageJson();
|
|
@@ -540,7 +541,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
540
541
|
while (true) {
|
|
541
542
|
const packageJsonPath = path.join(currentDir, "package.json");
|
|
542
543
|
if (fs.existsSync(packageJsonPath)) {
|
|
543
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "
|
|
544
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
544
545
|
const scripts = packageJson.scripts || {};
|
|
545
546
|
const verifyScripts = Object.keys(scripts).filter(
|
|
546
547
|
(name) => name.startsWith("verify:")
|
|
@@ -679,7 +680,7 @@ import { join as join3 } from "path";
|
|
|
679
680
|
import chalk7 from "chalk";
|
|
680
681
|
function loadKnipConfig(knipJsonPath) {
|
|
681
682
|
if (existsSync4(knipJsonPath)) {
|
|
682
|
-
return JSON.parse(readFileSync3(knipJsonPath, "
|
|
683
|
+
return JSON.parse(readFileSync3(knipJsonPath, "utf8"));
|
|
683
684
|
}
|
|
684
685
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
685
686
|
}
|
|
@@ -802,7 +803,7 @@ function removeEslintFromPackageJson(options2) {
|
|
|
802
803
|
if (!existsSync6(packageJsonPath)) {
|
|
803
804
|
return false;
|
|
804
805
|
}
|
|
805
|
-
const packageJson = JSON.parse(readFileSync4(packageJsonPath, "
|
|
806
|
+
const packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
|
|
806
807
|
let modified = false;
|
|
807
808
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
808
809
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -881,8 +882,8 @@ async function init() {
|
|
|
881
882
|
return;
|
|
882
883
|
}
|
|
883
884
|
const linterConfigPath = join4(__dirname2, "commands/lint/biome.linter.json");
|
|
884
|
-
const linterConfig = JSON.parse(readFileSync5(linterConfigPath, "
|
|
885
|
-
const biomeConfig = JSON.parse(readFileSync5(biomeConfigPath, "
|
|
885
|
+
const linterConfig = JSON.parse(readFileSync5(linterConfigPath, "utf8"));
|
|
886
|
+
const biomeConfig = JSON.parse(readFileSync5(biomeConfigPath, "utf8"));
|
|
886
887
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
887
888
|
`;
|
|
888
889
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -1165,7 +1166,7 @@ function removeVscodeFromGitignore() {
|
|
|
1165
1166
|
if (!fs2.existsSync(gitignorePath)) {
|
|
1166
1167
|
return;
|
|
1167
1168
|
}
|
|
1168
|
-
const content = fs2.readFileSync(gitignorePath, "
|
|
1169
|
+
const content = fs2.readFileSync(gitignorePath, "utf8");
|
|
1169
1170
|
const lines = content.split("\n");
|
|
1170
1171
|
const filteredLines = lines.filter(
|
|
1171
1172
|
(line) => !line.trim().toLowerCase().includes(".vscode")
|
|
@@ -1370,7 +1371,7 @@ function checkFileNames() {
|
|
|
1370
1371
|
const nameWithoutExt = fileName.replace(/\.(ts|tsx)$/, "");
|
|
1371
1372
|
if (/\.(stories|test)\.(ts|tsx)$/.test(fileName)) continue;
|
|
1372
1373
|
if (/^[A-Z]/.test(nameWithoutExt)) {
|
|
1373
|
-
const content = fs5.readFileSync(filePath, "
|
|
1374
|
+
const content = fs5.readFileSync(filePath, "utf8");
|
|
1374
1375
|
if (!hasClassOrComponent(content) && !hasMatchingTypeExport(content, nameWithoutExt)) {
|
|
1375
1376
|
violations.push({
|
|
1376
1377
|
filePath,
|
|
@@ -1539,7 +1540,7 @@ ${checkName} failed:
|
|
|
1539
1540
|
|
|
1540
1541
|
// src/commands/lint/lint/runImportExtensionCheck.ts
|
|
1541
1542
|
function checkForImportExtensions(filePath) {
|
|
1542
|
-
const content = fs8.readFileSync(filePath, "
|
|
1543
|
+
const content = fs8.readFileSync(filePath, "utf8");
|
|
1543
1544
|
const lines = content.split("\n");
|
|
1544
1545
|
const violations = [];
|
|
1545
1546
|
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
@@ -1575,7 +1576,7 @@ function runImportExtensionCheck() {
|
|
|
1575
1576
|
// src/commands/lint/lint/runStaticImportCheck.ts
|
|
1576
1577
|
import fs9 from "fs";
|
|
1577
1578
|
function checkForDynamicImports(filePath) {
|
|
1578
|
-
const content = fs9.readFileSync(filePath, "
|
|
1579
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
1579
1580
|
const lines = content.split("\n");
|
|
1580
1581
|
const violations = [];
|
|
1581
1582
|
const requirePattern = /\brequire\s*\(/;
|
|
@@ -1652,6 +1653,8 @@ function collectComments(sourceFile) {
|
|
|
1652
1653
|
// src/commands/verify/commentPolicy/isCommentExempt.ts
|
|
1653
1654
|
var MACHINE_DIRECTIVES = [
|
|
1654
1655
|
"biome-ignore",
|
|
1656
|
+
"oxlint-disable",
|
|
1657
|
+
"oxlint-enable",
|
|
1655
1658
|
"@ts-expect-error",
|
|
1656
1659
|
"@ts-ignore",
|
|
1657
1660
|
"@ts-nocheck",
|
|
@@ -1716,7 +1719,7 @@ function shouldScan(file, ignoreGlobs) {
|
|
|
1716
1719
|
}
|
|
1717
1720
|
function findAddedComments(options2) {
|
|
1718
1721
|
const diff2 = execSync6("git diff HEAD", {
|
|
1719
|
-
encoding: "
|
|
1722
|
+
encoding: "utf8",
|
|
1720
1723
|
maxBuffer: 64 * 1024 * 1024
|
|
1721
1724
|
});
|
|
1722
1725
|
const addedLines = parseDiffAddedLines(diff2);
|
|
@@ -1774,7 +1777,7 @@ function hardcodedColors() {
|
|
|
1774
1777
|
const ignoreGlobs = loadConfig().hardcodedColors?.ignore ?? [];
|
|
1775
1778
|
try {
|
|
1776
1779
|
const output = execSync7(`grep -rEnH '${pattern}' src/`, {
|
|
1777
|
-
encoding: "
|
|
1780
|
+
encoding: "utf8"
|
|
1778
1781
|
});
|
|
1779
1782
|
const lines = output.trim().split("\n").filter((line) => {
|
|
1780
1783
|
const match = line.match(/^(.+?):\d+:/);
|
|
@@ -1960,7 +1963,7 @@ function noVenv() {
|
|
|
1960
1963
|
const output = execSync8(
|
|
1961
1964
|
"find . -type d -name venv -not -path '*/node_modules/*'",
|
|
1962
1965
|
{
|
|
1963
|
-
encoding: "
|
|
1966
|
+
encoding: "utf8"
|
|
1964
1967
|
}
|
|
1965
1968
|
).trim();
|
|
1966
1969
|
if (output.length === 0) {
|
|
@@ -1992,7 +1995,7 @@ import { minimatch as minimatch3 } from "minimatch";
|
|
|
1992
1995
|
import { execSync as execSync9 } from "child_process";
|
|
1993
1996
|
function getChangedFiles() {
|
|
1994
1997
|
const output = execSync9("git diff --name-only HEAD", {
|
|
1995
|
-
encoding: "
|
|
1998
|
+
encoding: "utf8"
|
|
1996
1999
|
}).trim();
|
|
1997
2000
|
if (output === "") return [];
|
|
1998
2001
|
return output.split("\n");
|
|
@@ -2274,13 +2277,13 @@ function getExistingSiteId() {
|
|
|
2274
2277
|
if (!existsSync11(WORKFLOW_PATH)) {
|
|
2275
2278
|
return null;
|
|
2276
2279
|
}
|
|
2277
|
-
const content = readFileSync7(WORKFLOW_PATH, "
|
|
2280
|
+
const content = readFileSync7(WORKFLOW_PATH, "utf8");
|
|
2278
2281
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
2279
2282
|
return match ? match[1] : null;
|
|
2280
2283
|
}
|
|
2281
2284
|
function getTemplateContent(siteId) {
|
|
2282
2285
|
const templatePath = join8(__dirname3, "commands/deploy/build.yml");
|
|
2283
|
-
const template = readFileSync7(templatePath, "
|
|
2286
|
+
const template = readFileSync7(templatePath, "utf8");
|
|
2284
2287
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
2285
2288
|
}
|
|
2286
2289
|
async function updateWorkflow(siteId) {
|
|
@@ -2290,7 +2293,7 @@ async function updateWorkflow(siteId) {
|
|
|
2290
2293
|
mkdirSync3(workflowDir, { recursive: true });
|
|
2291
2294
|
}
|
|
2292
2295
|
if (existsSync11(WORKFLOW_PATH)) {
|
|
2293
|
-
const oldContent = readFileSync7(WORKFLOW_PATH, "
|
|
2296
|
+
const oldContent = readFileSync7(WORKFLOW_PATH, "utf8");
|
|
2294
2297
|
if (oldContent === newContent) {
|
|
2295
2298
|
console.log(chalk22.green("build.yml is already up to date"));
|
|
2296
2299
|
return;
|
|
@@ -2388,7 +2391,7 @@ function addViteBaseConfig() {
|
|
|
2388
2391
|
console.log("No vite.config.ts found, skipping base config");
|
|
2389
2392
|
return;
|
|
2390
2393
|
}
|
|
2391
|
-
const content = readFileSync8(viteConfigPath, "
|
|
2394
|
+
const content = readFileSync8(viteConfigPath, "utf8");
|
|
2392
2395
|
if (content.includes("base:")) {
|
|
2393
2396
|
console.log("vite.config.ts already has base config");
|
|
2394
2397
|
return;
|
|
@@ -2569,7 +2572,7 @@ function fetchContributions(from, to) {
|
|
|
2569
2572
|
const query = `{ viewer { contributionsCollection(from: "${from}T00:00:00Z", to: "${to}T23:59:59Z") { contributionCalendar { weeks { contributionDays { date contributionCount } } } } } }`;
|
|
2570
2573
|
const jq = ".data.viewer.contributionsCollection.contributionCalendar.weeks[].contributionDays[]";
|
|
2571
2574
|
const raw = execSync15(`gh api graphql -f query='${query}' --jq '${jq}'`, {
|
|
2572
|
-
encoding: "
|
|
2575
|
+
encoding: "utf8"
|
|
2573
2576
|
}).trim();
|
|
2574
2577
|
if (!raw) return [];
|
|
2575
2578
|
return raw.split("\n").map((line) => {
|
|
@@ -2630,7 +2633,7 @@ function registerActivity(program2) {
|
|
|
2630
2633
|
}
|
|
2631
2634
|
|
|
2632
2635
|
// src/commands/backlog/next.ts
|
|
2633
|
-
import
|
|
2636
|
+
import chalk36 from "chalk";
|
|
2634
2637
|
import enquirer5 from "enquirer";
|
|
2635
2638
|
|
|
2636
2639
|
// src/shared/pullIfConfigured.ts
|
|
@@ -2675,7 +2678,7 @@ function isLockedByOther(itemId) {
|
|
|
2675
2678
|
const lockPath = getLockPath(itemId);
|
|
2676
2679
|
if (!existsSync13(lockPath)) return false;
|
|
2677
2680
|
try {
|
|
2678
|
-
const lock = JSON.parse(readFileSync9(lockPath, "
|
|
2681
|
+
const lock = JSON.parse(readFileSync9(lockPath, "utf8"));
|
|
2679
2682
|
if (lock.pid === process.pid) return false;
|
|
2680
2683
|
return isProcessAlive(lock.pid);
|
|
2681
2684
|
} catch {
|
|
@@ -2778,7 +2781,7 @@ function findUnblockedTodos(items2) {
|
|
|
2778
2781
|
}
|
|
2779
2782
|
|
|
2780
2783
|
// src/commands/backlog/run.ts
|
|
2781
|
-
import
|
|
2784
|
+
import chalk35 from "chalk";
|
|
2782
2785
|
|
|
2783
2786
|
// src/shared/spawnClaude.ts
|
|
2784
2787
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -3230,7 +3233,7 @@ var backlogFileSchema = z3.array(backlogItemSchema);
|
|
|
3230
3233
|
|
|
3231
3234
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
3232
3235
|
function parseBacklogJsonl(path56) {
|
|
3233
|
-
const content = readFileSync10(path56, "
|
|
3236
|
+
const content = readFileSync10(path56, "utf8").trim();
|
|
3234
3237
|
if (content.length === 0) return [];
|
|
3235
3238
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
3236
3239
|
}
|
|
@@ -3528,7 +3531,7 @@ function tryGit(cwd, args) {
|
|
|
3528
3531
|
const argv = windows ? ["-C", cwd, ...args] : args;
|
|
3529
3532
|
try {
|
|
3530
3533
|
const out = execFileSync(file, argv, {
|
|
3531
|
-
encoding: "
|
|
3534
|
+
encoding: "utf8",
|
|
3532
3535
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3533
3536
|
...windows ? {} : { cwd }
|
|
3534
3537
|
}).trim();
|
|
@@ -3748,7 +3751,23 @@ function consumePause(itemId) {
|
|
|
3748
3751
|
|
|
3749
3752
|
// src/commands/backlog/executePhase.ts
|
|
3750
3753
|
import { randomUUID } from "crypto";
|
|
3751
|
-
import
|
|
3754
|
+
import chalk34 from "chalk";
|
|
3755
|
+
|
|
3756
|
+
// src/shared/awaitClaude.ts
|
|
3757
|
+
import chalk32 from "chalk";
|
|
3758
|
+
async function awaitClaude(done2, context) {
|
|
3759
|
+
try {
|
|
3760
|
+
await done2;
|
|
3761
|
+
return true;
|
|
3762
|
+
} catch (error) {
|
|
3763
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3764
|
+
console.error(
|
|
3765
|
+
chalk32.red(`
|
|
3766
|
+
Failed to launch Claude for ${context}: ${message}`)
|
|
3767
|
+
);
|
|
3768
|
+
return false;
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3752
3771
|
|
|
3753
3772
|
// src/shared/emitActivity.ts
|
|
3754
3773
|
import { mkdirSync as mkdirSync6, readFileSync as readFileSync11, rmSync, writeFileSync as writeFileSync13 } from "fs";
|
|
@@ -3777,7 +3796,7 @@ function emitActivity(activity2) {
|
|
|
3777
3796
|
}
|
|
3778
3797
|
function readActivity(path56) {
|
|
3779
3798
|
try {
|
|
3780
|
-
return JSON.parse(readFileSync11(path56, "
|
|
3799
|
+
return JSON.parse(readFileSync11(path56, "utf8"));
|
|
3781
3800
|
} catch {
|
|
3782
3801
|
return void 0;
|
|
3783
3802
|
}
|
|
@@ -3878,8 +3897,8 @@ function buildReviewPrompt(item, phaseNumber) {
|
|
|
3878
3897
|
"Wait for the user to confirm before proceeding.",
|
|
3879
3898
|
"",
|
|
3880
3899
|
"Once the user confirms:",
|
|
3881
|
-
|
|
3882
|
-
|
|
3900
|
+
"1. Run: /commit",
|
|
3901
|
+
`2. Run: assist backlog done ${item.id} "<summary>"`,
|
|
3883
3902
|
`3. Run: assist backlog phase-done ${item.id} ${phaseNumber} "done"`
|
|
3884
3903
|
].filter((line) => line !== void 0).join("\n");
|
|
3885
3904
|
}
|
|
@@ -3900,7 +3919,7 @@ function buildResumePrompt() {
|
|
|
3900
3919
|
|
|
3901
3920
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
3902
3921
|
import { existsSync as existsSync19, unlinkSync as unlinkSync4 } from "fs";
|
|
3903
|
-
import
|
|
3922
|
+
import chalk33 from "chalk";
|
|
3904
3923
|
|
|
3905
3924
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
3906
3925
|
import enquirer4 from "enquirer";
|
|
@@ -3940,7 +3959,7 @@ function readSignal() {
|
|
|
3940
3959
|
const path56 = getSignalPath();
|
|
3941
3960
|
if (!existsSync18(path56)) return void 0;
|
|
3942
3961
|
try {
|
|
3943
|
-
return JSON.parse(readFileSync12(path56, "
|
|
3962
|
+
return JSON.parse(readFileSync12(path56, "utf8"));
|
|
3944
3963
|
} catch {
|
|
3945
3964
|
return void 0;
|
|
3946
3965
|
}
|
|
@@ -3970,12 +3989,12 @@ async function resolvePhaseResult(phaseIndex, itemId) {
|
|
|
3970
3989
|
if (signal?.event === "rewind") {
|
|
3971
3990
|
const targetPhase = signal.targetPhase;
|
|
3972
3991
|
const targetPhaseNumber = targetPhase + 1;
|
|
3973
|
-
console.log(
|
|
3992
|
+
console.log(chalk33.yellow(`
|
|
3974
3993
|
Rewinding to phase ${targetPhaseNumber}.`));
|
|
3975
3994
|
return targetPhase;
|
|
3976
3995
|
}
|
|
3977
3996
|
const phaseNumber = phaseIndex + 1;
|
|
3978
|
-
console.log(
|
|
3997
|
+
console.log(chalk33.green(`
|
|
3979
3998
|
Phase ${phaseNumber} completed.`));
|
|
3980
3999
|
return phaseIndex + 1;
|
|
3981
4000
|
}
|
|
@@ -4002,7 +4021,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4002
4021
|
const phase = phases[phaseIndex];
|
|
4003
4022
|
const phaseNumber = phaseIndex + 1;
|
|
4004
4023
|
console.log(
|
|
4005
|
-
|
|
4024
|
+
chalk34.bold(
|
|
4006
4025
|
`
|
|
4007
4026
|
--- Phase ${phaseNumber}/${totalPhases}: ${phase.name} ---
|
|
4008
4027
|
`
|
|
@@ -4024,8 +4043,12 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4024
4043
|
resumeSessionId ? spawnOptions : { ...spawnOptions, sessionId: claudeSessionId }
|
|
4025
4044
|
);
|
|
4026
4045
|
watchForMarker(child);
|
|
4027
|
-
await
|
|
4046
|
+
const launched = await awaitClaude(
|
|
4047
|
+
done2,
|
|
4048
|
+
`phase ${phaseNumber}/${totalPhases}`
|
|
4049
|
+
);
|
|
4028
4050
|
stopWatching();
|
|
4051
|
+
if (!launched) return -1;
|
|
4029
4052
|
return await resolvePhaseResult(phaseIndex, item.id);
|
|
4030
4053
|
}
|
|
4031
4054
|
|
|
@@ -4064,7 +4087,7 @@ function buildReviewPhase() {
|
|
|
4064
4087
|
name: REVIEW_PHASE_NAME,
|
|
4065
4088
|
tasks: [
|
|
4066
4089
|
{
|
|
4067
|
-
task: "Verify acceptance criteria, confirm manual checks, mark done,
|
|
4090
|
+
task: "Verify acceptance criteria, confirm manual checks, commit, mark done, and signal phase-done."
|
|
4068
4091
|
}
|
|
4069
4092
|
]
|
|
4070
4093
|
};
|
|
@@ -4123,16 +4146,16 @@ async function runPrepared(id2, prepared, spawnOptions) {
|
|
|
4123
4146
|
}
|
|
4124
4147
|
}
|
|
4125
4148
|
function logProgress(id2, { plan: plan2, startPhase, item }) {
|
|
4126
|
-
console.log(
|
|
4149
|
+
console.log(chalk35.bold(`Running plan for #${id2}: ${item.name}`));
|
|
4127
4150
|
const totalPhases = plan2.length + 1;
|
|
4128
4151
|
if (startPhase > 0) {
|
|
4129
4152
|
const phaseNumber = startPhase + 1;
|
|
4130
4153
|
console.log(
|
|
4131
|
-
|
|
4154
|
+
chalk35.dim(`Resuming from phase ${phaseNumber}/${totalPhases}
|
|
4132
4155
|
`)
|
|
4133
4156
|
);
|
|
4134
4157
|
} else {
|
|
4135
|
-
console.log(
|
|
4158
|
+
console.log(chalk35.dim(`${totalPhases} phase(s)
|
|
4136
4159
|
`));
|
|
4137
4160
|
}
|
|
4138
4161
|
}
|
|
@@ -4140,7 +4163,7 @@ function logProgress(id2, { plan: plan2, startPhase, item }) {
|
|
|
4140
4163
|
// src/commands/backlog/next.ts
|
|
4141
4164
|
function toChoice(item, items2) {
|
|
4142
4165
|
const name = `${typeLabel(item.type)} #${item.id}: ${item.name}`;
|
|
4143
|
-
return isBlocked(item, items2) ? { name, disabled:
|
|
4166
|
+
return isBlocked(item, items2) ? { name, disabled: chalk36.red("[blocked]") } : { name };
|
|
4144
4167
|
}
|
|
4145
4168
|
async function selectItem(todo, items2) {
|
|
4146
4169
|
const { selected } = await exitOnCancel(
|
|
@@ -4157,13 +4180,13 @@ function pickResumable(items2) {
|
|
|
4157
4180
|
const resumable = findResumable(items2);
|
|
4158
4181
|
if (!resumable) return void 0;
|
|
4159
4182
|
console.log(
|
|
4160
|
-
|
|
4183
|
+
chalk36.bold(`Resuming in-progress item #${resumable.id}: ${resumable.name}`)
|
|
4161
4184
|
);
|
|
4162
4185
|
return String(resumable.id);
|
|
4163
4186
|
}
|
|
4164
4187
|
function autoSelect(unblocked) {
|
|
4165
4188
|
const item = unblocked[0];
|
|
4166
|
-
console.log(
|
|
4189
|
+
console.log(chalk36.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
4167
4190
|
return String(item.id);
|
|
4168
4191
|
}
|
|
4169
4192
|
async function pickItem(items2, firstPick = false) {
|
|
@@ -4190,7 +4213,7 @@ async function next(options2, startId) {
|
|
|
4190
4213
|
}
|
|
4191
4214
|
|
|
4192
4215
|
// src/commands/backlog/phaseDone.ts
|
|
4193
|
-
import
|
|
4216
|
+
import chalk37 from "chalk";
|
|
4194
4217
|
|
|
4195
4218
|
// src/commands/backlog/appendComment.ts
|
|
4196
4219
|
import { sql as sql2 } from "drizzle-orm";
|
|
@@ -4225,11 +4248,11 @@ async function phaseDone(id2, phase, summary) {
|
|
|
4225
4248
|
const { orm } = await getReady();
|
|
4226
4249
|
const status2 = await getItemStatus(orm, itemId);
|
|
4227
4250
|
if (status2 === void 0) {
|
|
4228
|
-
console.log(
|
|
4251
|
+
console.log(chalk37.red(`Item #${id2} not found.`));
|
|
4229
4252
|
return;
|
|
4230
4253
|
}
|
|
4231
4254
|
if (status2 === "done") {
|
|
4232
|
-
console.log(
|
|
4255
|
+
console.log(chalk37.dim(`Item #${id2} already done, skipping phase advance.`));
|
|
4233
4256
|
return;
|
|
4234
4257
|
}
|
|
4235
4258
|
await appendComment(orm, itemId, summary, {
|
|
@@ -4238,24 +4261,24 @@ async function phaseDone(id2, phase, summary) {
|
|
|
4238
4261
|
});
|
|
4239
4262
|
await setCurrentPhase(id2, phaseNumber + 1);
|
|
4240
4263
|
console.log(
|
|
4241
|
-
|
|
4264
|
+
chalk37.green(`Phase ${phaseNumber} of item #${id2} marked as complete.`)
|
|
4242
4265
|
);
|
|
4243
4266
|
}
|
|
4244
4267
|
|
|
4245
4268
|
// src/commands/backlog/plan.ts
|
|
4246
|
-
import
|
|
4269
|
+
import chalk38 from "chalk";
|
|
4247
4270
|
async function plan(id2) {
|
|
4248
4271
|
const found = await findOneItem(id2);
|
|
4249
4272
|
if (!found) return;
|
|
4250
4273
|
const { item } = found;
|
|
4251
4274
|
if (!item.plan || item.plan.length === 0) {
|
|
4252
|
-
console.log(
|
|
4275
|
+
console.log(chalk38.dim("No plan defined for this item."));
|
|
4253
4276
|
return;
|
|
4254
4277
|
}
|
|
4255
|
-
console.log(
|
|
4278
|
+
console.log(chalk38.bold(item.name));
|
|
4256
4279
|
console.log();
|
|
4257
4280
|
for (const [i, phase] of item.plan.entries()) {
|
|
4258
|
-
console.log(`${
|
|
4281
|
+
console.log(`${chalk38.bold(`Phase ${i + 1}:`)} ${phase.name}`);
|
|
4259
4282
|
for (const task of phase.tasks) {
|
|
4260
4283
|
console.log(` - ${task.task}`);
|
|
4261
4284
|
}
|
|
@@ -4264,21 +4287,21 @@ async function plan(id2) {
|
|
|
4264
4287
|
}
|
|
4265
4288
|
|
|
4266
4289
|
// src/commands/backlog/show/index.ts
|
|
4267
|
-
import
|
|
4290
|
+
import chalk42 from "chalk";
|
|
4268
4291
|
|
|
4269
4292
|
// src/commands/backlog/formatComment.ts
|
|
4270
|
-
import
|
|
4293
|
+
import chalk39 from "chalk";
|
|
4271
4294
|
function formatComment(entry) {
|
|
4272
|
-
const id2 = entry.id !== void 0 ?
|
|
4273
|
-
const tag = entry.type === "summary" ?
|
|
4274
|
-
const phase = entry.phase !== void 0 ?
|
|
4275
|
-
const time =
|
|
4295
|
+
const id2 = entry.id !== void 0 ? chalk39.dim(`#${entry.id} `) : "";
|
|
4296
|
+
const tag = entry.type === "summary" ? chalk39.magenta("[summary]") : chalk39.cyan("[comment]");
|
|
4297
|
+
const phase = entry.phase !== void 0 ? chalk39.dim(` (phase ${entry.phase})`) : "";
|
|
4298
|
+
const time = chalk39.dim(entry.timestamp);
|
|
4276
4299
|
return `${id2}${tag}${phase} ${time}
|
|
4277
4300
|
${entry.text}`;
|
|
4278
4301
|
}
|
|
4279
4302
|
|
|
4280
4303
|
// src/commands/backlog/show/printLinks.ts
|
|
4281
|
-
import
|
|
4304
|
+
import chalk40 from "chalk";
|
|
4282
4305
|
|
|
4283
4306
|
// src/commands/backlog/show/loadLinkTargets.ts
|
|
4284
4307
|
import { inArray as inArray2 } from "drizzle-orm";
|
|
@@ -4300,17 +4323,17 @@ async function printLinks(orm, item) {
|
|
|
4300
4323
|
orm,
|
|
4301
4324
|
links2.map((l) => l.targetId)
|
|
4302
4325
|
);
|
|
4303
|
-
console.log(
|
|
4326
|
+
console.log(chalk40.bold("Links"));
|
|
4304
4327
|
for (const link3 of links2) {
|
|
4305
4328
|
const target = targets.find((i) => i.id === link3.targetId);
|
|
4306
|
-
const typeLabel2 = link3.type === "depends-on" ?
|
|
4329
|
+
const typeLabel2 = link3.type === "depends-on" ? chalk40.red("depends-on") : chalk40.blue("relates-to");
|
|
4307
4330
|
if (target) {
|
|
4308
4331
|
console.log(
|
|
4309
|
-
` ${typeLabel2} #${target.id} ${target.name} ${
|
|
4332
|
+
` ${typeLabel2} #${target.id} ${target.name} ${chalk40.dim(`(${target.status})`)}`
|
|
4310
4333
|
);
|
|
4311
4334
|
} else {
|
|
4312
4335
|
console.log(
|
|
4313
|
-
` ${typeLabel2} #${link3.targetId} ${
|
|
4336
|
+
` ${typeLabel2} #${link3.targetId} ${chalk40.dim("(not found)")}`
|
|
4314
4337
|
);
|
|
4315
4338
|
}
|
|
4316
4339
|
}
|
|
@@ -4318,15 +4341,15 @@ async function printLinks(orm, item) {
|
|
|
4318
4341
|
}
|
|
4319
4342
|
|
|
4320
4343
|
// src/commands/backlog/show/printPhaseTasks.ts
|
|
4321
|
-
import
|
|
4344
|
+
import chalk41 from "chalk";
|
|
4322
4345
|
function printPhaseTasks(phase) {
|
|
4323
4346
|
for (const task of phase.tasks) {
|
|
4324
4347
|
console.log(` - ${task.task}`);
|
|
4325
4348
|
}
|
|
4326
4349
|
if (phase.manualChecks && phase.manualChecks.length > 0) {
|
|
4327
|
-
console.log(` ${
|
|
4350
|
+
console.log(` ${chalk41.dim("Manual checks:")}`);
|
|
4328
4351
|
for (const check2 of phase.manualChecks) {
|
|
4329
|
-
console.log(` ${
|
|
4352
|
+
console.log(` ${chalk41.dim(`- ${check2}`)}`);
|
|
4330
4353
|
}
|
|
4331
4354
|
}
|
|
4332
4355
|
}
|
|
@@ -4334,7 +4357,7 @@ function printPhaseTasks(phase) {
|
|
|
4334
4357
|
// src/commands/backlog/show/index.ts
|
|
4335
4358
|
function printPlan(item) {
|
|
4336
4359
|
if (!item.plan || item.plan.length === 0) return;
|
|
4337
|
-
console.log(
|
|
4360
|
+
console.log(chalk42.bold("Plan"));
|
|
4338
4361
|
for (const [i, phase] of item.plan.entries()) {
|
|
4339
4362
|
const isCurrent = item.currentPhase === i + 1;
|
|
4340
4363
|
printPhase(phase, i, isCurrent);
|
|
@@ -4343,8 +4366,8 @@ function printPlan(item) {
|
|
|
4343
4366
|
}
|
|
4344
4367
|
function phaseHeader(index3, name, isCurrent) {
|
|
4345
4368
|
const phaseNumber = index3 + 1;
|
|
4346
|
-
const marker = isCurrent ?
|
|
4347
|
-
const label2 = isCurrent ?
|
|
4369
|
+
const marker = isCurrent ? chalk42.green("\u25B6 ") : " ";
|
|
4370
|
+
const label2 = isCurrent ? chalk42.green.bold(`Phase ${phaseNumber}: ${name}`) : `${chalk42.bold(`Phase ${phaseNumber}:`)} ${name}`;
|
|
4348
4371
|
return `${marker}${label2}`;
|
|
4349
4372
|
}
|
|
4350
4373
|
function printPhase(phase, index3, isCurrent) {
|
|
@@ -4352,15 +4375,15 @@ function printPhase(phase, index3, isCurrent) {
|
|
|
4352
4375
|
printPhaseTasks(phase);
|
|
4353
4376
|
}
|
|
4354
4377
|
function printHeader(item) {
|
|
4355
|
-
console.log(
|
|
4378
|
+
console.log(chalk42.bold(`#${item.id} ${item.name}`));
|
|
4356
4379
|
console.log(
|
|
4357
|
-
`${
|
|
4380
|
+
`${chalk42.dim("Type:")} ${item.type} ${chalk42.dim("Status:")} ${item.status}`
|
|
4358
4381
|
);
|
|
4359
4382
|
console.log();
|
|
4360
4383
|
}
|
|
4361
4384
|
function printAcceptanceCriteria(criteria) {
|
|
4362
4385
|
if (criteria.length === 0) return;
|
|
4363
|
-
console.log(
|
|
4386
|
+
console.log(chalk42.bold("Acceptance Criteria"));
|
|
4364
4387
|
for (const [i, ac] of criteria.entries()) {
|
|
4365
4388
|
console.log(` ${i + 1}. ${ac}`);
|
|
4366
4389
|
}
|
|
@@ -4372,7 +4395,7 @@ async function show(id2) {
|
|
|
4372
4395
|
const { orm, item } = found;
|
|
4373
4396
|
printHeader(item);
|
|
4374
4397
|
if (item.description) {
|
|
4375
|
-
console.log(
|
|
4398
|
+
console.log(chalk42.bold("Description"));
|
|
4376
4399
|
console.log(item.description);
|
|
4377
4400
|
console.log();
|
|
4378
4401
|
}
|
|
@@ -4384,7 +4407,7 @@ async function show(id2) {
|
|
|
4384
4407
|
function printComments(item) {
|
|
4385
4408
|
const entries = item.comments ?? [];
|
|
4386
4409
|
if (entries.length === 0) return;
|
|
4387
|
-
console.log(
|
|
4410
|
+
console.log(chalk42.bold("Comments"));
|
|
4388
4411
|
for (const entry of entries) {
|
|
4389
4412
|
console.log(` ${formatComment(entry)}`);
|
|
4390
4413
|
}
|
|
@@ -4419,7 +4442,7 @@ function isGitRepo(dir) {
|
|
|
4419
4442
|
import {
|
|
4420
4443
|
createServer
|
|
4421
4444
|
} from "http";
|
|
4422
|
-
import
|
|
4445
|
+
import chalk43 from "chalk";
|
|
4423
4446
|
|
|
4424
4447
|
// src/lib/openBrowser.ts
|
|
4425
4448
|
import { execSync as execSync19 } from "child_process";
|
|
@@ -4481,9 +4504,9 @@ function runHandler(handler, req, res, port) {
|
|
|
4481
4504
|
res.on("finish", () => {
|
|
4482
4505
|
logRequest(method, url, res.statusCode, Date.now() - startedAt);
|
|
4483
4506
|
});
|
|
4484
|
-
Promise.resolve(handler(req, res, port)).catch((
|
|
4507
|
+
Promise.resolve(handler(req, res, port)).catch((error) => {
|
|
4485
4508
|
console.error(
|
|
4486
|
-
`${(/* @__PURE__ */ new Date()).toISOString()} ${method} ${url} failed: ${
|
|
4509
|
+
`${(/* @__PURE__ */ new Date()).toISOString()} ${method} ${url} failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4487
4510
|
);
|
|
4488
4511
|
if (!res.headersSent)
|
|
4489
4512
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
@@ -4529,8 +4552,8 @@ function startWebServer(label2, port, handler, initialPath, open = true) {
|
|
|
4529
4552
|
runHandler(handler, req, res, port);
|
|
4530
4553
|
});
|
|
4531
4554
|
server.listen(port, () => {
|
|
4532
|
-
console.log(
|
|
4533
|
-
console.log(
|
|
4555
|
+
console.log(chalk43.green(`${label2}: ${url}`));
|
|
4556
|
+
console.log(chalk43.dim("Press Ctrl+C to stop"));
|
|
4534
4557
|
if (open) {
|
|
4535
4558
|
openBrowser(url);
|
|
4536
4559
|
}
|
|
@@ -4558,7 +4581,7 @@ import { join as join16 } from "path";
|
|
|
4558
4581
|
var DAEMON_DIR = join16(homedir6(), ".assist", "daemon");
|
|
4559
4582
|
var daemonPaths = {
|
|
4560
4583
|
dir: DAEMON_DIR,
|
|
4561
|
-
socket: process.platform === "win32" ?
|
|
4584
|
+
socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` : join16(DAEMON_DIR, "daemon.sock"),
|
|
4562
4585
|
log: join16(DAEMON_DIR, "daemon.log"),
|
|
4563
4586
|
pid: join16(DAEMON_DIR, "daemon.pid"),
|
|
4564
4587
|
spawnLock: join16(DAEMON_DIR, "spawn.lock")
|
|
@@ -4652,22 +4675,38 @@ function delay(ms) {
|
|
|
4652
4675
|
}
|
|
4653
4676
|
|
|
4654
4677
|
// src/commands/sessions/web/handleRequest.ts
|
|
4678
|
+
import { createHash as createHash2 } from "crypto";
|
|
4655
4679
|
import { readFileSync as readFileSync14 } from "fs";
|
|
4656
4680
|
import { createRequire as createRequire2 } from "module";
|
|
4657
4681
|
|
|
4658
4682
|
// src/shared/createBundleHandler.ts
|
|
4683
|
+
import { createHash } from "crypto";
|
|
4659
4684
|
import { readFileSync as readFileSync13 } from "fs";
|
|
4660
4685
|
import { dirname as dirname16, join as join17 } from "path";
|
|
4661
4686
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
4662
4687
|
function createBundleHandler(importMetaUrl, bundlePath) {
|
|
4663
4688
|
const dir = dirname16(fileURLToPath4(importMetaUrl));
|
|
4664
4689
|
let cache;
|
|
4665
|
-
return (
|
|
4690
|
+
return (req, res) => {
|
|
4666
4691
|
if (!cache) {
|
|
4667
|
-
|
|
4692
|
+
const body = readFileSync13(join17(dir, bundlePath), "utf8");
|
|
4693
|
+
const etag = `"${createHash("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
4694
|
+
cache = { body, etag };
|
|
4695
|
+
}
|
|
4696
|
+
const headers = {
|
|
4697
|
+
ETag: cache.etag,
|
|
4698
|
+
"Cache-Control": "no-cache"
|
|
4699
|
+
};
|
|
4700
|
+
if (req.headers["if-none-match"] === cache.etag) {
|
|
4701
|
+
res.writeHead(304, headers);
|
|
4702
|
+
res.end();
|
|
4703
|
+
return;
|
|
4668
4704
|
}
|
|
4669
|
-
res.writeHead(200, {
|
|
4670
|
-
|
|
4705
|
+
res.writeHead(200, {
|
|
4706
|
+
"Content-Type": "application/javascript",
|
|
4707
|
+
...headers
|
|
4708
|
+
});
|
|
4709
|
+
res.end(cache.body);
|
|
4671
4710
|
};
|
|
4672
4711
|
}
|
|
4673
4712
|
|
|
@@ -4960,11 +4999,11 @@ async function handleItemRoute(req, res, pathname) {
|
|
|
4960
4999
|
}
|
|
4961
5000
|
|
|
4962
5001
|
// src/commands/backlog/init/index.ts
|
|
4963
|
-
import
|
|
5002
|
+
import chalk44 from "chalk";
|
|
4964
5003
|
async function init6() {
|
|
4965
5004
|
await getDb();
|
|
4966
5005
|
console.log(
|
|
4967
|
-
|
|
5006
|
+
chalk44.green(
|
|
4968
5007
|
`Backlog database ready. This repository maps to origin: ${getOrigin()}`
|
|
4969
5008
|
)
|
|
4970
5009
|
);
|
|
@@ -5017,7 +5056,7 @@ function parseGitHubUrl(url) {
|
|
|
5017
5056
|
function tryGetRemoteUrl(remote, cwd) {
|
|
5018
5057
|
try {
|
|
5019
5058
|
return execSync20(`git remote get-url ${remote}`, {
|
|
5020
|
-
encoding: "
|
|
5059
|
+
encoding: "utf8",
|
|
5021
5060
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5022
5061
|
cwd
|
|
5023
5062
|
}).trim();
|
|
@@ -5029,7 +5068,7 @@ function getCurrentBranchRemote(cwd) {
|
|
|
5029
5068
|
try {
|
|
5030
5069
|
const ref = execSync20(
|
|
5031
5070
|
"git rev-parse --abbrev-ref --symbolic-full-name @{u}",
|
|
5032
|
-
{ encoding: "
|
|
5071
|
+
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], cwd }
|
|
5033
5072
|
).trim();
|
|
5034
5073
|
const [remote] = ref.split("/", 1);
|
|
5035
5074
|
return remote || null;
|
|
@@ -5040,7 +5079,7 @@ function getCurrentBranchRemote(cwd) {
|
|
|
5040
5079
|
function listRemotes(cwd) {
|
|
5041
5080
|
try {
|
|
5042
5081
|
return execSync20("git remote", {
|
|
5043
|
-
encoding: "
|
|
5082
|
+
encoding: "utf8",
|
|
5044
5083
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5045
5084
|
cwd
|
|
5046
5085
|
}).trim().split("\n").filter(Boolean);
|
|
@@ -5141,7 +5180,7 @@ function runGitStatus(cwd) {
|
|
|
5141
5180
|
const args = ["status", "--porcelain"];
|
|
5142
5181
|
const { file, argv } = /^[A-Za-z]:[\\/]/.test(cwd) ? { file: "git.exe", argv: ["-C", cwd, ...args] } : { file: "git", argv: args };
|
|
5143
5182
|
return execFileAsync(file, argv, {
|
|
5144
|
-
encoding: "
|
|
5183
|
+
encoding: "utf8",
|
|
5145
5184
|
...file === "git" ? { cwd } : {}
|
|
5146
5185
|
}).then((r) => r.stdout);
|
|
5147
5186
|
}
|
|
@@ -5386,13 +5425,21 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
5386
5425
|
var require3 = createRequire2(import.meta.url);
|
|
5387
5426
|
function createCssHandler(packageEntry) {
|
|
5388
5427
|
let cache;
|
|
5389
|
-
return (
|
|
5428
|
+
return (req, res) => {
|
|
5390
5429
|
if (!cache) {
|
|
5391
5430
|
const resolved = require3.resolve(packageEntry);
|
|
5392
|
-
|
|
5431
|
+
const body = readFileSync14(resolved, "utf8");
|
|
5432
|
+
const etag = `"${createHash2("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
5433
|
+
cache = { body, etag };
|
|
5434
|
+
}
|
|
5435
|
+
const headers = { ETag: cache.etag, "Cache-Control": "no-cache" };
|
|
5436
|
+
if (req.headers["if-none-match"] === cache.etag) {
|
|
5437
|
+
res.writeHead(304, headers);
|
|
5438
|
+
res.end();
|
|
5439
|
+
return;
|
|
5393
5440
|
}
|
|
5394
|
-
res.writeHead(200, { "Content-Type": "text/css" });
|
|
5395
|
-
res.end(cache);
|
|
5441
|
+
res.writeHead(200, { "Content-Type": "text/css", ...headers });
|
|
5442
|
+
res.end(cache.body);
|
|
5396
5443
|
};
|
|
5397
5444
|
}
|
|
5398
5445
|
var htmlHandler = createHtmlHandler(getHtml);
|
|
@@ -5466,7 +5513,7 @@ function applySnapshot(known, sessions) {
|
|
|
5466
5513
|
if (previous === void 0) logEvent("started", session);
|
|
5467
5514
|
else if (isDone(session) && !isDone(previous)) logEvent("ended", session);
|
|
5468
5515
|
}
|
|
5469
|
-
for (const [id2, session] of
|
|
5516
|
+
for (const [id2, session] of known) {
|
|
5470
5517
|
if (present.has(id2)) continue;
|
|
5471
5518
|
known.delete(id2);
|
|
5472
5519
|
if (!isDone(session)) logEvent("ended", session);
|
|
@@ -5514,9 +5561,9 @@ async function openDaemonConnection(ws, ctx) {
|
|
|
5514
5561
|
const conn = await connectToDaemon();
|
|
5515
5562
|
relayDaemonLines(conn, ws, ctx.repoCwd);
|
|
5516
5563
|
return conn;
|
|
5517
|
-
} catch (
|
|
5518
|
-
closeWithError(ws,
|
|
5519
|
-
throw
|
|
5564
|
+
} catch (error) {
|
|
5565
|
+
closeWithError(ws, error);
|
|
5566
|
+
throw error;
|
|
5520
5567
|
}
|
|
5521
5568
|
}
|
|
5522
5569
|
function relayDaemonLines(conn, ws, repoCwd) {
|
|
@@ -5565,25 +5612,25 @@ function withRepoCwd(line, repoCwd) {
|
|
|
5565
5612
|
}
|
|
5566
5613
|
|
|
5567
5614
|
// src/commands/sessions/web/restartMenu/installRestartMenu.ts
|
|
5568
|
-
import
|
|
5615
|
+
import chalk47 from "chalk";
|
|
5569
5616
|
import { createLogUpdate } from "log-update";
|
|
5570
5617
|
|
|
5571
5618
|
// src/commands/sessions/web/restartMenu/runRestartItem.ts
|
|
5572
|
-
import
|
|
5619
|
+
import chalk45 from "chalk";
|
|
5573
5620
|
async function runRestartItem(item, { runRestartDaemon, reExec }) {
|
|
5574
5621
|
if (item.disabled) return;
|
|
5575
5622
|
try {
|
|
5576
5623
|
if (item.action === "restart-daemon" || item.action === "restart-both") {
|
|
5577
|
-
console.log(
|
|
5624
|
+
console.log(chalk45.cyan("Restarting sessions daemon\u2026"));
|
|
5578
5625
|
await runRestartDaemon();
|
|
5579
5626
|
}
|
|
5580
5627
|
if (item.action === "restart-webserver" || item.action === "restart-both") {
|
|
5581
|
-
console.log(
|
|
5628
|
+
console.log(chalk45.cyan("Restarting web server\u2026"));
|
|
5582
5629
|
reExec();
|
|
5583
5630
|
}
|
|
5584
5631
|
} catch (error) {
|
|
5585
5632
|
const message = error instanceof Error ? error.message : String(error);
|
|
5586
|
-
console.error(
|
|
5633
|
+
console.error(chalk45.red(`Restart failed: ${message}`));
|
|
5587
5634
|
}
|
|
5588
5635
|
}
|
|
5589
5636
|
|
|
@@ -5640,7 +5687,8 @@ function createKeyHandler(deps2) {
|
|
|
5640
5687
|
const { key, digit } = parseMenuKey(chunk, toggleKey);
|
|
5641
5688
|
if (key === "quit") return quit();
|
|
5642
5689
|
if (key === "toggle") {
|
|
5643
|
-
menu.isOpen()
|
|
5690
|
+
if (menu.isOpen()) menu.close();
|
|
5691
|
+
else menu.open();
|
|
5644
5692
|
return;
|
|
5645
5693
|
}
|
|
5646
5694
|
if (!menu.isOpen()) return;
|
|
@@ -5660,24 +5708,24 @@ function nextIndex(items2, current, direction) {
|
|
|
5660
5708
|
}
|
|
5661
5709
|
function firstEnabledIndex(items2) {
|
|
5662
5710
|
const idx = items2.findIndex((item) => !item.disabled);
|
|
5663
|
-
return idx
|
|
5711
|
+
return idx === -1 ? 0 : idx;
|
|
5664
5712
|
}
|
|
5665
5713
|
|
|
5666
5714
|
// src/commands/sessions/web/restartMenu/renderRestartMenu.ts
|
|
5667
|
-
import
|
|
5715
|
+
import chalk46 from "chalk";
|
|
5668
5716
|
function renderRestartMenu(items2, selected) {
|
|
5669
|
-
const lines = [
|
|
5717
|
+
const lines = [chalk46.bold.cyan("assist \u2014 restart menu")];
|
|
5670
5718
|
items2.forEach((item, i) => {
|
|
5671
5719
|
const active = i === selected;
|
|
5672
|
-
const pointer = active ?
|
|
5673
|
-
const number =
|
|
5674
|
-
const note = item.note ?
|
|
5720
|
+
const pointer = active ? chalk46.cyan("\u276F ") : " ";
|
|
5721
|
+
const number = chalk46.dim(`${i + 1}. `);
|
|
5722
|
+
const note = item.note ? chalk46.dim(` (${item.note})`) : "";
|
|
5675
5723
|
let label2 = item.label;
|
|
5676
|
-
if (item.disabled) label2 =
|
|
5677
|
-
else if (active) label2 =
|
|
5724
|
+
if (item.disabled) label2 = chalk46.dim(label2);
|
|
5725
|
+
else if (active) label2 = chalk46.cyan.bold(label2);
|
|
5678
5726
|
lines.push(`${pointer}${number}${label2}${note}`);
|
|
5679
5727
|
});
|
|
5680
|
-
lines.push(
|
|
5728
|
+
lines.push(chalk46.dim("\u2191/\u2193 move \xB7 1-3 jump \xB7 enter select \xB7 esc close"));
|
|
5681
5729
|
return lines.join("\n");
|
|
5682
5730
|
}
|
|
5683
5731
|
|
|
@@ -5771,7 +5819,7 @@ function installRestartMenu(options2 = {}) {
|
|
|
5771
5819
|
}
|
|
5772
5820
|
});
|
|
5773
5821
|
const restoreRaw = enableRawMode(stdin, handler);
|
|
5774
|
-
console.log(
|
|
5822
|
+
console.log(chalk47.dim("Press Ctrl+R for the restart menu"));
|
|
5775
5823
|
let cleaned = false;
|
|
5776
5824
|
function cleanup() {
|
|
5777
5825
|
if (cleaned) return;
|
|
@@ -5823,26 +5871,26 @@ async function web2(options2) {
|
|
|
5823
5871
|
}
|
|
5824
5872
|
|
|
5825
5873
|
// src/commands/backlog/comment/index.ts
|
|
5826
|
-
import
|
|
5874
|
+
import chalk48 from "chalk";
|
|
5827
5875
|
async function comment(id2, text4) {
|
|
5828
5876
|
const found = await findOneItem(id2);
|
|
5829
5877
|
if (!found) process.exit(1);
|
|
5830
5878
|
await appendComment(found.orm, found.item.id, text4);
|
|
5831
|
-
console.log(
|
|
5879
|
+
console.log(chalk48.green(`Comment added to item #${id2}.`));
|
|
5832
5880
|
}
|
|
5833
5881
|
|
|
5834
5882
|
// src/commands/backlog/comments/index.ts
|
|
5835
|
-
import
|
|
5883
|
+
import chalk49 from "chalk";
|
|
5836
5884
|
async function comments2(id2) {
|
|
5837
5885
|
const found = await findOneItem(id2);
|
|
5838
5886
|
if (!found) process.exit(1);
|
|
5839
5887
|
const { item } = found;
|
|
5840
5888
|
const entries = item.comments ?? [];
|
|
5841
5889
|
if (entries.length === 0) {
|
|
5842
|
-
console.log(
|
|
5890
|
+
console.log(chalk49.dim(`No comments on item #${id2}.`));
|
|
5843
5891
|
return;
|
|
5844
5892
|
}
|
|
5845
|
-
console.log(
|
|
5893
|
+
console.log(chalk49.bold(`Comments for #${id2}: ${item.name}
|
|
5846
5894
|
`));
|
|
5847
5895
|
for (const entry of entries) {
|
|
5848
5896
|
console.log(`${formatComment(entry)}
|
|
@@ -5851,7 +5899,7 @@ async function comments2(id2) {
|
|
|
5851
5899
|
}
|
|
5852
5900
|
|
|
5853
5901
|
// src/commands/backlog/delete-comment/index.ts
|
|
5854
|
-
import
|
|
5902
|
+
import chalk50 from "chalk";
|
|
5855
5903
|
async function deleteCommentCmd(id2, commentId) {
|
|
5856
5904
|
const found = await findOneItem(id2);
|
|
5857
5905
|
if (!found) process.exit(1);
|
|
@@ -5863,16 +5911,16 @@ async function deleteCommentCmd(id2, commentId) {
|
|
|
5863
5911
|
switch (outcome) {
|
|
5864
5912
|
case "deleted":
|
|
5865
5913
|
console.log(
|
|
5866
|
-
|
|
5914
|
+
chalk50.green(`Comment #${commentId} deleted from item #${id2}.`)
|
|
5867
5915
|
);
|
|
5868
5916
|
break;
|
|
5869
5917
|
case "not-found":
|
|
5870
|
-
console.log(
|
|
5918
|
+
console.log(chalk50.red(`Comment #${commentId} not found on item #${id2}.`));
|
|
5871
5919
|
process.exit(1);
|
|
5872
5920
|
break;
|
|
5873
5921
|
case "is-summary":
|
|
5874
5922
|
console.log(
|
|
5875
|
-
|
|
5923
|
+
chalk50.red(
|
|
5876
5924
|
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
5877
5925
|
)
|
|
5878
5926
|
);
|
|
@@ -5890,7 +5938,7 @@ function registerCommentCommands(cmd) {
|
|
|
5890
5938
|
|
|
5891
5939
|
// src/commands/backlog/export/index.ts
|
|
5892
5940
|
import { writeFile } from "fs/promises";
|
|
5893
|
-
import
|
|
5941
|
+
import chalk51 from "chalk";
|
|
5894
5942
|
|
|
5895
5943
|
// src/commands/backlog/dump/DumpTable.ts
|
|
5896
5944
|
var DUMP_FORMAT = "assist-backlog-dump";
|
|
@@ -5957,7 +6005,7 @@ async function exportBacklog(file) {
|
|
|
5957
6005
|
if (file) {
|
|
5958
6006
|
await writeFile(file, dump);
|
|
5959
6007
|
console.error(
|
|
5960
|
-
|
|
6008
|
+
chalk51.green(`Exported backlog to ${file} (${dump.length} bytes).`)
|
|
5961
6009
|
);
|
|
5962
6010
|
return;
|
|
5963
6011
|
}
|
|
@@ -5973,7 +6021,7 @@ function registerExportCommand(cmd) {
|
|
|
5973
6021
|
|
|
5974
6022
|
// src/commands/backlog/import/index.ts
|
|
5975
6023
|
import { readFile } from "fs/promises";
|
|
5976
|
-
import
|
|
6024
|
+
import chalk53 from "chalk";
|
|
5977
6025
|
|
|
5978
6026
|
// src/commands/backlog/dump/countCopyRows.ts
|
|
5979
6027
|
function countCopyRows(data) {
|
|
@@ -6050,7 +6098,7 @@ function validateDump({ header, sections }) {
|
|
|
6050
6098
|
}
|
|
6051
6099
|
|
|
6052
6100
|
// src/commands/backlog/import/confirmReplace.ts
|
|
6053
|
-
import
|
|
6101
|
+
import chalk52 from "chalk";
|
|
6054
6102
|
async function countRows(client, table) {
|
|
6055
6103
|
const { rows } = await client.query(
|
|
6056
6104
|
`SELECT count(*)::int AS n FROM ${table}`
|
|
@@ -6061,7 +6109,7 @@ function printSummary(current, incoming) {
|
|
|
6061
6109
|
const lines = DUMP_TABLES.map(
|
|
6062
6110
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
6063
6111
|
);
|
|
6064
|
-
console.error(
|
|
6112
|
+
console.error(chalk52.bold("\nThis will REPLACE all backlog data:"));
|
|
6065
6113
|
console.error(`${lines.join("\n")}
|
|
6066
6114
|
`);
|
|
6067
6115
|
}
|
|
@@ -6137,13 +6185,13 @@ async function importBacklog(file, options2 = {}) {
|
|
|
6137
6185
|
);
|
|
6138
6186
|
await withDbClient(async (client) => {
|
|
6139
6187
|
if (!options2.yes && !await confirmReplace(client, incoming, !file)) {
|
|
6140
|
-
console.error(
|
|
6188
|
+
console.error(chalk53.yellow("Import cancelled; no changes made."));
|
|
6141
6189
|
return;
|
|
6142
6190
|
}
|
|
6143
6191
|
await restore(client, parsed);
|
|
6144
6192
|
const total = incoming.reduce((sum, n) => sum + n, 0);
|
|
6145
6193
|
console.error(
|
|
6146
|
-
|
|
6194
|
+
chalk53.green(
|
|
6147
6195
|
`Imported backlog: ${total} rows restored across ${DUMP_TABLES.length} tables.`
|
|
6148
6196
|
)
|
|
6149
6197
|
);
|
|
@@ -6160,7 +6208,7 @@ function registerImportCommand(cmd) {
|
|
|
6160
6208
|
}
|
|
6161
6209
|
|
|
6162
6210
|
// src/commands/backlog/add/index.ts
|
|
6163
|
-
import
|
|
6211
|
+
import chalk54 from "chalk";
|
|
6164
6212
|
|
|
6165
6213
|
// src/commands/backlog/add/shared.ts
|
|
6166
6214
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -6214,7 +6262,7 @@ function openEditor() {
|
|
|
6214
6262
|
unlinkSync6(filePath);
|
|
6215
6263
|
return void 0;
|
|
6216
6264
|
}
|
|
6217
|
-
const content = readFileSync15(filePath, "
|
|
6265
|
+
const content = readFileSync15(filePath, "utf8").trim();
|
|
6218
6266
|
unlinkSync6(filePath);
|
|
6219
6267
|
return content || void 0;
|
|
6220
6268
|
}
|
|
@@ -6236,7 +6284,7 @@ async function promptAcceptanceCriteria() {
|
|
|
6236
6284
|
async function add(options2) {
|
|
6237
6285
|
const type = options2.type ?? await promptType();
|
|
6238
6286
|
const name = options2.name ?? await promptName();
|
|
6239
|
-
const description = options2.desc?.replaceAll(
|
|
6287
|
+
const description = options2.desc?.replaceAll(String.raw`\n`, "\n") ?? await promptDescription();
|
|
6240
6288
|
const acceptanceCriteria2 = options2.ac ?? await promptAcceptanceCriteria();
|
|
6241
6289
|
const orm = await getDb();
|
|
6242
6290
|
const id2 = await insertItem(
|
|
@@ -6251,11 +6299,11 @@ async function add(options2) {
|
|
|
6251
6299
|
},
|
|
6252
6300
|
getOrigin()
|
|
6253
6301
|
);
|
|
6254
|
-
console.log(
|
|
6302
|
+
console.log(chalk54.green(`Added item #${id2}: ${name}`));
|
|
6255
6303
|
}
|
|
6256
6304
|
|
|
6257
6305
|
// src/commands/backlog/addPhase.ts
|
|
6258
|
-
import
|
|
6306
|
+
import chalk56 from "chalk";
|
|
6259
6307
|
|
|
6260
6308
|
// src/commands/backlog/insertPhaseAt.ts
|
|
6261
6309
|
import { count, eq as eq17 } from "drizzle-orm";
|
|
@@ -6288,7 +6336,7 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
|
|
|
6288
6336
|
}
|
|
6289
6337
|
|
|
6290
6338
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
6291
|
-
import
|
|
6339
|
+
import chalk55 from "chalk";
|
|
6292
6340
|
import { count as count2, eq as eq18 } from "drizzle-orm";
|
|
6293
6341
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
6294
6342
|
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq18(planPhases.itemId, itemId));
|
|
@@ -6297,7 +6345,7 @@ async function resolveInsertPosition(orm, itemId, position) {
|
|
|
6297
6345
|
const pos = Number.parseInt(position, 10);
|
|
6298
6346
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
6299
6347
|
console.log(
|
|
6300
|
-
|
|
6348
|
+
chalk55.red(
|
|
6301
6349
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
6302
6350
|
)
|
|
6303
6351
|
);
|
|
@@ -6318,7 +6366,7 @@ async function addPhase(id2, name, options2) {
|
|
|
6318
6366
|
if (!found) return;
|
|
6319
6367
|
const tasks = options2.task ?? [];
|
|
6320
6368
|
if (tasks.length === 0) {
|
|
6321
|
-
console.log(
|
|
6369
|
+
console.log(chalk56.red("At least one --task is required."));
|
|
6322
6370
|
process.exitCode = 1;
|
|
6323
6371
|
return;
|
|
6324
6372
|
}
|
|
@@ -6337,14 +6385,14 @@ async function addPhase(id2, name, options2) {
|
|
|
6337
6385
|
);
|
|
6338
6386
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
6339
6387
|
console.log(
|
|
6340
|
-
|
|
6388
|
+
chalk56.green(
|
|
6341
6389
|
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
6342
6390
|
)
|
|
6343
6391
|
);
|
|
6344
6392
|
}
|
|
6345
6393
|
|
|
6346
6394
|
// src/commands/backlog/list/index.ts
|
|
6347
|
-
import
|
|
6395
|
+
import chalk57 from "chalk";
|
|
6348
6396
|
|
|
6349
6397
|
// src/commands/backlog/originDisplayName.ts
|
|
6350
6398
|
function originDisplayName(origin) {
|
|
@@ -6396,7 +6444,7 @@ async function list2(options2) {
|
|
|
6396
6444
|
const allItems = await loadBacklog(options2.allRepos);
|
|
6397
6445
|
const items2 = filterItems(allItems, options2);
|
|
6398
6446
|
if (items2.length === 0) {
|
|
6399
|
-
console.log(
|
|
6447
|
+
console.log(chalk57.dim("Backlog is empty."));
|
|
6400
6448
|
return;
|
|
6401
6449
|
}
|
|
6402
6450
|
const labels = originDisplayLabels(
|
|
@@ -6405,9 +6453,9 @@ async function list2(options2) {
|
|
|
6405
6453
|
const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
|
|
6406
6454
|
const prefixWidth = options2.allRepos ? Math.max(0, ...items2.map((i) => repoNameOf(i).length)) : 0;
|
|
6407
6455
|
for (const item of items2) {
|
|
6408
|
-
const repoPrefix = options2.allRepos ? `${
|
|
6456
|
+
const repoPrefix = options2.allRepos ? `${chalk57.dim(repoNameOf(item).padEnd(prefixWidth))} ` : "";
|
|
6409
6457
|
console.log(
|
|
6410
|
-
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
6458
|
+
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk57.dim(`#${item.id}`)} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
6411
6459
|
);
|
|
6412
6460
|
if (options2.verbose) {
|
|
6413
6461
|
printVerboseDetails(item);
|
|
@@ -6433,7 +6481,7 @@ function registerItemCommands(cmd) {
|
|
|
6433
6481
|
}
|
|
6434
6482
|
|
|
6435
6483
|
// src/commands/backlog/link.ts
|
|
6436
|
-
import
|
|
6484
|
+
import chalk59 from "chalk";
|
|
6437
6485
|
|
|
6438
6486
|
// src/commands/backlog/hasCycle.ts
|
|
6439
6487
|
function hasCycle(adjacency, fromId, toId) {
|
|
@@ -6465,14 +6513,14 @@ async function loadDependencyGraph(orm) {
|
|
|
6465
6513
|
}
|
|
6466
6514
|
|
|
6467
6515
|
// src/commands/backlog/validateLinkTarget.ts
|
|
6468
|
-
import
|
|
6516
|
+
import chalk58 from "chalk";
|
|
6469
6517
|
function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
6470
6518
|
const duplicate = (fromItem.links ?? []).some(
|
|
6471
6519
|
(l) => l.targetId === toNum && l.type === linkType
|
|
6472
6520
|
);
|
|
6473
6521
|
if (duplicate) {
|
|
6474
6522
|
console.log(
|
|
6475
|
-
|
|
6523
|
+
chalk58.yellow(`Link already exists: #${fromNum} ${linkType} #${toNum}`)
|
|
6476
6524
|
);
|
|
6477
6525
|
return false;
|
|
6478
6526
|
}
|
|
@@ -6481,7 +6529,7 @@ function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
|
6481
6529
|
|
|
6482
6530
|
// src/commands/backlog/link.ts
|
|
6483
6531
|
function fail(message) {
|
|
6484
|
-
console.log(
|
|
6532
|
+
console.log(chalk59.red(message));
|
|
6485
6533
|
return void 0;
|
|
6486
6534
|
}
|
|
6487
6535
|
function parseLinkType(type) {
|
|
@@ -6511,12 +6559,12 @@ async function link(fromId, toId, opts) {
|
|
|
6511
6559
|
if (await createsCycle(orm, linkType, fromNum, toNum)) return;
|
|
6512
6560
|
await orm.insert(links).values({ itemId: fromNum, type: linkType, targetId: toNum });
|
|
6513
6561
|
console.log(
|
|
6514
|
-
|
|
6562
|
+
chalk59.green(`Linked #${fromNum} ${linkType} #${toNum} (${toItem.name})`)
|
|
6515
6563
|
);
|
|
6516
6564
|
}
|
|
6517
6565
|
|
|
6518
6566
|
// src/commands/backlog/unlink.ts
|
|
6519
|
-
import
|
|
6567
|
+
import chalk60 from "chalk";
|
|
6520
6568
|
import { and as and4, eq as eq20 } from "drizzle-orm";
|
|
6521
6569
|
async function unlink(fromId, toId) {
|
|
6522
6570
|
const fromNum = Number.parseInt(fromId, 10);
|
|
@@ -6524,19 +6572,19 @@ async function unlink(fromId, toId) {
|
|
|
6524
6572
|
const { orm } = await getReady();
|
|
6525
6573
|
const fromItem = await loadItem(orm, fromNum);
|
|
6526
6574
|
if (!fromItem) {
|
|
6527
|
-
console.log(
|
|
6575
|
+
console.log(chalk60.red(`Item #${fromId} not found.`));
|
|
6528
6576
|
return;
|
|
6529
6577
|
}
|
|
6530
6578
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
6531
|
-
console.log(
|
|
6579
|
+
console.log(chalk60.yellow(`No links found on item #${fromId}.`));
|
|
6532
6580
|
return;
|
|
6533
6581
|
}
|
|
6534
6582
|
if (!fromItem.links.some((l) => l.targetId === toNum)) {
|
|
6535
|
-
console.log(
|
|
6583
|
+
console.log(chalk60.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
6536
6584
|
return;
|
|
6537
6585
|
}
|
|
6538
6586
|
await orm.delete(links).where(and4(eq20(links.itemId, fromNum), eq20(links.targetId, toNum)));
|
|
6539
|
-
console.log(
|
|
6587
|
+
console.log(chalk60.green(`Removed link from #${fromId} to #${toId}.`));
|
|
6540
6588
|
}
|
|
6541
6589
|
|
|
6542
6590
|
// src/commands/backlog/registerLinkCommands.ts
|
|
@@ -6550,17 +6598,17 @@ function registerLinkCommands(cmd) {
|
|
|
6550
6598
|
}
|
|
6551
6599
|
|
|
6552
6600
|
// src/commands/backlog/move-repo/index.ts
|
|
6553
|
-
import
|
|
6601
|
+
import chalk62 from "chalk";
|
|
6554
6602
|
import { eq as eq22 } from "drizzle-orm";
|
|
6555
6603
|
|
|
6556
6604
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
6557
|
-
import
|
|
6605
|
+
import chalk61 from "chalk";
|
|
6558
6606
|
function pluralItems(n) {
|
|
6559
6607
|
return `${n} item${n === 1 ? "" : "s"}`;
|
|
6560
6608
|
}
|
|
6561
6609
|
async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
6562
6610
|
console.log(
|
|
6563
|
-
`${pluralItems(cnt)}: ${
|
|
6611
|
+
`${pluralItems(cnt)}: ${chalk61.cyan(oldOrigin)} \u2192 ${chalk61.cyan(newOrigin)}`
|
|
6564
6612
|
);
|
|
6565
6613
|
return promptConfirm(`Retag ${pluralItems(cnt)}?`);
|
|
6566
6614
|
}
|
|
@@ -6592,7 +6640,7 @@ Pass the full origin.`
|
|
|
6592
6640
|
|
|
6593
6641
|
// src/commands/backlog/move-repo/index.ts
|
|
6594
6642
|
function fail2(message) {
|
|
6595
|
-
console.log(
|
|
6643
|
+
console.log(chalk62.red(message));
|
|
6596
6644
|
process.exitCode = 1;
|
|
6597
6645
|
}
|
|
6598
6646
|
async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
@@ -6608,12 +6656,12 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
6608
6656
|
}
|
|
6609
6657
|
const cnt = await countByOrigin(orm, oldOrigin);
|
|
6610
6658
|
if (!options2.yes && !await confirmMove(cnt, oldOrigin, newOrigin)) {
|
|
6611
|
-
console.log(
|
|
6659
|
+
console.log(chalk62.yellow("Move cancelled; no changes made."));
|
|
6612
6660
|
return;
|
|
6613
6661
|
}
|
|
6614
6662
|
await orm.update(items).set({ origin: newOrigin }).where(eq22(items.origin, oldOrigin));
|
|
6615
6663
|
console.log(
|
|
6616
|
-
|
|
6664
|
+
chalk62.green(
|
|
6617
6665
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
6618
6666
|
)
|
|
6619
6667
|
);
|
|
@@ -6642,11 +6690,11 @@ function registerPlanCommands(cmd) {
|
|
|
6642
6690
|
}
|
|
6643
6691
|
|
|
6644
6692
|
// src/commands/backlog/refine.ts
|
|
6645
|
-
import
|
|
6693
|
+
import chalk65 from "chalk";
|
|
6646
6694
|
import enquirer7 from "enquirer";
|
|
6647
6695
|
|
|
6648
|
-
// src/commands/backlog/
|
|
6649
|
-
import
|
|
6696
|
+
// src/commands/backlog/handleLaunchSignal.ts
|
|
6697
|
+
import chalk64 from "chalk";
|
|
6650
6698
|
|
|
6651
6699
|
// src/commands/backlog/surfaceCreatedItem.ts
|
|
6652
6700
|
async function surfaceCreatedItem(slashCommand, id2) {
|
|
@@ -6664,37 +6712,53 @@ async function surfaceCreatedItem(slashCommand, id2) {
|
|
|
6664
6712
|
}
|
|
6665
6713
|
|
|
6666
6714
|
// src/commands/backlog/tryRunById.ts
|
|
6667
|
-
import
|
|
6715
|
+
import chalk63 from "chalk";
|
|
6668
6716
|
async function tryRunById(id2, options2) {
|
|
6669
6717
|
const numericId = Number.parseInt(id2, 10);
|
|
6670
6718
|
const { orm } = await getReady();
|
|
6671
6719
|
const item = Number.isNaN(numericId) ? void 0 : await loadItem(orm, numericId);
|
|
6672
6720
|
if (!item) {
|
|
6673
|
-
console.log(
|
|
6721
|
+
console.log(chalk63.red(`Item #${id2} not found.`));
|
|
6674
6722
|
return false;
|
|
6675
6723
|
}
|
|
6676
6724
|
if (item.status === "done") {
|
|
6677
|
-
console.log(
|
|
6725
|
+
console.log(chalk63.red(`Item #${id2} is already done.`));
|
|
6678
6726
|
return false;
|
|
6679
6727
|
}
|
|
6680
6728
|
if (item.status === "wontdo") {
|
|
6681
|
-
console.log(
|
|
6729
|
+
console.log(chalk63.red(`Item #${id2} is marked won't do.`));
|
|
6682
6730
|
return false;
|
|
6683
6731
|
}
|
|
6684
6732
|
const hasDeps = (item.links ?? []).some((l) => l.type === "depends-on");
|
|
6685
6733
|
if (hasDeps && isBlocked(item, await loadItemSummaries(orm, getOrigin()))) {
|
|
6686
6734
|
console.log(
|
|
6687
|
-
|
|
6735
|
+
chalk63.red(`Item #${id2} is blocked by unresolved dependencies.`)
|
|
6688
6736
|
);
|
|
6689
6737
|
return false;
|
|
6690
6738
|
}
|
|
6691
|
-
console.log(
|
|
6739
|
+
console.log(chalk63.bold(`
|
|
6692
6740
|
Running backlog item #${id2}...
|
|
6693
6741
|
`));
|
|
6694
6742
|
await run2(id2, options2);
|
|
6695
6743
|
return true;
|
|
6696
6744
|
}
|
|
6697
6745
|
|
|
6746
|
+
// src/commands/backlog/handleLaunchSignal.ts
|
|
6747
|
+
async function handleLaunchSignal(slashCommand, once) {
|
|
6748
|
+
const signal = readSignal();
|
|
6749
|
+
cleanupSignal();
|
|
6750
|
+
if (signal?.event === "done" && typeof signal.id === "string" && signal.id) {
|
|
6751
|
+
await surfaceCreatedItem(slashCommand, signal.id);
|
|
6752
|
+
}
|
|
6753
|
+
if (signal?.event === "next") {
|
|
6754
|
+
if (typeof signal.id === "string" && signal.id) {
|
|
6755
|
+
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
6756
|
+
}
|
|
6757
|
+
console.log(chalk64.bold("\nChaining into assist next...\n"));
|
|
6758
|
+
await next({ allowEdits: true, once });
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
|
|
6698
6762
|
// src/commands/backlog/launchMode.ts
|
|
6699
6763
|
function buildSlashCommand(slashCommand, description) {
|
|
6700
6764
|
const trimmed = description?.trim();
|
|
@@ -6714,20 +6778,10 @@ async function launchMode(slashCommand, options2) {
|
|
|
6714
6778
|
{ allowEdits: true }
|
|
6715
6779
|
);
|
|
6716
6780
|
watchForMarker(child, { actOnDone: options2?.once });
|
|
6717
|
-
await done2;
|
|
6781
|
+
const launched = await awaitClaude(done2, `/${slashCommand}`);
|
|
6718
6782
|
stopWatching();
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
if (signal?.event === "done" && typeof signal.id === "string" && signal.id) {
|
|
6722
|
-
await surfaceCreatedItem(slashCommand, signal.id);
|
|
6723
|
-
}
|
|
6724
|
-
if (signal?.event === "next") {
|
|
6725
|
-
if (typeof signal.id === "string" && signal.id) {
|
|
6726
|
-
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
6727
|
-
}
|
|
6728
|
-
console.log(chalk63.bold("\nChaining into assist next...\n"));
|
|
6729
|
-
await next({ allowEdits: true, once: options2?.once });
|
|
6730
|
-
}
|
|
6783
|
+
if (!launched) return;
|
|
6784
|
+
await handleLaunchSignal(slashCommand, options2?.once);
|
|
6731
6785
|
}
|
|
6732
6786
|
|
|
6733
6787
|
// src/commands/backlog/refine.ts
|
|
@@ -6737,12 +6791,12 @@ async function pickItemForRefine() {
|
|
|
6737
6791
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
6738
6792
|
);
|
|
6739
6793
|
if (active.length === 0) {
|
|
6740
|
-
console.log(
|
|
6794
|
+
console.log(chalk65.yellow("No active backlog items to refine."));
|
|
6741
6795
|
return void 0;
|
|
6742
6796
|
}
|
|
6743
6797
|
if (active.length === 1) {
|
|
6744
6798
|
const item = active[0];
|
|
6745
|
-
console.log(
|
|
6799
|
+
console.log(chalk65.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
6746
6800
|
return String(item.id);
|
|
6747
6801
|
}
|
|
6748
6802
|
const { selected } = await exitOnCancel(
|
|
@@ -6777,7 +6831,7 @@ function registerRefineCommand(cmd) {
|
|
|
6777
6831
|
}
|
|
6778
6832
|
|
|
6779
6833
|
// src/commands/backlog/rewindPhase.ts
|
|
6780
|
-
import
|
|
6834
|
+
import chalk66 from "chalk";
|
|
6781
6835
|
function validateRewind2(item, phaseNumber) {
|
|
6782
6836
|
if (!item.plan || item.plan.length === 0) {
|
|
6783
6837
|
return `Item #${item.id} has no plan phases.`;
|
|
@@ -6797,12 +6851,12 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
6797
6851
|
const { orm } = await getReady();
|
|
6798
6852
|
const item = await loadItem(orm, Number.parseInt(id2, 10));
|
|
6799
6853
|
if (!item) {
|
|
6800
|
-
console.log(
|
|
6854
|
+
console.log(chalk66.red(`Item #${id2} not found.`));
|
|
6801
6855
|
return;
|
|
6802
6856
|
}
|
|
6803
6857
|
const error = validateRewind2(item, phaseNumber);
|
|
6804
6858
|
if (error) {
|
|
6805
|
-
console.log(
|
|
6859
|
+
console.log(chalk66.red(error));
|
|
6806
6860
|
process.exitCode = 1;
|
|
6807
6861
|
return;
|
|
6808
6862
|
}
|
|
@@ -6820,7 +6874,7 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
6820
6874
|
targetPhase: phaseIndex
|
|
6821
6875
|
});
|
|
6822
6876
|
console.log(
|
|
6823
|
-
|
|
6877
|
+
chalk66.green(`Rewound item #${id2} to phase ${phaseNumber} (${phaseName}).`)
|
|
6824
6878
|
);
|
|
6825
6879
|
}
|
|
6826
6880
|
|
|
@@ -6846,22 +6900,22 @@ function registerRunCommand(cmd) {
|
|
|
6846
6900
|
}
|
|
6847
6901
|
|
|
6848
6902
|
// src/commands/backlog/search/index.ts
|
|
6849
|
-
import
|
|
6903
|
+
import chalk67 from "chalk";
|
|
6850
6904
|
async function search(query) {
|
|
6851
6905
|
const items2 = await searchBacklog(query);
|
|
6852
6906
|
if (items2.length === 0) {
|
|
6853
|
-
console.log(
|
|
6907
|
+
console.log(chalk67.dim(`No items matching "${query}".`));
|
|
6854
6908
|
return;
|
|
6855
6909
|
}
|
|
6856
6910
|
console.log(
|
|
6857
|
-
|
|
6911
|
+
chalk67.dim(
|
|
6858
6912
|
`${items2.length} item${items2.length === 1 ? "" : "s"} matching "${query}":
|
|
6859
6913
|
`
|
|
6860
6914
|
)
|
|
6861
6915
|
);
|
|
6862
6916
|
for (const item of items2) {
|
|
6863
6917
|
console.log(
|
|
6864
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
6918
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk67.dim(`#${item.id}`)} ${item.name}`
|
|
6865
6919
|
);
|
|
6866
6920
|
}
|
|
6867
6921
|
}
|
|
@@ -6872,16 +6926,16 @@ function registerSearchCommand(cmd) {
|
|
|
6872
6926
|
}
|
|
6873
6927
|
|
|
6874
6928
|
// src/commands/backlog/delete/index.ts
|
|
6875
|
-
import
|
|
6929
|
+
import chalk68 from "chalk";
|
|
6876
6930
|
async function del(id2) {
|
|
6877
6931
|
const name = await removeItem(id2);
|
|
6878
6932
|
if (name) {
|
|
6879
|
-
console.log(
|
|
6933
|
+
console.log(chalk68.green(`Deleted item #${id2}: ${name}`));
|
|
6880
6934
|
}
|
|
6881
6935
|
}
|
|
6882
6936
|
|
|
6883
6937
|
// src/commands/backlog/done/index.ts
|
|
6884
|
-
import
|
|
6938
|
+
import chalk69 from "chalk";
|
|
6885
6939
|
async function done(id2, summary) {
|
|
6886
6940
|
const found = await findOneItem(id2);
|
|
6887
6941
|
if (!found) return;
|
|
@@ -6891,12 +6945,12 @@ async function done(id2, summary) {
|
|
|
6891
6945
|
const pending = item.plan.slice(completedCount);
|
|
6892
6946
|
if (pending.length > 0) {
|
|
6893
6947
|
console.log(
|
|
6894
|
-
|
|
6948
|
+
chalk69.red(
|
|
6895
6949
|
`Cannot complete item #${id2}: ${pending.length} pending phase(s):`
|
|
6896
6950
|
)
|
|
6897
6951
|
);
|
|
6898
6952
|
for (const phase of pending) {
|
|
6899
|
-
console.log(
|
|
6953
|
+
console.log(chalk69.yellow(` - ${phase.name}`));
|
|
6900
6954
|
}
|
|
6901
6955
|
process.exitCode = 1;
|
|
6902
6956
|
return;
|
|
@@ -6907,18 +6961,18 @@ async function done(id2, summary) {
|
|
|
6907
6961
|
const phase = item.currentPhase ?? 1;
|
|
6908
6962
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
6909
6963
|
}
|
|
6910
|
-
console.log(
|
|
6964
|
+
console.log(chalk69.green(`Completed item #${id2}: ${item.name}`));
|
|
6911
6965
|
}
|
|
6912
6966
|
|
|
6913
6967
|
// src/commands/backlog/star/index.ts
|
|
6914
|
-
import
|
|
6968
|
+
import chalk71 from "chalk";
|
|
6915
6969
|
|
|
6916
6970
|
// src/commands/backlog/setStarred.ts
|
|
6917
|
-
import
|
|
6971
|
+
import chalk70 from "chalk";
|
|
6918
6972
|
async function setStarred(id2, starred) {
|
|
6919
6973
|
const { orm } = await getReady();
|
|
6920
6974
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
6921
|
-
if (name === void 0) console.log(
|
|
6975
|
+
if (name === void 0) console.log(chalk70.red(`Item #${id2} not found.`));
|
|
6922
6976
|
return name;
|
|
6923
6977
|
}
|
|
6924
6978
|
|
|
@@ -6926,45 +6980,45 @@ async function setStarred(id2, starred) {
|
|
|
6926
6980
|
async function star(id2) {
|
|
6927
6981
|
const name = await setStarred(id2, true);
|
|
6928
6982
|
if (name) {
|
|
6929
|
-
console.log(
|
|
6983
|
+
console.log(chalk71.green(`Starred item #${id2}: ${name}`));
|
|
6930
6984
|
}
|
|
6931
6985
|
}
|
|
6932
6986
|
|
|
6933
6987
|
// src/commands/backlog/start/index.ts
|
|
6934
|
-
import
|
|
6988
|
+
import chalk72 from "chalk";
|
|
6935
6989
|
async function start(id2) {
|
|
6936
6990
|
const name = await setStatus(id2, "in-progress");
|
|
6937
6991
|
if (name) {
|
|
6938
|
-
console.log(
|
|
6992
|
+
console.log(chalk72.green(`Started item #${id2}: ${name}`));
|
|
6939
6993
|
}
|
|
6940
6994
|
}
|
|
6941
6995
|
|
|
6942
6996
|
// src/commands/backlog/stop/index.ts
|
|
6943
|
-
import
|
|
6997
|
+
import chalk73 from "chalk";
|
|
6944
6998
|
import { and as and5, eq as eq23 } from "drizzle-orm";
|
|
6945
6999
|
async function stop() {
|
|
6946
7000
|
const { orm } = await getReady();
|
|
6947
7001
|
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and5(eq23(items.status, "in-progress"), eq23(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
6948
7002
|
if (stopped.length === 0) {
|
|
6949
|
-
console.log(
|
|
7003
|
+
console.log(chalk73.yellow("No in-progress items to stop."));
|
|
6950
7004
|
return;
|
|
6951
7005
|
}
|
|
6952
7006
|
for (const item of stopped) {
|
|
6953
|
-
console.log(
|
|
7007
|
+
console.log(chalk73.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
6954
7008
|
}
|
|
6955
7009
|
}
|
|
6956
7010
|
|
|
6957
7011
|
// src/commands/backlog/unstar/index.ts
|
|
6958
|
-
import
|
|
7012
|
+
import chalk74 from "chalk";
|
|
6959
7013
|
async function unstar(id2) {
|
|
6960
7014
|
const name = await setStarred(id2, false);
|
|
6961
7015
|
if (name) {
|
|
6962
|
-
console.log(
|
|
7016
|
+
console.log(chalk74.green(`Unstarred item #${id2}: ${name}`));
|
|
6963
7017
|
}
|
|
6964
7018
|
}
|
|
6965
7019
|
|
|
6966
7020
|
// src/commands/backlog/wontdo/index.ts
|
|
6967
|
-
import
|
|
7021
|
+
import chalk75 from "chalk";
|
|
6968
7022
|
async function wontdo(id2, reason) {
|
|
6969
7023
|
const found = await findOneItem(id2);
|
|
6970
7024
|
if (!found) return;
|
|
@@ -6974,7 +7028,7 @@ async function wontdo(id2, reason) {
|
|
|
6974
7028
|
const phase = item.currentPhase ?? 1;
|
|
6975
7029
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
6976
7030
|
}
|
|
6977
|
-
console.log(
|
|
7031
|
+
console.log(chalk75.red(`Won't do item #${id2}: ${item.name}`));
|
|
6978
7032
|
}
|
|
6979
7033
|
|
|
6980
7034
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -6989,11 +7043,11 @@ function registerStatusCommands(cmd) {
|
|
|
6989
7043
|
}
|
|
6990
7044
|
|
|
6991
7045
|
// src/commands/backlog/removePhase.ts
|
|
6992
|
-
import
|
|
7046
|
+
import chalk77 from "chalk";
|
|
6993
7047
|
import { and as and8, eq as eq26 } from "drizzle-orm";
|
|
6994
7048
|
|
|
6995
7049
|
// src/commands/backlog/findPhase.ts
|
|
6996
|
-
import
|
|
7050
|
+
import chalk76 from "chalk";
|
|
6997
7051
|
import { and as and6, count as count4, eq as eq24 } from "drizzle-orm";
|
|
6998
7052
|
async function findPhase(id2, phase) {
|
|
6999
7053
|
const found = await findOneItem(id2);
|
|
@@ -7004,7 +7058,7 @@ async function findPhase(id2, phase) {
|
|
|
7004
7058
|
const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and6(eq24(planPhases.itemId, itemId), eq24(planPhases.idx, phaseIdx)));
|
|
7005
7059
|
if (!row || row.cnt === 0) {
|
|
7006
7060
|
console.log(
|
|
7007
|
-
|
|
7061
|
+
chalk76.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
7008
7062
|
);
|
|
7009
7063
|
process.exitCode = 1;
|
|
7010
7064
|
return void 0;
|
|
@@ -7051,12 +7105,12 @@ async function removePhase(id2, phase) {
|
|
|
7051
7105
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
7052
7106
|
});
|
|
7053
7107
|
console.log(
|
|
7054
|
-
|
|
7108
|
+
chalk77.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
7055
7109
|
);
|
|
7056
7110
|
}
|
|
7057
7111
|
|
|
7058
7112
|
// src/commands/backlog/update/index.ts
|
|
7059
|
-
import
|
|
7113
|
+
import chalk79 from "chalk";
|
|
7060
7114
|
import { eq as eq27 } from "drizzle-orm";
|
|
7061
7115
|
|
|
7062
7116
|
// src/commands/backlog/update/parseListIndex.ts
|
|
@@ -7132,16 +7186,16 @@ function applyAcMutations(current, options2) {
|
|
|
7132
7186
|
}
|
|
7133
7187
|
|
|
7134
7188
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7135
|
-
import
|
|
7189
|
+
import chalk78 from "chalk";
|
|
7136
7190
|
function buildUpdateValues(options2) {
|
|
7137
7191
|
const { name, desc: desc4, type, ac } = options2;
|
|
7138
7192
|
if (!name && !desc4 && !type && !ac) {
|
|
7139
|
-
console.log(
|
|
7193
|
+
console.log(chalk78.red("Nothing to update. Provide at least one flag."));
|
|
7140
7194
|
process.exitCode = 1;
|
|
7141
7195
|
return void 0;
|
|
7142
7196
|
}
|
|
7143
7197
|
if (type && type !== "story" && type !== "bug") {
|
|
7144
|
-
console.log(
|
|
7198
|
+
console.log(chalk78.red('Invalid type. Must be "story" or "bug".'));
|
|
7145
7199
|
process.exitCode = 1;
|
|
7146
7200
|
return void 0;
|
|
7147
7201
|
}
|
|
@@ -7174,14 +7228,14 @@ async function update(id2, options2) {
|
|
|
7174
7228
|
if (hasAcMutations(options2)) {
|
|
7175
7229
|
if (options2.ac) {
|
|
7176
7230
|
console.log(
|
|
7177
|
-
|
|
7231
|
+
chalk79.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
7178
7232
|
);
|
|
7179
7233
|
process.exitCode = 1;
|
|
7180
7234
|
return;
|
|
7181
7235
|
}
|
|
7182
7236
|
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
7183
7237
|
if (!mutation.ok) {
|
|
7184
|
-
console.log(
|
|
7238
|
+
console.log(chalk79.red(mutation.error));
|
|
7185
7239
|
process.exitCode = 1;
|
|
7186
7240
|
return;
|
|
7187
7241
|
}
|
|
@@ -7192,11 +7246,11 @@ async function update(id2, options2) {
|
|
|
7192
7246
|
const { orm } = found;
|
|
7193
7247
|
const itemId = found.item.id;
|
|
7194
7248
|
await orm.update(items).set(built.set).where(eq27(items.id, itemId));
|
|
7195
|
-
console.log(
|
|
7249
|
+
console.log(chalk79.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
7196
7250
|
}
|
|
7197
7251
|
|
|
7198
7252
|
// src/commands/backlog/updatePhase.ts
|
|
7199
|
-
import
|
|
7253
|
+
import chalk80 from "chalk";
|
|
7200
7254
|
|
|
7201
7255
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
7202
7256
|
import { and as and9, eq as eq28 } from "drizzle-orm";
|
|
@@ -7300,7 +7354,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
7300
7354
|
const { item, orm, itemId, phaseIdx } = found;
|
|
7301
7355
|
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
7302
7356
|
if (!resolved.ok) {
|
|
7303
|
-
console.log(
|
|
7357
|
+
console.log(chalk80.red(resolved.error));
|
|
7304
7358
|
process.exitCode = 1;
|
|
7305
7359
|
return;
|
|
7306
7360
|
}
|
|
@@ -7312,7 +7366,7 @@ async function updatePhase(id2, phase, options2) {
|
|
|
7312
7366
|
manualCheck && "manual checks"
|
|
7313
7367
|
].filter(Boolean).join(", ");
|
|
7314
7368
|
console.log(
|
|
7315
|
-
|
|
7369
|
+
chalk80.green(
|
|
7316
7370
|
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
7317
7371
|
)
|
|
7318
7372
|
);
|
|
@@ -7532,7 +7586,7 @@ function findBuiltinDeny(parts) {
|
|
|
7532
7586
|
};
|
|
7533
7587
|
}
|
|
7534
7588
|
function rawDenyRegex(pattern2) {
|
|
7535
|
-
const tokens = pattern2.trim().split(/\s+/).map((token) => token.replace(/[.*+?^${}()|[\]\\]/g,
|
|
7589
|
+
const tokens = pattern2.trim().split(/\s+/).map((token) => token.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)).join(String.raw`\s+`);
|
|
7536
7590
|
return new RegExp(`(?<=^|\\s)${tokens}(?=\\s|$)`);
|
|
7537
7591
|
}
|
|
7538
7592
|
var RAW_BUILTIN_DENIES = BUILTIN_DENIES.map((rule) => ({
|
|
@@ -7686,7 +7740,7 @@ function packageRoot() {
|
|
|
7686
7740
|
}
|
|
7687
7741
|
function readLines(path56) {
|
|
7688
7742
|
if (!existsSync21(path56)) return [];
|
|
7689
|
-
return readFileSync16(path56, "
|
|
7743
|
+
return readFileSync16(path56, "utf8").split("\n").filter((line) => line.trim() !== "");
|
|
7690
7744
|
}
|
|
7691
7745
|
var cachedReads;
|
|
7692
7746
|
var cachedWrites;
|
|
@@ -7750,7 +7804,7 @@ function readSettingsPerms(key) {
|
|
|
7750
7804
|
function readPermissionArray(filePath, key) {
|
|
7751
7805
|
if (!existsSync22(filePath)) return [];
|
|
7752
7806
|
try {
|
|
7753
|
-
const data = JSON.parse(readFileSync17(filePath, "
|
|
7807
|
+
const data = JSON.parse(readFileSync17(filePath, "utf8"));
|
|
7754
7808
|
const arr = data?.permissions?.[key];
|
|
7755
7809
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
7756
7810
|
} catch {
|
|
@@ -8021,7 +8075,7 @@ import { execSync as execSync21 } from "child_process";
|
|
|
8021
8075
|
function checkCliAvailable(cli) {
|
|
8022
8076
|
const binary = cli.split(/\s+/)[0];
|
|
8023
8077
|
const opts = {
|
|
8024
|
-
encoding: "
|
|
8078
|
+
encoding: "utf8",
|
|
8025
8079
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8026
8080
|
};
|
|
8027
8081
|
try {
|
|
@@ -8045,11 +8099,11 @@ function assertCliExists(cli) {
|
|
|
8045
8099
|
}
|
|
8046
8100
|
|
|
8047
8101
|
// src/commands/permitCliReads/colorize.ts
|
|
8048
|
-
import
|
|
8102
|
+
import chalk81 from "chalk";
|
|
8049
8103
|
function colorize(plainOutput) {
|
|
8050
8104
|
return plainOutput.split("\n").map((line) => {
|
|
8051
|
-
if (line.startsWith(" R ")) return
|
|
8052
|
-
if (line.startsWith(" W ")) return
|
|
8105
|
+
if (line.startsWith(" R ")) return chalk81.green(line);
|
|
8106
|
+
if (line.startsWith(" W ")) return chalk81.red(line);
|
|
8053
8107
|
return line;
|
|
8054
8108
|
}).join("\n");
|
|
8055
8109
|
}
|
|
@@ -8061,7 +8115,7 @@ function isClaudeCode() {
|
|
|
8061
8115
|
|
|
8062
8116
|
// src/commands/permitCliReads/mapAsync.ts
|
|
8063
8117
|
async function mapAsync(items2, concurrency, fn) {
|
|
8064
|
-
const results =
|
|
8118
|
+
const results = Array.from({ length: items2.length });
|
|
8065
8119
|
let next3 = 0;
|
|
8066
8120
|
async function worker() {
|
|
8067
8121
|
while (next3 < items2.length) {
|
|
@@ -8134,7 +8188,7 @@ function runHelp(args) {
|
|
|
8134
8188
|
return new Promise((resolve16) => {
|
|
8135
8189
|
exec2(
|
|
8136
8190
|
`${args.join(" ")} --help`,
|
|
8137
|
-
{ encoding: "
|
|
8191
|
+
{ encoding: "utf8", timeout: 3e4 },
|
|
8138
8192
|
(_err, stdout, stderr) => {
|
|
8139
8193
|
resolve16(stdout || stderr || "");
|
|
8140
8194
|
}
|
|
@@ -8283,8 +8337,8 @@ function parseCached(cli, cached) {
|
|
|
8283
8337
|
if (!trimmed.startsWith(prefix2)) continue;
|
|
8284
8338
|
const rest = trimmed.slice(prefix2.length);
|
|
8285
8339
|
const dashIdx = rest.indexOf(" \u2014 ");
|
|
8286
|
-
const pathStr = dashIdx
|
|
8287
|
-
const description = dashIdx
|
|
8340
|
+
const pathStr = dashIdx !== -1 ? rest.slice(0, dashIdx) : rest;
|
|
8341
|
+
const description = dashIdx !== -1 ? rest.slice(dashIdx + 3) : "";
|
|
8288
8342
|
commands.push({ path: pathStr.split(" "), description });
|
|
8289
8343
|
}
|
|
8290
8344
|
return commands;
|
|
@@ -8308,7 +8362,7 @@ function logPath(cli) {
|
|
|
8308
8362
|
function readCache(cli) {
|
|
8309
8363
|
const path56 = logPath(cli);
|
|
8310
8364
|
if (!existsSync23(path56)) return void 0;
|
|
8311
|
-
return readFileSync18(path56, "
|
|
8365
|
+
return readFileSync18(path56, "utf8");
|
|
8312
8366
|
}
|
|
8313
8367
|
function writeCache(cli, output) {
|
|
8314
8368
|
const dir = join21(homedir9(), ".assist");
|
|
@@ -8347,7 +8401,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
8347
8401
|
}
|
|
8348
8402
|
|
|
8349
8403
|
// src/commands/deny/denyAdd.ts
|
|
8350
|
-
import
|
|
8404
|
+
import chalk82 from "chalk";
|
|
8351
8405
|
|
|
8352
8406
|
// src/commands/deny/loadDenyConfig.ts
|
|
8353
8407
|
function loadDenyConfig(global) {
|
|
@@ -8367,16 +8421,16 @@ function loadDenyConfig(global) {
|
|
|
8367
8421
|
function denyAdd(pattern2, message, options2) {
|
|
8368
8422
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
8369
8423
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
8370
|
-
console.log(
|
|
8424
|
+
console.log(chalk82.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
8371
8425
|
return;
|
|
8372
8426
|
}
|
|
8373
8427
|
deny.push({ pattern: pattern2, message });
|
|
8374
8428
|
saveDeny(deny);
|
|
8375
|
-
console.log(
|
|
8429
|
+
console.log(chalk82.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
8376
8430
|
}
|
|
8377
8431
|
|
|
8378
8432
|
// src/commands/deny/denyList.ts
|
|
8379
|
-
import
|
|
8433
|
+
import chalk83 from "chalk";
|
|
8380
8434
|
function denyList() {
|
|
8381
8435
|
const globalRaw = loadGlobalConfigRaw();
|
|
8382
8436
|
const projectRaw = loadProjectConfig();
|
|
@@ -8387,7 +8441,7 @@ function denyList() {
|
|
|
8387
8441
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
8388
8442
|
);
|
|
8389
8443
|
if (!merged || merged.length === 0) {
|
|
8390
|
-
console.log(
|
|
8444
|
+
console.log(chalk83.dim("No deny rules configured."));
|
|
8391
8445
|
return;
|
|
8392
8446
|
}
|
|
8393
8447
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -8395,23 +8449,23 @@ function denyList() {
|
|
|
8395
8449
|
for (const rule of merged) {
|
|
8396
8450
|
const inProject = projectPatterns.has(rule.pattern);
|
|
8397
8451
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
8398
|
-
const label2 = inProject && inGlobal ?
|
|
8399
|
-
console.log(`${
|
|
8452
|
+
const label2 = inProject && inGlobal ? chalk83.dim(" (project, overrides global)") : inGlobal ? chalk83.dim(" (global)") : "";
|
|
8453
|
+
console.log(`${chalk83.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
8400
8454
|
}
|
|
8401
8455
|
}
|
|
8402
8456
|
|
|
8403
8457
|
// src/commands/deny/denyRemove.ts
|
|
8404
|
-
import
|
|
8458
|
+
import chalk84 from "chalk";
|
|
8405
8459
|
function denyRemove(pattern2, options2) {
|
|
8406
8460
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
8407
8461
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
8408
8462
|
if (index3 === -1) {
|
|
8409
|
-
console.log(
|
|
8463
|
+
console.log(chalk84.yellow(`No deny rule found for: ${pattern2}`));
|
|
8410
8464
|
return;
|
|
8411
8465
|
}
|
|
8412
8466
|
deny.splice(index3, 1);
|
|
8413
8467
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
8414
|
-
console.log(
|
|
8468
|
+
console.log(chalk84.green(`Removed deny rule: ${pattern2}`));
|
|
8415
8469
|
}
|
|
8416
8470
|
|
|
8417
8471
|
// src/commands/registerDeny.ts
|
|
@@ -8440,15 +8494,15 @@ function registerCliHook(program2) {
|
|
|
8440
8494
|
}
|
|
8441
8495
|
|
|
8442
8496
|
// src/commands/complexity/analyze.ts
|
|
8443
|
-
import
|
|
8497
|
+
import chalk91 from "chalk";
|
|
8444
8498
|
|
|
8445
8499
|
// src/commands/complexity/cyclomatic.ts
|
|
8446
|
-
import
|
|
8500
|
+
import chalk86 from "chalk";
|
|
8447
8501
|
|
|
8448
8502
|
// src/commands/complexity/shared/index.ts
|
|
8449
8503
|
import fs13 from "fs";
|
|
8450
8504
|
import path19 from "path";
|
|
8451
|
-
import
|
|
8505
|
+
import chalk85 from "chalk";
|
|
8452
8506
|
import ts5 from "typescript";
|
|
8453
8507
|
|
|
8454
8508
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -8687,7 +8741,7 @@ function countSloc(content) {
|
|
|
8687
8741
|
|
|
8688
8742
|
// src/commands/complexity/shared/index.ts
|
|
8689
8743
|
function createSourceFromFile(filePath) {
|
|
8690
|
-
const content = fs13.readFileSync(filePath, "
|
|
8744
|
+
const content = fs13.readFileSync(filePath, "utf8");
|
|
8691
8745
|
return ts5.createSourceFile(
|
|
8692
8746
|
path19.basename(filePath),
|
|
8693
8747
|
content,
|
|
@@ -8699,7 +8753,7 @@ function createSourceFromFile(filePath) {
|
|
|
8699
8753
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
8700
8754
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
8701
8755
|
if (files.length === 0) {
|
|
8702
|
-
console.log(
|
|
8756
|
+
console.log(chalk85.yellow("No files found matching pattern"));
|
|
8703
8757
|
return void 0;
|
|
8704
8758
|
}
|
|
8705
8759
|
return callback(files);
|
|
@@ -8732,11 +8786,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8732
8786
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
8733
8787
|
for (const { file, name, complexity } of results) {
|
|
8734
8788
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
8735
|
-
const color = exceedsThreshold ?
|
|
8736
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
8789
|
+
const color = exceedsThreshold ? chalk86.red : chalk86.white;
|
|
8790
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk86.cyan(complexity)}`);
|
|
8737
8791
|
}
|
|
8738
8792
|
console.log(
|
|
8739
|
-
|
|
8793
|
+
chalk86.dim(
|
|
8740
8794
|
`
|
|
8741
8795
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
8742
8796
|
)
|
|
@@ -8748,7 +8802,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
8748
8802
|
}
|
|
8749
8803
|
|
|
8750
8804
|
// src/commands/complexity/halstead.ts
|
|
8751
|
-
import
|
|
8805
|
+
import chalk87 from "chalk";
|
|
8752
8806
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
8753
8807
|
withSourceFiles(pattern2, (files) => {
|
|
8754
8808
|
const results = [];
|
|
@@ -8763,13 +8817,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8763
8817
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
8764
8818
|
for (const { file, name, metrics } of results) {
|
|
8765
8819
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
8766
|
-
const color = exceedsThreshold ?
|
|
8820
|
+
const color = exceedsThreshold ? chalk87.red : chalk87.white;
|
|
8767
8821
|
console.log(
|
|
8768
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
8822
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk87.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk87.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk87.magenta(metrics.effort.toFixed(1))}`
|
|
8769
8823
|
);
|
|
8770
8824
|
}
|
|
8771
8825
|
console.log(
|
|
8772
|
-
|
|
8826
|
+
chalk87.dim(
|
|
8773
8827
|
`
|
|
8774
8828
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
8775
8829
|
)
|
|
@@ -8793,28 +8847,28 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
|
|
|
8793
8847
|
}
|
|
8794
8848
|
|
|
8795
8849
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
8796
|
-
import
|
|
8850
|
+
import chalk88 from "chalk";
|
|
8797
8851
|
function displayMaintainabilityResults(results, threshold) {
|
|
8798
8852
|
const filtered = threshold !== void 0 ? results.filter((r) => r.minMaintainability < threshold) : results;
|
|
8799
8853
|
if (threshold !== void 0 && filtered.length === 0) {
|
|
8800
|
-
console.log(
|
|
8854
|
+
console.log(chalk88.green("All files pass maintainability threshold"));
|
|
8801
8855
|
} else {
|
|
8802
8856
|
for (const { file, avgMaintainability, minMaintainability } of filtered) {
|
|
8803
|
-
const color = threshold !== void 0 ?
|
|
8857
|
+
const color = threshold !== void 0 ? chalk88.red : chalk88.white;
|
|
8804
8858
|
console.log(
|
|
8805
|
-
`${color(file)} \u2192 avg: ${
|
|
8859
|
+
`${color(file)} \u2192 avg: ${chalk88.cyan(avgMaintainability.toFixed(1))}, min: ${chalk88.yellow(minMaintainability.toFixed(1))}`
|
|
8806
8860
|
);
|
|
8807
8861
|
}
|
|
8808
8862
|
}
|
|
8809
|
-
console.log(
|
|
8863
|
+
console.log(chalk88.dim(`
|
|
8810
8864
|
Analyzed ${results.length} files`));
|
|
8811
8865
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
8812
8866
|
console.error(
|
|
8813
|
-
|
|
8867
|
+
chalk88.red(
|
|
8814
8868
|
`
|
|
8815
8869
|
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
8816
8870
|
|
|
8817
|
-
\u26A0\uFE0F ${
|
|
8871
|
+
\u26A0\uFE0F ${chalk88.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel. Run 'assist complexity <file>' to see all metrics. For larger files, start by extracting responsibilities into smaller files.`
|
|
8818
8872
|
)
|
|
8819
8873
|
);
|
|
8820
8874
|
process.exit(1);
|
|
@@ -8822,17 +8876,17 @@ Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability i
|
|
|
8822
8876
|
}
|
|
8823
8877
|
|
|
8824
8878
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
8825
|
-
import
|
|
8879
|
+
import chalk89 from "chalk";
|
|
8826
8880
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
8827
8881
|
function printMaintainabilityFormula() {
|
|
8828
|
-
console.log(
|
|
8882
|
+
console.log(chalk89.dim(MI_FORMULA));
|
|
8829
8883
|
}
|
|
8830
8884
|
|
|
8831
8885
|
// src/commands/complexity/maintainability/index.ts
|
|
8832
8886
|
function collectFileMetrics(files) {
|
|
8833
8887
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
8834
8888
|
for (const file of files) {
|
|
8835
|
-
const content = fs14.readFileSync(file, "
|
|
8889
|
+
const content = fs14.readFileSync(file, "utf8");
|
|
8836
8890
|
fileMetrics.set(file, { sloc: countSloc(content), functions: [] });
|
|
8837
8891
|
}
|
|
8838
8892
|
forEachFunction(files, (file, _name, node) => {
|
|
@@ -8876,13 +8930,13 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8876
8930
|
|
|
8877
8931
|
// src/commands/complexity/sloc.ts
|
|
8878
8932
|
import fs15 from "fs";
|
|
8879
|
-
import
|
|
8933
|
+
import chalk90 from "chalk";
|
|
8880
8934
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
8881
8935
|
withSourceFiles(pattern2, (files) => {
|
|
8882
8936
|
const results = [];
|
|
8883
8937
|
let hasViolation = false;
|
|
8884
8938
|
for (const file of files) {
|
|
8885
|
-
const content = fs15.readFileSync(file, "
|
|
8939
|
+
const content = fs15.readFileSync(file, "utf8");
|
|
8886
8940
|
const lines = countSloc(content);
|
|
8887
8941
|
results.push({ file, lines });
|
|
8888
8942
|
if (options2.threshold !== void 0 && lines > options2.threshold) {
|
|
@@ -8892,12 +8946,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
8892
8946
|
results.sort((a, b) => b.lines - a.lines);
|
|
8893
8947
|
for (const { file, lines } of results) {
|
|
8894
8948
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
8895
|
-
const color = exceedsThreshold ?
|
|
8896
|
-
console.log(`${color(file)} \u2192 ${
|
|
8949
|
+
const color = exceedsThreshold ? chalk90.red : chalk90.white;
|
|
8950
|
+
console.log(`${color(file)} \u2192 ${chalk90.cyan(lines)} lines`);
|
|
8897
8951
|
}
|
|
8898
8952
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
8899
8953
|
console.log(
|
|
8900
|
-
|
|
8954
|
+
chalk90.dim(`
|
|
8901
8955
|
Total: ${total} lines across ${files.length} files`)
|
|
8902
8956
|
);
|
|
8903
8957
|
if (hasViolation) {
|
|
@@ -8911,25 +8965,25 @@ async function analyze(pattern2) {
|
|
|
8911
8965
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
8912
8966
|
const files = findSourceFiles2(searchPattern);
|
|
8913
8967
|
if (files.length === 0) {
|
|
8914
|
-
console.log(
|
|
8968
|
+
console.log(chalk91.yellow("No files found matching pattern"));
|
|
8915
8969
|
return;
|
|
8916
8970
|
}
|
|
8917
8971
|
if (files.length === 1) {
|
|
8918
8972
|
const file = files[0];
|
|
8919
|
-
console.log(
|
|
8973
|
+
console.log(chalk91.bold.underline("SLOC"));
|
|
8920
8974
|
await sloc(file);
|
|
8921
8975
|
console.log();
|
|
8922
|
-
console.log(
|
|
8976
|
+
console.log(chalk91.bold.underline("Cyclomatic Complexity"));
|
|
8923
8977
|
await cyclomatic(file);
|
|
8924
8978
|
console.log();
|
|
8925
|
-
console.log(
|
|
8979
|
+
console.log(chalk91.bold.underline("Halstead Metrics"));
|
|
8926
8980
|
await halstead(file);
|
|
8927
8981
|
console.log();
|
|
8928
|
-
console.log(
|
|
8982
|
+
console.log(chalk91.bold.underline("Maintainability Index"));
|
|
8929
8983
|
await maintainability(file);
|
|
8930
8984
|
console.log();
|
|
8931
8985
|
console.log(
|
|
8932
|
-
|
|
8986
|
+
chalk91.dim(
|
|
8933
8987
|
"To improve the maintainability index, extract functions and logic out of this file into separate, smaller modules. Collapsing whitespace or removing comments is not the goal."
|
|
8934
8988
|
)
|
|
8935
8989
|
);
|
|
@@ -8963,7 +9017,7 @@ function registerComplexity(program2) {
|
|
|
8963
9017
|
}
|
|
8964
9018
|
|
|
8965
9019
|
// src/commands/config/index.ts
|
|
8966
|
-
import
|
|
9020
|
+
import chalk92 from "chalk";
|
|
8967
9021
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
8968
9022
|
|
|
8969
9023
|
// src/commands/config/setNestedValue.ts
|
|
@@ -9026,7 +9080,7 @@ function formatIssuePath(issue, key) {
|
|
|
9026
9080
|
function printValidationErrors(issues, key) {
|
|
9027
9081
|
for (const issue of issues) {
|
|
9028
9082
|
console.error(
|
|
9029
|
-
|
|
9083
|
+
chalk92.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
9030
9084
|
);
|
|
9031
9085
|
}
|
|
9032
9086
|
}
|
|
@@ -9043,7 +9097,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
9043
9097
|
function assertNotGlobalOnly(key, global) {
|
|
9044
9098
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
9045
9099
|
console.error(
|
|
9046
|
-
|
|
9100
|
+
chalk92.red(
|
|
9047
9101
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
9048
9102
|
)
|
|
9049
9103
|
);
|
|
@@ -9066,7 +9120,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
9066
9120
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
9067
9121
|
const target = options2.global ? "global" : "project";
|
|
9068
9122
|
console.log(
|
|
9069
|
-
|
|
9123
|
+
chalk92.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
9070
9124
|
);
|
|
9071
9125
|
}
|
|
9072
9126
|
function configList() {
|
|
@@ -9075,7 +9129,7 @@ function configList() {
|
|
|
9075
9129
|
}
|
|
9076
9130
|
|
|
9077
9131
|
// src/commands/config/configGet.ts
|
|
9078
|
-
import
|
|
9132
|
+
import chalk93 from "chalk";
|
|
9079
9133
|
|
|
9080
9134
|
// src/commands/config/getNestedValue.ts
|
|
9081
9135
|
function isTraversable(value) {
|
|
@@ -9107,7 +9161,7 @@ function requireNestedValue(config, key) {
|
|
|
9107
9161
|
return value;
|
|
9108
9162
|
}
|
|
9109
9163
|
function exitKeyNotSet(key) {
|
|
9110
|
-
console.error(
|
|
9164
|
+
console.error(chalk93.red(`Key "${key}" is not set`));
|
|
9111
9165
|
process.exit(1);
|
|
9112
9166
|
}
|
|
9113
9167
|
|
|
@@ -9121,7 +9175,7 @@ function registerConfig(program2) {
|
|
|
9121
9175
|
|
|
9122
9176
|
// src/commands/deploy/redirect.ts
|
|
9123
9177
|
import { existsSync as existsSync24, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
9124
|
-
import
|
|
9178
|
+
import chalk94 from "chalk";
|
|
9125
9179
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
9126
9180
|
if (!window.location.pathname.endsWith('/')) {
|
|
9127
9181
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -9130,22 +9184,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
9130
9184
|
function redirect() {
|
|
9131
9185
|
const indexPath = "index.html";
|
|
9132
9186
|
if (!existsSync24(indexPath)) {
|
|
9133
|
-
console.log(
|
|
9187
|
+
console.log(chalk94.yellow("No index.html found"));
|
|
9134
9188
|
return;
|
|
9135
9189
|
}
|
|
9136
|
-
const content = readFileSync19(indexPath, "
|
|
9190
|
+
const content = readFileSync19(indexPath, "utf8");
|
|
9137
9191
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
9138
|
-
console.log(
|
|
9192
|
+
console.log(chalk94.dim("Trailing slash script already present"));
|
|
9139
9193
|
return;
|
|
9140
9194
|
}
|
|
9141
9195
|
const headCloseIndex = content.indexOf("</head>");
|
|
9142
9196
|
if (headCloseIndex === -1) {
|
|
9143
|
-
console.log(
|
|
9197
|
+
console.log(chalk94.red("Could not find </head> tag in index.html"));
|
|
9144
9198
|
return;
|
|
9145
9199
|
}
|
|
9146
|
-
const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT
|
|
9200
|
+
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
9201
|
+
${content.slice(headCloseIndex)}`;
|
|
9147
9202
|
writeFileSync18(indexPath, newContent);
|
|
9148
|
-
console.log(
|
|
9203
|
+
console.log(chalk94.green("Added trailing slash redirect to index.html"));
|
|
9149
9204
|
}
|
|
9150
9205
|
|
|
9151
9206
|
// src/commands/registerDeploy.ts
|
|
@@ -9167,12 +9222,12 @@ function loadBlogSkipDays(repoName) {
|
|
|
9167
9222
|
const config = loadRawYaml(join22(BLOG_REPO_ROOT, "assist.yml"));
|
|
9168
9223
|
const devlog = config.devlog;
|
|
9169
9224
|
const skip2 = devlog?.skip;
|
|
9170
|
-
return new Set(skip2?.[repoName]
|
|
9225
|
+
return new Set(skip2?.[repoName]);
|
|
9171
9226
|
}
|
|
9172
9227
|
|
|
9173
9228
|
// src/commands/devlog/shared.ts
|
|
9174
9229
|
import { execSync as execSync22 } from "child_process";
|
|
9175
|
-
import
|
|
9230
|
+
import chalk95 from "chalk";
|
|
9176
9231
|
|
|
9177
9232
|
// src/shared/getRepoName.ts
|
|
9178
9233
|
import { existsSync as existsSync25, readFileSync as readFileSync20 } from "fs";
|
|
@@ -9185,7 +9240,7 @@ function getRepoName() {
|
|
|
9185
9240
|
const packageJsonPath = join23(process.cwd(), "package.json");
|
|
9186
9241
|
if (existsSync25(packageJsonPath)) {
|
|
9187
9242
|
try {
|
|
9188
|
-
const content = readFileSync20(packageJsonPath, "
|
|
9243
|
+
const content = readFileSync20(packageJsonPath, "utf8");
|
|
9189
9244
|
const pkg = JSON.parse(content);
|
|
9190
9245
|
if (pkg.name) {
|
|
9191
9246
|
return pkg.name;
|
|
@@ -9227,7 +9282,7 @@ function readDevlogFiles(callback) {
|
|
|
9227
9282
|
try {
|
|
9228
9283
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
9229
9284
|
for (const file of files) {
|
|
9230
|
-
const content = readFileSync21(join24(DEVLOG_DIR, file), "
|
|
9285
|
+
const content = readFileSync21(join24(DEVLOG_DIR, file), "utf8");
|
|
9231
9286
|
const parsed = parseFrontmatter(content, file);
|
|
9232
9287
|
if (parsed) callback(parsed);
|
|
9233
9288
|
}
|
|
@@ -9264,7 +9319,7 @@ function loadAllDevlogLatestDates() {
|
|
|
9264
9319
|
function getCommitFiles(hash) {
|
|
9265
9320
|
try {
|
|
9266
9321
|
const output = execSync22(`git show --name-only --format="" ${hash}`, {
|
|
9267
|
-
encoding: "
|
|
9322
|
+
encoding: "utf8"
|
|
9268
9323
|
});
|
|
9269
9324
|
return output.trim().split("\n").filter(Boolean);
|
|
9270
9325
|
} catch {
|
|
@@ -9281,13 +9336,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
9281
9336
|
}
|
|
9282
9337
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
9283
9338
|
for (const commit2 of commits2) {
|
|
9284
|
-
console.log(` ${
|
|
9339
|
+
console.log(` ${chalk95.yellow(commit2.hash)} ${commit2.message}`);
|
|
9285
9340
|
if (verbose) {
|
|
9286
9341
|
const visibleFiles = commit2.files.filter(
|
|
9287
9342
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
9288
9343
|
);
|
|
9289
9344
|
for (const file of visibleFiles) {
|
|
9290
|
-
console.log(` ${
|
|
9345
|
+
console.log(` ${chalk95.dim(file)}`);
|
|
9291
9346
|
}
|
|
9292
9347
|
}
|
|
9293
9348
|
}
|
|
@@ -9312,15 +9367,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
9312
9367
|
}
|
|
9313
9368
|
|
|
9314
9369
|
// src/commands/devlog/list/printDateHeader.ts
|
|
9315
|
-
import
|
|
9370
|
+
import chalk96 from "chalk";
|
|
9316
9371
|
function printDateHeader(date, isSkipped, entries) {
|
|
9317
9372
|
if (isSkipped) {
|
|
9318
|
-
console.log(`${
|
|
9373
|
+
console.log(`${chalk96.bold.blue(date)} ${chalk96.dim("skipped")}`);
|
|
9319
9374
|
} else if (entries && entries.length > 0) {
|
|
9320
|
-
const entryInfo = entries.map((e) => `${
|
|
9321
|
-
console.log(`${
|
|
9375
|
+
const entryInfo = entries.map((e) => `${chalk96.green(e.version)} ${e.title}`).join(" | ");
|
|
9376
|
+
console.log(`${chalk96.bold.blue(date)} ${entryInfo}`);
|
|
9322
9377
|
} else {
|
|
9323
|
-
console.log(`${
|
|
9378
|
+
console.log(`${chalk96.bold.blue(date)} ${chalk96.red("\u26A0 devlog missing")}`);
|
|
9324
9379
|
}
|
|
9325
9380
|
}
|
|
9326
9381
|
|
|
@@ -9336,7 +9391,7 @@ function list3(options2) {
|
|
|
9336
9391
|
if (options2.reverse) args.push("--reverse");
|
|
9337
9392
|
else args.push("-n", "500");
|
|
9338
9393
|
args.push("--pretty=format:%ad|%h|%s", "--date=short");
|
|
9339
|
-
const output = execFileSync2("git", args, { encoding: "
|
|
9394
|
+
const output = execFileSync2("git", args, { encoding: "utf8" });
|
|
9340
9395
|
const commitsByDate = parseGitLogCommits(output, ignore2);
|
|
9341
9396
|
let dateCount = 0;
|
|
9342
9397
|
let isFirst = true;
|
|
@@ -9364,7 +9419,7 @@ import semver from "semver";
|
|
|
9364
9419
|
function getVersionAtCommit(hash) {
|
|
9365
9420
|
try {
|
|
9366
9421
|
const content = execSync23(`git show ${hash}:package.json`, {
|
|
9367
|
-
encoding: "
|
|
9422
|
+
encoding: "utf8"
|
|
9368
9423
|
});
|
|
9369
9424
|
const pkg = JSON.parse(content);
|
|
9370
9425
|
return pkg.version ?? null;
|
|
@@ -9382,7 +9437,7 @@ function getLastVersionInfoFromGit() {
|
|
|
9382
9437
|
"git",
|
|
9383
9438
|
["log", "-1", "--pretty=format:%ad|%h", "--date=short"],
|
|
9384
9439
|
{
|
|
9385
|
-
encoding: "
|
|
9440
|
+
encoding: "utf8"
|
|
9386
9441
|
}
|
|
9387
9442
|
).trim();
|
|
9388
9443
|
const [date, hash] = output.split("|");
|
|
@@ -9424,24 +9479,24 @@ function bumpVersion(version2, type) {
|
|
|
9424
9479
|
|
|
9425
9480
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
9426
9481
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
9427
|
-
import
|
|
9482
|
+
import chalk98 from "chalk";
|
|
9428
9483
|
|
|
9429
9484
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
9430
|
-
import
|
|
9485
|
+
import chalk97 from "chalk";
|
|
9431
9486
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
9432
9487
|
if (conventional && firstHash) {
|
|
9433
9488
|
const version2 = getVersionAtCommit(firstHash);
|
|
9434
9489
|
if (version2) {
|
|
9435
|
-
console.log(`${
|
|
9490
|
+
console.log(`${chalk97.bold("version:")} ${stripToMinor(version2)}`);
|
|
9436
9491
|
} else {
|
|
9437
|
-
console.log(`${
|
|
9492
|
+
console.log(`${chalk97.bold("version:")} ${chalk97.red("unknown")}`);
|
|
9438
9493
|
}
|
|
9439
9494
|
} else if (patchVersion && minorVersion) {
|
|
9440
9495
|
console.log(
|
|
9441
|
-
`${
|
|
9496
|
+
`${chalk97.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
9442
9497
|
);
|
|
9443
9498
|
} else {
|
|
9444
|
-
console.log(`${
|
|
9499
|
+
console.log(`${chalk97.bold("version:")} v0.1 (initial)`);
|
|
9445
9500
|
}
|
|
9446
9501
|
}
|
|
9447
9502
|
|
|
@@ -9460,7 +9515,7 @@ function fetchCommitsByDate(ignore2, lastDate) {
|
|
|
9460
9515
|
const output = execFileSync4(
|
|
9461
9516
|
"git",
|
|
9462
9517
|
["log", "--pretty=format:%ad|%h|%s", "--date=short", "-n", "500"],
|
|
9463
|
-
{ encoding: "
|
|
9518
|
+
{ encoding: "utf8" }
|
|
9464
9519
|
);
|
|
9465
9520
|
return parseGitLogCommits(output, ignore2, lastDate);
|
|
9466
9521
|
}
|
|
@@ -9489,16 +9544,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
9489
9544
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
9490
9545
|
}
|
|
9491
9546
|
function logName(repoName) {
|
|
9492
|
-
console.log(`${
|
|
9547
|
+
console.log(`${chalk98.bold("name:")} ${repoName}`);
|
|
9493
9548
|
}
|
|
9494
9549
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
9495
9550
|
logName(ctx.repoName);
|
|
9496
9551
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
9497
|
-
console.log(
|
|
9552
|
+
console.log(chalk98.bold.blue(targetDate));
|
|
9498
9553
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
9499
9554
|
}
|
|
9500
9555
|
function logNoCommits(lastInfo) {
|
|
9501
|
-
console.log(
|
|
9556
|
+
console.log(chalk98.dim(noCommitsMessage(!!lastInfo)));
|
|
9502
9557
|
}
|
|
9503
9558
|
|
|
9504
9559
|
// src/commands/devlog/next/index.ts
|
|
@@ -9539,11 +9594,11 @@ function next2(options2) {
|
|
|
9539
9594
|
import { execSync as execSync24 } from "child_process";
|
|
9540
9595
|
|
|
9541
9596
|
// src/commands/devlog/repos/printReposTable.ts
|
|
9542
|
-
import
|
|
9597
|
+
import chalk99 from "chalk";
|
|
9543
9598
|
function colorStatus(status2) {
|
|
9544
|
-
if (status2 === "missing") return
|
|
9545
|
-
if (status2 === "outdated") return
|
|
9546
|
-
return
|
|
9599
|
+
if (status2 === "missing") return chalk99.red(status2);
|
|
9600
|
+
if (status2 === "outdated") return chalk99.yellow(status2);
|
|
9601
|
+
return chalk99.green(status2);
|
|
9547
9602
|
}
|
|
9548
9603
|
function formatRow(row, nameWidth) {
|
|
9549
9604
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -9557,8 +9612,8 @@ function printReposTable(rows) {
|
|
|
9557
9612
|
"Last Devlog".padEnd(11),
|
|
9558
9613
|
"Status"
|
|
9559
9614
|
].join(" ");
|
|
9560
|
-
console.log(
|
|
9561
|
-
console.log(
|
|
9615
|
+
console.log(chalk99.dim(header));
|
|
9616
|
+
console.log(chalk99.dim("-".repeat(header.length)));
|
|
9562
9617
|
for (const row of rows) {
|
|
9563
9618
|
console.log(formatRow(row, nameWidth));
|
|
9564
9619
|
}
|
|
@@ -9573,7 +9628,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
9573
9628
|
function fetchRepos(days, all) {
|
|
9574
9629
|
const json = execSync24(
|
|
9575
9630
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
9576
|
-
{ encoding: "
|
|
9631
|
+
{ encoding: "utf8" }
|
|
9577
9632
|
);
|
|
9578
9633
|
const allRepos = JSON.parse(json);
|
|
9579
9634
|
const cutoff = /* @__PURE__ */ new Date();
|
|
@@ -9616,14 +9671,14 @@ function repos(options2) {
|
|
|
9616
9671
|
// src/commands/devlog/skip.ts
|
|
9617
9672
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
9618
9673
|
import { join as join25 } from "path";
|
|
9619
|
-
import
|
|
9674
|
+
import chalk100 from "chalk";
|
|
9620
9675
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
9621
9676
|
function getBlogConfigPath() {
|
|
9622
9677
|
return join25(BLOG_REPO_ROOT, "assist.yml");
|
|
9623
9678
|
}
|
|
9624
9679
|
function skip(date) {
|
|
9625
9680
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
9626
|
-
console.log(
|
|
9681
|
+
console.log(chalk100.red("Invalid date format. Use YYYY-MM-DD"));
|
|
9627
9682
|
process.exit(1);
|
|
9628
9683
|
}
|
|
9629
9684
|
const repoName = getRepoName();
|
|
@@ -9634,7 +9689,7 @@ function skip(date) {
|
|
|
9634
9689
|
const skipDays = skip2[repoName] ?? [];
|
|
9635
9690
|
if (skipDays.includes(date)) {
|
|
9636
9691
|
console.log(
|
|
9637
|
-
|
|
9692
|
+
chalk100.yellow(`${date} is already in skip list for ${repoName}`)
|
|
9638
9693
|
);
|
|
9639
9694
|
return;
|
|
9640
9695
|
}
|
|
@@ -9644,20 +9699,20 @@ function skip(date) {
|
|
|
9644
9699
|
devlog.skip = skip2;
|
|
9645
9700
|
config.devlog = devlog;
|
|
9646
9701
|
writeFileSync19(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
9647
|
-
console.log(
|
|
9702
|
+
console.log(chalk100.green(`Added ${date} to skip list for ${repoName}`));
|
|
9648
9703
|
}
|
|
9649
9704
|
|
|
9650
9705
|
// src/commands/devlog/version.ts
|
|
9651
|
-
import
|
|
9706
|
+
import chalk101 from "chalk";
|
|
9652
9707
|
function version() {
|
|
9653
9708
|
const config = loadConfig();
|
|
9654
9709
|
const name = getRepoName();
|
|
9655
9710
|
const lastInfo = getLastVersionInfo(name, config);
|
|
9656
9711
|
const lastVersion = lastInfo?.version ?? null;
|
|
9657
9712
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
9658
|
-
console.log(`${
|
|
9659
|
-
console.log(`${
|
|
9660
|
-
console.log(`${
|
|
9713
|
+
console.log(`${chalk101.bold("name:")} ${name}`);
|
|
9714
|
+
console.log(`${chalk101.bold("last:")} ${lastVersion ?? chalk101.dim("none")}`);
|
|
9715
|
+
console.log(`${chalk101.bold("next:")} ${nextVersion ?? chalk101.dim("none")}`);
|
|
9661
9716
|
}
|
|
9662
9717
|
|
|
9663
9718
|
// src/commands/registerDevlog.ts
|
|
@@ -9681,7 +9736,7 @@ function registerDevlog(program2) {
|
|
|
9681
9736
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
9682
9737
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync2 } from "fs";
|
|
9683
9738
|
import { join as join26 } from "path";
|
|
9684
|
-
import
|
|
9739
|
+
import chalk102 from "chalk";
|
|
9685
9740
|
|
|
9686
9741
|
// src/shared/findRepoRoot.ts
|
|
9687
9742
|
import { existsSync as existsSync26 } from "fs";
|
|
@@ -9744,14 +9799,14 @@ function checkBuildLocks(startDir) {
|
|
|
9744
9799
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
9745
9800
|
if (locked) {
|
|
9746
9801
|
console.error(
|
|
9747
|
-
|
|
9802
|
+
chalk102.red("Build output locked (is VS debugging?): ") + locked
|
|
9748
9803
|
);
|
|
9749
9804
|
process.exit(1);
|
|
9750
9805
|
}
|
|
9751
9806
|
}
|
|
9752
9807
|
async function checkBuildLocksCommand() {
|
|
9753
9808
|
checkBuildLocks();
|
|
9754
|
-
console.log(
|
|
9809
|
+
console.log(chalk102.green("No build locks detected"));
|
|
9755
9810
|
}
|
|
9756
9811
|
|
|
9757
9812
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -9759,7 +9814,7 @@ import { readFileSync as readFileSync22 } from "fs";
|
|
|
9759
9814
|
import path21 from "path";
|
|
9760
9815
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
9761
9816
|
function getProjectRefs(csprojPath) {
|
|
9762
|
-
const content = readFileSync22(csprojPath, "
|
|
9817
|
+
const content = readFileSync22(csprojPath, "utf8");
|
|
9763
9818
|
const refs = [];
|
|
9764
9819
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
9765
9820
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -9836,7 +9891,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
9836
9891
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
9837
9892
|
for (const sln of slnFiles) {
|
|
9838
9893
|
try {
|
|
9839
|
-
const content = readFileSync23(sln, "
|
|
9894
|
+
const content = readFileSync23(sln, "utf8");
|
|
9840
9895
|
if (pattern2.test(content)) {
|
|
9841
9896
|
matches.push(path22.relative(repoRoot, sln));
|
|
9842
9897
|
}
|
|
@@ -9846,34 +9901,34 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
9846
9901
|
return matches;
|
|
9847
9902
|
}
|
|
9848
9903
|
function escapeRegex(s) {
|
|
9849
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g,
|
|
9904
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
9850
9905
|
}
|
|
9851
9906
|
|
|
9852
9907
|
// src/commands/dotnet/printTree.ts
|
|
9853
|
-
import
|
|
9908
|
+
import chalk103 from "chalk";
|
|
9854
9909
|
function printNodes(nodes, prefix2) {
|
|
9855
9910
|
for (let i = 0; i < nodes.length; i++) {
|
|
9856
9911
|
const isLast = i === nodes.length - 1;
|
|
9857
9912
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
9858
9913
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
9859
9914
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
9860
|
-
const label2 = isMissing ?
|
|
9915
|
+
const label2 = isMissing ? chalk103.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
9861
9916
|
console.log(`${prefix2}${connector}${label2}`);
|
|
9862
9917
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
9863
9918
|
}
|
|
9864
9919
|
}
|
|
9865
9920
|
function printTree(tree, totalCount, solutions) {
|
|
9866
|
-
console.log(
|
|
9867
|
-
console.log(
|
|
9921
|
+
console.log(chalk103.bold("\nProject Dependency Tree"));
|
|
9922
|
+
console.log(chalk103.cyan(tree.relativePath));
|
|
9868
9923
|
printNodes(tree.children, "");
|
|
9869
|
-
console.log(
|
|
9924
|
+
console.log(chalk103.dim(`
|
|
9870
9925
|
${totalCount} projects total (including root)`));
|
|
9871
|
-
console.log(
|
|
9926
|
+
console.log(chalk103.bold("\nSolution Membership"));
|
|
9872
9927
|
if (solutions.length === 0) {
|
|
9873
|
-
console.log(
|
|
9928
|
+
console.log(chalk103.yellow(" Not found in any .sln"));
|
|
9874
9929
|
} else {
|
|
9875
9930
|
for (const sln of solutions) {
|
|
9876
|
-
console.log(` ${
|
|
9931
|
+
console.log(` ${chalk103.green(sln)}`);
|
|
9877
9932
|
}
|
|
9878
9933
|
}
|
|
9879
9934
|
console.log();
|
|
@@ -9902,16 +9957,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
9902
9957
|
// src/commands/dotnet/resolveCsproj.ts
|
|
9903
9958
|
import { existsSync as existsSync27 } from "fs";
|
|
9904
9959
|
import path23 from "path";
|
|
9905
|
-
import
|
|
9960
|
+
import chalk104 from "chalk";
|
|
9906
9961
|
function resolveCsproj(csprojPath) {
|
|
9907
9962
|
const resolved = path23.resolve(csprojPath);
|
|
9908
9963
|
if (!existsSync27(resolved)) {
|
|
9909
|
-
console.error(
|
|
9964
|
+
console.error(chalk104.red(`File not found: ${resolved}`));
|
|
9910
9965
|
process.exit(1);
|
|
9911
9966
|
}
|
|
9912
9967
|
const repoRoot = findRepoRoot(path23.dirname(resolved));
|
|
9913
9968
|
if (!repoRoot) {
|
|
9914
|
-
console.error(
|
|
9969
|
+
console.error(chalk104.red("Could not find git repository root"));
|
|
9915
9970
|
process.exit(1);
|
|
9916
9971
|
}
|
|
9917
9972
|
return { resolved, repoRoot };
|
|
@@ -9955,18 +10010,18 @@ function getChangedCsFiles(scope) {
|
|
|
9955
10010
|
} else {
|
|
9956
10011
|
cmd = "git diff --name-only HEAD";
|
|
9957
10012
|
}
|
|
9958
|
-
const output = execSync25(cmd, { encoding: "
|
|
10013
|
+
const output = execSync25(cmd, { encoding: "utf8" }).trim();
|
|
9959
10014
|
if (output === "") return [];
|
|
9960
10015
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
9961
10016
|
}
|
|
9962
10017
|
|
|
9963
10018
|
// src/commands/dotnet/inSln.ts
|
|
9964
|
-
import
|
|
10019
|
+
import chalk105 from "chalk";
|
|
9965
10020
|
async function inSln(csprojPath) {
|
|
9966
10021
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
9967
10022
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
9968
10023
|
if (solutions.length === 0) {
|
|
9969
|
-
console.log(
|
|
10024
|
+
console.log(chalk105.yellow("Not found in any .sln file"));
|
|
9970
10025
|
process.exit(1);
|
|
9971
10026
|
}
|
|
9972
10027
|
for (const sln of solutions) {
|
|
@@ -9975,7 +10030,7 @@ async function inSln(csprojPath) {
|
|
|
9975
10030
|
}
|
|
9976
10031
|
|
|
9977
10032
|
// src/commands/dotnet/inspect.ts
|
|
9978
|
-
import
|
|
10033
|
+
import chalk111 from "chalk";
|
|
9979
10034
|
|
|
9980
10035
|
// src/shared/formatElapsed.ts
|
|
9981
10036
|
function formatElapsed(ms) {
|
|
@@ -9987,12 +10042,12 @@ function formatElapsed(ms) {
|
|
|
9987
10042
|
}
|
|
9988
10043
|
|
|
9989
10044
|
// src/commands/dotnet/displayIssues.ts
|
|
9990
|
-
import
|
|
10045
|
+
import chalk106 from "chalk";
|
|
9991
10046
|
var SEVERITY_COLOR = {
|
|
9992
|
-
ERROR:
|
|
9993
|
-
WARNING:
|
|
9994
|
-
SUGGESTION:
|
|
9995
|
-
HINT:
|
|
10047
|
+
ERROR: chalk106.red,
|
|
10048
|
+
WARNING: chalk106.yellow,
|
|
10049
|
+
SUGGESTION: chalk106.cyan,
|
|
10050
|
+
HINT: chalk106.dim
|
|
9996
10051
|
};
|
|
9997
10052
|
function groupByFile(issues) {
|
|
9998
10053
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -10008,15 +10063,15 @@ function groupByFile(issues) {
|
|
|
10008
10063
|
}
|
|
10009
10064
|
function displayIssues(issues) {
|
|
10010
10065
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
10011
|
-
console.log(
|
|
10066
|
+
console.log(chalk106.bold(file));
|
|
10012
10067
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
10013
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
10068
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk106.white;
|
|
10014
10069
|
console.log(
|
|
10015
|
-
` ${
|
|
10070
|
+
` ${chalk106.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
10016
10071
|
);
|
|
10017
10072
|
}
|
|
10018
10073
|
}
|
|
10019
|
-
console.log(
|
|
10074
|
+
console.log(chalk106.dim(`
|
|
10020
10075
|
${issues.length} issue(s) found`));
|
|
10021
10076
|
}
|
|
10022
10077
|
|
|
@@ -10075,12 +10130,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
10075
10130
|
// src/commands/dotnet/resolveSolution.ts
|
|
10076
10131
|
import { existsSync as existsSync28 } from "fs";
|
|
10077
10132
|
import path24 from "path";
|
|
10078
|
-
import
|
|
10133
|
+
import chalk108 from "chalk";
|
|
10079
10134
|
|
|
10080
10135
|
// src/commands/dotnet/findSolution.ts
|
|
10081
10136
|
import { readdirSync as readdirSync4 } from "fs";
|
|
10082
10137
|
import { dirname as dirname18, join as join27 } from "path";
|
|
10083
|
-
import
|
|
10138
|
+
import chalk107 from "chalk";
|
|
10084
10139
|
function findSlnInDir(dir) {
|
|
10085
10140
|
try {
|
|
10086
10141
|
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join27(dir, f));
|
|
@@ -10096,17 +10151,17 @@ function findSolution() {
|
|
|
10096
10151
|
const slnFiles = findSlnInDir(current);
|
|
10097
10152
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
10098
10153
|
if (slnFiles.length > 1) {
|
|
10099
|
-
console.error(
|
|
10154
|
+
console.error(chalk107.red(`Multiple .sln files found in ${current}:`));
|
|
10100
10155
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
10101
10156
|
console.error(
|
|
10102
|
-
|
|
10157
|
+
chalk107.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
10103
10158
|
);
|
|
10104
10159
|
process.exit(1);
|
|
10105
10160
|
}
|
|
10106
10161
|
if (current === ceiling) break;
|
|
10107
10162
|
current = dirname18(current);
|
|
10108
10163
|
}
|
|
10109
|
-
console.error(
|
|
10164
|
+
console.error(chalk107.red("No .sln file found between cwd and repo root"));
|
|
10110
10165
|
process.exit(1);
|
|
10111
10166
|
}
|
|
10112
10167
|
|
|
@@ -10115,7 +10170,7 @@ function resolveSolution(sln) {
|
|
|
10115
10170
|
if (sln) {
|
|
10116
10171
|
const resolved = path24.resolve(sln);
|
|
10117
10172
|
if (!existsSync28(resolved)) {
|
|
10118
|
-
console.error(
|
|
10173
|
+
console.error(chalk108.red(`Solution file not found: ${resolved}`));
|
|
10119
10174
|
process.exit(1);
|
|
10120
10175
|
}
|
|
10121
10176
|
return resolved;
|
|
@@ -10157,14 +10212,14 @@ import { execSync as execSync26 } from "child_process";
|
|
|
10157
10212
|
import { existsSync as existsSync29, readFileSync as readFileSync24, unlinkSync as unlinkSync7 } from "fs";
|
|
10158
10213
|
import { tmpdir as tmpdir3 } from "os";
|
|
10159
10214
|
import path25 from "path";
|
|
10160
|
-
import
|
|
10215
|
+
import chalk109 from "chalk";
|
|
10161
10216
|
function assertJbInstalled() {
|
|
10162
10217
|
try {
|
|
10163
10218
|
execSync26("jb inspectcode --version", { stdio: "pipe" });
|
|
10164
10219
|
} catch {
|
|
10165
|
-
console.error(
|
|
10220
|
+
console.error(chalk109.red("jb is not installed. Install with:"));
|
|
10166
10221
|
console.error(
|
|
10167
|
-
|
|
10222
|
+
chalk109.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
10168
10223
|
);
|
|
10169
10224
|
process.exit(1);
|
|
10170
10225
|
}
|
|
@@ -10178,25 +10233,25 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
10178
10233
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
10179
10234
|
{ stdio: "pipe" }
|
|
10180
10235
|
);
|
|
10181
|
-
} catch (
|
|
10182
|
-
if (
|
|
10183
|
-
process.stderr.write(
|
|
10236
|
+
} catch (error) {
|
|
10237
|
+
if (error && typeof error === "object" && "stderr" in error) {
|
|
10238
|
+
process.stderr.write(error.stderr);
|
|
10184
10239
|
}
|
|
10185
|
-
console.error(
|
|
10240
|
+
console.error(chalk109.red("jb inspectcode failed"));
|
|
10186
10241
|
process.exit(1);
|
|
10187
10242
|
}
|
|
10188
10243
|
if (!existsSync29(reportPath)) {
|
|
10189
|
-
console.error(
|
|
10244
|
+
console.error(chalk109.red("Report file not generated"));
|
|
10190
10245
|
process.exit(1);
|
|
10191
10246
|
}
|
|
10192
|
-
const xml = readFileSync24(reportPath, "
|
|
10247
|
+
const xml = readFileSync24(reportPath, "utf8");
|
|
10193
10248
|
unlinkSync7(reportPath);
|
|
10194
10249
|
return xml;
|
|
10195
10250
|
}
|
|
10196
10251
|
|
|
10197
10252
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
10198
10253
|
import { execSync as execSync27 } from "child_process";
|
|
10199
|
-
import
|
|
10254
|
+
import chalk110 from "chalk";
|
|
10200
10255
|
function resolveMsbuildPath() {
|
|
10201
10256
|
const { run: run4 } = loadConfig();
|
|
10202
10257
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -10208,9 +10263,9 @@ function assertMsbuildInstalled() {
|
|
|
10208
10263
|
try {
|
|
10209
10264
|
execSync27(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
10210
10265
|
} catch {
|
|
10211
|
-
console.error(
|
|
10266
|
+
console.error(chalk110.red(`msbuild not found at: ${msbuild}`));
|
|
10212
10267
|
console.error(
|
|
10213
|
-
|
|
10268
|
+
chalk110.yellow(
|
|
10214
10269
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
10215
10270
|
)
|
|
10216
10271
|
);
|
|
@@ -10234,10 +10289,10 @@ function runRoslynInspect(slnPath) {
|
|
|
10234
10289
|
try {
|
|
10235
10290
|
output = execSync27(
|
|
10236
10291
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
10237
|
-
{ encoding: "
|
|
10292
|
+
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
10238
10293
|
);
|
|
10239
|
-
} catch (
|
|
10240
|
-
const e =
|
|
10294
|
+
} catch (error) {
|
|
10295
|
+
const e = error;
|
|
10241
10296
|
output = e.stdout ?? "";
|
|
10242
10297
|
}
|
|
10243
10298
|
return parseMsbuildOutput(output);
|
|
@@ -10257,17 +10312,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
10257
10312
|
// src/commands/dotnet/inspect.ts
|
|
10258
10313
|
function logScope(changedFiles) {
|
|
10259
10314
|
if (changedFiles === null) {
|
|
10260
|
-
console.log(
|
|
10315
|
+
console.log(chalk111.dim("Inspecting full solution..."));
|
|
10261
10316
|
} else {
|
|
10262
10317
|
console.log(
|
|
10263
|
-
|
|
10318
|
+
chalk111.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
10264
10319
|
);
|
|
10265
10320
|
}
|
|
10266
10321
|
}
|
|
10267
10322
|
function reportResults(issues, elapsed) {
|
|
10268
10323
|
if (issues.length > 0) displayIssues(issues);
|
|
10269
|
-
else console.log(
|
|
10270
|
-
console.log(
|
|
10324
|
+
else console.log(chalk111.green("No issues found"));
|
|
10325
|
+
console.log(chalk111.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
10271
10326
|
if (issues.length > 0) process.exit(1);
|
|
10272
10327
|
}
|
|
10273
10328
|
async function inspect(sln, options2) {
|
|
@@ -10278,7 +10333,7 @@ async function inspect(sln, options2) {
|
|
|
10278
10333
|
const scope = parseScope(options2.scope);
|
|
10279
10334
|
const changedFiles = getChangedCsFiles(scope);
|
|
10280
10335
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
10281
|
-
console.log(
|
|
10336
|
+
console.log(chalk111.green("No changed .cs files found"));
|
|
10282
10337
|
return;
|
|
10283
10338
|
}
|
|
10284
10339
|
logScope(changedFiles);
|
|
@@ -10347,7 +10402,7 @@ function runGhGraphql(mutation, vars) {
|
|
|
10347
10402
|
writeFileSync20(queryFile, mutation);
|
|
10348
10403
|
try {
|
|
10349
10404
|
const result = spawnSync3("gh", buildArgs2(queryFile, vars), {
|
|
10350
|
-
encoding: "
|
|
10405
|
+
encoding: "utf8"
|
|
10351
10406
|
});
|
|
10352
10407
|
if (result.status !== 0) throw new Error(result.stderr || result.stdout);
|
|
10353
10408
|
throwOnGraphqlErrors(result.stdout);
|
|
@@ -10407,25 +10462,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
10407
10462
|
}
|
|
10408
10463
|
|
|
10409
10464
|
// src/commands/github/printCountTable.ts
|
|
10410
|
-
import
|
|
10465
|
+
import chalk112 from "chalk";
|
|
10411
10466
|
function printCountTable(labelHeader, rows) {
|
|
10412
10467
|
const labelWidth = Math.max(
|
|
10413
10468
|
labelHeader.length,
|
|
10414
10469
|
...rows.map((row) => row.label.length)
|
|
10415
10470
|
);
|
|
10416
10471
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
10417
|
-
console.log(
|
|
10418
|
-
console.log(
|
|
10472
|
+
console.log(chalk112.dim(header));
|
|
10473
|
+
console.log(chalk112.dim("-".repeat(header.length)));
|
|
10419
10474
|
for (const row of rows) {
|
|
10420
10475
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
10421
10476
|
}
|
|
10422
10477
|
}
|
|
10423
10478
|
|
|
10424
10479
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
10425
|
-
import
|
|
10480
|
+
import chalk113 from "chalk";
|
|
10426
10481
|
function printRepoAuthorBreakdown(repos2) {
|
|
10427
10482
|
for (const repo of repos2) {
|
|
10428
|
-
console.log(
|
|
10483
|
+
console.log(chalk113.bold(repo.name));
|
|
10429
10484
|
const authorWidth = Math.max(
|
|
10430
10485
|
0,
|
|
10431
10486
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -10595,7 +10650,7 @@ function collectMarkdown(dir) {
|
|
|
10595
10650
|
return out;
|
|
10596
10651
|
}
|
|
10597
10652
|
async function migrateFile(orm, origin, file, createdAt) {
|
|
10598
|
-
const content = readFileSync25(file, "
|
|
10653
|
+
const content = readFileSync25(file, "utf8");
|
|
10599
10654
|
await saveHandover(orm, {
|
|
10600
10655
|
origin,
|
|
10601
10656
|
summary: summariseHandoverContent(content),
|
|
@@ -10743,7 +10798,7 @@ function registerHandover(program2) {
|
|
|
10743
10798
|
}
|
|
10744
10799
|
|
|
10745
10800
|
// src/commands/jira/acceptanceCriteria.ts
|
|
10746
|
-
import
|
|
10801
|
+
import chalk115 from "chalk";
|
|
10747
10802
|
|
|
10748
10803
|
// src/commands/jira/adfToText.ts
|
|
10749
10804
|
function renderInline(node) {
|
|
@@ -10804,28 +10859,28 @@ function adfToText(doc) {
|
|
|
10804
10859
|
|
|
10805
10860
|
// src/commands/jira/fetchIssue.ts
|
|
10806
10861
|
import { execSync as execSync28 } from "child_process";
|
|
10807
|
-
import
|
|
10862
|
+
import chalk114 from "chalk";
|
|
10808
10863
|
function fetchIssue(issueKey, fields) {
|
|
10809
10864
|
let result;
|
|
10810
10865
|
try {
|
|
10811
10866
|
result = execSync28(
|
|
10812
10867
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
10813
|
-
{ encoding: "
|
|
10868
|
+
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
10814
10869
|
);
|
|
10815
10870
|
} catch (error) {
|
|
10816
10871
|
if (error instanceof Error && "stderr" in error) {
|
|
10817
10872
|
const stderr = error.stderr;
|
|
10818
10873
|
if (stderr.includes("unauthorized")) {
|
|
10819
10874
|
console.error(
|
|
10820
|
-
|
|
10875
|
+
chalk114.red("Jira authentication expired."),
|
|
10821
10876
|
"Run",
|
|
10822
|
-
|
|
10877
|
+
chalk114.cyan("assist jira auth"),
|
|
10823
10878
|
"to re-authenticate."
|
|
10824
10879
|
);
|
|
10825
10880
|
process.exit(1);
|
|
10826
10881
|
}
|
|
10827
10882
|
}
|
|
10828
|
-
console.error(
|
|
10883
|
+
console.error(chalk114.red(`Failed to fetch ${issueKey}.`));
|
|
10829
10884
|
process.exit(1);
|
|
10830
10885
|
}
|
|
10831
10886
|
return JSON.parse(result);
|
|
@@ -10839,7 +10894,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
10839
10894
|
const parsed = fetchIssue(issueKey, field);
|
|
10840
10895
|
const acValue = parsed?.fields?.[field];
|
|
10841
10896
|
if (!acValue) {
|
|
10842
|
-
console.log(
|
|
10897
|
+
console.log(chalk115.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
10843
10898
|
return;
|
|
10844
10899
|
}
|
|
10845
10900
|
if (typeof acValue === "string") {
|
|
@@ -10870,7 +10925,7 @@ function loadJson(filename) {
|
|
|
10870
10925
|
const path56 = getStorePath(filename);
|
|
10871
10926
|
if (existsSync31(path56)) {
|
|
10872
10927
|
try {
|
|
10873
|
-
return JSON.parse(readFileSync26(path56, "
|
|
10928
|
+
return JSON.parse(readFileSync26(path56, "utf8"));
|
|
10874
10929
|
} catch {
|
|
10875
10930
|
return {};
|
|
10876
10931
|
}
|
|
@@ -10919,7 +10974,7 @@ async function jiraAuth() {
|
|
|
10919
10974
|
process.exit(1);
|
|
10920
10975
|
}
|
|
10921
10976
|
execSync29(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
10922
|
-
encoding: "
|
|
10977
|
+
encoding: "utf8",
|
|
10923
10978
|
input: token,
|
|
10924
10979
|
stdio: ["pipe", "inherit", "inherit"]
|
|
10925
10980
|
});
|
|
@@ -10934,14 +10989,14 @@ async function jiraAuth() {
|
|
|
10934
10989
|
}
|
|
10935
10990
|
|
|
10936
10991
|
// src/commands/jira/viewIssue.ts
|
|
10937
|
-
import
|
|
10992
|
+
import chalk116 from "chalk";
|
|
10938
10993
|
function viewIssue(issueKey) {
|
|
10939
10994
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
10940
10995
|
const fields = parsed?.fields;
|
|
10941
10996
|
const summary = fields?.summary;
|
|
10942
10997
|
const description = fields?.description;
|
|
10943
10998
|
if (summary) {
|
|
10944
|
-
console.log(
|
|
10999
|
+
console.log(chalk116.bold(summary));
|
|
10945
11000
|
}
|
|
10946
11001
|
if (description) {
|
|
10947
11002
|
if (summary) console.log();
|
|
@@ -10955,7 +11010,7 @@ function viewIssue(issueKey) {
|
|
|
10955
11010
|
}
|
|
10956
11011
|
if (!summary && !description) {
|
|
10957
11012
|
console.log(
|
|
10958
|
-
|
|
11013
|
+
chalk116.yellow(`No summary or description found on ${issueKey}.`)
|
|
10959
11014
|
);
|
|
10960
11015
|
}
|
|
10961
11016
|
}
|
|
@@ -10970,13 +11025,13 @@ function registerJira(program2) {
|
|
|
10970
11025
|
|
|
10971
11026
|
// src/commands/reviewComments.ts
|
|
10972
11027
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
10973
|
-
import
|
|
11028
|
+
import chalk117 from "chalk";
|
|
10974
11029
|
async function reviewComments(number) {
|
|
10975
11030
|
if (number) {
|
|
10976
11031
|
try {
|
|
10977
11032
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
10978
11033
|
} catch {
|
|
10979
|
-
console.error(
|
|
11034
|
+
console.error(chalk117.red(`gh pr checkout ${number} failed; aborting.`));
|
|
10980
11035
|
process.exit(1);
|
|
10981
11036
|
}
|
|
10982
11037
|
}
|
|
@@ -11019,15 +11074,15 @@ function registerList(program2) {
|
|
|
11019
11074
|
// src/commands/mermaid/index.ts
|
|
11020
11075
|
import { mkdirSync as mkdirSync11, readdirSync as readdirSync6 } from "fs";
|
|
11021
11076
|
import { resolve as resolve10 } from "path";
|
|
11022
|
-
import
|
|
11077
|
+
import chalk120 from "chalk";
|
|
11023
11078
|
|
|
11024
11079
|
// src/commands/mermaid/exportFile.ts
|
|
11025
11080
|
import { readFileSync as readFileSync27, writeFileSync as writeFileSync22 } from "fs";
|
|
11026
11081
|
import { basename as basename6, extname, resolve as resolve9 } from "path";
|
|
11027
|
-
import
|
|
11082
|
+
import chalk119 from "chalk";
|
|
11028
11083
|
|
|
11029
11084
|
// src/commands/mermaid/renderBlock.ts
|
|
11030
|
-
import
|
|
11085
|
+
import chalk118 from "chalk";
|
|
11031
11086
|
async function renderBlock(krokiUrl, source) {
|
|
11032
11087
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
11033
11088
|
method: "POST",
|
|
@@ -11036,7 +11091,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
11036
11091
|
});
|
|
11037
11092
|
if (!response.ok) {
|
|
11038
11093
|
console.error(
|
|
11039
|
-
|
|
11094
|
+
chalk118.red(
|
|
11040
11095
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
11041
11096
|
)
|
|
11042
11097
|
);
|
|
@@ -11054,19 +11109,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11054
11109
|
if (onlyIndex !== void 0) {
|
|
11055
11110
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
11056
11111
|
console.error(
|
|
11057
|
-
|
|
11112
|
+
chalk119.red(
|
|
11058
11113
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
11059
11114
|
)
|
|
11060
11115
|
);
|
|
11061
11116
|
process.exit(1);
|
|
11062
11117
|
}
|
|
11063
11118
|
console.log(
|
|
11064
|
-
|
|
11119
|
+
chalk119.gray(
|
|
11065
11120
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
11066
11121
|
)
|
|
11067
11122
|
);
|
|
11068
11123
|
} else {
|
|
11069
|
-
console.log(
|
|
11124
|
+
console.log(chalk119.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
11070
11125
|
}
|
|
11071
11126
|
for (const [i, source] of blocks.entries()) {
|
|
11072
11127
|
const idx = i + 1;
|
|
@@ -11074,7 +11129,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
11074
11129
|
const outPath = resolve9(outDir, `${stem}-${idx}.svg`);
|
|
11075
11130
|
const svg = await renderBlock(krokiUrl, source);
|
|
11076
11131
|
writeFileSync22(outPath, svg, "utf8");
|
|
11077
|
-
console.log(
|
|
11132
|
+
console.log(chalk119.green(` \u2192 ${outPath}`));
|
|
11078
11133
|
}
|
|
11079
11134
|
}
|
|
11080
11135
|
function extractMermaidBlocks(markdown) {
|
|
@@ -11090,18 +11145,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
11090
11145
|
if (options2.index !== void 0) {
|
|
11091
11146
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
11092
11147
|
console.error(
|
|
11093
|
-
|
|
11148
|
+
chalk120.red(`--index must be a positive integer (got ${options2.index})`)
|
|
11094
11149
|
);
|
|
11095
11150
|
process.exit(1);
|
|
11096
11151
|
}
|
|
11097
11152
|
if (!file) {
|
|
11098
|
-
console.error(
|
|
11153
|
+
console.error(chalk120.red("--index requires a file argument"));
|
|
11099
11154
|
process.exit(1);
|
|
11100
11155
|
}
|
|
11101
11156
|
}
|
|
11102
11157
|
const files = file ? [file] : readdirSync6(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
11103
11158
|
if (files.length === 0) {
|
|
11104
|
-
console.log(
|
|
11159
|
+
console.log(chalk120.gray("No markdown files found in current directory."));
|
|
11105
11160
|
return;
|
|
11106
11161
|
}
|
|
11107
11162
|
for (const f of files) {
|
|
@@ -11124,7 +11179,7 @@ function registerMermaid(program2) {
|
|
|
11124
11179
|
}
|
|
11125
11180
|
|
|
11126
11181
|
// src/commands/news/add/index.ts
|
|
11127
|
-
import
|
|
11182
|
+
import chalk121 from "chalk";
|
|
11128
11183
|
import enquirer8 from "enquirer";
|
|
11129
11184
|
async function add2(url) {
|
|
11130
11185
|
if (!url) {
|
|
@@ -11146,10 +11201,10 @@ async function add2(url) {
|
|
|
11146
11201
|
const { orm } = await getReady();
|
|
11147
11202
|
const added = await addFeed(orm, url);
|
|
11148
11203
|
if (!added) {
|
|
11149
|
-
console.log(
|
|
11204
|
+
console.log(chalk121.yellow("Feed already exists"));
|
|
11150
11205
|
return;
|
|
11151
11206
|
}
|
|
11152
|
-
console.log(
|
|
11207
|
+
console.log(chalk121.green(`Added feed: ${url}`));
|
|
11153
11208
|
}
|
|
11154
11209
|
|
|
11155
11210
|
// src/commands/registerNews.ts
|
|
@@ -11159,7 +11214,7 @@ function registerNews(program2) {
|
|
|
11159
11214
|
}
|
|
11160
11215
|
|
|
11161
11216
|
// src/commands/prompts/printPromptsTable.ts
|
|
11162
|
-
import
|
|
11217
|
+
import chalk122 from "chalk";
|
|
11163
11218
|
function truncate(str, max) {
|
|
11164
11219
|
if (str.length <= max) return str;
|
|
11165
11220
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -11177,14 +11232,14 @@ function printPromptsTable(rows) {
|
|
|
11177
11232
|
"Command".padEnd(commandWidth),
|
|
11178
11233
|
"Repos"
|
|
11179
11234
|
].join(" ");
|
|
11180
|
-
console.log(
|
|
11181
|
-
console.log(
|
|
11235
|
+
console.log(chalk122.dim(header));
|
|
11236
|
+
console.log(chalk122.dim("-".repeat(header.length)));
|
|
11182
11237
|
for (const row of rows) {
|
|
11183
11238
|
const count6 = String(row.count).padStart(countWidth);
|
|
11184
11239
|
const tool = row.tool.padEnd(toolWidth);
|
|
11185
11240
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
11186
11241
|
console.log(
|
|
11187
|
-
`${
|
|
11242
|
+
`${chalk122.yellow(count6)} ${tool} ${command} ${chalk122.dim(row.repos)}`
|
|
11188
11243
|
);
|
|
11189
11244
|
}
|
|
11190
11245
|
}
|
|
@@ -11231,13 +11286,13 @@ function getRepoInfo() {
|
|
|
11231
11286
|
const preferred = getPreferredRemoteRepo();
|
|
11232
11287
|
if (preferred) return preferred;
|
|
11233
11288
|
const repoInfo = JSON.parse(
|
|
11234
|
-
execSync30("gh repo view --json owner,name", { encoding: "
|
|
11289
|
+
execSync30("gh repo view --json owner,name", { encoding: "utf8" })
|
|
11235
11290
|
);
|
|
11236
11291
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
11237
11292
|
}
|
|
11238
11293
|
function getCurrentBranch() {
|
|
11239
11294
|
return execSync30("git rev-parse --abbrev-ref HEAD", {
|
|
11240
|
-
encoding: "
|
|
11295
|
+
encoding: "utf8"
|
|
11241
11296
|
}).trim();
|
|
11242
11297
|
}
|
|
11243
11298
|
function viewCurrentPr(fields) {
|
|
@@ -11245,7 +11300,7 @@ function viewCurrentPr(fields) {
|
|
|
11245
11300
|
const branch = getCurrentBranch();
|
|
11246
11301
|
return JSON.parse(
|
|
11247
11302
|
execSync30(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
|
|
11248
|
-
encoding: "
|
|
11303
|
+
encoding: "utf8"
|
|
11249
11304
|
})
|
|
11250
11305
|
);
|
|
11251
11306
|
}
|
|
@@ -11522,7 +11577,7 @@ function edit(options2) {
|
|
|
11522
11577
|
args.push(`--body ${shellQuote(newBody)}`);
|
|
11523
11578
|
try {
|
|
11524
11579
|
execSync31(args.join(" "), { stdio: "inherit" });
|
|
11525
|
-
} catch
|
|
11580
|
+
} catch {
|
|
11526
11581
|
process.exit(1);
|
|
11527
11582
|
}
|
|
11528
11583
|
}
|
|
@@ -11548,7 +11603,7 @@ function loadCommentsCache(prNumber) {
|
|
|
11548
11603
|
if (!existsSync32(cachePath)) {
|
|
11549
11604
|
return null;
|
|
11550
11605
|
}
|
|
11551
|
-
const content = readFileSync28(cachePath, "
|
|
11606
|
+
const content = readFileSync28(cachePath, "utf8");
|
|
11552
11607
|
return parse2(content);
|
|
11553
11608
|
}
|
|
11554
11609
|
function deleteCommentsCache(prNumber) {
|
|
@@ -11562,7 +11617,7 @@ function deleteCommentsCache(prNumber) {
|
|
|
11562
11617
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
11563
11618
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
11564
11619
|
execSync32(
|
|
11565
|
-
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g,
|
|
11620
|
+
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, String.raw`\"`)}" -F in_reply_to=${commentId}`,
|
|
11566
11621
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
11567
11622
|
);
|
|
11568
11623
|
}
|
|
@@ -11624,7 +11679,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
11624
11679
|
function verifySha(sha) {
|
|
11625
11680
|
try {
|
|
11626
11681
|
return execSync33(`git rev-parse --verify ${sha}`, {
|
|
11627
|
-
encoding: "
|
|
11682
|
+
encoding: "utf8"
|
|
11628
11683
|
}).trim();
|
|
11629
11684
|
} catch {
|
|
11630
11685
|
console.error(`Error: '${sha}' is not a valid commit in this repository.`);
|
|
@@ -11666,7 +11721,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
11666
11721
|
try {
|
|
11667
11722
|
const result = execSync34(
|
|
11668
11723
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
11669
|
-
{ encoding: "
|
|
11724
|
+
{ encoding: "utf8" }
|
|
11670
11725
|
);
|
|
11671
11726
|
const response = JSON.parse(result);
|
|
11672
11727
|
const threadMap = /* @__PURE__ */ new Map();
|
|
@@ -11689,7 +11744,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
11689
11744
|
import { execSync as execSync35 } from "child_process";
|
|
11690
11745
|
function fetchJson(endpoint) {
|
|
11691
11746
|
const result = execSync35(`gh api --paginate ${endpoint}`, {
|
|
11692
|
-
encoding: "
|
|
11747
|
+
encoding: "utf8"
|
|
11693
11748
|
});
|
|
11694
11749
|
if (!result.trim()) return [];
|
|
11695
11750
|
return JSON.parse(result);
|
|
@@ -11730,20 +11785,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
11730
11785
|
}
|
|
11731
11786
|
|
|
11732
11787
|
// src/commands/prs/listComments/printComments.ts
|
|
11733
|
-
import
|
|
11788
|
+
import chalk123 from "chalk";
|
|
11734
11789
|
function formatForHuman(comment3) {
|
|
11735
11790
|
if (comment3.type === "review") {
|
|
11736
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
11791
|
+
const stateColor = comment3.state === "APPROVED" ? chalk123.green : comment3.state === "CHANGES_REQUESTED" ? chalk123.red : chalk123.yellow;
|
|
11737
11792
|
return [
|
|
11738
|
-
`${
|
|
11793
|
+
`${chalk123.cyan("Review")} by ${chalk123.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
11739
11794
|
comment3.body,
|
|
11740
11795
|
""
|
|
11741
11796
|
].join("\n");
|
|
11742
11797
|
}
|
|
11743
11798
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
11744
11799
|
return [
|
|
11745
|
-
`${
|
|
11746
|
-
|
|
11800
|
+
`${chalk123.cyan("Line comment")} by ${chalk123.bold(comment3.user)} on ${chalk123.dim(`${comment3.path}${location}`)}`,
|
|
11801
|
+
chalk123.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
11747
11802
|
comment3.body,
|
|
11748
11803
|
""
|
|
11749
11804
|
].join("\n");
|
|
@@ -11833,13 +11888,13 @@ import { execSync as execSync36 } from "child_process";
|
|
|
11833
11888
|
import enquirer9 from "enquirer";
|
|
11834
11889
|
|
|
11835
11890
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
11836
|
-
import
|
|
11891
|
+
import chalk124 from "chalk";
|
|
11837
11892
|
var STATUS_MAP = {
|
|
11838
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
11839
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
11893
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk124.magenta("merged"), date: pr.mergedAt } : null,
|
|
11894
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk124.red("closed"), date: pr.closedAt } : null
|
|
11840
11895
|
};
|
|
11841
11896
|
function defaultStatus(pr) {
|
|
11842
|
-
return { label:
|
|
11897
|
+
return { label: chalk124.green("opened"), date: pr.createdAt };
|
|
11843
11898
|
}
|
|
11844
11899
|
function getStatus2(pr) {
|
|
11845
11900
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -11848,11 +11903,11 @@ function formatDate(dateStr) {
|
|
|
11848
11903
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
11849
11904
|
}
|
|
11850
11905
|
function formatPrHeader(pr, status2) {
|
|
11851
|
-
return `${
|
|
11906
|
+
return `${chalk124.cyan(`#${pr.number}`)} ${pr.title} ${chalk124.dim(`(${pr.author.login},`)} ${status2.label} ${chalk124.dim(`${formatDate(status2.date)})`)}`;
|
|
11852
11907
|
}
|
|
11853
11908
|
function logPrDetails(pr) {
|
|
11854
11909
|
console.log(
|
|
11855
|
-
|
|
11910
|
+
chalk124.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
11856
11911
|
);
|
|
11857
11912
|
console.log();
|
|
11858
11913
|
}
|
|
@@ -11936,7 +11991,7 @@ async function prs(options2) {
|
|
|
11936
11991
|
const { org, repo } = getRepoInfo();
|
|
11937
11992
|
const result = execSync36(
|
|
11938
11993
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
|
|
11939
|
-
{ encoding: "
|
|
11994
|
+
{ encoding: "utf8" }
|
|
11940
11995
|
);
|
|
11941
11996
|
const pullRequests = JSON.parse(result);
|
|
11942
11997
|
if (pullRequests.length === 0) {
|
|
@@ -12018,7 +12073,7 @@ function raise(options2) {
|
|
|
12018
12073
|
] : buildCreateArgs(options2.title, body, options2);
|
|
12019
12074
|
try {
|
|
12020
12075
|
execSync37(args.join(" "), { stdio: "inherit" });
|
|
12021
|
-
} catch
|
|
12076
|
+
} catch {
|
|
12022
12077
|
process.exit(1);
|
|
12023
12078
|
}
|
|
12024
12079
|
}
|
|
@@ -12131,10 +12186,10 @@ function registerPrs(program2) {
|
|
|
12131
12186
|
}
|
|
12132
12187
|
|
|
12133
12188
|
// src/commands/ravendb/ravendbAuth.ts
|
|
12134
|
-
import
|
|
12189
|
+
import chalk130 from "chalk";
|
|
12135
12190
|
|
|
12136
12191
|
// src/shared/createConnectionAuth.ts
|
|
12137
|
-
import
|
|
12192
|
+
import chalk125 from "chalk";
|
|
12138
12193
|
function listConnections(connections, format2) {
|
|
12139
12194
|
if (connections.length === 0) {
|
|
12140
12195
|
console.log("No connections configured.");
|
|
@@ -12147,7 +12202,7 @@ function listConnections(connections, format2) {
|
|
|
12147
12202
|
function removeConnection(connections, name, save) {
|
|
12148
12203
|
const filtered = connections.filter((c) => c.name !== name);
|
|
12149
12204
|
if (filtered.length === connections.length) {
|
|
12150
|
-
console.error(
|
|
12205
|
+
console.error(chalk125.red(`Connection "${name}" not found.`));
|
|
12151
12206
|
process.exit(1);
|
|
12152
12207
|
}
|
|
12153
12208
|
save(filtered);
|
|
@@ -12193,18 +12248,18 @@ function saveConnections(connections) {
|
|
|
12193
12248
|
}
|
|
12194
12249
|
|
|
12195
12250
|
// src/commands/ravendb/promptConnection.ts
|
|
12196
|
-
import
|
|
12251
|
+
import chalk128 from "chalk";
|
|
12197
12252
|
|
|
12198
12253
|
// src/commands/ravendb/selectOpSecret.ts
|
|
12199
|
-
import
|
|
12254
|
+
import chalk127 from "chalk";
|
|
12200
12255
|
import Enquirer2 from "enquirer";
|
|
12201
12256
|
|
|
12202
12257
|
// src/commands/ravendb/searchItems.ts
|
|
12203
12258
|
import { execSync as execSync39 } from "child_process";
|
|
12204
|
-
import
|
|
12259
|
+
import chalk126 from "chalk";
|
|
12205
12260
|
function opExec(args) {
|
|
12206
12261
|
return execSync39(`op ${args}`, {
|
|
12207
|
-
encoding: "
|
|
12262
|
+
encoding: "utf8",
|
|
12208
12263
|
stdio: ["pipe", "pipe", "pipe"]
|
|
12209
12264
|
}).trim();
|
|
12210
12265
|
}
|
|
@@ -12214,7 +12269,7 @@ function searchItems(search2) {
|
|
|
12214
12269
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
12215
12270
|
} catch {
|
|
12216
12271
|
console.error(
|
|
12217
|
-
|
|
12272
|
+
chalk126.red(
|
|
12218
12273
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
12219
12274
|
)
|
|
12220
12275
|
);
|
|
@@ -12228,7 +12283,7 @@ function getItemFields(itemId) {
|
|
|
12228
12283
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
12229
12284
|
return item.fields.filter((f) => f.reference && f.label);
|
|
12230
12285
|
} catch {
|
|
12231
|
-
console.error(
|
|
12286
|
+
console.error(chalk126.red("Failed to get item details from 1Password."));
|
|
12232
12287
|
process.exit(1);
|
|
12233
12288
|
}
|
|
12234
12289
|
}
|
|
@@ -12247,7 +12302,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12247
12302
|
}).run();
|
|
12248
12303
|
const items2 = searchItems(search2);
|
|
12249
12304
|
if (items2.length === 0) {
|
|
12250
|
-
console.error(
|
|
12305
|
+
console.error(chalk127.red(`No items found matching "${search2}".`));
|
|
12251
12306
|
process.exit(1);
|
|
12252
12307
|
}
|
|
12253
12308
|
const itemId = await selectOne(
|
|
@@ -12256,7 +12311,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12256
12311
|
);
|
|
12257
12312
|
const fields = getItemFields(itemId);
|
|
12258
12313
|
if (fields.length === 0) {
|
|
12259
|
-
console.error(
|
|
12314
|
+
console.error(chalk127.red("No fields with references found on this item."));
|
|
12260
12315
|
process.exit(1);
|
|
12261
12316
|
}
|
|
12262
12317
|
const ref = await selectOne(
|
|
@@ -12270,7 +12325,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
12270
12325
|
async function promptConnection(existingNames) {
|
|
12271
12326
|
const name = await promptInput("name", "Connection name:");
|
|
12272
12327
|
if (existingNames.includes(name)) {
|
|
12273
|
-
console.error(
|
|
12328
|
+
console.error(chalk128.red(`Connection "${name}" already exists.`));
|
|
12274
12329
|
process.exit(1);
|
|
12275
12330
|
}
|
|
12276
12331
|
const url = await promptInput(
|
|
@@ -12279,22 +12334,22 @@ async function promptConnection(existingNames) {
|
|
|
12279
12334
|
);
|
|
12280
12335
|
const database = await promptInput("database", "Database name:");
|
|
12281
12336
|
if (!name || !url || !database) {
|
|
12282
|
-
console.error(
|
|
12337
|
+
console.error(chalk128.red("All fields are required."));
|
|
12283
12338
|
process.exit(1);
|
|
12284
12339
|
}
|
|
12285
12340
|
const apiKeyRef = await selectOpSecret();
|
|
12286
|
-
console.log(
|
|
12341
|
+
console.log(chalk128.dim(`Using: ${apiKeyRef}`));
|
|
12287
12342
|
return { name, url, database, apiKeyRef };
|
|
12288
12343
|
}
|
|
12289
12344
|
|
|
12290
12345
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
12291
|
-
import
|
|
12346
|
+
import chalk129 from "chalk";
|
|
12292
12347
|
function ravendbSetConnection(name) {
|
|
12293
12348
|
const raw = loadGlobalConfigRaw();
|
|
12294
12349
|
const ravendb = raw.ravendb ?? {};
|
|
12295
12350
|
const connections = ravendb.connections ?? [];
|
|
12296
12351
|
if (!connections.some((c) => c.name === name)) {
|
|
12297
|
-
console.error(
|
|
12352
|
+
console.error(chalk129.red(`Connection "${name}" not found.`));
|
|
12298
12353
|
console.error(
|
|
12299
12354
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12300
12355
|
);
|
|
@@ -12310,16 +12365,16 @@ function ravendbSetConnection(name) {
|
|
|
12310
12365
|
var ravendbAuth = createConnectionAuth({
|
|
12311
12366
|
load: loadConnections,
|
|
12312
12367
|
save: saveConnections,
|
|
12313
|
-
format: (c) => `${
|
|
12368
|
+
format: (c) => `${chalk130.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
12314
12369
|
promptNew: promptConnection,
|
|
12315
12370
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
12316
12371
|
});
|
|
12317
12372
|
|
|
12318
12373
|
// src/commands/ravendb/ravendbCollections.ts
|
|
12319
|
-
import
|
|
12374
|
+
import chalk134 from "chalk";
|
|
12320
12375
|
|
|
12321
12376
|
// src/commands/ravendb/ravenFetch.ts
|
|
12322
|
-
import
|
|
12377
|
+
import chalk132 from "chalk";
|
|
12323
12378
|
|
|
12324
12379
|
// src/commands/ravendb/getAccessToken.ts
|
|
12325
12380
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -12356,20 +12411,20 @@ ${errorText}`
|
|
|
12356
12411
|
|
|
12357
12412
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
12358
12413
|
import { execSync as execSync40 } from "child_process";
|
|
12359
|
-
import
|
|
12414
|
+
import chalk131 from "chalk";
|
|
12360
12415
|
function resolveOpSecret(reference) {
|
|
12361
12416
|
if (!reference.startsWith("op://")) {
|
|
12362
|
-
console.error(
|
|
12417
|
+
console.error(chalk131.red(`Invalid secret reference: must start with op://`));
|
|
12363
12418
|
process.exit(1);
|
|
12364
12419
|
}
|
|
12365
12420
|
try {
|
|
12366
12421
|
return execSync40(`op read "${reference}"`, {
|
|
12367
|
-
encoding: "
|
|
12422
|
+
encoding: "utf8",
|
|
12368
12423
|
stdio: ["pipe", "pipe", "pipe"]
|
|
12369
12424
|
}).trim();
|
|
12370
12425
|
} catch {
|
|
12371
12426
|
console.error(
|
|
12372
|
-
|
|
12427
|
+
chalk131.red(
|
|
12373
12428
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
12374
12429
|
)
|
|
12375
12430
|
);
|
|
@@ -12396,7 +12451,7 @@ async function ravenFetch(connection, path56) {
|
|
|
12396
12451
|
if (!response.ok) {
|
|
12397
12452
|
const body = await response.text();
|
|
12398
12453
|
console.error(
|
|
12399
|
-
|
|
12454
|
+
chalk132.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
12400
12455
|
);
|
|
12401
12456
|
console.error(body.substring(0, 500));
|
|
12402
12457
|
process.exit(1);
|
|
@@ -12405,7 +12460,7 @@ async function ravenFetch(connection, path56) {
|
|
|
12405
12460
|
}
|
|
12406
12461
|
|
|
12407
12462
|
// src/commands/ravendb/resolveConnection.ts
|
|
12408
|
-
import
|
|
12463
|
+
import chalk133 from "chalk";
|
|
12409
12464
|
function loadRavendb() {
|
|
12410
12465
|
const raw = loadGlobalConfigRaw();
|
|
12411
12466
|
const ravendb = raw.ravendb;
|
|
@@ -12419,7 +12474,7 @@ function resolveConnection(name) {
|
|
|
12419
12474
|
const connectionName = name ?? defaultConnection;
|
|
12420
12475
|
if (!connectionName) {
|
|
12421
12476
|
console.error(
|
|
12422
|
-
|
|
12477
|
+
chalk133.red(
|
|
12423
12478
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
12424
12479
|
)
|
|
12425
12480
|
);
|
|
@@ -12427,7 +12482,7 @@ function resolveConnection(name) {
|
|
|
12427
12482
|
}
|
|
12428
12483
|
const connection = connections.find((c) => c.name === connectionName);
|
|
12429
12484
|
if (!connection) {
|
|
12430
|
-
console.error(
|
|
12485
|
+
console.error(chalk133.red(`Connection "${connectionName}" not found.`));
|
|
12431
12486
|
console.error(
|
|
12432
12487
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
12433
12488
|
);
|
|
@@ -12458,15 +12513,15 @@ async function ravendbCollections(connectionName) {
|
|
|
12458
12513
|
return;
|
|
12459
12514
|
}
|
|
12460
12515
|
for (const c of collections) {
|
|
12461
|
-
console.log(`${
|
|
12516
|
+
console.log(`${chalk134.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
12462
12517
|
}
|
|
12463
12518
|
}
|
|
12464
12519
|
|
|
12465
12520
|
// src/commands/ravendb/ravendbQuery.ts
|
|
12466
|
-
import
|
|
12521
|
+
import chalk136 from "chalk";
|
|
12467
12522
|
|
|
12468
12523
|
// src/commands/ravendb/fetchAllPages.ts
|
|
12469
|
-
import
|
|
12524
|
+
import chalk135 from "chalk";
|
|
12470
12525
|
|
|
12471
12526
|
// src/commands/ravendb/buildQueryPath.ts
|
|
12472
12527
|
function buildQueryPath(opts) {
|
|
@@ -12504,7 +12559,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12504
12559
|
allResults.push(...results);
|
|
12505
12560
|
start3 += results.length;
|
|
12506
12561
|
process.stderr.write(
|
|
12507
|
-
`\r${
|
|
12562
|
+
`\r${chalk135.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
12508
12563
|
);
|
|
12509
12564
|
if (start3 >= totalResults) break;
|
|
12510
12565
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -12519,7 +12574,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
12519
12574
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
12520
12575
|
const resolved = resolveArgs(connectionName, collection);
|
|
12521
12576
|
if (!resolved.collection && !options2.query) {
|
|
12522
|
-
console.error(
|
|
12577
|
+
console.error(chalk136.red("Provide a collection name or --query filter."));
|
|
12523
12578
|
process.exit(1);
|
|
12524
12579
|
}
|
|
12525
12580
|
const { collection: col } = resolved;
|
|
@@ -12557,7 +12612,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
12557
12612
|
import * as path26 from "path";
|
|
12558
12613
|
|
|
12559
12614
|
// src/commands/refactor/logViolations.ts
|
|
12560
|
-
import
|
|
12615
|
+
import chalk137 from "chalk";
|
|
12561
12616
|
var DEFAULT_MAX_LINES = 100;
|
|
12562
12617
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
12563
12618
|
if (violations.length === 0) {
|
|
@@ -12566,43 +12621,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
12566
12621
|
}
|
|
12567
12622
|
return;
|
|
12568
12623
|
}
|
|
12569
|
-
console.error(
|
|
12624
|
+
console.error(chalk137.red(`
|
|
12570
12625
|
Refactor check failed:
|
|
12571
12626
|
`));
|
|
12572
|
-
console.error(
|
|
12627
|
+
console.error(chalk137.red(` The following files exceed ${maxLines} lines:
|
|
12573
12628
|
`));
|
|
12574
12629
|
for (const violation of violations) {
|
|
12575
|
-
console.error(
|
|
12630
|
+
console.error(chalk137.red(` ${violation.file} (${violation.lines} lines)`));
|
|
12576
12631
|
}
|
|
12577
12632
|
console.error(
|
|
12578
|
-
|
|
12633
|
+
chalk137.yellow(
|
|
12579
12634
|
`
|
|
12580
12635
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
12581
12636
|
way to refactor it, ignore it with:
|
|
12582
12637
|
`
|
|
12583
12638
|
)
|
|
12584
12639
|
);
|
|
12585
|
-
console.error(
|
|
12640
|
+
console.error(chalk137.gray(` assist refactor ignore <file>
|
|
12586
12641
|
`));
|
|
12587
12642
|
if (process.env.CLAUDECODE) {
|
|
12588
|
-
console.error(
|
|
12643
|
+
console.error(chalk137.cyan(`
|
|
12589
12644
|
## Extracting Code to New Files
|
|
12590
12645
|
`));
|
|
12591
12646
|
console.error(
|
|
12592
|
-
|
|
12647
|
+
chalk137.cyan(
|
|
12593
12648
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
12594
12649
|
`
|
|
12595
12650
|
)
|
|
12596
12651
|
);
|
|
12597
12652
|
console.error(
|
|
12598
|
-
|
|
12653
|
+
chalk137.cyan(
|
|
12599
12654
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
12600
12655
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
12601
12656
|
`
|
|
12602
12657
|
)
|
|
12603
12658
|
);
|
|
12604
12659
|
console.error(
|
|
12605
|
-
|
|
12660
|
+
chalk137.cyan(
|
|
12606
12661
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
12607
12662
|
domains, move it to a common/shared folder.
|
|
12608
12663
|
`
|
|
@@ -12623,7 +12678,7 @@ function parseRefactorYml() {
|
|
|
12623
12678
|
if (!fs16.existsSync(REFACTOR_YML_PATH)) {
|
|
12624
12679
|
return [];
|
|
12625
12680
|
}
|
|
12626
|
-
const content = fs16.readFileSync(REFACTOR_YML_PATH, "
|
|
12681
|
+
const content = fs16.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
12627
12682
|
const entries = [];
|
|
12628
12683
|
const lines = content.split("\n");
|
|
12629
12684
|
let currentEntry = {};
|
|
@@ -12653,7 +12708,7 @@ function getIgnoredFiles() {
|
|
|
12653
12708
|
|
|
12654
12709
|
// src/commands/refactor/check/getViolations/index.ts
|
|
12655
12710
|
function countLines(filePath) {
|
|
12656
|
-
const content = fs17.readFileSync(filePath, "
|
|
12711
|
+
const content = fs17.readFileSync(filePath, "utf8");
|
|
12657
12712
|
return content.split("\n").length;
|
|
12658
12713
|
}
|
|
12659
12714
|
function getGitFiles(options2) {
|
|
@@ -12663,14 +12718,14 @@ function getGitFiles(options2) {
|
|
|
12663
12718
|
const files = /* @__PURE__ */ new Set();
|
|
12664
12719
|
if (options2.staged || options2.modified) {
|
|
12665
12720
|
const staged = execSync41("git diff --cached --name-only", {
|
|
12666
|
-
encoding: "
|
|
12721
|
+
encoding: "utf8"
|
|
12667
12722
|
});
|
|
12668
12723
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
12669
12724
|
files.add(file);
|
|
12670
12725
|
}
|
|
12671
12726
|
}
|
|
12672
12727
|
if (options2.unstaged || options2.modified) {
|
|
12673
|
-
const unstaged = execSync41("git diff --name-only", { encoding: "
|
|
12728
|
+
const unstaged = execSync41("git diff --name-only", { encoding: "utf8" });
|
|
12674
12729
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
12675
12730
|
files.add(file);
|
|
12676
12731
|
}
|
|
@@ -12758,7 +12813,7 @@ async function check(pattern2, options2) {
|
|
|
12758
12813
|
|
|
12759
12814
|
// src/commands/refactor/extract/index.ts
|
|
12760
12815
|
import path33 from "path";
|
|
12761
|
-
import
|
|
12816
|
+
import chalk140 from "chalk";
|
|
12762
12817
|
|
|
12763
12818
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
12764
12819
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -12767,7 +12822,7 @@ import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
|
12767
12822
|
import {
|
|
12768
12823
|
SyntaxKind as SyntaxKind2
|
|
12769
12824
|
} from "ts-morph";
|
|
12770
|
-
var suppressionPattern = /^\s*(\/\/|\/\*)\s*biome-ignore(-all)
|
|
12825
|
+
var suppressionPattern = /^\s*(\/\/|\/\*)\s*(biome-ignore(-all)?|oxlint-disable)\b/;
|
|
12771
12826
|
function countLeadingSuppressions(sourceFile) {
|
|
12772
12827
|
let count6 = 0;
|
|
12773
12828
|
for (const stmt of sourceFile.getStatementsWithComments()) {
|
|
@@ -13333,23 +13388,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
13333
13388
|
|
|
13334
13389
|
// src/commands/refactor/extract/displayPlan.ts
|
|
13335
13390
|
import path30 from "path";
|
|
13336
|
-
import
|
|
13391
|
+
import chalk138 from "chalk";
|
|
13337
13392
|
function section(title) {
|
|
13338
13393
|
return `
|
|
13339
|
-
${
|
|
13394
|
+
${chalk138.cyan(title)}`;
|
|
13340
13395
|
}
|
|
13341
13396
|
function displayImporters(plan2, cwd) {
|
|
13342
13397
|
if (plan2.importersToUpdate.length === 0) return;
|
|
13343
13398
|
console.log(section("Update importers:"));
|
|
13344
13399
|
for (const imp of plan2.importersToUpdate) {
|
|
13345
13400
|
const rel = path30.relative(cwd, imp.file.getFilePath());
|
|
13346
|
-
console.log(` ${
|
|
13401
|
+
console.log(` ${chalk138.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
13347
13402
|
}
|
|
13348
13403
|
}
|
|
13349
13404
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
13350
|
-
console.log(
|
|
13405
|
+
console.log(chalk138.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
13351
13406
|
`));
|
|
13352
|
-
console.log(` ${
|
|
13407
|
+
console.log(` ${chalk138.cyan("Functions to move:")}`);
|
|
13353
13408
|
for (const name of plan2.extractedNames) {
|
|
13354
13409
|
console.log(` ${name}`);
|
|
13355
13410
|
}
|
|
@@ -13383,7 +13438,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
13383
13438
|
|
|
13384
13439
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
13385
13440
|
import path32 from "path";
|
|
13386
|
-
import
|
|
13441
|
+
import chalk139 from "chalk";
|
|
13387
13442
|
import { Project as Project4 } from "ts-morph";
|
|
13388
13443
|
|
|
13389
13444
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -13410,7 +13465,7 @@ function findTsConfig(sourcePath) {
|
|
|
13410
13465
|
}
|
|
13411
13466
|
function readReferences(configPath) {
|
|
13412
13467
|
if (!fs18.existsSync(configPath)) return [];
|
|
13413
|
-
const raw = fs18.readFileSync(configPath, "
|
|
13468
|
+
const raw = fs18.readFileSync(configPath, "utf8");
|
|
13414
13469
|
const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
13415
13470
|
let parsed;
|
|
13416
13471
|
try {
|
|
@@ -13443,7 +13498,7 @@ function loadProjectFile(file) {
|
|
|
13443
13498
|
});
|
|
13444
13499
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
13445
13500
|
if (!sourceFile) {
|
|
13446
|
-
console.log(
|
|
13501
|
+
console.log(chalk139.red(`File not found in project: ${file}`));
|
|
13447
13502
|
process.exit(1);
|
|
13448
13503
|
}
|
|
13449
13504
|
return { project, sourceFile };
|
|
@@ -13466,35 +13521,35 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
13466
13521
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
13467
13522
|
if (options2.apply) {
|
|
13468
13523
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
13469
|
-
console.log(
|
|
13524
|
+
console.log(chalk140.green("\nExtraction complete"));
|
|
13470
13525
|
} else {
|
|
13471
|
-
console.log(
|
|
13526
|
+
console.log(chalk140.dim("\nDry run. Use --apply to execute."));
|
|
13472
13527
|
}
|
|
13473
13528
|
}
|
|
13474
13529
|
|
|
13475
13530
|
// src/commands/refactor/ignore.ts
|
|
13476
13531
|
import fs19 from "fs";
|
|
13477
|
-
import
|
|
13532
|
+
import chalk141 from "chalk";
|
|
13478
13533
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
13479
13534
|
function ignore(file) {
|
|
13480
13535
|
if (!fs19.existsSync(file)) {
|
|
13481
|
-
console.error(
|
|
13536
|
+
console.error(chalk141.red(`Error: File does not exist: ${file}`));
|
|
13482
13537
|
process.exit(1);
|
|
13483
13538
|
}
|
|
13484
|
-
const content = fs19.readFileSync(file, "
|
|
13539
|
+
const content = fs19.readFileSync(file, "utf8");
|
|
13485
13540
|
const lineCount = content.split("\n").length;
|
|
13486
13541
|
const maxLines = lineCount + 10;
|
|
13487
13542
|
const entry = `- file: ${file}
|
|
13488
13543
|
maxLines: ${maxLines}
|
|
13489
13544
|
`;
|
|
13490
13545
|
if (fs19.existsSync(REFACTOR_YML_PATH2)) {
|
|
13491
|
-
const existing = fs19.readFileSync(REFACTOR_YML_PATH2, "
|
|
13546
|
+
const existing = fs19.readFileSync(REFACTOR_YML_PATH2, "utf8");
|
|
13492
13547
|
fs19.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
13493
13548
|
} else {
|
|
13494
13549
|
fs19.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
13495
13550
|
}
|
|
13496
13551
|
console.log(
|
|
13497
|
-
|
|
13552
|
+
chalk141.green(
|
|
13498
13553
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
13499
13554
|
)
|
|
13500
13555
|
);
|
|
@@ -13503,12 +13558,12 @@ function ignore(file) {
|
|
|
13503
13558
|
// src/commands/refactor/rename/index.ts
|
|
13504
13559
|
import fs22 from "fs";
|
|
13505
13560
|
import path38 from "path";
|
|
13506
|
-
import
|
|
13561
|
+
import chalk144 from "chalk";
|
|
13507
13562
|
|
|
13508
13563
|
// src/commands/refactor/rename/applyRename.ts
|
|
13509
13564
|
import fs21 from "fs";
|
|
13510
13565
|
import path35 from "path";
|
|
13511
|
-
import
|
|
13566
|
+
import chalk142 from "chalk";
|
|
13512
13567
|
|
|
13513
13568
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
13514
13569
|
import path34 from "path";
|
|
@@ -13528,12 +13583,12 @@ function groupByFile2(rewrites) {
|
|
|
13528
13583
|
return grouped;
|
|
13529
13584
|
}
|
|
13530
13585
|
function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
|
|
13531
|
-
const escaped = oldSpecifier.replace(/[.*+?^${}()|[\]\\]/g,
|
|
13586
|
+
const escaped = oldSpecifier.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
13532
13587
|
const pattern2 = new RegExp(`(from\\s+["'])${escaped}(["'])`, "g");
|
|
13533
13588
|
return content.replace(pattern2, `$1${newSpecifier}$2`);
|
|
13534
13589
|
}
|
|
13535
13590
|
function applyFileRewrites(file, fileRewrites) {
|
|
13536
|
-
let content = fs20.readFileSync(file, "
|
|
13591
|
+
let content = fs20.readFileSync(file, "utf8");
|
|
13537
13592
|
for (const { oldSpecifier, newSpecifier } of fileRewrites) {
|
|
13538
13593
|
content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
|
|
13539
13594
|
}
|
|
@@ -13612,14 +13667,14 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
13612
13667
|
function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
13613
13668
|
const updatedContents = applyRewrites(rewrites);
|
|
13614
13669
|
for (const [file, content] of updatedContents) {
|
|
13615
|
-
fs21.writeFileSync(file, content, "
|
|
13616
|
-
console.log(
|
|
13670
|
+
fs21.writeFileSync(file, content, "utf8");
|
|
13671
|
+
console.log(chalk142.cyan(` Updated imports in ${path35.relative(cwd, file)}`));
|
|
13617
13672
|
}
|
|
13618
13673
|
const destDir = path35.dirname(destPath);
|
|
13619
13674
|
if (!fs21.existsSync(destDir)) fs21.mkdirSync(destDir, { recursive: true });
|
|
13620
13675
|
fs21.renameSync(sourcePath, destPath);
|
|
13621
13676
|
console.log(
|
|
13622
|
-
|
|
13677
|
+
chalk142.white(
|
|
13623
13678
|
` Moved ${path35.relative(cwd, sourcePath)} \u2192 ${path35.relative(cwd, destPath)}`
|
|
13624
13679
|
)
|
|
13625
13680
|
);
|
|
@@ -13706,16 +13761,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
13706
13761
|
|
|
13707
13762
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
13708
13763
|
import path37 from "path";
|
|
13709
|
-
import
|
|
13764
|
+
import chalk143 from "chalk";
|
|
13710
13765
|
function printRenamePreview(rewrites, cwd) {
|
|
13711
13766
|
for (const rewrite of rewrites) {
|
|
13712
13767
|
console.log(
|
|
13713
|
-
|
|
13768
|
+
chalk143.dim(
|
|
13714
13769
|
` ${path37.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
13715
13770
|
)
|
|
13716
13771
|
);
|
|
13717
13772
|
}
|
|
13718
|
-
console.log(
|
|
13773
|
+
console.log(chalk143.dim("Dry run. Use --apply to execute."));
|
|
13719
13774
|
}
|
|
13720
13775
|
|
|
13721
13776
|
// src/commands/refactor/rename/index.ts
|
|
@@ -13726,20 +13781,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
13726
13781
|
const relSource = path38.relative(cwd, sourcePath);
|
|
13727
13782
|
const relDest = path38.relative(cwd, destPath);
|
|
13728
13783
|
if (!fs22.existsSync(sourcePath)) {
|
|
13729
|
-
console.log(
|
|
13784
|
+
console.log(chalk144.red(`File not found: ${source}`));
|
|
13730
13785
|
process.exit(1);
|
|
13731
13786
|
}
|
|
13732
13787
|
if (destPath !== sourcePath && fs22.existsSync(destPath)) {
|
|
13733
|
-
console.log(
|
|
13788
|
+
console.log(chalk144.red(`Destination already exists: ${destination}`));
|
|
13734
13789
|
process.exit(1);
|
|
13735
13790
|
}
|
|
13736
|
-
console.log(
|
|
13737
|
-
console.log(
|
|
13738
|
-
console.log(
|
|
13791
|
+
console.log(chalk144.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
13792
|
+
console.log(chalk144.dim("Loading project..."));
|
|
13793
|
+
console.log(chalk144.dim("Scanning imports across the project..."));
|
|
13739
13794
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
13740
13795
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
13741
13796
|
console.log(
|
|
13742
|
-
|
|
13797
|
+
chalk144.dim(
|
|
13743
13798
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
13744
13799
|
)
|
|
13745
13800
|
);
|
|
@@ -13748,11 +13803,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
13748
13803
|
return;
|
|
13749
13804
|
}
|
|
13750
13805
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
13751
|
-
console.log(
|
|
13806
|
+
console.log(chalk144.green("Done"));
|
|
13752
13807
|
}
|
|
13753
13808
|
|
|
13754
13809
|
// src/commands/refactor/renameSymbol/index.ts
|
|
13755
|
-
import
|
|
13810
|
+
import chalk145 from "chalk";
|
|
13756
13811
|
|
|
13757
13812
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
13758
13813
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -13798,33 +13853,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
13798
13853
|
const { project, sourceFile } = loadProjectFile(file);
|
|
13799
13854
|
const symbol = findSymbol(sourceFile, oldName);
|
|
13800
13855
|
if (!symbol) {
|
|
13801
|
-
console.log(
|
|
13856
|
+
console.log(chalk145.red(`Symbol "${oldName}" not found in ${file}`));
|
|
13802
13857
|
process.exit(1);
|
|
13803
13858
|
}
|
|
13804
13859
|
const grouped = groupReferences(symbol, cwd);
|
|
13805
13860
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
13806
13861
|
console.log(
|
|
13807
|
-
|
|
13862
|
+
chalk145.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
13808
13863
|
`)
|
|
13809
13864
|
);
|
|
13810
13865
|
for (const [refFile, lines] of grouped) {
|
|
13811
13866
|
console.log(
|
|
13812
|
-
` ${
|
|
13867
|
+
` ${chalk145.dim(refFile)}: lines ${chalk145.cyan(lines.join(", "))}`
|
|
13813
13868
|
);
|
|
13814
13869
|
}
|
|
13815
13870
|
if (options2.apply) {
|
|
13816
13871
|
symbol.rename(newName);
|
|
13817
13872
|
await project.save();
|
|
13818
|
-
console.log(
|
|
13873
|
+
console.log(chalk145.green(`
|
|
13819
13874
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
13820
13875
|
} else {
|
|
13821
|
-
console.log(
|
|
13876
|
+
console.log(chalk145.dim("\nDry run. Use --apply to execute."));
|
|
13822
13877
|
}
|
|
13823
13878
|
}
|
|
13824
13879
|
|
|
13825
13880
|
// src/commands/refactor/restructure/index.ts
|
|
13826
13881
|
import path46 from "path";
|
|
13827
|
-
import
|
|
13882
|
+
import chalk148 from "chalk";
|
|
13828
13883
|
|
|
13829
13884
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
13830
13885
|
import path40 from "path";
|
|
@@ -13903,50 +13958,50 @@ function clusterFiles(graph) {
|
|
|
13903
13958
|
|
|
13904
13959
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
13905
13960
|
import path42 from "path";
|
|
13906
|
-
import
|
|
13961
|
+
import chalk146 from "chalk";
|
|
13907
13962
|
function relPath(filePath) {
|
|
13908
13963
|
return path42.relative(process.cwd(), filePath);
|
|
13909
13964
|
}
|
|
13910
13965
|
function displayMoves(plan2) {
|
|
13911
13966
|
if (plan2.moves.length === 0) return;
|
|
13912
|
-
console.log(
|
|
13967
|
+
console.log(chalk146.bold("\nFile moves:"));
|
|
13913
13968
|
for (const move of plan2.moves) {
|
|
13914
13969
|
console.log(
|
|
13915
|
-
` ${
|
|
13970
|
+
` ${chalk146.red(relPath(move.from))} \u2192 ${chalk146.green(relPath(move.to))}`
|
|
13916
13971
|
);
|
|
13917
|
-
console.log(
|
|
13972
|
+
console.log(chalk146.dim(` ${move.reason}`));
|
|
13918
13973
|
}
|
|
13919
13974
|
}
|
|
13920
13975
|
function displayRewrites(rewrites) {
|
|
13921
13976
|
if (rewrites.length === 0) return;
|
|
13922
13977
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
13923
|
-
console.log(
|
|
13978
|
+
console.log(chalk146.bold(`
|
|
13924
13979
|
Import rewrites (${affectedFiles.size} files):`));
|
|
13925
13980
|
for (const file of affectedFiles) {
|
|
13926
|
-
console.log(` ${
|
|
13981
|
+
console.log(` ${chalk146.cyan(relPath(file))}:`);
|
|
13927
13982
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
13928
13983
|
(r) => r.file === file
|
|
13929
13984
|
)) {
|
|
13930
13985
|
console.log(
|
|
13931
|
-
` ${
|
|
13986
|
+
` ${chalk146.red(`"${oldSpecifier}"`)} \u2192 ${chalk146.green(`"${newSpecifier}"`)}`
|
|
13932
13987
|
);
|
|
13933
13988
|
}
|
|
13934
13989
|
}
|
|
13935
13990
|
}
|
|
13936
13991
|
function displayPlan2(plan2) {
|
|
13937
13992
|
if (plan2.warnings.length > 0) {
|
|
13938
|
-
console.log(
|
|
13939
|
-
for (const w of plan2.warnings) console.log(
|
|
13993
|
+
console.log(chalk146.yellow("\nWarnings:"));
|
|
13994
|
+
for (const w of plan2.warnings) console.log(chalk146.yellow(` ${w}`));
|
|
13940
13995
|
}
|
|
13941
13996
|
if (plan2.newDirectories.length > 0) {
|
|
13942
|
-
console.log(
|
|
13997
|
+
console.log(chalk146.bold("\nNew directories:"));
|
|
13943
13998
|
for (const dir of plan2.newDirectories)
|
|
13944
|
-
console.log(
|
|
13999
|
+
console.log(chalk146.green(` ${dir}/`));
|
|
13945
14000
|
}
|
|
13946
14001
|
displayMoves(plan2);
|
|
13947
14002
|
displayRewrites(plan2.rewrites);
|
|
13948
14003
|
console.log(
|
|
13949
|
-
|
|
14004
|
+
chalk146.dim(
|
|
13950
14005
|
`
|
|
13951
14006
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
13952
14007
|
)
|
|
@@ -13956,18 +14011,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
13956
14011
|
// src/commands/refactor/restructure/executePlan.ts
|
|
13957
14012
|
import fs23 from "fs";
|
|
13958
14013
|
import path43 from "path";
|
|
13959
|
-
import
|
|
14014
|
+
import chalk147 from "chalk";
|
|
13960
14015
|
function executePlan(plan2) {
|
|
13961
14016
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
13962
14017
|
for (const [file, content] of updatedContents) {
|
|
13963
|
-
fs23.writeFileSync(file, content, "
|
|
14018
|
+
fs23.writeFileSync(file, content, "utf8");
|
|
13964
14019
|
console.log(
|
|
13965
|
-
|
|
14020
|
+
chalk147.cyan(` Rewrote imports in ${path43.relative(process.cwd(), file)}`)
|
|
13966
14021
|
);
|
|
13967
14022
|
}
|
|
13968
14023
|
for (const dir of plan2.newDirectories) {
|
|
13969
14024
|
fs23.mkdirSync(dir, { recursive: true });
|
|
13970
|
-
console.log(
|
|
14025
|
+
console.log(chalk147.green(` Created ${path43.relative(process.cwd(), dir)}/`));
|
|
13971
14026
|
}
|
|
13972
14027
|
for (const move of plan2.moves) {
|
|
13973
14028
|
const targetDir = path43.dirname(move.to);
|
|
@@ -13976,7 +14031,7 @@ function executePlan(plan2) {
|
|
|
13976
14031
|
}
|
|
13977
14032
|
fs23.renameSync(move.from, move.to);
|
|
13978
14033
|
console.log(
|
|
13979
|
-
|
|
14034
|
+
chalk147.white(
|
|
13980
14035
|
` Moved ${path43.relative(process.cwd(), move.from)} \u2192 ${path43.relative(process.cwd(), move.to)}`
|
|
13981
14036
|
)
|
|
13982
14037
|
);
|
|
@@ -13991,7 +14046,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
13991
14046
|
if (entries.length === 0) {
|
|
13992
14047
|
fs23.rmdirSync(dir);
|
|
13993
14048
|
console.log(
|
|
13994
|
-
|
|
14049
|
+
chalk147.dim(
|
|
13995
14050
|
` Removed empty directory ${path43.relative(process.cwd(), dir)}`
|
|
13996
14051
|
)
|
|
13997
14052
|
);
|
|
@@ -14124,22 +14179,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
14124
14179
|
const targetPattern = pattern2 ?? "src";
|
|
14125
14180
|
const files = findSourceFiles2(targetPattern);
|
|
14126
14181
|
if (files.length === 0) {
|
|
14127
|
-
console.log(
|
|
14182
|
+
console.log(chalk148.yellow("No files found matching pattern"));
|
|
14128
14183
|
return;
|
|
14129
14184
|
}
|
|
14130
14185
|
const tsConfigPath = path46.resolve("tsconfig.json");
|
|
14131
14186
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
14132
14187
|
if (plan2.moves.length === 0) {
|
|
14133
|
-
console.log(
|
|
14188
|
+
console.log(chalk148.green("No restructuring needed"));
|
|
14134
14189
|
return;
|
|
14135
14190
|
}
|
|
14136
14191
|
displayPlan2(plan2);
|
|
14137
14192
|
if (options2.apply) {
|
|
14138
|
-
console.log(
|
|
14193
|
+
console.log(chalk148.bold("\nApplying changes..."));
|
|
14139
14194
|
executePlan(plan2);
|
|
14140
|
-
console.log(
|
|
14195
|
+
console.log(chalk148.green("\nRestructuring complete"));
|
|
14141
14196
|
} else {
|
|
14142
|
-
console.log(
|
|
14197
|
+
console.log(chalk148.dim("\nDry run. Use --apply to execute."));
|
|
14143
14198
|
}
|
|
14144
14199
|
}
|
|
14145
14200
|
|
|
@@ -14318,7 +14373,7 @@ import { execSync as execSync42 } from "child_process";
|
|
|
14318
14373
|
function fetchRawComments(org, repo, prNumber) {
|
|
14319
14374
|
const out = execSync42(
|
|
14320
14375
|
`gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
14321
|
-
{ encoding: "
|
|
14376
|
+
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
|
|
14322
14377
|
);
|
|
14323
14378
|
if (!out.trim()) return [];
|
|
14324
14379
|
return JSON.parse(out);
|
|
@@ -14355,7 +14410,7 @@ function fetchPrDiff(prNumber, baseSha, headSha) {
|
|
|
14355
14410
|
const { org, repo } = getRepoInfo();
|
|
14356
14411
|
try {
|
|
14357
14412
|
return execSync43(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
14358
|
-
encoding: "
|
|
14413
|
+
encoding: "utf8",
|
|
14359
14414
|
maxBuffer: 256 * 1024 * 1024,
|
|
14360
14415
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14361
14416
|
});
|
|
@@ -14373,7 +14428,7 @@ function fetchDiffViaGit(baseSha, headSha) {
|
|
|
14373
14428
|
} catch {
|
|
14374
14429
|
}
|
|
14375
14430
|
return execSync43(`git diff ${baseSha}...${headSha}`, {
|
|
14376
|
-
encoding: "
|
|
14431
|
+
encoding: "utf8",
|
|
14377
14432
|
maxBuffer: 256 * 1024 * 1024
|
|
14378
14433
|
});
|
|
14379
14434
|
}
|
|
@@ -14382,7 +14437,7 @@ function fetchDiffViaGit(baseSha, headSha) {
|
|
|
14382
14437
|
import { execSync as execSync44 } from "child_process";
|
|
14383
14438
|
function getCurrentBranch2() {
|
|
14384
14439
|
return execSync44("git rev-parse --abbrev-ref HEAD", {
|
|
14385
|
-
encoding: "
|
|
14440
|
+
encoding: "utf8"
|
|
14386
14441
|
}).trim();
|
|
14387
14442
|
}
|
|
14388
14443
|
function fetchPrDiffInfo() {
|
|
@@ -14392,7 +14447,7 @@ function fetchPrDiffInfo() {
|
|
|
14392
14447
|
let raw;
|
|
14393
14448
|
try {
|
|
14394
14449
|
raw = execSync44(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
|
|
14395
|
-
encoding: "
|
|
14450
|
+
encoding: "utf8",
|
|
14396
14451
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14397
14452
|
});
|
|
14398
14453
|
} catch (error) {
|
|
@@ -14418,7 +14473,7 @@ function fetchPrChangedFiles(prNumber) {
|
|
|
14418
14473
|
const out = execSync44(
|
|
14419
14474
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
|
|
14420
14475
|
{
|
|
14421
|
-
encoding: "
|
|
14476
|
+
encoding: "utf8",
|
|
14422
14477
|
maxBuffer: 64 * 1024 * 1024
|
|
14423
14478
|
}
|
|
14424
14479
|
);
|
|
@@ -14428,11 +14483,11 @@ function fetchPrChangedFiles(prNumber) {
|
|
|
14428
14483
|
// src/commands/review/gatherContext.ts
|
|
14429
14484
|
function gatherContext() {
|
|
14430
14485
|
const branch = execSync45("git rev-parse --abbrev-ref HEAD", {
|
|
14431
|
-
encoding: "
|
|
14486
|
+
encoding: "utf8"
|
|
14432
14487
|
}).trim();
|
|
14433
|
-
const sha = execSync45("git rev-parse HEAD", { encoding: "
|
|
14488
|
+
const sha = execSync45("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
14434
14489
|
const shortSha = execSync45("git rev-parse --short=7 HEAD", {
|
|
14435
|
-
encoding: "
|
|
14490
|
+
encoding: "utf8"
|
|
14436
14491
|
}).trim();
|
|
14437
14492
|
const prInfo = fetchPrDiffInfo();
|
|
14438
14493
|
const changedFiles = fetchPrChangedFiles(prInfo.prNumber);
|
|
@@ -14708,18 +14763,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
14708
14763
|
}
|
|
14709
14764
|
|
|
14710
14765
|
// src/commands/review/warnOutOfDiff.ts
|
|
14711
|
-
import
|
|
14766
|
+
import chalk149 from "chalk";
|
|
14712
14767
|
function warnOutOfDiff(outOfDiff) {
|
|
14713
14768
|
if (outOfDiff.length === 0) return;
|
|
14714
14769
|
console.warn(
|
|
14715
|
-
|
|
14770
|
+
chalk149.yellow(
|
|
14716
14771
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
14717
14772
|
)
|
|
14718
14773
|
);
|
|
14719
14774
|
for (const finding of outOfDiff) {
|
|
14720
14775
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
14721
14776
|
console.warn(
|
|
14722
|
-
` ${
|
|
14777
|
+
` ${chalk149.yellow("\xB7")} ${finding.title} ${chalk149.dim(
|
|
14723
14778
|
`(${finding.file}:${range})`
|
|
14724
14779
|
)}`
|
|
14725
14780
|
);
|
|
@@ -14738,18 +14793,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
14738
14793
|
}
|
|
14739
14794
|
|
|
14740
14795
|
// src/commands/review/warnUnlocated.ts
|
|
14741
|
-
import
|
|
14796
|
+
import chalk150 from "chalk";
|
|
14742
14797
|
function warnUnlocated(unlocated) {
|
|
14743
14798
|
if (unlocated.length === 0) return;
|
|
14744
14799
|
console.warn(
|
|
14745
|
-
|
|
14800
|
+
chalk150.yellow(
|
|
14746
14801
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
14747
14802
|
)
|
|
14748
14803
|
);
|
|
14749
14804
|
for (const finding of unlocated) {
|
|
14750
|
-
const where = finding.location ||
|
|
14805
|
+
const where = finding.location || chalk150.dim("missing");
|
|
14751
14806
|
console.warn(
|
|
14752
|
-
` ${
|
|
14807
|
+
` ${chalk150.yellow("\xB7")} ${finding.title} ${chalk150.dim(`(${where})`)}`
|
|
14753
14808
|
);
|
|
14754
14809
|
}
|
|
14755
14810
|
}
|
|
@@ -14762,7 +14817,7 @@ async function confirmPost(prNumber, count6, options2) {
|
|
|
14762
14817
|
async function postReviewToPr(synthesisPath, options2) {
|
|
14763
14818
|
const prInfo = fetchPrDiffInfo();
|
|
14764
14819
|
const prNumber = prInfo.prNumber;
|
|
14765
|
-
const markdown = readFileSync29(synthesisPath, "
|
|
14820
|
+
const markdown = readFileSync29(synthesisPath, "utf8");
|
|
14766
14821
|
const findings = parseFindings(markdown);
|
|
14767
14822
|
if (findings.length === 0) {
|
|
14768
14823
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -15344,7 +15399,7 @@ function flushBuffer(buffer, onLine) {
|
|
|
15344
15399
|
function attachLineParser(child, onLine) {
|
|
15345
15400
|
let buffer = "";
|
|
15346
15401
|
child.stdout?.on("data", (chunk) => {
|
|
15347
|
-
buffer += chunk.toString("
|
|
15402
|
+
buffer += chunk.toString("utf8");
|
|
15348
15403
|
buffer = flushBuffer(buffer, onLine);
|
|
15349
15404
|
});
|
|
15350
15405
|
return () => {
|
|
@@ -15356,7 +15411,7 @@ function attachLineParser(child, onLine) {
|
|
|
15356
15411
|
function attachStderrCollector(child) {
|
|
15357
15412
|
const state = { value: "" };
|
|
15358
15413
|
child.stderr?.on("data", (chunk) => {
|
|
15359
|
-
state.value += chunk.toString("
|
|
15414
|
+
state.value += chunk.toString("utf8");
|
|
15360
15415
|
});
|
|
15361
15416
|
return state;
|
|
15362
15417
|
}
|
|
@@ -15365,7 +15420,7 @@ function attachStderrCollector(child) {
|
|
|
15365
15420
|
function attachStdoutTail(child, maxBytes = 8192) {
|
|
15366
15421
|
const state = { value: "" };
|
|
15367
15422
|
child.stdout?.on("data", (chunk) => {
|
|
15368
|
-
state.value += chunk.toString("
|
|
15423
|
+
state.value += chunk.toString("utf8");
|
|
15369
15424
|
if (state.value.length > maxBytes) {
|
|
15370
15425
|
state.value = state.value.slice(state.value.length - maxBytes);
|
|
15371
15426
|
}
|
|
@@ -15702,7 +15757,7 @@ Files:
|
|
|
15702
15757
|
|
|
15703
15758
|
// src/commands/review/synthesise.ts
|
|
15704
15759
|
function printSummary2(synthesisPath) {
|
|
15705
|
-
const markdown = readFileSync30(synthesisPath, "
|
|
15760
|
+
const markdown = readFileSync30(synthesisPath, "utf8");
|
|
15706
15761
|
console.log("");
|
|
15707
15762
|
console.log(buildReviewSummary(markdown));
|
|
15708
15763
|
console.log("");
|
|
@@ -15797,9 +15852,9 @@ async function runReviewPipeline(paths, options2) {
|
|
|
15797
15852
|
finishUi(ui, outcome.ok);
|
|
15798
15853
|
reportFailures(outcome.failures, ui.multi !== void 0);
|
|
15799
15854
|
return outcome.ok;
|
|
15800
|
-
} catch (
|
|
15855
|
+
} catch (error) {
|
|
15801
15856
|
ui.multi?.failRemaining();
|
|
15802
|
-
throw
|
|
15857
|
+
throw error;
|
|
15803
15858
|
}
|
|
15804
15859
|
}
|
|
15805
15860
|
|
|
@@ -15920,7 +15975,7 @@ function registerReview(program2) {
|
|
|
15920
15975
|
}
|
|
15921
15976
|
|
|
15922
15977
|
// src/commands/seq/seqAuth.ts
|
|
15923
|
-
import
|
|
15978
|
+
import chalk152 from "chalk";
|
|
15924
15979
|
|
|
15925
15980
|
// src/commands/seq/loadConnections.ts
|
|
15926
15981
|
function loadConnections2() {
|
|
@@ -15949,10 +16004,10 @@ function setDefaultConnection(name) {
|
|
|
15949
16004
|
}
|
|
15950
16005
|
|
|
15951
16006
|
// src/shared/assertUniqueName.ts
|
|
15952
|
-
import
|
|
16007
|
+
import chalk151 from "chalk";
|
|
15953
16008
|
function assertUniqueName(existingNames, name) {
|
|
15954
16009
|
if (existingNames.includes(name)) {
|
|
15955
|
-
console.error(
|
|
16010
|
+
console.error(chalk151.red(`Connection "${name}" already exists.`));
|
|
15956
16011
|
process.exit(1);
|
|
15957
16012
|
}
|
|
15958
16013
|
}
|
|
@@ -15970,16 +16025,16 @@ async function promptConnection2(existingNames) {
|
|
|
15970
16025
|
var seqAuth = createConnectionAuth({
|
|
15971
16026
|
load: loadConnections2,
|
|
15972
16027
|
save: saveConnections2,
|
|
15973
|
-
format: (c) => `${
|
|
16028
|
+
format: (c) => `${chalk152.bold(c.name)} ${c.url}`,
|
|
15974
16029
|
promptNew: promptConnection2,
|
|
15975
16030
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
15976
16031
|
});
|
|
15977
16032
|
|
|
15978
16033
|
// src/commands/seq/seqQuery.ts
|
|
15979
|
-
import
|
|
16034
|
+
import chalk156 from "chalk";
|
|
15980
16035
|
|
|
15981
16036
|
// src/commands/seq/fetchSeq.ts
|
|
15982
|
-
import
|
|
16037
|
+
import chalk153 from "chalk";
|
|
15983
16038
|
async function fetchSeq(conn, path56, params) {
|
|
15984
16039
|
const url = `${conn.url}${path56}?${params}`;
|
|
15985
16040
|
const response = await fetch(url, {
|
|
@@ -15990,7 +16045,7 @@ async function fetchSeq(conn, path56, params) {
|
|
|
15990
16045
|
});
|
|
15991
16046
|
if (!response.ok) {
|
|
15992
16047
|
const body = await response.text();
|
|
15993
|
-
console.error(
|
|
16048
|
+
console.error(chalk153.red(`Seq returned ${response.status}: ${body}`));
|
|
15994
16049
|
process.exit(1);
|
|
15995
16050
|
}
|
|
15996
16051
|
return response;
|
|
@@ -16049,23 +16104,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
16049
16104
|
}
|
|
16050
16105
|
|
|
16051
16106
|
// src/commands/seq/formatEvent.ts
|
|
16052
|
-
import
|
|
16107
|
+
import chalk154 from "chalk";
|
|
16053
16108
|
function levelColor(level) {
|
|
16054
16109
|
switch (level) {
|
|
16055
16110
|
case "Fatal":
|
|
16056
|
-
return
|
|
16111
|
+
return chalk154.bgRed.white;
|
|
16057
16112
|
case "Error":
|
|
16058
|
-
return
|
|
16113
|
+
return chalk154.red;
|
|
16059
16114
|
case "Warning":
|
|
16060
|
-
return
|
|
16115
|
+
return chalk154.yellow;
|
|
16061
16116
|
case "Information":
|
|
16062
|
-
return
|
|
16117
|
+
return chalk154.cyan;
|
|
16063
16118
|
case "Debug":
|
|
16064
|
-
return
|
|
16119
|
+
return chalk154.gray;
|
|
16065
16120
|
case "Verbose":
|
|
16066
|
-
return
|
|
16121
|
+
return chalk154.dim;
|
|
16067
16122
|
default:
|
|
16068
|
-
return
|
|
16123
|
+
return chalk154.white;
|
|
16069
16124
|
}
|
|
16070
16125
|
}
|
|
16071
16126
|
function levelAbbrev(level) {
|
|
@@ -16106,12 +16161,12 @@ function formatTimestamp(iso) {
|
|
|
16106
16161
|
function formatEvent(event) {
|
|
16107
16162
|
const color = levelColor(event.Level);
|
|
16108
16163
|
const abbrev = levelAbbrev(event.Level);
|
|
16109
|
-
const ts8 =
|
|
16164
|
+
const ts8 = chalk154.dim(formatTimestamp(event.Timestamp));
|
|
16110
16165
|
const msg = renderMessage(event);
|
|
16111
16166
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
16112
16167
|
if (event.Exception) {
|
|
16113
16168
|
for (const line of event.Exception.split("\n")) {
|
|
16114
|
-
lines.push(
|
|
16169
|
+
lines.push(chalk154.red(` ${line}`));
|
|
16115
16170
|
}
|
|
16116
16171
|
}
|
|
16117
16172
|
return lines.join("\n");
|
|
@@ -16144,11 +16199,11 @@ function rejectTimestampFilter(filter) {
|
|
|
16144
16199
|
}
|
|
16145
16200
|
|
|
16146
16201
|
// src/shared/resolveNamedConnection.ts
|
|
16147
|
-
import
|
|
16202
|
+
import chalk155 from "chalk";
|
|
16148
16203
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
16149
16204
|
if (connections.length === 0) {
|
|
16150
16205
|
console.error(
|
|
16151
|
-
|
|
16206
|
+
chalk155.red(
|
|
16152
16207
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
16153
16208
|
)
|
|
16154
16209
|
);
|
|
@@ -16157,7 +16212,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
16157
16212
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
16158
16213
|
const connection = connections.find((c) => c.name === target);
|
|
16159
16214
|
if (!connection) {
|
|
16160
|
-
console.error(
|
|
16215
|
+
console.error(chalk155.red(`${kind} connection "${target}" not found.`));
|
|
16161
16216
|
process.exit(1);
|
|
16162
16217
|
}
|
|
16163
16218
|
return connection;
|
|
@@ -16186,7 +16241,7 @@ async function seqQuery(filter, options2) {
|
|
|
16186
16241
|
new URLSearchParams({ filter, count: String(count6) })
|
|
16187
16242
|
);
|
|
16188
16243
|
if (events.length === 0) {
|
|
16189
|
-
console.log(
|
|
16244
|
+
console.log(chalk156.yellow("No events found."));
|
|
16190
16245
|
return;
|
|
16191
16246
|
}
|
|
16192
16247
|
if (options2.json) {
|
|
@@ -16197,11 +16252,11 @@ async function seqQuery(filter, options2) {
|
|
|
16197
16252
|
for (const event of chronological) {
|
|
16198
16253
|
console.log(formatEvent(event));
|
|
16199
16254
|
}
|
|
16200
|
-
console.log(
|
|
16255
|
+
console.log(chalk156.dim(`
|
|
16201
16256
|
${events.length} events`));
|
|
16202
16257
|
if (events.length >= count6) {
|
|
16203
16258
|
console.log(
|
|
16204
|
-
|
|
16259
|
+
chalk156.yellow(
|
|
16205
16260
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
16206
16261
|
)
|
|
16207
16262
|
);
|
|
@@ -16209,10 +16264,10 @@ ${events.length} events`));
|
|
|
16209
16264
|
}
|
|
16210
16265
|
|
|
16211
16266
|
// src/shared/setNamedDefaultConnection.ts
|
|
16212
|
-
import
|
|
16267
|
+
import chalk157 from "chalk";
|
|
16213
16268
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
16214
16269
|
if (!connections.find((c) => c.name === name)) {
|
|
16215
|
-
console.error(
|
|
16270
|
+
console.error(chalk157.red(`Connection "${name}" not found.`));
|
|
16216
16271
|
process.exit(1);
|
|
16217
16272
|
}
|
|
16218
16273
|
setDefault(name);
|
|
@@ -16260,7 +16315,7 @@ function registerSignal(program2) {
|
|
|
16260
16315
|
}
|
|
16261
16316
|
|
|
16262
16317
|
// src/commands/sql/sqlAuth.ts
|
|
16263
|
-
import
|
|
16318
|
+
import chalk159 from "chalk";
|
|
16264
16319
|
|
|
16265
16320
|
// src/commands/sql/loadConnections.ts
|
|
16266
16321
|
function loadConnections3() {
|
|
@@ -16289,7 +16344,7 @@ function setDefaultConnection2(name) {
|
|
|
16289
16344
|
}
|
|
16290
16345
|
|
|
16291
16346
|
// src/commands/sql/promptConnection.ts
|
|
16292
|
-
import
|
|
16347
|
+
import chalk158 from "chalk";
|
|
16293
16348
|
async function promptConnection3(existingNames) {
|
|
16294
16349
|
const name = await promptInput("name", "Connection name:", "default");
|
|
16295
16350
|
assertUniqueName(existingNames, name);
|
|
@@ -16297,7 +16352,7 @@ async function promptConnection3(existingNames) {
|
|
|
16297
16352
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
16298
16353
|
const port = Number.parseInt(portStr, 10);
|
|
16299
16354
|
if (!Number.isFinite(port)) {
|
|
16300
|
-
console.error(
|
|
16355
|
+
console.error(chalk158.red(`Invalid port "${portStr}".`));
|
|
16301
16356
|
process.exit(1);
|
|
16302
16357
|
}
|
|
16303
16358
|
const user = await promptInput("user", "User:");
|
|
@@ -16310,13 +16365,13 @@ async function promptConnection3(existingNames) {
|
|
|
16310
16365
|
var sqlAuth = createConnectionAuth({
|
|
16311
16366
|
load: loadConnections3,
|
|
16312
16367
|
save: saveConnections3,
|
|
16313
|
-
format: (c) => `${
|
|
16368
|
+
format: (c) => `${chalk159.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
16314
16369
|
promptNew: promptConnection3,
|
|
16315
16370
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
16316
16371
|
});
|
|
16317
16372
|
|
|
16318
16373
|
// src/commands/sql/printTable.ts
|
|
16319
|
-
import
|
|
16374
|
+
import chalk160 from "chalk";
|
|
16320
16375
|
function formatCell(value) {
|
|
16321
16376
|
if (value === null || value === void 0) return "";
|
|
16322
16377
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -16325,7 +16380,7 @@ function formatCell(value) {
|
|
|
16325
16380
|
}
|
|
16326
16381
|
function printTable(rows) {
|
|
16327
16382
|
if (rows.length === 0) {
|
|
16328
|
-
console.log(
|
|
16383
|
+
console.log(chalk160.yellow("(no rows)"));
|
|
16329
16384
|
return;
|
|
16330
16385
|
}
|
|
16331
16386
|
const columns = Object.keys(rows[0]);
|
|
@@ -16333,13 +16388,13 @@ function printTable(rows) {
|
|
|
16333
16388
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
16334
16389
|
);
|
|
16335
16390
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
16336
|
-
console.log(
|
|
16337
|
-
console.log(
|
|
16391
|
+
console.log(chalk160.dim(header));
|
|
16392
|
+
console.log(chalk160.dim("-".repeat(header.length)));
|
|
16338
16393
|
for (const row of rows) {
|
|
16339
16394
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
16340
16395
|
console.log(line);
|
|
16341
16396
|
}
|
|
16342
|
-
console.log(
|
|
16397
|
+
console.log(chalk160.dim(`
|
|
16343
16398
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
16344
16399
|
}
|
|
16345
16400
|
|
|
@@ -16399,7 +16454,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
16399
16454
|
}
|
|
16400
16455
|
|
|
16401
16456
|
// src/commands/sql/sqlMutate.ts
|
|
16402
|
-
import
|
|
16457
|
+
import chalk161 from "chalk";
|
|
16403
16458
|
|
|
16404
16459
|
// src/commands/sql/isMutation.ts
|
|
16405
16460
|
var MUTATION_KEYWORDS = [
|
|
@@ -16433,7 +16488,7 @@ function isMutation(sql5) {
|
|
|
16433
16488
|
async function sqlMutate(query, connectionName) {
|
|
16434
16489
|
if (!isMutation(query)) {
|
|
16435
16490
|
console.error(
|
|
16436
|
-
|
|
16491
|
+
chalk161.red(
|
|
16437
16492
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
16438
16493
|
)
|
|
16439
16494
|
);
|
|
@@ -16443,18 +16498,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
16443
16498
|
const pool = await sqlConnect(conn);
|
|
16444
16499
|
try {
|
|
16445
16500
|
const result = await pool.request().query(query);
|
|
16446
|
-
console.log(
|
|
16501
|
+
console.log(chalk161.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
16447
16502
|
} finally {
|
|
16448
16503
|
await pool.close();
|
|
16449
16504
|
}
|
|
16450
16505
|
}
|
|
16451
16506
|
|
|
16452
16507
|
// src/commands/sql/sqlQuery.ts
|
|
16453
|
-
import
|
|
16508
|
+
import chalk162 from "chalk";
|
|
16454
16509
|
async function sqlQuery(query, connectionName) {
|
|
16455
16510
|
if (isMutation(query)) {
|
|
16456
16511
|
console.error(
|
|
16457
|
-
|
|
16512
|
+
chalk162.red(
|
|
16458
16513
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
16459
16514
|
)
|
|
16460
16515
|
);
|
|
@@ -16469,7 +16524,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
16469
16524
|
printTable(rows);
|
|
16470
16525
|
} else {
|
|
16471
16526
|
console.log(
|
|
16472
|
-
|
|
16527
|
+
chalk162.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
16473
16528
|
);
|
|
16474
16529
|
}
|
|
16475
16530
|
} finally {
|
|
@@ -16964,10 +17019,10 @@ function logReduction(cueCount, messageCount) {
|
|
|
16964
17019
|
}
|
|
16965
17020
|
function readAndParseCues(inputPath) {
|
|
16966
17021
|
console.log(`Reading: ${inputPath}`);
|
|
16967
|
-
return processCues(readFileSync31(inputPath, "
|
|
17022
|
+
return processCues(readFileSync31(inputPath, "utf8"));
|
|
16968
17023
|
}
|
|
16969
17024
|
function writeFormatted(outputPath, content) {
|
|
16970
|
-
writeFileSync28(outputPath, content, "
|
|
17025
|
+
writeFileSync28(outputPath, content, "utf8");
|
|
16971
17026
|
console.log(`Written: ${outputPath}`);
|
|
16972
17027
|
}
|
|
16973
17028
|
function convertVttToMarkdown(inputPath, outputPath) {
|
|
@@ -17049,14 +17104,14 @@ import {
|
|
|
17049
17104
|
import { dirname as dirname22, join as join42 } from "path";
|
|
17050
17105
|
|
|
17051
17106
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
17052
|
-
import
|
|
17107
|
+
import chalk163 from "chalk";
|
|
17053
17108
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
17054
17109
|
function validateStagedContent(filename, content) {
|
|
17055
17110
|
const firstLine = content.split("\n")[0];
|
|
17056
17111
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
17057
17112
|
if (!match) {
|
|
17058
17113
|
console.error(
|
|
17059
|
-
|
|
17114
|
+
chalk163.red(
|
|
17060
17115
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
17061
17116
|
)
|
|
17062
17117
|
);
|
|
@@ -17065,7 +17120,7 @@ function validateStagedContent(filename, content) {
|
|
|
17065
17120
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
17066
17121
|
if (!contentAfterLink) {
|
|
17067
17122
|
console.error(
|
|
17068
|
-
|
|
17123
|
+
chalk163.red(
|
|
17069
17124
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
17070
17125
|
)
|
|
17071
17126
|
);
|
|
@@ -17086,7 +17141,7 @@ function processStagedFile() {
|
|
|
17086
17141
|
}
|
|
17087
17142
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
17088
17143
|
const stagedFile = stagedFiles[0];
|
|
17089
|
-
const content = readFileSync32(stagedFile.absolutePath, "
|
|
17144
|
+
const content = readFileSync32(stagedFile.absolutePath, "utf8");
|
|
17090
17145
|
validateStagedContent(stagedFile.filename, content);
|
|
17091
17146
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
17092
17147
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -17243,7 +17298,7 @@ function logs(options2) {
|
|
|
17243
17298
|
return;
|
|
17244
17299
|
}
|
|
17245
17300
|
const count6 = Number.parseInt(options2.lines ?? "150", 10);
|
|
17246
|
-
const content = readFileSync33(voicePaths.log, "
|
|
17301
|
+
const content = readFileSync33(voicePaths.log, "utf8").trim();
|
|
17247
17302
|
if (!content) {
|
|
17248
17303
|
console.log("Voice log is empty");
|
|
17249
17304
|
return;
|
|
@@ -17284,7 +17339,7 @@ function checkLockFile() {
|
|
|
17284
17339
|
const lockFile = getLockFile();
|
|
17285
17340
|
if (!existsSync43(lockFile)) return;
|
|
17286
17341
|
try {
|
|
17287
|
-
const lock = JSON.parse(readFileSync34(lockFile, "
|
|
17342
|
+
const lock = JSON.parse(readFileSync34(lockFile, "utf8"));
|
|
17288
17343
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
17289
17344
|
console.error(
|
|
17290
17345
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -17397,7 +17452,7 @@ function isProcessAlive3(pid) {
|
|
|
17397
17452
|
}
|
|
17398
17453
|
function readRecentLogs(count6) {
|
|
17399
17454
|
if (!existsSync44(voicePaths.log)) return [];
|
|
17400
|
-
const lines = readFileSync35(voicePaths.log, "
|
|
17455
|
+
const lines = readFileSync35(voicePaths.log, "utf8").trim().split("\n");
|
|
17401
17456
|
return lines.slice(-count6);
|
|
17402
17457
|
}
|
|
17403
17458
|
function status() {
|
|
@@ -17405,7 +17460,7 @@ function status() {
|
|
|
17405
17460
|
console.log("Voice daemon: not running (no PID file)");
|
|
17406
17461
|
return;
|
|
17407
17462
|
}
|
|
17408
|
-
const pid = Number.parseInt(readFileSync35(voicePaths.pid, "
|
|
17463
|
+
const pid = Number.parseInt(readFileSync35(voicePaths.pid, "utf8").trim(), 10);
|
|
17409
17464
|
const alive = isProcessAlive3(pid);
|
|
17410
17465
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
17411
17466
|
const recent = readRecentLogs(5);
|
|
@@ -17430,7 +17485,7 @@ function stop2() {
|
|
|
17430
17485
|
console.log("Voice daemon is not running (no PID file)");
|
|
17431
17486
|
return;
|
|
17432
17487
|
}
|
|
17433
|
-
const pid = Number.parseInt(readFileSync36(voicePaths.pid, "
|
|
17488
|
+
const pid = Number.parseInt(readFileSync36(voicePaths.pid, "utf8").trim(), 10);
|
|
17434
17489
|
try {
|
|
17435
17490
|
process.kill(pid, "SIGTERM");
|
|
17436
17491
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -17462,7 +17517,7 @@ function registerVoice(program2) {
|
|
|
17462
17517
|
|
|
17463
17518
|
// src/commands/roam/auth.ts
|
|
17464
17519
|
import { randomBytes } from "crypto";
|
|
17465
|
-
import
|
|
17520
|
+
import chalk164 from "chalk";
|
|
17466
17521
|
|
|
17467
17522
|
// src/commands/roam/waitForCallback.ts
|
|
17468
17523
|
import { createServer as createServer2 } from "http";
|
|
@@ -17501,10 +17556,10 @@ function waitForCallback(port, expectedState) {
|
|
|
17501
17556
|
respondHtml(res, 200, "Authorization successful!");
|
|
17502
17557
|
server.close();
|
|
17503
17558
|
resolve16(code);
|
|
17504
|
-
} catch (
|
|
17505
|
-
respondHtml(res, 400,
|
|
17559
|
+
} catch (error) {
|
|
17560
|
+
respondHtml(res, 400, error.message);
|
|
17506
17561
|
server.close();
|
|
17507
|
-
reject(
|
|
17562
|
+
reject(error);
|
|
17508
17563
|
}
|
|
17509
17564
|
});
|
|
17510
17565
|
server.listen(port);
|
|
@@ -17593,13 +17648,13 @@ async function auth() {
|
|
|
17593
17648
|
saveGlobalConfig(config);
|
|
17594
17649
|
const state = randomBytes(16).toString("hex");
|
|
17595
17650
|
console.log(
|
|
17596
|
-
|
|
17651
|
+
chalk164.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
17597
17652
|
);
|
|
17598
|
-
console.log(
|
|
17599
|
-
console.log(
|
|
17600
|
-
console.log(
|
|
17653
|
+
console.log(chalk164.white("http://localhost:14523/callback\n"));
|
|
17654
|
+
console.log(chalk164.blue("Opening browser for authorization..."));
|
|
17655
|
+
console.log(chalk164.dim("Waiting for authorization callback..."));
|
|
17601
17656
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
17602
|
-
console.log(
|
|
17657
|
+
console.log(chalk164.dim("Exchanging code for tokens..."));
|
|
17603
17658
|
const tokens = await exchangeToken({
|
|
17604
17659
|
code,
|
|
17605
17660
|
clientId,
|
|
@@ -17615,7 +17670,7 @@ async function auth() {
|
|
|
17615
17670
|
};
|
|
17616
17671
|
saveGlobalConfig(config);
|
|
17617
17672
|
console.log(
|
|
17618
|
-
|
|
17673
|
+
chalk164.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
17619
17674
|
);
|
|
17620
17675
|
}
|
|
17621
17676
|
|
|
@@ -17647,7 +17702,7 @@ function postRoamActivity(app, event) {
|
|
|
17647
17702
|
if (!portFile) return;
|
|
17648
17703
|
let port;
|
|
17649
17704
|
try {
|
|
17650
|
-
port = readFileSync37(portFile, "
|
|
17705
|
+
port = readFileSync37(portFile, "utf8").trim();
|
|
17651
17706
|
} catch {
|
|
17652
17707
|
return;
|
|
17653
17708
|
}
|
|
@@ -17780,8 +17835,8 @@ function runPreCommands(pre, cwd) {
|
|
|
17780
17835
|
for (const cmd of pre) {
|
|
17781
17836
|
try {
|
|
17782
17837
|
execSync47(cmd, { stdio: "inherit", cwd });
|
|
17783
|
-
} catch (
|
|
17784
|
-
const code =
|
|
17838
|
+
} catch (error) {
|
|
17839
|
+
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
17785
17840
|
process.exit(code);
|
|
17786
17841
|
}
|
|
17787
17842
|
}
|
|
@@ -18067,7 +18122,7 @@ import { execSync as execSync48 } from "child_process";
|
|
|
18067
18122
|
import { existsSync as existsSync48, mkdirSync as mkdirSync20, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
|
|
18068
18123
|
import { tmpdir as tmpdir7 } from "os";
|
|
18069
18124
|
import { join as join53, resolve as resolve13 } from "path";
|
|
18070
|
-
import
|
|
18125
|
+
import chalk165 from "chalk";
|
|
18071
18126
|
|
|
18072
18127
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
18073
18128
|
var captureWindowPs1 = `
|
|
@@ -18204,11 +18259,11 @@ function buildOutputPath(outputDir, processName) {
|
|
|
18204
18259
|
}
|
|
18205
18260
|
function runPowerShellScript(processName, outputPath) {
|
|
18206
18261
|
const scriptPath = join53(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
18207
|
-
writeFileSync32(scriptPath, captureWindowPs1, "
|
|
18262
|
+
writeFileSync32(scriptPath, captureWindowPs1, "utf8");
|
|
18208
18263
|
try {
|
|
18209
18264
|
execSync48(
|
|
18210
18265
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
18211
|
-
{ stdio: ["ignore", "pipe", "pipe"], encoding: "
|
|
18266
|
+
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
|
|
18212
18267
|
);
|
|
18213
18268
|
} finally {
|
|
18214
18269
|
unlinkSync17(scriptPath);
|
|
@@ -18218,13 +18273,13 @@ function screenshot(processName) {
|
|
|
18218
18273
|
const config = loadConfig();
|
|
18219
18274
|
const outputDir = resolve13(config.screenshot.outputDir);
|
|
18220
18275
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
18221
|
-
console.log(
|
|
18276
|
+
console.log(chalk165.gray(`Capturing window for process "${processName}" ...`));
|
|
18222
18277
|
try {
|
|
18223
18278
|
runPowerShellScript(processName, outputPath);
|
|
18224
|
-
console.log(
|
|
18279
|
+
console.log(chalk165.green(`Screenshot saved: ${outputPath}`));
|
|
18225
18280
|
} catch (error) {
|
|
18226
18281
|
const msg = error instanceof Error ? error.message : String(error);
|
|
18227
|
-
console.error(
|
|
18282
|
+
console.error(chalk165.red(`Failed to capture screenshot: ${msg}`));
|
|
18228
18283
|
process.exit(1);
|
|
18229
18284
|
}
|
|
18230
18285
|
}
|
|
@@ -18235,7 +18290,7 @@ function listDaemonPids() {
|
|
|
18235
18290
|
if (process.platform === "win32") return [];
|
|
18236
18291
|
try {
|
|
18237
18292
|
const out = execFileSync9("ps", ["-eo", "pid=,args="], {
|
|
18238
|
-
encoding: "
|
|
18293
|
+
encoding: "utf8"
|
|
18239
18294
|
});
|
|
18240
18295
|
return out.split("\n").filter((line) => line.includes("assist") && / daemon run\b/.test(line)).map((line) => Number.parseInt(line.trim(), 10)).filter((pid) => Number.isInteger(pid));
|
|
18241
18296
|
} catch {
|
|
@@ -18292,7 +18347,7 @@ function reportStolenSocket(socketPid) {
|
|
|
18292
18347
|
function readPidFile() {
|
|
18293
18348
|
try {
|
|
18294
18349
|
const pid = Number.parseInt(
|
|
18295
|
-
readFileSync38(daemonPaths.pid, "
|
|
18350
|
+
readFileSync38(daemonPaths.pid, "utf8").trim(),
|
|
18296
18351
|
10
|
|
18297
18352
|
);
|
|
18298
18353
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -18509,7 +18564,7 @@ function spawnPty(args, cwd, sessionId) {
|
|
|
18509
18564
|
});
|
|
18510
18565
|
}
|
|
18511
18566
|
function shellEscape(s) {
|
|
18512
|
-
return `'${s.replace(/'/g,
|
|
18567
|
+
return `'${s.replace(/'/g, String.raw`'\''`)}'`;
|
|
18513
18568
|
}
|
|
18514
18569
|
|
|
18515
18570
|
// src/commands/sessions/daemon/createAssistSession.ts
|
|
@@ -18838,8 +18893,8 @@ async function autoHealWindowsDaemon(conn, state, heal, version2) {
|
|
|
18838
18893
|
await heal();
|
|
18839
18894
|
daemonLog("windows proxy: heal complete, reconnecting to windows daemon");
|
|
18840
18895
|
await conn.ensure();
|
|
18841
|
-
} catch (
|
|
18842
|
-
const message =
|
|
18896
|
+
} catch (error) {
|
|
18897
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18843
18898
|
daemonLog(`windows proxy: auto-heal failed: ${message}`);
|
|
18844
18899
|
state.broadcast({
|
|
18845
18900
|
type: "error",
|
|
@@ -18888,6 +18943,18 @@ async function isWindowsDaemonRunning() {
|
|
|
18888
18943
|
|
|
18889
18944
|
// src/commands/sessions/daemon/ensureWindowsDaemonRunning.ts
|
|
18890
18945
|
import { spawn as spawn10 } from "child_process";
|
|
18946
|
+
|
|
18947
|
+
// src/commands/sessions/daemon/logChildStream.ts
|
|
18948
|
+
import { createInterface as createInterface5 } from "readline";
|
|
18949
|
+
function logChildStream(stream, label2) {
|
|
18950
|
+
if (!stream) return;
|
|
18951
|
+
const lines = createInterface5({ input: stream });
|
|
18952
|
+
lines.on("line", (line) => daemonLog(`[${label2}] ${line}`));
|
|
18953
|
+
lines.on("error", () => {
|
|
18954
|
+
});
|
|
18955
|
+
}
|
|
18956
|
+
|
|
18957
|
+
// src/commands/sessions/daemon/ensureWindowsDaemonRunning.ts
|
|
18891
18958
|
var SPAWN_TIMEOUT_MS2 = 3e4;
|
|
18892
18959
|
var RETRY_DELAY_MS2 = 300;
|
|
18893
18960
|
async function ensureWindowsDaemonRunning() {
|
|
@@ -18902,12 +18969,18 @@ async function ensureWindowsDaemonRunning() {
|
|
|
18902
18969
|
function launchWindowsDaemon() {
|
|
18903
18970
|
const child = spawn10("pwsh.exe", ["-Command", "assist daemon run"], {
|
|
18904
18971
|
detached: true,
|
|
18905
|
-
stdio: "ignore"
|
|
18972
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
18906
18973
|
});
|
|
18974
|
+
logChildStream(child.stdout, "windows daemon run");
|
|
18975
|
+
logChildStream(child.stderr, "windows daemon run");
|
|
18907
18976
|
child.on(
|
|
18908
18977
|
"error",
|
|
18909
18978
|
(e) => daemonLog(`failed to launch windows daemon: ${e.message}`)
|
|
18910
18979
|
);
|
|
18980
|
+
child.on("exit", (code) => {
|
|
18981
|
+
if (code !== 0)
|
|
18982
|
+
daemonLog(`windows daemon launch exited early with code ${code}`);
|
|
18983
|
+
});
|
|
18911
18984
|
child.unref();
|
|
18912
18985
|
}
|
|
18913
18986
|
async function waitForWindowsDaemon() {
|
|
@@ -18947,8 +19020,8 @@ async function discoverWindowsSessions(conn) {
|
|
|
18947
19020
|
daemonLog("windows proxy: discovering sessions on running windows daemon");
|
|
18948
19021
|
try {
|
|
18949
19022
|
await conn.ensure();
|
|
18950
|
-
} catch (
|
|
18951
|
-
const message =
|
|
19023
|
+
} catch (error) {
|
|
19024
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18952
19025
|
daemonLog(`windows proxy: discovery failed: ${message}`);
|
|
18953
19026
|
}
|
|
18954
19027
|
}
|
|
@@ -18961,8 +19034,8 @@ async function forwardWindowsCreate(conn, state, client, data) {
|
|
|
18961
19034
|
daemonLog("windows proxy: connection ready, forwarding create");
|
|
18962
19035
|
state.pendingCreators.push(client);
|
|
18963
19036
|
conn.write(data);
|
|
18964
|
-
} catch (
|
|
18965
|
-
const message =
|
|
19037
|
+
} catch (error) {
|
|
19038
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18966
19039
|
daemonLog(`windows proxy: forwardCreate failed: ${message}`);
|
|
18967
19040
|
sendTo(client, {
|
|
18968
19041
|
type: "error",
|
|
@@ -19077,12 +19150,19 @@ function nsId(msg) {
|
|
|
19077
19150
|
|
|
19078
19151
|
// src/commands/sessions/daemon/healWindowsDaemon.ts
|
|
19079
19152
|
import { spawn as spawn11 } from "child_process";
|
|
19080
|
-
import { createInterface as createInterface5 } from "readline";
|
|
19081
19153
|
var UPDATE_TIMEOUT_MS = 5 * 6e4;
|
|
19082
19154
|
var STOP_TIMEOUT_MS2 = 3e4;
|
|
19083
19155
|
async function healWindowsDaemon() {
|
|
19084
19156
|
daemonLog("windows daemon: auto-heal: running `assist update` on host");
|
|
19085
|
-
|
|
19157
|
+
try {
|
|
19158
|
+
await runOnWindowsHost("assist update", UPDATE_TIMEOUT_MS);
|
|
19159
|
+
} catch (error) {
|
|
19160
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19161
|
+
daemonLog(
|
|
19162
|
+
`windows daemon: auto-heal: \`assist update\` failed: ${message}`
|
|
19163
|
+
);
|
|
19164
|
+
throw error;
|
|
19165
|
+
}
|
|
19086
19166
|
daemonLog("windows daemon: auto-heal: update done, stopping stale daemon");
|
|
19087
19167
|
await runOnWindowsHost("assist daemon stop", STOP_TIMEOUT_MS2);
|
|
19088
19168
|
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
@@ -19092,8 +19172,8 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
19092
19172
|
const child = spawn11("pwsh.exe", ["-Command", command], {
|
|
19093
19173
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19094
19174
|
});
|
|
19095
|
-
|
|
19096
|
-
|
|
19175
|
+
logChildStream(child.stdout, `windows ${command}`);
|
|
19176
|
+
logChildStream(child.stderr, `windows ${command}`);
|
|
19097
19177
|
const timer = setTimeout(() => {
|
|
19098
19178
|
child.kill();
|
|
19099
19179
|
reject(
|
|
@@ -19118,13 +19198,6 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
19118
19198
|
});
|
|
19119
19199
|
});
|
|
19120
19200
|
}
|
|
19121
|
-
function logStream(stream, command) {
|
|
19122
|
-
if (!stream) return;
|
|
19123
|
-
const lines = createInterface5({ input: stream });
|
|
19124
|
-
lines.on("line", (line) => daemonLog(`[windows ${command}] ${line}`));
|
|
19125
|
-
lines.on("error", () => {
|
|
19126
|
-
});
|
|
19127
|
-
}
|
|
19128
19201
|
|
|
19129
19202
|
// src/commands/sessions/daemon/isWindowsCwd.ts
|
|
19130
19203
|
function isWindowsCwd(cwd) {
|
|
@@ -19144,24 +19217,62 @@ function isWindowsIo(data) {
|
|
|
19144
19217
|
|
|
19145
19218
|
// src/commands/sessions/daemon/WindowsConnection.ts
|
|
19146
19219
|
import { createInterface as createInterface6 } from "readline";
|
|
19220
|
+
|
|
19221
|
+
// src/commands/sessions/daemon/LaunchCircuitBreaker.ts
|
|
19222
|
+
var MAX_FAILURES = 3;
|
|
19223
|
+
var BACKOFF_MS = 6e4;
|
|
19224
|
+
var LaunchCircuitBreaker = class {
|
|
19225
|
+
failures = 0;
|
|
19226
|
+
until = 0;
|
|
19227
|
+
tripped() {
|
|
19228
|
+
return this.failures >= MAX_FAILURES && Date.now() < this.until;
|
|
19229
|
+
}
|
|
19230
|
+
reason() {
|
|
19231
|
+
const secs = Math.ceil((this.until - Date.now()) / 1e3);
|
|
19232
|
+
return `Windows daemon failed to start ${this.failures} times in a row; not retrying for ${secs}s`;
|
|
19233
|
+
}
|
|
19234
|
+
clear() {
|
|
19235
|
+
this.failures = 0;
|
|
19236
|
+
this.until = 0;
|
|
19237
|
+
}
|
|
19238
|
+
fail() {
|
|
19239
|
+
this.failures++;
|
|
19240
|
+
if (this.failures < MAX_FAILURES) return;
|
|
19241
|
+
this.until = Date.now() + BACKOFF_MS;
|
|
19242
|
+
daemonLog(
|
|
19243
|
+
`windows connection: ${this.failures} consecutive launch failures; backing off ${BACKOFF_MS / 1e3}s`
|
|
19244
|
+
);
|
|
19245
|
+
}
|
|
19246
|
+
};
|
|
19247
|
+
|
|
19248
|
+
// src/commands/sessions/daemon/WindowsConnection.ts
|
|
19147
19249
|
var WindowsConnection = class {
|
|
19148
19250
|
constructor(deps2) {
|
|
19149
19251
|
this.deps = deps2;
|
|
19150
19252
|
}
|
|
19151
19253
|
connection = null;
|
|
19152
19254
|
socket = null;
|
|
19255
|
+
// why: survives reset()/dispose() so a reconnect can't re-arm it into a loop; only a successful open clears it
|
|
19256
|
+
breaker = new LaunchCircuitBreaker();
|
|
19153
19257
|
get connected() {
|
|
19154
19258
|
return this.connection !== null;
|
|
19155
19259
|
}
|
|
19156
19260
|
ensure() {
|
|
19157
19261
|
if (this.connection) return this.connection;
|
|
19262
|
+
if (this.breaker.tripped())
|
|
19263
|
+
return Promise.reject(new Error(this.breaker.reason()));
|
|
19158
19264
|
const connection = this.open();
|
|
19159
19265
|
this.connection = connection;
|
|
19160
|
-
connection.
|
|
19161
|
-
|
|
19162
|
-
|
|
19266
|
+
connection.then(
|
|
19267
|
+
() => this.breaker.clear(),
|
|
19268
|
+
() => this.onOpenFailure(connection)
|
|
19269
|
+
);
|
|
19163
19270
|
return connection;
|
|
19164
19271
|
}
|
|
19272
|
+
onOpenFailure(connection) {
|
|
19273
|
+
if (this.connection === connection) this.connection = null;
|
|
19274
|
+
this.breaker.fail();
|
|
19275
|
+
}
|
|
19165
19276
|
write(msg) {
|
|
19166
19277
|
this.socket?.write(`${JSON.stringify(msg)}
|
|
19167
19278
|
`);
|
|
@@ -19180,6 +19291,11 @@ var WindowsConnection = class {
|
|
|
19180
19291
|
const socket = await this.deps.connect();
|
|
19181
19292
|
daemonLog("windows connection: tcp connected, sending hello");
|
|
19182
19293
|
this.socket = socket;
|
|
19294
|
+
this.wire(socket);
|
|
19295
|
+
this.write(buildHello());
|
|
19296
|
+
return socket;
|
|
19297
|
+
}
|
|
19298
|
+
wire(socket) {
|
|
19183
19299
|
const lines = createInterface6({ input: socket });
|
|
19184
19300
|
lines.on("error", () => {
|
|
19185
19301
|
});
|
|
@@ -19190,8 +19306,6 @@ var WindowsConnection = class {
|
|
|
19190
19306
|
this.reset();
|
|
19191
19307
|
this.deps.onClose();
|
|
19192
19308
|
});
|
|
19193
|
-
this.write(buildHello());
|
|
19194
|
-
return socket;
|
|
19195
19309
|
}
|
|
19196
19310
|
reset() {
|
|
19197
19311
|
this.socket = null;
|
|
@@ -19857,10 +19971,10 @@ function handleConnection(socket, manager) {
|
|
|
19857
19971
|
}
|
|
19858
19972
|
try {
|
|
19859
19973
|
dispatchMessage(client, manager, data);
|
|
19860
|
-
} catch (
|
|
19974
|
+
} catch (error) {
|
|
19861
19975
|
sendTo(client, {
|
|
19862
19976
|
type: "error",
|
|
19863
|
-
message: `${data.type} failed: ${
|
|
19977
|
+
message: `${data.type} failed: ${error instanceof Error ? error.message : String(error)}`
|
|
19864
19978
|
});
|
|
19865
19979
|
}
|
|
19866
19980
|
});
|
|
@@ -19884,7 +19998,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
19884
19998
|
}
|
|
19885
19999
|
function ownsPidFile() {
|
|
19886
20000
|
try {
|
|
19887
|
-
return readFileSync39(daemonPaths.pid, "
|
|
20001
|
+
return readFileSync39(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
19888
20002
|
} catch {
|
|
19889
20003
|
return false;
|
|
19890
20004
|
}
|
|
@@ -20000,7 +20114,7 @@ function registerDaemon(program2) {
|
|
|
20000
20114
|
|
|
20001
20115
|
// src/commands/sessions/summarise/index.ts
|
|
20002
20116
|
import * as fs32 from "fs";
|
|
20003
|
-
import
|
|
20117
|
+
import chalk166 from "chalk";
|
|
20004
20118
|
|
|
20005
20119
|
// src/commands/sessions/summarise/shared.ts
|
|
20006
20120
|
import * as fs30 from "fs";
|
|
@@ -20154,22 +20268,22 @@ ${firstMessage}`);
|
|
|
20154
20268
|
async function summarise3(options2) {
|
|
20155
20269
|
const files = await discoverSessionFiles();
|
|
20156
20270
|
if (files.length === 0) {
|
|
20157
|
-
console.log(
|
|
20271
|
+
console.log(chalk166.yellow("No sessions found."));
|
|
20158
20272
|
return;
|
|
20159
20273
|
}
|
|
20160
20274
|
const toProcess = selectCandidates(files, options2);
|
|
20161
20275
|
if (toProcess.length === 0) {
|
|
20162
|
-
console.log(
|
|
20276
|
+
console.log(chalk166.green("All sessions already summarised."));
|
|
20163
20277
|
return;
|
|
20164
20278
|
}
|
|
20165
20279
|
console.log(
|
|
20166
|
-
|
|
20280
|
+
chalk166.cyan(
|
|
20167
20281
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
20168
20282
|
)
|
|
20169
20283
|
);
|
|
20170
20284
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
20171
20285
|
console.log(
|
|
20172
|
-
|
|
20286
|
+
chalk166.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk166.yellow(`, ${failed2} skipped`) : "")
|
|
20173
20287
|
);
|
|
20174
20288
|
}
|
|
20175
20289
|
function selectCandidates(files, options2) {
|
|
@@ -20189,16 +20303,16 @@ function processSessions(files) {
|
|
|
20189
20303
|
let failed2 = 0;
|
|
20190
20304
|
for (let i = 0; i < files.length; i++) {
|
|
20191
20305
|
const file = files[i];
|
|
20192
|
-
process.stdout.write(
|
|
20306
|
+
process.stdout.write(chalk166.dim(` [${i + 1}/${files.length}] `));
|
|
20193
20307
|
const summary = summariseSession(file);
|
|
20194
20308
|
if (summary) {
|
|
20195
20309
|
writeSummary(file, summary);
|
|
20196
20310
|
succeeded++;
|
|
20197
|
-
process.stdout.write(`${
|
|
20311
|
+
process.stdout.write(`${chalk166.green("\u2713")} ${summary}
|
|
20198
20312
|
`);
|
|
20199
20313
|
} else {
|
|
20200
20314
|
failed2++;
|
|
20201
|
-
process.stdout.write(` ${
|
|
20315
|
+
process.stdout.write(` ${chalk166.yellow("skip")}
|
|
20202
20316
|
`);
|
|
20203
20317
|
}
|
|
20204
20318
|
}
|
|
@@ -20213,10 +20327,10 @@ function registerSessions(program2) {
|
|
|
20213
20327
|
}
|
|
20214
20328
|
|
|
20215
20329
|
// src/commands/statusLine.ts
|
|
20216
|
-
import
|
|
20330
|
+
import chalk168 from "chalk";
|
|
20217
20331
|
|
|
20218
20332
|
// src/commands/buildLimitsSegment.ts
|
|
20219
|
-
import
|
|
20333
|
+
import chalk167 from "chalk";
|
|
20220
20334
|
|
|
20221
20335
|
// src/shared/rateLimitLevel.ts
|
|
20222
20336
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -20247,9 +20361,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
20247
20361
|
|
|
20248
20362
|
// src/commands/buildLimitsSegment.ts
|
|
20249
20363
|
var LEVEL_COLOR = {
|
|
20250
|
-
ok:
|
|
20251
|
-
warn:
|
|
20252
|
-
over:
|
|
20364
|
+
ok: chalk167.green,
|
|
20365
|
+
warn: chalk167.yellow,
|
|
20366
|
+
over: chalk167.red
|
|
20253
20367
|
};
|
|
20254
20368
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
20255
20369
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -20297,14 +20411,14 @@ async function relayRateLimits(rateLimits) {
|
|
|
20297
20411
|
}
|
|
20298
20412
|
|
|
20299
20413
|
// src/commands/statusLine.ts
|
|
20300
|
-
|
|
20414
|
+
chalk168.level = 3;
|
|
20301
20415
|
function formatNumber(num) {
|
|
20302
20416
|
return num.toLocaleString("en-US");
|
|
20303
20417
|
}
|
|
20304
20418
|
function colorizePercent(pct) {
|
|
20305
20419
|
const label2 = `${Math.round(pct)}%`;
|
|
20306
|
-
if (pct > 80) return
|
|
20307
|
-
if (pct > 40) return
|
|
20420
|
+
if (pct > 80) return chalk168.red(label2);
|
|
20421
|
+
if (pct > 40) return chalk168.yellow(label2);
|
|
20308
20422
|
return label2;
|
|
20309
20423
|
}
|
|
20310
20424
|
async function statusLine() {
|
|
@@ -20328,21 +20442,21 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
20328
20442
|
// src/commands/sync/syncClaudeMd.ts
|
|
20329
20443
|
import * as fs33 from "fs";
|
|
20330
20444
|
import * as path52 from "path";
|
|
20331
|
-
import
|
|
20445
|
+
import chalk169 from "chalk";
|
|
20332
20446
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
20333
20447
|
const source = path52.join(claudeDir, "CLAUDE.md");
|
|
20334
20448
|
const target = path52.join(targetBase, "CLAUDE.md");
|
|
20335
|
-
const sourceContent = fs33.readFileSync(source, "
|
|
20449
|
+
const sourceContent = fs33.readFileSync(source, "utf8");
|
|
20336
20450
|
if (fs33.existsSync(target)) {
|
|
20337
|
-
const targetContent = fs33.readFileSync(target, "
|
|
20451
|
+
const targetContent = fs33.readFileSync(target, "utf8");
|
|
20338
20452
|
if (sourceContent !== targetContent) {
|
|
20339
20453
|
console.log(
|
|
20340
|
-
|
|
20454
|
+
chalk169.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
20341
20455
|
);
|
|
20342
20456
|
console.log();
|
|
20343
20457
|
printDiff(targetContent, sourceContent);
|
|
20344
20458
|
const confirm = options2?.yes || await promptConfirm(
|
|
20345
|
-
|
|
20459
|
+
chalk169.red("Overwrite existing CLAUDE.md?"),
|
|
20346
20460
|
false
|
|
20347
20461
|
);
|
|
20348
20462
|
if (!confirm) {
|
|
@@ -20358,14 +20472,14 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
20358
20472
|
// src/commands/sync/syncSettings.ts
|
|
20359
20473
|
import * as fs34 from "fs";
|
|
20360
20474
|
import * as path53 from "path";
|
|
20361
|
-
import
|
|
20475
|
+
import chalk170 from "chalk";
|
|
20362
20476
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
20363
20477
|
const source = path53.join(claudeDir, "settings.json");
|
|
20364
20478
|
const target = path53.join(targetBase, "settings.json");
|
|
20365
|
-
const sourceContent = fs34.readFileSync(source, "
|
|
20479
|
+
const sourceContent = fs34.readFileSync(source, "utf8");
|
|
20366
20480
|
const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
|
|
20367
20481
|
if (fs34.existsSync(target)) {
|
|
20368
|
-
const targetContent = fs34.readFileSync(target, "
|
|
20482
|
+
const targetContent = fs34.readFileSync(target, "utf8");
|
|
20369
20483
|
const normalizedTarget = JSON.stringify(
|
|
20370
20484
|
JSON.parse(targetContent),
|
|
20371
20485
|
null,
|
|
@@ -20374,14 +20488,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
20374
20488
|
if (mergedContent !== normalizedTarget) {
|
|
20375
20489
|
if (!options2?.yes) {
|
|
20376
20490
|
console.log(
|
|
20377
|
-
|
|
20491
|
+
chalk170.yellow(
|
|
20378
20492
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
20379
20493
|
)
|
|
20380
20494
|
);
|
|
20381
20495
|
console.log();
|
|
20382
20496
|
printDiff(targetContent, mergedContent);
|
|
20383
20497
|
const confirm = await promptConfirm(
|
|
20384
|
-
|
|
20498
|
+
chalk170.red("Overwrite existing settings.json?"),
|
|
20385
20499
|
false
|
|
20386
20500
|
);
|
|
20387
20501
|
if (!confirm) {
|
|
@@ -20468,7 +20582,7 @@ program.command("commit").description("Create a git commit with validation").arg
|
|
|
20468
20582
|
registerConfig(program);
|
|
20469
20583
|
registerRun(program);
|
|
20470
20584
|
registerNew(program);
|
|
20471
|
-
var lintCommand = program.command("lint").description("Run lint checks for conventions not enforced by
|
|
20585
|
+
var lintCommand = program.command("lint").description("Run lint checks for conventions not enforced by oxlint").option("-f, --fix", "Auto-fix violations where possible").action(lint);
|
|
20472
20586
|
lintCommand.command("init").description("Initialize Biome with standard linter config").action(init);
|
|
20473
20587
|
var vscodeCommand = program.command("vscode").description("VS Code configuration utilities");
|
|
20474
20588
|
vscodeCommand.command("init").description("Add VS Code configuration files").action(init3);
|