@staff0rd/assist 0.180.1 → 0.182.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +288 -250
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.182.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -407,7 +407,9 @@ import { join as join2 } from "path";
|
|
|
407
407
|
var gitignoreEntries = [
|
|
408
408
|
".assist/backlog.db",
|
|
409
409
|
".assist/backlog.db-shm",
|
|
410
|
-
".assist/backlog.db-wal"
|
|
410
|
+
".assist/backlog.db-wal",
|
|
411
|
+
".assist-signal*.json",
|
|
412
|
+
".assist-lock-*.json"
|
|
411
413
|
];
|
|
412
414
|
function ensureGitignore(dir) {
|
|
413
415
|
const gitignorePath = join2(dir, ".gitignore");
|
|
@@ -903,8 +905,8 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
903
905
|
const child = spawn("claude", args, {
|
|
904
906
|
stdio: "inherit"
|
|
905
907
|
});
|
|
906
|
-
const done2 = new Promise((
|
|
907
|
-
child.on("close", (code) =>
|
|
908
|
+
const done2 = new Promise((resolve8, reject) => {
|
|
909
|
+
child.on("close", (code) => resolve8(code ?? 0));
|
|
908
910
|
child.on("error", reject);
|
|
909
911
|
});
|
|
910
912
|
return { child, done: done2 };
|
|
@@ -1358,12 +1360,12 @@ function getHtml() {
|
|
|
1358
1360
|
|
|
1359
1361
|
// src/commands/backlog/web/parseItemBody.ts
|
|
1360
1362
|
function readBody(req) {
|
|
1361
|
-
return new Promise((
|
|
1363
|
+
return new Promise((resolve8, reject) => {
|
|
1362
1364
|
let body = "";
|
|
1363
1365
|
req.on("data", (chunk) => {
|
|
1364
1366
|
body += chunk.toString();
|
|
1365
1367
|
});
|
|
1366
|
-
req.on("end", () =>
|
|
1368
|
+
req.on("end", () => resolve8(body));
|
|
1367
1369
|
req.on("error", reject);
|
|
1368
1370
|
});
|
|
1369
1371
|
}
|
|
@@ -1542,9 +1544,9 @@ async function refine(id) {
|
|
|
1542
1544
|
import { execSync } from "child_process";
|
|
1543
1545
|
|
|
1544
1546
|
// src/shared/loadConfig.ts
|
|
1545
|
-
import { existsSync as existsSync9,
|
|
1547
|
+
import { existsSync as existsSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
1546
1548
|
import { homedir } from "os";
|
|
1547
|
-
import {
|
|
1549
|
+
import { dirname as dirname2, join as join8 } from "path";
|
|
1548
1550
|
import chalk18 from "chalk";
|
|
1549
1551
|
import { stringify as stringifyYaml } from "yaml";
|
|
1550
1552
|
|
|
@@ -1576,7 +1578,8 @@ var runConfigSchema = z2.strictObject({
|
|
|
1576
1578
|
params: z2.array(runParamSchema).optional(),
|
|
1577
1579
|
env: z2.record(z2.string(), z2.string()).optional(),
|
|
1578
1580
|
filter: z2.string().optional(),
|
|
1579
|
-
pre: z2.array(z2.string()).optional()
|
|
1581
|
+
pre: z2.array(z2.string()).optional(),
|
|
1582
|
+
cwd: z2.string().optional()
|
|
1580
1583
|
});
|
|
1581
1584
|
var transcriptConfigSchema = z2.strictObject({
|
|
1582
1585
|
vttDir: z2.string(),
|
|
@@ -1703,6 +1706,9 @@ function getConfigPath() {
|
|
|
1703
1706
|
function getGlobalConfigPath() {
|
|
1704
1707
|
return join8(homedir(), ".assist.yml");
|
|
1705
1708
|
}
|
|
1709
|
+
function getConfigDir() {
|
|
1710
|
+
return dirname2(getConfigPath());
|
|
1711
|
+
}
|
|
1706
1712
|
function loadConfig() {
|
|
1707
1713
|
const globalRaw = loadRawYaml(getGlobalConfigPath());
|
|
1708
1714
|
const projectRaw = loadRawYaml(getConfigPath());
|
|
@@ -1722,24 +1728,6 @@ function saveConfig(config) {
|
|
|
1722
1728
|
const configPath = getConfigPath();
|
|
1723
1729
|
writeFileSync5(configPath, stringifyYaml(config, { lineWidth: 0 }));
|
|
1724
1730
|
}
|
|
1725
|
-
function getRepoName() {
|
|
1726
|
-
const config = loadConfig();
|
|
1727
|
-
if (config.devlog?.name) {
|
|
1728
|
-
return config.devlog.name;
|
|
1729
|
-
}
|
|
1730
|
-
const packageJsonPath = join8(process.cwd(), "package.json");
|
|
1731
|
-
if (existsSync9(packageJsonPath)) {
|
|
1732
|
-
try {
|
|
1733
|
-
const content = readFileSync8(packageJsonPath, "utf-8");
|
|
1734
|
-
const pkg = JSON.parse(content);
|
|
1735
|
-
if (pkg.name) {
|
|
1736
|
-
return pkg.name;
|
|
1737
|
-
}
|
|
1738
|
-
} catch {
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
return basename(process.cwd());
|
|
1742
|
-
}
|
|
1743
1731
|
function getTranscriptConfig() {
|
|
1744
1732
|
const config = loadConfig();
|
|
1745
1733
|
if (!config.transcript) {
|
|
@@ -1955,11 +1943,12 @@ function setupVerifyScript(packageJsonPath, scriptName, command) {
|
|
|
1955
1943
|
}
|
|
1956
1944
|
|
|
1957
1945
|
// src/commands/run/buildRunEntry.ts
|
|
1958
|
-
function buildRunEntry(name, command, args) {
|
|
1946
|
+
function buildRunEntry(name, command, args, options2) {
|
|
1959
1947
|
const effectiveArgs = args.length === 0 && command.includes(" ") ? command.split(/\s+/).slice(1) : args;
|
|
1960
1948
|
const effectiveCommand = args.length === 0 && command.includes(" ") ? command.split(/\s+/)[0] : command;
|
|
1961
1949
|
const entry = { name, command: effectiveCommand };
|
|
1962
1950
|
if (effectiveArgs.length > 0) entry.args = effectiveArgs;
|
|
1951
|
+
if (options2?.cwd) entry.cwd = options2.cwd;
|
|
1963
1952
|
return entry;
|
|
1964
1953
|
}
|
|
1965
1954
|
|
|
@@ -2030,12 +2019,12 @@ import * as path3 from "path";
|
|
|
2030
2019
|
import chalk25 from "chalk";
|
|
2031
2020
|
|
|
2032
2021
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
2033
|
-
import { existsSync as existsSync11, readFileSync as
|
|
2022
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
2034
2023
|
import { join as join10 } from "path";
|
|
2035
2024
|
import chalk24 from "chalk";
|
|
2036
2025
|
function loadKnipConfig(knipJsonPath) {
|
|
2037
2026
|
if (existsSync11(knipJsonPath)) {
|
|
2038
|
-
return JSON.parse(
|
|
2027
|
+
return JSON.parse(readFileSync9(knipJsonPath, "utf-8"));
|
|
2039
2028
|
}
|
|
2040
2029
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
2041
2030
|
}
|
|
@@ -2088,7 +2077,7 @@ import chalk29 from "chalk";
|
|
|
2088
2077
|
|
|
2089
2078
|
// src/commands/lint/init.ts
|
|
2090
2079
|
import { execSync as execSync5 } from "child_process";
|
|
2091
|
-
import { existsSync as existsSync14, readFileSync as
|
|
2080
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
2092
2081
|
import { dirname as dirname7, join as join11 } from "path";
|
|
2093
2082
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2094
2083
|
import chalk28 from "chalk";
|
|
@@ -2114,7 +2103,7 @@ async function promptConfirm(message, initial = true) {
|
|
|
2114
2103
|
|
|
2115
2104
|
// src/shared/removeEslint/index.ts
|
|
2116
2105
|
import { execSync as execSync4 } from "child_process";
|
|
2117
|
-
import { existsSync as existsSync13, readFileSync as
|
|
2106
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
2118
2107
|
|
|
2119
2108
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
2120
2109
|
import { existsSync as existsSync12, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -2158,7 +2147,7 @@ function removeEslintFromPackageJson(options2) {
|
|
|
2158
2147
|
if (!existsSync13(packageJsonPath)) {
|
|
2159
2148
|
return false;
|
|
2160
2149
|
}
|
|
2161
|
-
const packageJson = JSON.parse(
|
|
2150
|
+
const packageJson = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
2162
2151
|
let modified = false;
|
|
2163
2152
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
2164
2153
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -2237,8 +2226,8 @@ async function init() {
|
|
|
2237
2226
|
return;
|
|
2238
2227
|
}
|
|
2239
2228
|
const linterConfigPath = join11(__dirname2, "commands/lint/biome.linter.json");
|
|
2240
|
-
const linterConfig = JSON.parse(
|
|
2241
|
-
const biomeConfig = JSON.parse(
|
|
2229
|
+
const linterConfig = JSON.parse(readFileSync11(linterConfigPath, "utf-8"));
|
|
2230
|
+
const biomeConfig = JSON.parse(readFileSync11(biomeConfigPath, "utf-8"));
|
|
2242
2231
|
const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
|
|
2243
2232
|
`;
|
|
2244
2233
|
biomeConfig.linter = linterConfig.linter;
|
|
@@ -2985,7 +2974,7 @@ function lint(options2 = {}) {
|
|
|
2985
2974
|
|
|
2986
2975
|
// src/commands/new/registerNew/newCli/index.ts
|
|
2987
2976
|
import { execSync as execSync11 } from "child_process";
|
|
2988
|
-
import { basename
|
|
2977
|
+
import { basename, resolve } from "path";
|
|
2989
2978
|
|
|
2990
2979
|
// src/commands/verify/hardcodedColors.ts
|
|
2991
2980
|
import { execSync as execSync6 } from "child_process";
|
|
@@ -3214,14 +3203,14 @@ function flushIfFailed(exitCode, chunks) {
|
|
|
3214
3203
|
|
|
3215
3204
|
// src/commands/verify/run/runAllEntries.ts
|
|
3216
3205
|
function runEntry(entry, onComplete) {
|
|
3217
|
-
return new Promise((
|
|
3206
|
+
return new Promise((resolve8) => {
|
|
3218
3207
|
const child = spawnCommand(entry.fullCommand, entry.cwd, entry.env);
|
|
3219
3208
|
const chunks = collectOutput(child);
|
|
3220
3209
|
child.on("close", (code) => {
|
|
3221
3210
|
const exitCode = code ?? 1;
|
|
3222
3211
|
flushIfFailed(exitCode, chunks);
|
|
3223
3212
|
onComplete?.(exitCode);
|
|
3224
|
-
|
|
3213
|
+
resolve8({ script: entry.name, code: exitCode });
|
|
3225
3214
|
});
|
|
3226
3215
|
});
|
|
3227
3216
|
}
|
|
@@ -3351,7 +3340,7 @@ program.parse();
|
|
|
3351
3340
|
|
|
3352
3341
|
// src/commands/new/registerNew/newCli/index.ts
|
|
3353
3342
|
async function newCli() {
|
|
3354
|
-
const name =
|
|
3343
|
+
const name = basename(resolve("."));
|
|
3355
3344
|
initGit();
|
|
3356
3345
|
initPackageJson(name);
|
|
3357
3346
|
console.log("Installing dependencies...");
|
|
@@ -3366,7 +3355,7 @@ async function newCli() {
|
|
|
3366
3355
|
|
|
3367
3356
|
// src/commands/new/registerNew/newProject.ts
|
|
3368
3357
|
import { execSync as execSync13 } from "child_process";
|
|
3369
|
-
import { existsSync as existsSync18, readFileSync as
|
|
3358
|
+
import { existsSync as existsSync18, readFileSync as readFileSync14, writeFileSync as writeFileSync14 } from "fs";
|
|
3370
3359
|
|
|
3371
3360
|
// src/commands/deploy/init/index.ts
|
|
3372
3361
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -3374,7 +3363,7 @@ import chalk40 from "chalk";
|
|
|
3374
3363
|
import enquirer6 from "enquirer";
|
|
3375
3364
|
|
|
3376
3365
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
3377
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync4, readFileSync as
|
|
3366
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync4, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
|
|
3378
3367
|
import { dirname as dirname13, join as join14 } from "path";
|
|
3379
3368
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3380
3369
|
import chalk39 from "chalk";
|
|
@@ -3384,13 +3373,13 @@ function getExistingSiteId() {
|
|
|
3384
3373
|
if (!existsSync17(WORKFLOW_PATH)) {
|
|
3385
3374
|
return null;
|
|
3386
3375
|
}
|
|
3387
|
-
const content =
|
|
3376
|
+
const content = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3388
3377
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
3389
3378
|
return match ? match[1] : null;
|
|
3390
3379
|
}
|
|
3391
3380
|
function getTemplateContent(siteId) {
|
|
3392
3381
|
const templatePath = join14(__dirname3, "commands/deploy/build.yml");
|
|
3393
|
-
const template =
|
|
3382
|
+
const template = readFileSync13(templatePath, "utf-8");
|
|
3394
3383
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
3395
3384
|
}
|
|
3396
3385
|
async function updateWorkflow(siteId) {
|
|
@@ -3400,7 +3389,7 @@ async function updateWorkflow(siteId) {
|
|
|
3400
3389
|
mkdirSync4(workflowDir, { recursive: true });
|
|
3401
3390
|
}
|
|
3402
3391
|
if (existsSync17(WORKFLOW_PATH)) {
|
|
3403
|
-
const oldContent =
|
|
3392
|
+
const oldContent = readFileSync13(WORKFLOW_PATH, "utf-8");
|
|
3404
3393
|
if (oldContent === newContent) {
|
|
3405
3394
|
console.log(chalk39.green("build.yml is already up to date"));
|
|
3406
3395
|
return;
|
|
@@ -3498,7 +3487,7 @@ function addViteBaseConfig() {
|
|
|
3498
3487
|
console.log("No vite.config.ts found, skipping base config");
|
|
3499
3488
|
return;
|
|
3500
3489
|
}
|
|
3501
|
-
const content =
|
|
3490
|
+
const content = readFileSync14(viteConfigPath, "utf-8");
|
|
3502
3491
|
if (content.includes("base:")) {
|
|
3503
3492
|
console.log("vite.config.ts already has base config");
|
|
3504
3493
|
return;
|
|
@@ -3643,7 +3632,7 @@ async function notify() {
|
|
|
3643
3632
|
// src/commands/activity/activityChart.ts
|
|
3644
3633
|
import blessed from "blessed";
|
|
3645
3634
|
import contrib from "blessed-contrib";
|
|
3646
|
-
function activityChart(data) {
|
|
3635
|
+
function activityChart(data, range) {
|
|
3647
3636
|
const screen = blessed.screen({
|
|
3648
3637
|
smartCSR: true,
|
|
3649
3638
|
title: "Commit Activity"
|
|
@@ -3652,7 +3641,7 @@ function activityChart(data) {
|
|
|
3652
3641
|
const labels = data.map((d) => d.date.slice(5));
|
|
3653
3642
|
const values = data.map((d) => d.count);
|
|
3654
3643
|
const line = grid.set(0, 0, 1, 1, contrib.line, {
|
|
3655
|
-
label:
|
|
3644
|
+
label: ` Commits per week \xB7 ${range.since} \u2192 ${range.until} (press q to close) `,
|
|
3656
3645
|
showLegend: true,
|
|
3657
3646
|
legend: { width: 12 },
|
|
3658
3647
|
xLabelPadding: 3,
|
|
@@ -3727,7 +3716,8 @@ async function activity(options2) {
|
|
|
3727
3716
|
weekly.set(weekStart, (weekly.get(weekStart) ?? 0) + count);
|
|
3728
3717
|
}
|
|
3729
3718
|
const weeklyData = [...weekly.entries()].map(([date, count]) => ({ date, count })).sort((a, b) => a.date.localeCompare(b.date));
|
|
3730
|
-
|
|
3719
|
+
const until = data[data.length - 1].date;
|
|
3720
|
+
activityChart(weeklyData, { since, until });
|
|
3731
3721
|
}
|
|
3732
3722
|
|
|
3733
3723
|
// src/commands/registerActivity.ts
|
|
@@ -3802,7 +3792,7 @@ function commitBacklog(id, name) {
|
|
|
3802
3792
|
|
|
3803
3793
|
// src/commands/backlog/add/shared.ts
|
|
3804
3794
|
import { spawnSync } from "child_process";
|
|
3805
|
-
import { mkdtempSync, readFileSync as
|
|
3795
|
+
import { mkdtempSync, readFileSync as readFileSync15, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
3806
3796
|
import { tmpdir } from "os";
|
|
3807
3797
|
import { join as join16 } from "path";
|
|
3808
3798
|
import enquirer7 from "enquirer";
|
|
@@ -3852,7 +3842,7 @@ function openEditor() {
|
|
|
3852
3842
|
unlinkSync4(filePath);
|
|
3853
3843
|
return void 0;
|
|
3854
3844
|
}
|
|
3855
|
-
const content =
|
|
3845
|
+
const content = readFileSync15(filePath, "utf-8").trim();
|
|
3856
3846
|
unlinkSync4(filePath);
|
|
3857
3847
|
return content || void 0;
|
|
3858
3848
|
}
|
|
@@ -4539,7 +4529,7 @@ function extractGraphqlQuery(args) {
|
|
|
4539
4529
|
}
|
|
4540
4530
|
|
|
4541
4531
|
// src/shared/loadCliReads.ts
|
|
4542
|
-
import { existsSync as existsSync19, readFileSync as
|
|
4532
|
+
import { existsSync as existsSync19, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
4543
4533
|
import { dirname as dirname14, resolve as resolve2 } from "path";
|
|
4544
4534
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
4545
4535
|
var __filename2 = fileURLToPath4(import.meta.url);
|
|
@@ -4549,7 +4539,7 @@ function packageRoot() {
|
|
|
4549
4539
|
}
|
|
4550
4540
|
function readLines(path50) {
|
|
4551
4541
|
if (!existsSync19(path50)) return [];
|
|
4552
|
-
return
|
|
4542
|
+
return readFileSync16(path50, "utf-8").split("\n").filter((line) => line.trim() !== "");
|
|
4553
4543
|
}
|
|
4554
4544
|
var cachedReads;
|
|
4555
4545
|
var cachedWrites;
|
|
@@ -4595,7 +4585,7 @@ function findCliWrite(command) {
|
|
|
4595
4585
|
}
|
|
4596
4586
|
|
|
4597
4587
|
// src/shared/readSettingsPerms.ts
|
|
4598
|
-
import { existsSync as existsSync20, readFileSync as
|
|
4588
|
+
import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
|
|
4599
4589
|
import { homedir as homedir3 } from "os";
|
|
4600
4590
|
import { join as join17 } from "path";
|
|
4601
4591
|
function readSettingsPerms(key) {
|
|
@@ -4613,7 +4603,7 @@ function readSettingsPerms(key) {
|
|
|
4613
4603
|
function readPermissionArray(filePath, key) {
|
|
4614
4604
|
if (!existsSync20(filePath)) return [];
|
|
4615
4605
|
try {
|
|
4616
|
-
const data = JSON.parse(
|
|
4606
|
+
const data = JSON.parse(readFileSync17(filePath, "utf-8"));
|
|
4617
4607
|
const arr = data?.permissions?.[key];
|
|
4618
4608
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
4619
4609
|
} catch {
|
|
@@ -4863,53 +4853,8 @@ function cliHookCheck(command, toolName = "Bash") {
|
|
|
4863
4853
|
${reasons.join("\n")}`);
|
|
4864
4854
|
}
|
|
4865
4855
|
|
|
4866
|
-
// src/commands/deny/denyAdd.ts
|
|
4867
|
-
import chalk61 from "chalk";
|
|
4868
|
-
function denyAdd(pattern2, message) {
|
|
4869
|
-
const config = loadProjectConfig();
|
|
4870
|
-
const deny = config.deny ?? [];
|
|
4871
|
-
if (deny.some((r) => r.pattern === pattern2)) {
|
|
4872
|
-
console.log(chalk61.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
4873
|
-
return;
|
|
4874
|
-
}
|
|
4875
|
-
deny.push({ pattern: pattern2, message });
|
|
4876
|
-
config.deny = deny;
|
|
4877
|
-
saveConfig(config);
|
|
4878
|
-
console.log(chalk61.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
4879
|
-
}
|
|
4880
|
-
|
|
4881
|
-
// src/commands/deny/denyList.ts
|
|
4882
|
-
import chalk62 from "chalk";
|
|
4883
|
-
function denyList() {
|
|
4884
|
-
const config = loadConfig();
|
|
4885
|
-
const deny = config.deny;
|
|
4886
|
-
if (!deny || deny.length === 0) {
|
|
4887
|
-
console.log(chalk62.dim("No deny rules configured."));
|
|
4888
|
-
return;
|
|
4889
|
-
}
|
|
4890
|
-
for (const rule of deny) {
|
|
4891
|
-
console.log(`${chalk62.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
4892
|
-
}
|
|
4893
|
-
}
|
|
4894
|
-
|
|
4895
|
-
// src/commands/deny/denyRemove.ts
|
|
4896
|
-
import chalk63 from "chalk";
|
|
4897
|
-
function denyRemove(pattern2) {
|
|
4898
|
-
const config = loadProjectConfig();
|
|
4899
|
-
const deny = config.deny ?? [];
|
|
4900
|
-
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
4901
|
-
if (index === -1) {
|
|
4902
|
-
console.log(chalk63.yellow(`No deny rule found for: ${pattern2}`));
|
|
4903
|
-
return;
|
|
4904
|
-
}
|
|
4905
|
-
deny.splice(index, 1);
|
|
4906
|
-
config.deny = deny.length > 0 ? deny : void 0;
|
|
4907
|
-
saveConfig(config);
|
|
4908
|
-
console.log(chalk63.green(`Removed deny rule: ${pattern2}`));
|
|
4909
|
-
}
|
|
4910
|
-
|
|
4911
4856
|
// src/commands/permitCliReads/index.ts
|
|
4912
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync5, readFileSync as
|
|
4857
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync5, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
4913
4858
|
import { homedir as homedir4 } from "os";
|
|
4914
4859
|
import { join as join18 } from "path";
|
|
4915
4860
|
|
|
@@ -4955,11 +4900,11 @@ function assertCliExists(cli) {
|
|
|
4955
4900
|
}
|
|
4956
4901
|
|
|
4957
4902
|
// src/commands/permitCliReads/colorize.ts
|
|
4958
|
-
import
|
|
4903
|
+
import chalk61 from "chalk";
|
|
4959
4904
|
function colorize(plainOutput) {
|
|
4960
4905
|
return plainOutput.split("\n").map((line) => {
|
|
4961
|
-
if (line.startsWith(" R ")) return
|
|
4962
|
-
if (line.startsWith(" W ")) return
|
|
4906
|
+
if (line.startsWith(" R ")) return chalk61.green(line);
|
|
4907
|
+
if (line.startsWith(" W ")) return chalk61.red(line);
|
|
4963
4908
|
return line;
|
|
4964
4909
|
}).join("\n");
|
|
4965
4910
|
}
|
|
@@ -5041,12 +4986,12 @@ function hasSubcommands(helpText) {
|
|
|
5041
4986
|
// src/commands/permitCliReads/runHelp.ts
|
|
5042
4987
|
import { exec as exec2 } from "child_process";
|
|
5043
4988
|
function runHelp(args) {
|
|
5044
|
-
return new Promise((
|
|
4989
|
+
return new Promise((resolve8) => {
|
|
5045
4990
|
exec2(
|
|
5046
4991
|
`${args.join(" ")} --help`,
|
|
5047
4992
|
{ encoding: "utf-8", timeout: 3e4 },
|
|
5048
4993
|
(_err, stdout, stderr) => {
|
|
5049
|
-
|
|
4994
|
+
resolve8(stdout || stderr || "");
|
|
5050
4995
|
}
|
|
5051
4996
|
);
|
|
5052
4997
|
});
|
|
@@ -5218,7 +5163,7 @@ function logPath(cli) {
|
|
|
5218
5163
|
function readCache(cli) {
|
|
5219
5164
|
const path50 = logPath(cli);
|
|
5220
5165
|
if (!existsSync21(path50)) return void 0;
|
|
5221
|
-
return
|
|
5166
|
+
return readFileSync18(path50, "utf-8");
|
|
5222
5167
|
}
|
|
5223
5168
|
function writeCache(cli, output) {
|
|
5224
5169
|
const dir = join18(homedir4(), ".assist");
|
|
@@ -5256,6 +5201,59 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
5256
5201
|
updateSettings(binary, commands);
|
|
5257
5202
|
}
|
|
5258
5203
|
|
|
5204
|
+
// src/commands/deny/denyAdd.ts
|
|
5205
|
+
import chalk62 from "chalk";
|
|
5206
|
+
function denyAdd(pattern2, message) {
|
|
5207
|
+
const config = loadProjectConfig();
|
|
5208
|
+
const deny = config.deny ?? [];
|
|
5209
|
+
if (deny.some((r) => r.pattern === pattern2)) {
|
|
5210
|
+
console.log(chalk62.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
5211
|
+
return;
|
|
5212
|
+
}
|
|
5213
|
+
deny.push({ pattern: pattern2, message });
|
|
5214
|
+
config.deny = deny;
|
|
5215
|
+
saveConfig(config);
|
|
5216
|
+
console.log(chalk62.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
5217
|
+
}
|
|
5218
|
+
|
|
5219
|
+
// src/commands/deny/denyList.ts
|
|
5220
|
+
import chalk63 from "chalk";
|
|
5221
|
+
function denyList() {
|
|
5222
|
+
const config = loadConfig();
|
|
5223
|
+
const deny = config.deny;
|
|
5224
|
+
if (!deny || deny.length === 0) {
|
|
5225
|
+
console.log(chalk63.dim("No deny rules configured."));
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
5228
|
+
for (const rule of deny) {
|
|
5229
|
+
console.log(`${chalk63.red(rule.pattern)} \u2192 ${rule.message}`);
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
5232
|
+
|
|
5233
|
+
// src/commands/deny/denyRemove.ts
|
|
5234
|
+
import chalk64 from "chalk";
|
|
5235
|
+
function denyRemove(pattern2) {
|
|
5236
|
+
const config = loadProjectConfig();
|
|
5237
|
+
const deny = config.deny ?? [];
|
|
5238
|
+
const index = deny.findIndex((r) => r.pattern === pattern2);
|
|
5239
|
+
if (index === -1) {
|
|
5240
|
+
console.log(chalk64.yellow(`No deny rule found for: ${pattern2}`));
|
|
5241
|
+
return;
|
|
5242
|
+
}
|
|
5243
|
+
deny.splice(index, 1);
|
|
5244
|
+
config.deny = deny.length > 0 ? deny : void 0;
|
|
5245
|
+
saveConfig(config);
|
|
5246
|
+
console.log(chalk64.green(`Removed deny rule: ${pattern2}`));
|
|
5247
|
+
}
|
|
5248
|
+
|
|
5249
|
+
// src/commands/registerDeny.ts
|
|
5250
|
+
function registerDeny(parent) {
|
|
5251
|
+
const denyCommand = parent.command("deny").description("Manage command deny rules").action(denyList);
|
|
5252
|
+
denyCommand.command("add").description("Add a deny rule for a command pattern").argument("<pattern>", "Command prefix to deny").argument("<message>", "Correction message shown to the agent").action(denyAdd);
|
|
5253
|
+
denyCommand.command("remove").description("Remove a deny rule by pattern").argument("<pattern>", "Command prefix to remove").action(denyRemove);
|
|
5254
|
+
denyCommand.command("list").description("List all deny rules").action(denyList);
|
|
5255
|
+
}
|
|
5256
|
+
|
|
5259
5257
|
// src/commands/registerCliHook.ts
|
|
5260
5258
|
function registerCliHook(program2) {
|
|
5261
5259
|
const cmd = program2.command("cli-hook").description("PreToolUse hook for auto-approving read-only CLI commands").action(() => {
|
|
@@ -5270,10 +5268,7 @@ function registerCliHook(program2) {
|
|
|
5270
5268
|
).option("--no-cache", "Force fresh discovery, ignoring cached results").action((cli, options2) => {
|
|
5271
5269
|
permitCliReads(cli.join(" "), { noCache: !options2.cache });
|
|
5272
5270
|
});
|
|
5273
|
-
|
|
5274
|
-
denyCommand.command("add").description("Add a deny rule for a command pattern").argument("<pattern>", "Command prefix to deny").argument("<message>", "Correction message shown to the agent").action(denyAdd);
|
|
5275
|
-
denyCommand.command("remove").description("Remove a deny rule by pattern").argument("<pattern>", "Command prefix to remove").action(denyRemove);
|
|
5276
|
-
denyCommand.command("list").description("List all deny rules").action(denyList);
|
|
5271
|
+
registerDeny(cmd);
|
|
5277
5272
|
}
|
|
5278
5273
|
|
|
5279
5274
|
// src/commands/complexity/analyze.ts
|
|
@@ -5927,7 +5922,7 @@ function registerConfig(program2) {
|
|
|
5927
5922
|
}
|
|
5928
5923
|
|
|
5929
5924
|
// src/commands/deploy/redirect.ts
|
|
5930
|
-
import { existsSync as existsSync22, readFileSync as
|
|
5925
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
5931
5926
|
import chalk73 from "chalk";
|
|
5932
5927
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
5933
5928
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -5940,7 +5935,7 @@ function redirect() {
|
|
|
5940
5935
|
console.log(chalk73.yellow("No index.html found"));
|
|
5941
5936
|
return;
|
|
5942
5937
|
}
|
|
5943
|
-
const content =
|
|
5938
|
+
const content = readFileSync19(indexPath, "utf-8");
|
|
5944
5939
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
5945
5940
|
console.log(chalk73.dim("Trailing slash script already present"));
|
|
5946
5941
|
return;
|
|
@@ -5981,10 +5976,32 @@ function loadBlogSkipDays(repoName) {
|
|
|
5981
5976
|
import { execSync as execSync18 } from "child_process";
|
|
5982
5977
|
import chalk74 from "chalk";
|
|
5983
5978
|
|
|
5979
|
+
// src/shared/getRepoName.ts
|
|
5980
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
|
|
5981
|
+
import { basename as basename2, join as join20 } from "path";
|
|
5982
|
+
function getRepoName() {
|
|
5983
|
+
const config = loadConfig();
|
|
5984
|
+
if (config.devlog?.name) {
|
|
5985
|
+
return config.devlog.name;
|
|
5986
|
+
}
|
|
5987
|
+
const packageJsonPath = join20(process.cwd(), "package.json");
|
|
5988
|
+
if (existsSync23(packageJsonPath)) {
|
|
5989
|
+
try {
|
|
5990
|
+
const content = readFileSync20(packageJsonPath, "utf-8");
|
|
5991
|
+
const pkg = JSON.parse(content);
|
|
5992
|
+
if (pkg.name) {
|
|
5993
|
+
return pkg.name;
|
|
5994
|
+
}
|
|
5995
|
+
} catch {
|
|
5996
|
+
}
|
|
5997
|
+
}
|
|
5998
|
+
return basename2(process.cwd());
|
|
5999
|
+
}
|
|
6000
|
+
|
|
5984
6001
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
5985
6002
|
import { readdirSync, readFileSync as readFileSync21 } from "fs";
|
|
5986
|
-
import { join as
|
|
5987
|
-
var DEVLOG_DIR =
|
|
6003
|
+
import { join as join21 } from "path";
|
|
6004
|
+
var DEVLOG_DIR = join21(BLOG_REPO_ROOT, "src/content/devlog");
|
|
5988
6005
|
function extractFrontmatter(content) {
|
|
5989
6006
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
5990
6007
|
return fm?.[1] ?? null;
|
|
@@ -6012,7 +6029,7 @@ function readDevlogFiles(callback) {
|
|
|
6012
6029
|
try {
|
|
6013
6030
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
6014
6031
|
for (const file of files) {
|
|
6015
|
-
const content = readFileSync21(
|
|
6032
|
+
const content = readFileSync21(join21(DEVLOG_DIR, file), "utf-8");
|
|
6016
6033
|
const parsed = parseFrontmatter(content, file);
|
|
6017
6034
|
if (parsed) callback(parsed);
|
|
6018
6035
|
}
|
|
@@ -6399,11 +6416,11 @@ function repos(options2) {
|
|
|
6399
6416
|
|
|
6400
6417
|
// src/commands/devlog/skip.ts
|
|
6401
6418
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6402
|
-
import { join as
|
|
6419
|
+
import { join as join22 } from "path";
|
|
6403
6420
|
import chalk79 from "chalk";
|
|
6404
6421
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6405
6422
|
function getBlogConfigPath() {
|
|
6406
|
-
return
|
|
6423
|
+
return join22(BLOG_REPO_ROOT, "assist.yml");
|
|
6407
6424
|
}
|
|
6408
6425
|
function skip(date) {
|
|
6409
6426
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -6464,16 +6481,16 @@ function registerDevlog(program2) {
|
|
|
6464
6481
|
|
|
6465
6482
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
6466
6483
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
6467
|
-
import { join as
|
|
6484
|
+
import { join as join23 } from "path";
|
|
6468
6485
|
import chalk81 from "chalk";
|
|
6469
6486
|
|
|
6470
6487
|
// src/shared/findRepoRoot.ts
|
|
6471
|
-
import { existsSync as
|
|
6488
|
+
import { existsSync as existsSync24 } from "fs";
|
|
6472
6489
|
import path21 from "path";
|
|
6473
6490
|
function findRepoRoot(dir) {
|
|
6474
6491
|
let current = dir;
|
|
6475
6492
|
while (current !== path21.dirname(current)) {
|
|
6476
|
-
if (
|
|
6493
|
+
if (existsSync24(path21.join(current, ".git"))) {
|
|
6477
6494
|
return current;
|
|
6478
6495
|
}
|
|
6479
6496
|
current = path21.dirname(current);
|
|
@@ -6492,7 +6509,7 @@ function isLockedDll(debugDir) {
|
|
|
6492
6509
|
}
|
|
6493
6510
|
for (const file of files) {
|
|
6494
6511
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
6495
|
-
const dllPath =
|
|
6512
|
+
const dllPath = join23(debugDir, file);
|
|
6496
6513
|
try {
|
|
6497
6514
|
const fd = openSync(dllPath, "r+");
|
|
6498
6515
|
closeSync(fd);
|
|
@@ -6510,13 +6527,13 @@ function findFirstLockedDll(dir) {
|
|
|
6510
6527
|
return null;
|
|
6511
6528
|
}
|
|
6512
6529
|
if (entries.includes("bin")) {
|
|
6513
|
-
const locked = isLockedDll(
|
|
6530
|
+
const locked = isLockedDll(join23(dir, "bin", "Debug"));
|
|
6514
6531
|
if (locked) return locked;
|
|
6515
6532
|
}
|
|
6516
6533
|
for (const entry of entries) {
|
|
6517
6534
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
6518
6535
|
continue;
|
|
6519
|
-
const found = findFirstLockedDll(
|
|
6536
|
+
const found = findFirstLockedDll(join23(dir, entry));
|
|
6520
6537
|
if (found) return found;
|
|
6521
6538
|
}
|
|
6522
6539
|
return null;
|
|
@@ -6684,12 +6701,12 @@ function printJson(tree, totalCount, solutions) {
|
|
|
6684
6701
|
}
|
|
6685
6702
|
|
|
6686
6703
|
// src/commands/dotnet/resolveCsproj.ts
|
|
6687
|
-
import { existsSync as
|
|
6704
|
+
import { existsSync as existsSync25 } from "fs";
|
|
6688
6705
|
import path24 from "path";
|
|
6689
6706
|
import chalk83 from "chalk";
|
|
6690
6707
|
function resolveCsproj(csprojPath) {
|
|
6691
6708
|
const resolved = path24.resolve(csprojPath);
|
|
6692
|
-
if (!
|
|
6709
|
+
if (!existsSync25(resolved)) {
|
|
6693
6710
|
console.error(chalk83.red(`File not found: ${resolved}`));
|
|
6694
6711
|
process.exit(1);
|
|
6695
6712
|
}
|
|
@@ -6857,17 +6874,17 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
6857
6874
|
}
|
|
6858
6875
|
|
|
6859
6876
|
// src/commands/dotnet/resolveSolution.ts
|
|
6860
|
-
import { existsSync as
|
|
6877
|
+
import { existsSync as existsSync26 } from "fs";
|
|
6861
6878
|
import path25 from "path";
|
|
6862
6879
|
import chalk87 from "chalk";
|
|
6863
6880
|
|
|
6864
6881
|
// src/commands/dotnet/findSolution.ts
|
|
6865
6882
|
import { readdirSync as readdirSync4 } from "fs";
|
|
6866
|
-
import { dirname as dirname16, join as
|
|
6883
|
+
import { dirname as dirname16, join as join24 } from "path";
|
|
6867
6884
|
import chalk86 from "chalk";
|
|
6868
6885
|
function findSlnInDir(dir) {
|
|
6869
6886
|
try {
|
|
6870
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
6887
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join24(dir, f));
|
|
6871
6888
|
} catch {
|
|
6872
6889
|
return [];
|
|
6873
6890
|
}
|
|
@@ -6898,7 +6915,7 @@ function findSolution() {
|
|
|
6898
6915
|
function resolveSolution(sln) {
|
|
6899
6916
|
if (sln) {
|
|
6900
6917
|
const resolved = path25.resolve(sln);
|
|
6901
|
-
if (!
|
|
6918
|
+
if (!existsSync26(resolved)) {
|
|
6902
6919
|
console.error(chalk87.red(`Solution file not found: ${resolved}`));
|
|
6903
6920
|
process.exit(1);
|
|
6904
6921
|
}
|
|
@@ -6938,7 +6955,7 @@ function parseInspectReport(json) {
|
|
|
6938
6955
|
|
|
6939
6956
|
// src/commands/dotnet/runInspectCode.ts
|
|
6940
6957
|
import { execSync as execSync24 } from "child_process";
|
|
6941
|
-
import { existsSync as
|
|
6958
|
+
import { existsSync as existsSync27, readFileSync as readFileSync24, unlinkSync as unlinkSync5 } from "fs";
|
|
6942
6959
|
import { tmpdir as tmpdir2 } from "os";
|
|
6943
6960
|
import path26 from "path";
|
|
6944
6961
|
import chalk88 from "chalk";
|
|
@@ -6969,7 +6986,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
6969
6986
|
console.error(chalk88.red("jb inspectcode failed"));
|
|
6970
6987
|
process.exit(1);
|
|
6971
6988
|
}
|
|
6972
|
-
if (!
|
|
6989
|
+
if (!existsSync27(reportPath)) {
|
|
6973
6990
|
console.error(chalk88.red("Report file not generated"));
|
|
6974
6991
|
process.exit(1);
|
|
6975
6992
|
}
|
|
@@ -7201,18 +7218,18 @@ function acceptanceCriteria(issueKey) {
|
|
|
7201
7218
|
import { execSync as execSync27 } from "child_process";
|
|
7202
7219
|
|
|
7203
7220
|
// src/shared/loadJson.ts
|
|
7204
|
-
import { existsSync as
|
|
7221
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
|
|
7205
7222
|
import { homedir as homedir6 } from "os";
|
|
7206
|
-
import { join as
|
|
7223
|
+
import { join as join25 } from "path";
|
|
7207
7224
|
function getStoreDir() {
|
|
7208
|
-
return
|
|
7225
|
+
return join25(homedir6(), ".assist");
|
|
7209
7226
|
}
|
|
7210
7227
|
function getStorePath(filename) {
|
|
7211
|
-
return
|
|
7228
|
+
return join25(getStoreDir(), filename);
|
|
7212
7229
|
}
|
|
7213
7230
|
function loadJson(filename) {
|
|
7214
7231
|
const path50 = getStorePath(filename);
|
|
7215
|
-
if (
|
|
7232
|
+
if (existsSync28(path50)) {
|
|
7216
7233
|
try {
|
|
7217
7234
|
return JSON.parse(readFileSync25(path50, "utf-8"));
|
|
7218
7235
|
} catch {
|
|
@@ -7223,7 +7240,7 @@ function loadJson(filename) {
|
|
|
7223
7240
|
}
|
|
7224
7241
|
function saveJson(filename, data) {
|
|
7225
7242
|
const dir = getStoreDir();
|
|
7226
|
-
if (!
|
|
7243
|
+
if (!existsSync28(dir)) {
|
|
7227
7244
|
mkdirSync6(dir, { recursive: true });
|
|
7228
7245
|
}
|
|
7229
7246
|
writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -7540,7 +7557,7 @@ function registerNews(program2) {
|
|
|
7540
7557
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7541
7558
|
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync21 } from "fs";
|
|
7542
7559
|
import { tmpdir as tmpdir3 } from "os";
|
|
7543
|
-
import { join as
|
|
7560
|
+
import { join as join26 } from "path";
|
|
7544
7561
|
|
|
7545
7562
|
// src/commands/prs/shared.ts
|
|
7546
7563
|
import { execSync as execSync28 } from "child_process";
|
|
@@ -7612,7 +7629,7 @@ function comment2(path50, line, body) {
|
|
|
7612
7629
|
validateLine(line);
|
|
7613
7630
|
try {
|
|
7614
7631
|
const prId = getCurrentPrNodeId();
|
|
7615
|
-
const queryFile =
|
|
7632
|
+
const queryFile = join26(tmpdir3(), `gh-query-${Date.now()}.graphql`);
|
|
7616
7633
|
writeFileSync21(queryFile, MUTATION);
|
|
7617
7634
|
try {
|
|
7618
7635
|
const result = spawnSync2(
|
|
@@ -7657,18 +7674,18 @@ import { execSync as execSync30 } from "child_process";
|
|
|
7657
7674
|
import { execSync as execSync29 } from "child_process";
|
|
7658
7675
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
7659
7676
|
import { tmpdir as tmpdir4 } from "os";
|
|
7660
|
-
import { join as
|
|
7677
|
+
import { join as join28 } from "path";
|
|
7661
7678
|
|
|
7662
7679
|
// src/commands/prs/loadCommentsCache.ts
|
|
7663
|
-
import { existsSync as
|
|
7664
|
-
import { join as
|
|
7680
|
+
import { existsSync as existsSync29, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
|
|
7681
|
+
import { join as join27 } from "path";
|
|
7665
7682
|
import { parse as parse2 } from "yaml";
|
|
7666
7683
|
function getCachePath(prNumber) {
|
|
7667
|
-
return
|
|
7684
|
+
return join27(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
7668
7685
|
}
|
|
7669
7686
|
function loadCommentsCache(prNumber) {
|
|
7670
7687
|
const cachePath = getCachePath(prNumber);
|
|
7671
|
-
if (!
|
|
7688
|
+
if (!existsSync29(cachePath)) {
|
|
7672
7689
|
return null;
|
|
7673
7690
|
}
|
|
7674
7691
|
const content = readFileSync26(cachePath, "utf-8");
|
|
@@ -7676,7 +7693,7 @@ function loadCommentsCache(prNumber) {
|
|
|
7676
7693
|
}
|
|
7677
7694
|
function deleteCommentsCache(prNumber) {
|
|
7678
7695
|
const cachePath = getCachePath(prNumber);
|
|
7679
|
-
if (
|
|
7696
|
+
if (existsSync29(cachePath)) {
|
|
7680
7697
|
unlinkSync7(cachePath);
|
|
7681
7698
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
7682
7699
|
}
|
|
@@ -7691,7 +7708,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
7691
7708
|
}
|
|
7692
7709
|
function resolveThread(threadId) {
|
|
7693
7710
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
7694
|
-
const queryFile =
|
|
7711
|
+
const queryFile = join28(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
7695
7712
|
writeFileSync22(queryFile, mutation);
|
|
7696
7713
|
try {
|
|
7697
7714
|
execSync29(
|
|
@@ -7773,18 +7790,18 @@ function fixed(commentId, sha) {
|
|
|
7773
7790
|
}
|
|
7774
7791
|
|
|
7775
7792
|
// src/commands/prs/listComments/index.ts
|
|
7776
|
-
import { existsSync as
|
|
7777
|
-
import { join as
|
|
7793
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync7, writeFileSync as writeFileSync24 } from "fs";
|
|
7794
|
+
import { join as join30 } from "path";
|
|
7778
7795
|
import { stringify } from "yaml";
|
|
7779
7796
|
|
|
7780
7797
|
// src/commands/prs/fetchThreadIds.ts
|
|
7781
7798
|
import { execSync as execSync31 } from "child_process";
|
|
7782
7799
|
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync23 } from "fs";
|
|
7783
7800
|
import { tmpdir as tmpdir5 } from "os";
|
|
7784
|
-
import { join as
|
|
7801
|
+
import { join as join29 } from "path";
|
|
7785
7802
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
7786
7803
|
function fetchThreadIds(org, repo, prNumber) {
|
|
7787
|
-
const queryFile =
|
|
7804
|
+
const queryFile = join29(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
7788
7805
|
writeFileSync23(queryFile, THREAD_QUERY);
|
|
7789
7806
|
try {
|
|
7790
7807
|
const result = execSync31(
|
|
@@ -7898,8 +7915,8 @@ function printComments2(result) {
|
|
|
7898
7915
|
|
|
7899
7916
|
// src/commands/prs/listComments/index.ts
|
|
7900
7917
|
function writeCommentsCache(prNumber, comments2) {
|
|
7901
|
-
const assistDir =
|
|
7902
|
-
if (!
|
|
7918
|
+
const assistDir = join30(process.cwd(), ".assist");
|
|
7919
|
+
if (!existsSync30(assistDir)) {
|
|
7903
7920
|
mkdirSync7(assistDir, { recursive: true });
|
|
7904
7921
|
}
|
|
7905
7922
|
const cacheData = {
|
|
@@ -7907,7 +7924,7 @@ function writeCommentsCache(prNumber, comments2) {
|
|
|
7907
7924
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7908
7925
|
comments: comments2
|
|
7909
7926
|
};
|
|
7910
|
-
const cachePath =
|
|
7927
|
+
const cachePath = join30(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
7911
7928
|
writeFileSync24(cachePath, stringify(cacheData));
|
|
7912
7929
|
}
|
|
7913
7930
|
function handleKnownErrors(error) {
|
|
@@ -7940,7 +7957,7 @@ async function listComments() {
|
|
|
7940
7957
|
];
|
|
7941
7958
|
updateCache(prNumber, allComments);
|
|
7942
7959
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
7943
|
-
const cachePath = hasLineComments ?
|
|
7960
|
+
const cachePath = hasLineComments ? join30(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
7944
7961
|
return { comments: allComments, cachePath };
|
|
7945
7962
|
} catch (error) {
|
|
7946
7963
|
const handled = handleKnownErrors(error);
|
|
@@ -8710,7 +8727,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
8710
8727
|
|
|
8711
8728
|
// src/commands/refactor/check/index.ts
|
|
8712
8729
|
function runScript(script, cwd) {
|
|
8713
|
-
return new Promise((
|
|
8730
|
+
return new Promise((resolve8) => {
|
|
8714
8731
|
const child = spawn4("npm", ["run", script], {
|
|
8715
8732
|
stdio: "pipe",
|
|
8716
8733
|
shell: true,
|
|
@@ -8724,7 +8741,7 @@ function runScript(script, cwd) {
|
|
|
8724
8741
|
output += data.toString();
|
|
8725
8742
|
});
|
|
8726
8743
|
child.on("close", (code) => {
|
|
8727
|
-
|
|
8744
|
+
resolve8({ script, code: code ?? 1, output });
|
|
8728
8745
|
});
|
|
8729
8746
|
});
|
|
8730
8747
|
}
|
|
@@ -10334,8 +10351,8 @@ function registerSeq(program2) {
|
|
|
10334
10351
|
}
|
|
10335
10352
|
|
|
10336
10353
|
// src/commands/transcript/shared.ts
|
|
10337
|
-
import { existsSync as
|
|
10338
|
-
import { basename as basename4, join as
|
|
10354
|
+
import { existsSync as existsSync31, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
10355
|
+
import { basename as basename4, join as join31, relative } from "path";
|
|
10339
10356
|
import * as readline2 from "readline";
|
|
10340
10357
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
10341
10358
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -10350,10 +10367,10 @@ function isValidDatePrefix(filename) {
|
|
|
10350
10367
|
return DATE_PREFIX_REGEX.test(filename);
|
|
10351
10368
|
}
|
|
10352
10369
|
function collectFiles(dir, extension) {
|
|
10353
|
-
if (!
|
|
10370
|
+
if (!existsSync31(dir)) return [];
|
|
10354
10371
|
const results = [];
|
|
10355
10372
|
for (const entry of readdirSync5(dir)) {
|
|
10356
|
-
const fullPath =
|
|
10373
|
+
const fullPath = join31(dir, entry);
|
|
10357
10374
|
if (statSync4(fullPath).isDirectory()) {
|
|
10358
10375
|
results.push(...collectFiles(fullPath, extension));
|
|
10359
10376
|
} else if (entry.endsWith(extension)) {
|
|
@@ -10385,9 +10402,9 @@ function createReadlineInterface() {
|
|
|
10385
10402
|
});
|
|
10386
10403
|
}
|
|
10387
10404
|
function askQuestion(rl, question) {
|
|
10388
|
-
return new Promise((
|
|
10405
|
+
return new Promise((resolve8) => {
|
|
10389
10406
|
rl.question(question, (answer) => {
|
|
10390
|
-
|
|
10407
|
+
resolve8(answer.trim());
|
|
10391
10408
|
});
|
|
10392
10409
|
});
|
|
10393
10410
|
}
|
|
@@ -10447,14 +10464,14 @@ async function configure() {
|
|
|
10447
10464
|
}
|
|
10448
10465
|
|
|
10449
10466
|
// src/commands/transcript/format/index.ts
|
|
10450
|
-
import { existsSync as
|
|
10467
|
+
import { existsSync as existsSync33 } from "fs";
|
|
10451
10468
|
|
|
10452
10469
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
10453
|
-
import { dirname as dirname18, join as
|
|
10470
|
+
import { dirname as dirname18, join as join33 } from "path";
|
|
10454
10471
|
|
|
10455
10472
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
10456
10473
|
import { renameSync as renameSync2 } from "fs";
|
|
10457
|
-
import { join as
|
|
10474
|
+
import { join as join32 } from "path";
|
|
10458
10475
|
async function resolveDate(rl, choice) {
|
|
10459
10476
|
if (choice === "1") return getDatePrefix(0);
|
|
10460
10477
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -10469,7 +10486,7 @@ async function resolveDate(rl, choice) {
|
|
|
10469
10486
|
}
|
|
10470
10487
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
10471
10488
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
10472
|
-
renameSync2(
|
|
10489
|
+
renameSync2(join32(vttDir, vttFile), join32(vttDir, newFilename));
|
|
10473
10490
|
console.log(`Renamed to: ${newFilename}`);
|
|
10474
10491
|
return newFilename;
|
|
10475
10492
|
}
|
|
@@ -10503,12 +10520,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10503
10520
|
const vttFileDir = dirname18(vttFile.absolutePath);
|
|
10504
10521
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
10505
10522
|
if (newFilename) {
|
|
10506
|
-
const newRelativePath =
|
|
10523
|
+
const newRelativePath = join33(
|
|
10507
10524
|
dirname18(vttFile.relativePath),
|
|
10508
10525
|
newFilename
|
|
10509
10526
|
);
|
|
10510
10527
|
vttFiles[i] = {
|
|
10511
|
-
absolutePath:
|
|
10528
|
+
absolutePath: join33(vttFileDir, newFilename),
|
|
10512
10529
|
relativePath: newRelativePath,
|
|
10513
10530
|
filename: newFilename
|
|
10514
10531
|
};
|
|
@@ -10521,8 +10538,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10521
10538
|
}
|
|
10522
10539
|
|
|
10523
10540
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
10524
|
-
import { existsSync as
|
|
10525
|
-
import { basename as basename5, dirname as dirname19, join as
|
|
10541
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync25 } from "fs";
|
|
10542
|
+
import { basename as basename5, dirname as dirname19, join as join34 } from "path";
|
|
10526
10543
|
|
|
10527
10544
|
// src/commands/transcript/cleanText.ts
|
|
10528
10545
|
function cleanText(text) {
|
|
@@ -10732,21 +10749,21 @@ function toMdFilename(vttFilename) {
|
|
|
10732
10749
|
return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
10733
10750
|
}
|
|
10734
10751
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
10735
|
-
return relativeDir === "." ? transcriptsDir :
|
|
10752
|
+
return relativeDir === "." ? transcriptsDir : join34(transcriptsDir, relativeDir);
|
|
10736
10753
|
}
|
|
10737
10754
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
10738
10755
|
const mdFile = toMdFilename(vttFile.filename);
|
|
10739
10756
|
const relativeDir = dirname19(vttFile.relativePath);
|
|
10740
10757
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
10741
|
-
const outputPath =
|
|
10758
|
+
const outputPath = join34(outputDir, mdFile);
|
|
10742
10759
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
10743
10760
|
}
|
|
10744
10761
|
function logSkipped(relativeDir, mdFile) {
|
|
10745
|
-
console.log(`Skipping (already exists): ${
|
|
10762
|
+
console.log(`Skipping (already exists): ${join34(relativeDir, mdFile)}`);
|
|
10746
10763
|
return "skipped";
|
|
10747
10764
|
}
|
|
10748
10765
|
function ensureDirectory(dir, label2) {
|
|
10749
|
-
if (!
|
|
10766
|
+
if (!existsSync32(dir)) {
|
|
10750
10767
|
mkdirSync8(dir, { recursive: true });
|
|
10751
10768
|
console.log(`Created ${label2}: ${dir}`);
|
|
10752
10769
|
}
|
|
@@ -10782,7 +10799,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
10782
10799
|
logReduction(cues.length, chatMessages.length);
|
|
10783
10800
|
}
|
|
10784
10801
|
function tryProcessVtt(vttFile, paths) {
|
|
10785
|
-
if (
|
|
10802
|
+
if (existsSync32(paths.outputPath))
|
|
10786
10803
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
10787
10804
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
10788
10805
|
return "processed";
|
|
@@ -10808,7 +10825,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
10808
10825
|
logSummary(counts);
|
|
10809
10826
|
}
|
|
10810
10827
|
function requireVttDir(vttDir) {
|
|
10811
|
-
if (!
|
|
10828
|
+
if (!existsSync33(vttDir)) {
|
|
10812
10829
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
10813
10830
|
process.exit(1);
|
|
10814
10831
|
}
|
|
@@ -10840,18 +10857,18 @@ async function format() {
|
|
|
10840
10857
|
}
|
|
10841
10858
|
|
|
10842
10859
|
// src/commands/transcript/summarise/index.ts
|
|
10843
|
-
import { existsSync as
|
|
10844
|
-
import { basename as basename6, dirname as dirname21, join as
|
|
10860
|
+
import { existsSync as existsSync35 } from "fs";
|
|
10861
|
+
import { basename as basename6, dirname as dirname21, join as join36, relative as relative2 } from "path";
|
|
10845
10862
|
|
|
10846
10863
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10847
10864
|
import {
|
|
10848
|
-
existsSync as
|
|
10865
|
+
existsSync as existsSync34,
|
|
10849
10866
|
mkdirSync as mkdirSync9,
|
|
10850
10867
|
readFileSync as readFileSync28,
|
|
10851
10868
|
renameSync as renameSync3,
|
|
10852
10869
|
rmSync
|
|
10853
10870
|
} from "fs";
|
|
10854
|
-
import { dirname as dirname20, join as
|
|
10871
|
+
import { dirname as dirname20, join as join35 } from "path";
|
|
10855
10872
|
|
|
10856
10873
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
10857
10874
|
import chalk127 from "chalk";
|
|
@@ -10880,9 +10897,9 @@ function validateStagedContent(filename, content) {
|
|
|
10880
10897
|
}
|
|
10881
10898
|
|
|
10882
10899
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
10883
|
-
var STAGING_DIR =
|
|
10900
|
+
var STAGING_DIR = join35(process.cwd(), ".assist", "transcript");
|
|
10884
10901
|
function processStagedFile() {
|
|
10885
|
-
if (!
|
|
10902
|
+
if (!existsSync34(STAGING_DIR)) {
|
|
10886
10903
|
return false;
|
|
10887
10904
|
}
|
|
10888
10905
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -10904,9 +10921,9 @@ function processStagedFile() {
|
|
|
10904
10921
|
);
|
|
10905
10922
|
process.exit(1);
|
|
10906
10923
|
}
|
|
10907
|
-
const destPath =
|
|
10924
|
+
const destPath = join35(summaryDir, matchingTranscript.relativePath);
|
|
10908
10925
|
const destDir = dirname20(destPath);
|
|
10909
|
-
if (!
|
|
10926
|
+
if (!existsSync34(destDir)) {
|
|
10910
10927
|
mkdirSync9(destDir, { recursive: true });
|
|
10911
10928
|
}
|
|
10912
10929
|
renameSync3(stagedFile.absolutePath, destPath);
|
|
@@ -10920,7 +10937,7 @@ function processStagedFile() {
|
|
|
10920
10937
|
// src/commands/transcript/summarise/index.ts
|
|
10921
10938
|
function buildRelativeKey(relativePath, baseName) {
|
|
10922
10939
|
const relDir = dirname21(relativePath);
|
|
10923
|
-
return relDir === "." ? baseName :
|
|
10940
|
+
return relDir === "." ? baseName : join36(relDir, baseName);
|
|
10924
10941
|
}
|
|
10925
10942
|
function buildSummaryIndex(summaryDir) {
|
|
10926
10943
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
@@ -10933,7 +10950,7 @@ function buildSummaryIndex(summaryDir) {
|
|
|
10933
10950
|
function summarise2() {
|
|
10934
10951
|
processStagedFile();
|
|
10935
10952
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
10936
|
-
if (!
|
|
10953
|
+
if (!existsSync35(transcriptsDir)) {
|
|
10937
10954
|
console.log("No transcripts directory found.");
|
|
10938
10955
|
return;
|
|
10939
10956
|
}
|
|
@@ -10954,8 +10971,8 @@ function summarise2() {
|
|
|
10954
10971
|
}
|
|
10955
10972
|
const next3 = missing[0];
|
|
10956
10973
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
10957
|
-
const outputPath =
|
|
10958
|
-
const summaryFileDir =
|
|
10974
|
+
const outputPath = join36(STAGING_DIR, outputFilename);
|
|
10975
|
+
const summaryFileDir = join36(summaryDir, dirname21(next3.relativePath));
|
|
10959
10976
|
const relativeTranscriptPath = encodeURI(
|
|
10960
10977
|
relative2(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
10961
10978
|
);
|
|
@@ -11001,45 +11018,45 @@ function registerVerify(program2) {
|
|
|
11001
11018
|
|
|
11002
11019
|
// src/commands/voice/devices.ts
|
|
11003
11020
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
11004
|
-
import { join as
|
|
11021
|
+
import { join as join38 } from "path";
|
|
11005
11022
|
|
|
11006
11023
|
// src/commands/voice/shared.ts
|
|
11007
11024
|
import { homedir as homedir7 } from "os";
|
|
11008
|
-
import { dirname as dirname22, join as
|
|
11025
|
+
import { dirname as dirname22, join as join37 } from "path";
|
|
11009
11026
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
11010
11027
|
var __dirname6 = dirname22(fileURLToPath6(import.meta.url));
|
|
11011
|
-
var VOICE_DIR =
|
|
11028
|
+
var VOICE_DIR = join37(homedir7(), ".assist", "voice");
|
|
11012
11029
|
var voicePaths = {
|
|
11013
11030
|
dir: VOICE_DIR,
|
|
11014
|
-
pid:
|
|
11015
|
-
log:
|
|
11016
|
-
venv:
|
|
11017
|
-
lock:
|
|
11031
|
+
pid: join37(VOICE_DIR, "voice.pid"),
|
|
11032
|
+
log: join37(VOICE_DIR, "voice.log"),
|
|
11033
|
+
venv: join37(VOICE_DIR, ".venv"),
|
|
11034
|
+
lock: join37(VOICE_DIR, "voice.lock")
|
|
11018
11035
|
};
|
|
11019
11036
|
function getPythonDir() {
|
|
11020
|
-
return
|
|
11037
|
+
return join37(__dirname6, "commands", "voice", "python");
|
|
11021
11038
|
}
|
|
11022
11039
|
function getVenvPython() {
|
|
11023
|
-
return process.platform === "win32" ?
|
|
11040
|
+
return process.platform === "win32" ? join37(voicePaths.venv, "Scripts", "python.exe") : join37(voicePaths.venv, "bin", "python");
|
|
11024
11041
|
}
|
|
11025
11042
|
function getLockDir() {
|
|
11026
11043
|
const config = loadConfig();
|
|
11027
11044
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
11028
11045
|
}
|
|
11029
11046
|
function getLockFile() {
|
|
11030
|
-
return
|
|
11047
|
+
return join37(getLockDir(), "voice.lock");
|
|
11031
11048
|
}
|
|
11032
11049
|
|
|
11033
11050
|
// src/commands/voice/devices.ts
|
|
11034
11051
|
function devices() {
|
|
11035
|
-
const script =
|
|
11052
|
+
const script = join38(getPythonDir(), "list_devices.py");
|
|
11036
11053
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
11037
11054
|
}
|
|
11038
11055
|
|
|
11039
11056
|
// src/commands/voice/logs.ts
|
|
11040
|
-
import { existsSync as
|
|
11057
|
+
import { existsSync as existsSync36, readFileSync as readFileSync29 } from "fs";
|
|
11041
11058
|
function logs(options2) {
|
|
11042
|
-
if (!
|
|
11059
|
+
if (!existsSync36(voicePaths.log)) {
|
|
11043
11060
|
console.log("No voice log file found");
|
|
11044
11061
|
return;
|
|
11045
11062
|
}
|
|
@@ -11067,12 +11084,12 @@ function logs(options2) {
|
|
|
11067
11084
|
// src/commands/voice/setup.ts
|
|
11068
11085
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
11069
11086
|
import { mkdirSync as mkdirSync11 } from "fs";
|
|
11070
|
-
import { join as
|
|
11087
|
+
import { join as join40 } from "path";
|
|
11071
11088
|
|
|
11072
11089
|
// src/commands/voice/checkLockFile.ts
|
|
11073
11090
|
import { execSync as execSync38 } from "child_process";
|
|
11074
|
-
import { existsSync as
|
|
11075
|
-
import { join as
|
|
11091
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync10, readFileSync as readFileSync30, writeFileSync as writeFileSync26 } from "fs";
|
|
11092
|
+
import { join as join39 } from "path";
|
|
11076
11093
|
function isProcessAlive2(pid) {
|
|
11077
11094
|
try {
|
|
11078
11095
|
process.kill(pid, 0);
|
|
@@ -11083,7 +11100,7 @@ function isProcessAlive2(pid) {
|
|
|
11083
11100
|
}
|
|
11084
11101
|
function checkLockFile() {
|
|
11085
11102
|
const lockFile = getLockFile();
|
|
11086
|
-
if (!
|
|
11103
|
+
if (!existsSync37(lockFile)) return;
|
|
11087
11104
|
try {
|
|
11088
11105
|
const lock = JSON.parse(readFileSync30(lockFile, "utf-8"));
|
|
11089
11106
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
@@ -11096,7 +11113,7 @@ function checkLockFile() {
|
|
|
11096
11113
|
}
|
|
11097
11114
|
}
|
|
11098
11115
|
function bootstrapVenv() {
|
|
11099
|
-
if (
|
|
11116
|
+
if (existsSync37(getVenvPython())) return;
|
|
11100
11117
|
console.log("Setting up Python environment...");
|
|
11101
11118
|
const pythonDir = getPythonDir();
|
|
11102
11119
|
execSync38(
|
|
@@ -11109,7 +11126,7 @@ function bootstrapVenv() {
|
|
|
11109
11126
|
}
|
|
11110
11127
|
function writeLockFile(pid) {
|
|
11111
11128
|
const lockFile = getLockFile();
|
|
11112
|
-
mkdirSync10(
|
|
11129
|
+
mkdirSync10(join39(lockFile, ".."), { recursive: true });
|
|
11113
11130
|
writeFileSync26(
|
|
11114
11131
|
lockFile,
|
|
11115
11132
|
JSON.stringify({
|
|
@@ -11125,7 +11142,7 @@ function setup() {
|
|
|
11125
11142
|
mkdirSync11(voicePaths.dir, { recursive: true });
|
|
11126
11143
|
bootstrapVenv();
|
|
11127
11144
|
console.log("\nDownloading models...\n");
|
|
11128
|
-
const script =
|
|
11145
|
+
const script = join40(getPythonDir(), "setup_models.py");
|
|
11129
11146
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
11130
11147
|
stdio: "inherit",
|
|
11131
11148
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -11139,7 +11156,7 @@ function setup() {
|
|
|
11139
11156
|
// src/commands/voice/start.ts
|
|
11140
11157
|
import { spawn as spawn5 } from "child_process";
|
|
11141
11158
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync27 } from "fs";
|
|
11142
|
-
import { join as
|
|
11159
|
+
import { join as join41 } from "path";
|
|
11143
11160
|
|
|
11144
11161
|
// src/commands/voice/buildDaemonEnv.ts
|
|
11145
11162
|
function buildDaemonEnv(options2) {
|
|
@@ -11177,7 +11194,7 @@ function start2(options2) {
|
|
|
11177
11194
|
bootstrapVenv();
|
|
11178
11195
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
11179
11196
|
const env = buildDaemonEnv({ debug });
|
|
11180
|
-
const script =
|
|
11197
|
+
const script = join41(getPythonDir(), "voice_daemon.py");
|
|
11181
11198
|
const python = getVenvPython();
|
|
11182
11199
|
if (options2.foreground) {
|
|
11183
11200
|
spawnForeground(python, script, env);
|
|
@@ -11187,7 +11204,7 @@ function start2(options2) {
|
|
|
11187
11204
|
}
|
|
11188
11205
|
|
|
11189
11206
|
// src/commands/voice/status.ts
|
|
11190
|
-
import { existsSync as
|
|
11207
|
+
import { existsSync as existsSync38, readFileSync as readFileSync31 } from "fs";
|
|
11191
11208
|
function isProcessAlive3(pid) {
|
|
11192
11209
|
try {
|
|
11193
11210
|
process.kill(pid, 0);
|
|
@@ -11197,12 +11214,12 @@ function isProcessAlive3(pid) {
|
|
|
11197
11214
|
}
|
|
11198
11215
|
}
|
|
11199
11216
|
function readRecentLogs(count) {
|
|
11200
|
-
if (!
|
|
11217
|
+
if (!existsSync38(voicePaths.log)) return [];
|
|
11201
11218
|
const lines = readFileSync31(voicePaths.log, "utf-8").trim().split("\n");
|
|
11202
11219
|
return lines.slice(-count);
|
|
11203
11220
|
}
|
|
11204
11221
|
function status() {
|
|
11205
|
-
if (!
|
|
11222
|
+
if (!existsSync38(voicePaths.pid)) {
|
|
11206
11223
|
console.log("Voice daemon: not running (no PID file)");
|
|
11207
11224
|
return;
|
|
11208
11225
|
}
|
|
@@ -11225,9 +11242,9 @@ function status() {
|
|
|
11225
11242
|
}
|
|
11226
11243
|
|
|
11227
11244
|
// src/commands/voice/stop.ts
|
|
11228
|
-
import { existsSync as
|
|
11245
|
+
import { existsSync as existsSync39, readFileSync as readFileSync32, unlinkSync as unlinkSync10 } from "fs";
|
|
11229
11246
|
function stop() {
|
|
11230
|
-
if (!
|
|
11247
|
+
if (!existsSync39(voicePaths.pid)) {
|
|
11231
11248
|
console.log("Voice daemon is not running (no PID file)");
|
|
11232
11249
|
return;
|
|
11233
11250
|
}
|
|
@@ -11244,7 +11261,7 @@ function stop() {
|
|
|
11244
11261
|
}
|
|
11245
11262
|
try {
|
|
11246
11263
|
const lockFile = getLockFile();
|
|
11247
|
-
if (
|
|
11264
|
+
if (existsSync39(lockFile)) unlinkSync10(lockFile);
|
|
11248
11265
|
} catch {
|
|
11249
11266
|
}
|
|
11250
11267
|
console.log("Voice daemon stopped");
|
|
@@ -11328,7 +11345,7 @@ function extractCode(url, expectedState) {
|
|
|
11328
11345
|
return code;
|
|
11329
11346
|
}
|
|
11330
11347
|
function waitForCallback(port, expectedState) {
|
|
11331
|
-
return new Promise((
|
|
11348
|
+
return new Promise((resolve8, reject) => {
|
|
11332
11349
|
const timeout = setTimeout(() => {
|
|
11333
11350
|
server.close();
|
|
11334
11351
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -11345,7 +11362,7 @@ function waitForCallback(port, expectedState) {
|
|
|
11345
11362
|
const code = extractCode(url, expectedState);
|
|
11346
11363
|
respondHtml(res, 200, "Authorization successful!");
|
|
11347
11364
|
server.close();
|
|
11348
|
-
|
|
11365
|
+
resolve8(code);
|
|
11349
11366
|
} catch (err) {
|
|
11350
11367
|
respondHtml(res, 400, err.message);
|
|
11351
11368
|
server.close();
|
|
@@ -11466,11 +11483,11 @@ async function auth() {
|
|
|
11466
11483
|
|
|
11467
11484
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
11468
11485
|
import { readFileSync as readFileSync33 } from "fs";
|
|
11469
|
-
import { join as
|
|
11486
|
+
import { join as join42 } from "path";
|
|
11470
11487
|
async function showClaudeCodeIcon() {
|
|
11471
11488
|
const appData = process.env.APPDATA;
|
|
11472
11489
|
if (!appData) return;
|
|
11473
|
-
const portFile =
|
|
11490
|
+
const portFile = join42(appData, "Roam", "roam-local-api.port");
|
|
11474
11491
|
let port;
|
|
11475
11492
|
try {
|
|
11476
11493
|
port = readFileSync33(portFile, "utf-8").trim();
|
|
@@ -11496,7 +11513,7 @@ function registerRoam(program2) {
|
|
|
11496
11513
|
}
|
|
11497
11514
|
|
|
11498
11515
|
// src/commands/run/index.ts
|
|
11499
|
-
import {
|
|
11516
|
+
import { resolve as resolve5 } from "path";
|
|
11500
11517
|
|
|
11501
11518
|
// src/commands/run/formatConfiguredCommands.ts
|
|
11502
11519
|
function formatConfiguredCommands() {
|
|
@@ -11532,14 +11549,28 @@ function resolveParams(params, cliArgs) {
|
|
|
11532
11549
|
return resolved;
|
|
11533
11550
|
}
|
|
11534
11551
|
|
|
11552
|
+
// src/commands/run/runPreCommands.ts
|
|
11553
|
+
import { execSync as execSync40 } from "child_process";
|
|
11554
|
+
function runPreCommands(pre, cwd) {
|
|
11555
|
+
for (const cmd of pre) {
|
|
11556
|
+
try {
|
|
11557
|
+
execSync40(cmd, { stdio: "inherit", cwd });
|
|
11558
|
+
} catch (err) {
|
|
11559
|
+
const code = err && typeof err === "object" && "status" in err ? err.status : 1;
|
|
11560
|
+
process.exit(code);
|
|
11561
|
+
}
|
|
11562
|
+
}
|
|
11563
|
+
}
|
|
11564
|
+
|
|
11535
11565
|
// src/commands/run/spawnRunCommand.ts
|
|
11536
11566
|
import { spawn as spawn6 } from "child_process";
|
|
11537
|
-
function spawnRunCommand(fullCommand, env) {
|
|
11567
|
+
function spawnRunCommand(fullCommand, env, cwd) {
|
|
11538
11568
|
const start3 = Date.now();
|
|
11539
11569
|
const child = spawn6(fullCommand, [], {
|
|
11540
11570
|
stdio: "inherit",
|
|
11541
11571
|
shell: true,
|
|
11542
|
-
env: env ? { ...process.env, ...expandEnv(env) } : void 0
|
|
11572
|
+
env: env ? { ...process.env, ...expandEnv(env) } : void 0,
|
|
11573
|
+
cwd
|
|
11543
11574
|
});
|
|
11544
11575
|
child.on("close", (code) => {
|
|
11545
11576
|
const elapsed = formatElapsed(Date.now() - start3);
|
|
@@ -11555,17 +11586,28 @@ Done in ${elapsed}`);
|
|
|
11555
11586
|
|
|
11556
11587
|
// src/commands/run/add.ts
|
|
11557
11588
|
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync28 } from "fs";
|
|
11558
|
-
import { join as
|
|
11589
|
+
import { join as join43 } from "path";
|
|
11559
11590
|
function findAddIndex() {
|
|
11560
11591
|
const addIndex = process.argv.indexOf("add");
|
|
11561
11592
|
if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
|
|
11562
11593
|
return addIndex;
|
|
11563
11594
|
}
|
|
11595
|
+
function extractOption(args, flag) {
|
|
11596
|
+
const index = args.indexOf(flag);
|
|
11597
|
+
if (index === -1) return { value: void 0, remaining: args };
|
|
11598
|
+
return {
|
|
11599
|
+
value: args[index + 1],
|
|
11600
|
+
remaining: [...args.slice(0, index), ...args.slice(index + 2)]
|
|
11601
|
+
};
|
|
11602
|
+
}
|
|
11564
11603
|
function extractAddArgs(addIndex) {
|
|
11604
|
+
const rawArgs = process.argv.slice(addIndex + 3);
|
|
11605
|
+
const { value: cwd, remaining: args } = extractOption(rawArgs, "--cwd");
|
|
11565
11606
|
return {
|
|
11566
11607
|
name: process.argv[addIndex + 1],
|
|
11567
11608
|
command: process.argv[addIndex + 2],
|
|
11568
|
-
args
|
|
11609
|
+
args,
|
|
11610
|
+
cwd
|
|
11569
11611
|
};
|
|
11570
11612
|
}
|
|
11571
11613
|
function parseAddArguments() {
|
|
@@ -11594,14 +11636,14 @@ function getOrInitRunList() {
|
|
|
11594
11636
|
if (!config.run) config.run = [];
|
|
11595
11637
|
return { config, runList: config.run };
|
|
11596
11638
|
}
|
|
11597
|
-
function saveNewRunConfig(name, command, args) {
|
|
11639
|
+
function saveNewRunConfig(name, command, args, cwd) {
|
|
11598
11640
|
const { config, runList } = getOrInitRunList();
|
|
11599
11641
|
ensureNoDuplicate(runList, name);
|
|
11600
|
-
runList.push(buildRunEntry(name, command, args));
|
|
11642
|
+
runList.push(buildRunEntry(name, command, args, { cwd }));
|
|
11601
11643
|
saveConfig(config);
|
|
11602
11644
|
}
|
|
11603
11645
|
function createCommandFile(name) {
|
|
11604
|
-
const dir =
|
|
11646
|
+
const dir = join43(".claude", "commands");
|
|
11605
11647
|
mkdirSync13(dir, { recursive: true });
|
|
11606
11648
|
const content = `---
|
|
11607
11649
|
description: Run ${name}
|
|
@@ -11609,13 +11651,13 @@ description: Run ${name}
|
|
|
11609
11651
|
|
|
11610
11652
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
11611
11653
|
`;
|
|
11612
|
-
const filePath =
|
|
11654
|
+
const filePath = join43(dir, `${name}.md`);
|
|
11613
11655
|
writeFileSync28(filePath, content);
|
|
11614
11656
|
console.log(`Created command file: ${filePath}`);
|
|
11615
11657
|
}
|
|
11616
11658
|
function add3() {
|
|
11617
|
-
const { name, command, args } = requireParsedArgs();
|
|
11618
|
-
saveNewRunConfig(name, command, args);
|
|
11659
|
+
const { name, command, args, cwd } = requireParsedArgs();
|
|
11660
|
+
saveNewRunConfig(name, command, args, cwd);
|
|
11619
11661
|
createCommandFile(name);
|
|
11620
11662
|
console.log(
|
|
11621
11663
|
`Added run configuration: ${name} -> ${formatDisplay(command, args)}`
|
|
@@ -11658,16 +11700,6 @@ function listRunConfigs() {
|
|
|
11658
11700
|
console.log(`${config.name}: ${config.command}${args}`);
|
|
11659
11701
|
}
|
|
11660
11702
|
}
|
|
11661
|
-
function runPreCommands(pre) {
|
|
11662
|
-
for (const cmd of pre) {
|
|
11663
|
-
try {
|
|
11664
|
-
execSync40(cmd, { stdio: "inherit" });
|
|
11665
|
-
} catch (err) {
|
|
11666
|
-
const code = err && typeof err === "object" && "status" in err ? err.status : 1;
|
|
11667
|
-
process.exit(code);
|
|
11668
|
-
}
|
|
11669
|
-
}
|
|
11670
|
-
}
|
|
11671
11703
|
function run3(name, args) {
|
|
11672
11704
|
if (!name) {
|
|
11673
11705
|
console.error("error: missing required argument 'name'");
|
|
@@ -11675,19 +11707,21 @@ function run3(name, args) {
|
|
|
11675
11707
|
process.exit(1);
|
|
11676
11708
|
}
|
|
11677
11709
|
const runConfig = findRunConfig(name);
|
|
11678
|
-
|
|
11710
|
+
const resolvedCwd = runConfig.cwd ? resolve5(getConfigDir(), runConfig.cwd) : void 0;
|
|
11711
|
+
if (runConfig.pre) runPreCommands(runConfig.pre, resolvedCwd);
|
|
11679
11712
|
const resolved = resolveParams(runConfig.params, args);
|
|
11680
11713
|
spawnRunCommand(
|
|
11681
11714
|
buildCommand(runConfig.command, runConfig.args ?? [], resolved),
|
|
11682
|
-
runConfig.env
|
|
11715
|
+
runConfig.env,
|
|
11716
|
+
resolvedCwd
|
|
11683
11717
|
);
|
|
11684
11718
|
}
|
|
11685
11719
|
|
|
11686
11720
|
// src/commands/screenshot/index.ts
|
|
11687
11721
|
import { execSync as execSync41 } from "child_process";
|
|
11688
|
-
import { existsSync as
|
|
11722
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync14, unlinkSync as unlinkSync11, writeFileSync as writeFileSync29 } from "fs";
|
|
11689
11723
|
import { tmpdir as tmpdir6 } from "os";
|
|
11690
|
-
import { join as
|
|
11724
|
+
import { join as join44, resolve as resolve6 } from "path";
|
|
11691
11725
|
import chalk129 from "chalk";
|
|
11692
11726
|
|
|
11693
11727
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -11817,14 +11851,14 @@ Write-Output $OutputPath
|
|
|
11817
11851
|
|
|
11818
11852
|
// src/commands/screenshot/index.ts
|
|
11819
11853
|
function buildOutputPath(outputDir, processName) {
|
|
11820
|
-
if (!
|
|
11854
|
+
if (!existsSync40(outputDir)) {
|
|
11821
11855
|
mkdirSync14(outputDir, { recursive: true });
|
|
11822
11856
|
}
|
|
11823
11857
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11824
|
-
return
|
|
11858
|
+
return resolve6(outputDir, `${processName}-${timestamp}.png`);
|
|
11825
11859
|
}
|
|
11826
11860
|
function runPowerShellScript(processName, outputPath) {
|
|
11827
|
-
const scriptPath =
|
|
11861
|
+
const scriptPath = join44(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
11828
11862
|
writeFileSync29(scriptPath, captureWindowPs1, "utf-8");
|
|
11829
11863
|
try {
|
|
11830
11864
|
execSync41(
|
|
@@ -11837,7 +11871,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
11837
11871
|
}
|
|
11838
11872
|
function screenshot(processName) {
|
|
11839
11873
|
const config = loadConfig();
|
|
11840
|
-
const outputDir =
|
|
11874
|
+
const outputDir = resolve6(config.screenshot.outputDir);
|
|
11841
11875
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
11842
11876
|
console.log(chalk129.gray(`Capturing window for process "${processName}" ...`));
|
|
11843
11877
|
try {
|
|
@@ -12076,7 +12110,10 @@ program.command("commit").description("Create a git commit with validation").arg
|
|
|
12076
12110
|
registerConfig(program);
|
|
12077
12111
|
var runCommand = program.command("run").description("Run a configured command from assist.yml").argument("[name]", "Name of the configured command").argument("[args...]", "Arguments to pass to the command").allowUnknownOption().addHelpText("after", () => formatConfiguredCommands()).action((name, args) => run3(name, args));
|
|
12078
12112
|
runCommand.command("list").description("List configured run commands").action(listRunConfigs);
|
|
12079
|
-
runCommand.command("add").description("Add a new run configuration to assist.yml").argument("<name>", "Name for the run configuration").argument("<command>", "Command to execute").argument("[args...]", "Static args to pass to the command").
|
|
12113
|
+
runCommand.command("add").description("Add a new run configuration to assist.yml").argument("<name>", "Name for the run configuration").argument("<command>", "Command to execute").argument("[args...]", "Static args to pass to the command").option(
|
|
12114
|
+
"--cwd <dir>",
|
|
12115
|
+
"Working directory (resolved relative to the config file)"
|
|
12116
|
+
).addHelpText(
|
|
12080
12117
|
"after",
|
|
12081
12118
|
'\nPositional params can be added to the config manually:\n params:\n - name: env # assist run deploy prod \u2192 appends "prod"\n required: true\n - name: tag\n default: latest'
|
|
12082
12119
|
).allowUnknownOption().allowExcessArguments().action(() => add3());
|
|
@@ -12109,6 +12146,7 @@ registerRavendb(program);
|
|
|
12109
12146
|
registerSeq(program);
|
|
12110
12147
|
registerTranscript(program);
|
|
12111
12148
|
registerVoice(program);
|
|
12149
|
+
registerDeny(program);
|
|
12112
12150
|
program.command("next").description("Alias for backlog next -w").action(() => next({ allowEdits: true }));
|
|
12113
12151
|
program.command("draft").alias("feat").description("Launch Claude in /draft mode, chain into next on /next signal").action(() => launchMode("draft"));
|
|
12114
12152
|
program.command("bug").description("Launch Claude in /bug mode, chain into next on /next signal").action(() => launchMode("bug"));
|