@staff0rd/assist 0.341.2 → 0.342.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sessions/web/bundle.js +84 -84
- package/dist/index.js +407 -318
- 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.342.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -3965,7 +3965,7 @@ function spawnClaude(prompt, options2 = {}) {
|
|
|
3965
3965
|
}
|
|
3966
3966
|
function buildArgs(prompt, options2) {
|
|
3967
3967
|
if (options2.resumeSessionId) {
|
|
3968
|
-
return ["--resume", options2.resumeSessionId, prompt];
|
|
3968
|
+
return prompt ? ["--resume", options2.resumeSessionId, prompt] : ["--resume", options2.resumeSessionId];
|
|
3969
3969
|
}
|
|
3970
3970
|
if (options2.sessionId) {
|
|
3971
3971
|
return ["--session-id", options2.sessionId, prompt];
|
|
@@ -4632,6 +4632,9 @@ Failed to launch Claude for ${context}: ${message}`)
|
|
|
4632
4632
|
}
|
|
4633
4633
|
}
|
|
4634
4634
|
|
|
4635
|
+
// src/commands/sessions/setSessionStatus.ts
|
|
4636
|
+
import { appendFileSync } from "fs";
|
|
4637
|
+
|
|
4635
4638
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
4636
4639
|
import * as net from "net";
|
|
4637
4640
|
function connectToDaemon() {
|
|
@@ -4666,12 +4669,21 @@ async function sendToDaemon(message) {
|
|
|
4666
4669
|
// src/commands/sessions/setSessionStatus.ts
|
|
4667
4670
|
async function setSessionStatus(status2) {
|
|
4668
4671
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
4672
|
+
logHookFired(status2, sessionId);
|
|
4669
4673
|
if (!sessionId) return;
|
|
4670
4674
|
try {
|
|
4671
4675
|
await sendToDaemon({ type: "set-status", sessionId, status: status2 });
|
|
4672
4676
|
} catch {
|
|
4673
4677
|
}
|
|
4674
4678
|
}
|
|
4679
|
+
function logHookFired(status2, sessionId) {
|
|
4680
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] set-status hook fired: id=${sessionId ?? "none"} status=${status2}`;
|
|
4681
|
+
try {
|
|
4682
|
+
appendFileSync(daemonPaths.log, `${line}
|
|
4683
|
+
`);
|
|
4684
|
+
} catch {
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4675
4687
|
|
|
4676
4688
|
// src/commands/backlog/buildCommentLines.ts
|
|
4677
4689
|
function buildCommentLines(comments3) {
|
|
@@ -4781,11 +4793,6 @@ function buildPhasePrompt(item, phaseNumber, phase) {
|
|
|
4781
4793
|
return buildAuthoredPhasePrompt(item, phaseNumber, phase);
|
|
4782
4794
|
}
|
|
4783
4795
|
|
|
4784
|
-
// src/commands/backlog/buildResumePrompt.ts
|
|
4785
|
-
function buildResumePrompt() {
|
|
4786
|
-
return "A restart interrupted this conversation. Continue from where you left off.";
|
|
4787
|
-
}
|
|
4788
|
-
|
|
4789
4796
|
// src/shared/emitActivity.ts
|
|
4790
4797
|
import { mkdirSync as mkdirSync7, readFileSync as readFileSync14, rmSync, writeFileSync as writeFileSync17 } from "fs";
|
|
4791
4798
|
import { homedir as homedir7 } from "os";
|
|
@@ -4936,6 +4943,16 @@ Phase ${phaseNumber} completed.`));
|
|
|
4936
4943
|
return phaseIndex + 1;
|
|
4937
4944
|
}
|
|
4938
4945
|
|
|
4946
|
+
// src/commands/backlog/buildResumePrompt.ts
|
|
4947
|
+
function buildResumePrompt() {
|
|
4948
|
+
return "A restart interrupted this conversation. Continue from where you left off.";
|
|
4949
|
+
}
|
|
4950
|
+
|
|
4951
|
+
// src/commands/backlog/resumeNudge.ts
|
|
4952
|
+
function resumeNudge() {
|
|
4953
|
+
return process.env.ASSIST_RESUME_IDLE ? "" : buildResumePrompt();
|
|
4954
|
+
}
|
|
4955
|
+
|
|
4939
4956
|
// src/commands/backlog/watchForMarker.ts
|
|
4940
4957
|
import { existsSync as existsSync23, unwatchFile, watchFile } from "fs";
|
|
4941
4958
|
function watchForMarker(child, options2) {
|
|
@@ -4971,7 +4988,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4971
4988
|
process.env.ASSIST_SESSION_ID ??= String(process.pid);
|
|
4972
4989
|
reportPhaseActivity(item, phaseNumber, totalPhases, phase, claudeSessionId);
|
|
4973
4990
|
const { child, done: done2 } = spawnClaude(
|
|
4974
|
-
resumeSessionId ?
|
|
4991
|
+
resumeSessionId ? resumeNudge() : buildPhasePrompt(item, phaseNumber, phase),
|
|
4975
4992
|
resumeSessionId ? spawnOptions : { ...spawnOptions, sessionId: claudeSessionId }
|
|
4976
4993
|
);
|
|
4977
4994
|
watchForMarker(child);
|
|
@@ -5579,7 +5596,7 @@ function delay(ms) {
|
|
|
5579
5596
|
|
|
5580
5597
|
// src/commands/sessions/web/handleRequest.ts
|
|
5581
5598
|
import { createHash as createHash2 } from "crypto";
|
|
5582
|
-
import { readFileSync as
|
|
5599
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
5583
5600
|
import { createRequire as createRequire2 } from "module";
|
|
5584
5601
|
|
|
5585
5602
|
// src/shared/createBundleHandler.ts
|
|
@@ -5940,6 +5957,81 @@ function getHtml() {
|
|
|
5940
5957
|
</html>`;
|
|
5941
5958
|
}
|
|
5942
5959
|
|
|
5960
|
+
// src/commands/sessions/web/getReviewSynthesis.ts
|
|
5961
|
+
import { execFile } from "child_process";
|
|
5962
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
5963
|
+
import { homedir as homedir9 } from "os";
|
|
5964
|
+
import { basename as basename3, join as join22 } from "path";
|
|
5965
|
+
import { promisify } from "util";
|
|
5966
|
+
|
|
5967
|
+
// src/commands/sessions/web/findSynthesisForBranch.ts
|
|
5968
|
+
import { existsSync as existsSync24, readdirSync, statSync as statSync2 } from "fs";
|
|
5969
|
+
import { basename as basename2, dirname as dirname18, join as join21 } from "path";
|
|
5970
|
+
function findSynthesisForBranch(repoReviewsDir, branch) {
|
|
5971
|
+
const branchKeyPath = join21(repoReviewsDir, `${branch}-`);
|
|
5972
|
+
const parent = dirname18(branchKeyPath);
|
|
5973
|
+
const branchPrefix = basename2(branchKeyPath);
|
|
5974
|
+
if (!existsSync24(parent)) return null;
|
|
5975
|
+
const synthesisFiles = readdirSync(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join21(parent, name, "synthesis.md")).filter((path57) => existsSync24(path57)).map((path57) => ({ path: path57, mtime: statSync2(path57).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
5976
|
+
return synthesisFiles[0]?.path ?? null;
|
|
5977
|
+
}
|
|
5978
|
+
|
|
5979
|
+
// src/commands/sessions/web/getCwdParam.ts
|
|
5980
|
+
function getCwdParam(req, res) {
|
|
5981
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
5982
|
+
const cwd = url.searchParams.get("cwd");
|
|
5983
|
+
if (!cwd) {
|
|
5984
|
+
respondJson(res, 400, { error: "Missing cwd" });
|
|
5985
|
+
return null;
|
|
5986
|
+
}
|
|
5987
|
+
return cwd;
|
|
5988
|
+
}
|
|
5989
|
+
|
|
5990
|
+
// src/commands/sessions/web/windowsCwdToWslPath.ts
|
|
5991
|
+
function windowsCwdToWslPath(cwd) {
|
|
5992
|
+
const match = /^([A-Za-z]):[\\/](.*)$/.exec(cwd);
|
|
5993
|
+
if (!match) return cwd;
|
|
5994
|
+
const drive = match[1].toLowerCase();
|
|
5995
|
+
const rest = match[2].replace(/\\/g, "/");
|
|
5996
|
+
return `/mnt/${drive}/${rest}`;
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5999
|
+
// src/commands/sessions/web/getReviewSynthesis.ts
|
|
6000
|
+
var execFileAsync = promisify(execFile);
|
|
6001
|
+
function runGit(cwd, args) {
|
|
6002
|
+
return execFileAsync("git", args, {
|
|
6003
|
+
encoding: "utf8",
|
|
6004
|
+
cwd: windowsCwdToWslPath(cwd)
|
|
6005
|
+
}).then((r) => r.stdout.trim());
|
|
6006
|
+
}
|
|
6007
|
+
async function resolveSynthesisPath(cwd) {
|
|
6008
|
+
const [repoRoot, branch] = await Promise.all([
|
|
6009
|
+
runGit(cwd, ["rev-parse", "--show-toplevel"]),
|
|
6010
|
+
runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
|
|
6011
|
+
]);
|
|
6012
|
+
const repoReviewsDir = join22(
|
|
6013
|
+
homedir9(),
|
|
6014
|
+
".assist",
|
|
6015
|
+
"reviews",
|
|
6016
|
+
basename3(repoRoot)
|
|
6017
|
+
);
|
|
6018
|
+
return findSynthesisForBranch(repoReviewsDir, branch);
|
|
6019
|
+
}
|
|
6020
|
+
async function getReviewSynthesis(req, res) {
|
|
6021
|
+
const cwd = getCwdParam(req, res);
|
|
6022
|
+
if (!cwd) return;
|
|
6023
|
+
try {
|
|
6024
|
+
const path57 = await resolveSynthesisPath(cwd);
|
|
6025
|
+
if (!path57) {
|
|
6026
|
+
respondJson(res, 404, { error: "No synthesis found" });
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
respondJson(res, 200, { synthesis: readFileSync17(path57, "utf8") });
|
|
6030
|
+
} catch {
|
|
6031
|
+
respondJson(res, 404, { error: "No synthesis found" });
|
|
6032
|
+
}
|
|
6033
|
+
}
|
|
6034
|
+
|
|
5943
6035
|
// src/commands/prs/getPreferredRemoteRepo.ts
|
|
5944
6036
|
import { execSync as execSync21 } from "child_process";
|
|
5945
6037
|
var GITHUB_URL_PATTERN = /(?:git@github\.com:|https:\/\/github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?\/?$/;
|
|
@@ -6001,26 +6093,6 @@ function getPreferredRemoteRepo(cwd) {
|
|
|
6001
6093
|
return null;
|
|
6002
6094
|
}
|
|
6003
6095
|
|
|
6004
|
-
// src/commands/sessions/web/getCwdParam.ts
|
|
6005
|
-
function getCwdParam(req, res) {
|
|
6006
|
-
const url = new URL(req.url ?? "/", "http://localhost");
|
|
6007
|
-
const cwd = url.searchParams.get("cwd");
|
|
6008
|
-
if (!cwd) {
|
|
6009
|
-
respondJson(res, 400, { error: "Missing cwd" });
|
|
6010
|
-
return null;
|
|
6011
|
-
}
|
|
6012
|
-
return cwd;
|
|
6013
|
-
}
|
|
6014
|
-
|
|
6015
|
-
// src/commands/sessions/web/windowsCwdToWslPath.ts
|
|
6016
|
-
function windowsCwdToWslPath(cwd) {
|
|
6017
|
-
const match = /^([A-Za-z]):[\\/](.*)$/.exec(cwd);
|
|
6018
|
-
if (!match) return cwd;
|
|
6019
|
-
const drive = match[1].toLowerCase();
|
|
6020
|
-
const rest = match[2].replace(/\\/g, "/");
|
|
6021
|
-
return `/mnt/${drive}/${rest}`;
|
|
6022
|
-
}
|
|
6023
|
-
|
|
6024
6096
|
// src/commands/sessions/web/githubUrl.ts
|
|
6025
6097
|
function githubUrl(req, res) {
|
|
6026
6098
|
const cwd = getCwdParam(req, res);
|
|
@@ -6032,8 +6104,8 @@ function githubUrl(req, res) {
|
|
|
6032
6104
|
}
|
|
6033
6105
|
|
|
6034
6106
|
// src/commands/sessions/web/gitStatus.ts
|
|
6035
|
-
import { execFile } from "child_process";
|
|
6036
|
-
import { promisify } from "util";
|
|
6107
|
+
import { execFile as execFile2 } from "child_process";
|
|
6108
|
+
import { promisify as promisify2 } from "util";
|
|
6037
6109
|
|
|
6038
6110
|
// src/commands/sessions/web/parseGitStatus.ts
|
|
6039
6111
|
function extractPath(rest) {
|
|
@@ -6063,7 +6135,7 @@ function parseGitStatus(output) {
|
|
|
6063
6135
|
}
|
|
6064
6136
|
|
|
6065
6137
|
// src/commands/sessions/web/gitStatus.ts
|
|
6066
|
-
var
|
|
6138
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
6067
6139
|
async function gitStatus(req, res) {
|
|
6068
6140
|
const cwd = getCwdParam(req, res);
|
|
6069
6141
|
if (!cwd) return;
|
|
@@ -6076,7 +6148,7 @@ async function gitStatus(req, res) {
|
|
|
6076
6148
|
function runGitStatus(cwd) {
|
|
6077
6149
|
const args = ["status", "--porcelain"];
|
|
6078
6150
|
const { file, argv } = /^[A-Za-z]:[\\/]/.test(cwd) ? { file: "git.exe", argv: ["-C", cwd, ...args] } : { file: "git", argv: args };
|
|
6079
|
-
return
|
|
6151
|
+
return execFileAsync2(file, argv, {
|
|
6080
6152
|
encoding: "utf8",
|
|
6081
6153
|
...file === "git" ? { cwd } : {}
|
|
6082
6154
|
}).then((r) => r.stdout);
|
|
@@ -6240,8 +6312,8 @@ async function listUsageHistory(req, res) {
|
|
|
6240
6312
|
|
|
6241
6313
|
// src/commands/sessions/web/openInCode.ts
|
|
6242
6314
|
import { exec } from "child_process";
|
|
6243
|
-
import { promisify as
|
|
6244
|
-
var execAsync =
|
|
6315
|
+
import { promisify as promisify3 } from "util";
|
|
6316
|
+
var execAsync = promisify3(exec);
|
|
6245
6317
|
async function openInCode(req, res) {
|
|
6246
6318
|
const cwd = getCwdParam(req, res);
|
|
6247
6319
|
if (!cwd) return;
|
|
@@ -6257,9 +6329,9 @@ async function openInCode(req, res) {
|
|
|
6257
6329
|
}
|
|
6258
6330
|
|
|
6259
6331
|
// src/commands/sessions/web/createCachedGhJson.ts
|
|
6260
|
-
import { execFile as
|
|
6261
|
-
import { promisify as
|
|
6262
|
-
var
|
|
6332
|
+
import { execFile as execFile3 } from "child_process";
|
|
6333
|
+
import { promisify as promisify4 } from "util";
|
|
6334
|
+
var execFileAsync3 = promisify4(execFile3);
|
|
6263
6335
|
var CACHE_TTL_MS = 3e4;
|
|
6264
6336
|
function createCachedGhJson(args, parse3, fallback) {
|
|
6265
6337
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -6269,7 +6341,7 @@ function createCachedGhJson(args, parse3, fallback) {
|
|
|
6269
6341
|
if (cached && cached.expires > now) return cached.value;
|
|
6270
6342
|
let value = fallback;
|
|
6271
6343
|
try {
|
|
6272
|
-
const { stdout } = await
|
|
6344
|
+
const { stdout } = await execFileAsync3("gh", args, {
|
|
6273
6345
|
encoding: "utf8",
|
|
6274
6346
|
cwd: windowsCwdToWslPath(cwd)
|
|
6275
6347
|
});
|
|
@@ -6435,7 +6507,7 @@ function createCssHandler(packageEntry) {
|
|
|
6435
6507
|
return (req, res) => {
|
|
6436
6508
|
if (!cache) {
|
|
6437
6509
|
const resolved = require3.resolve(packageEntry);
|
|
6438
|
-
const body =
|
|
6510
|
+
const body = readFileSync18(resolved, "utf8");
|
|
6439
6511
|
const etag = `"${createHash2("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
6440
6512
|
cache = { body, etag };
|
|
6441
6513
|
}
|
|
@@ -6468,7 +6540,8 @@ var routes2 = {
|
|
|
6468
6540
|
"GET /api/pr-list": prList,
|
|
6469
6541
|
"GET /api/news/items": listNewsItems,
|
|
6470
6542
|
"GET /api/usage/history": listUsageHistory,
|
|
6471
|
-
"GET /api/backups/list": getBackups
|
|
6543
|
+
"GET /api/backups/list": getBackups,
|
|
6544
|
+
"GET /api/review/synthesis": getReviewSynthesis
|
|
6472
6545
|
};
|
|
6473
6546
|
var handleRequest = createFallbackHandler(
|
|
6474
6547
|
routes2,
|
|
@@ -7245,9 +7318,9 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
|
|
|
7245
7318
|
|
|
7246
7319
|
// src/commands/backlog/add/shared.ts
|
|
7247
7320
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7248
|
-
import { mkdtempSync, readFileSync as
|
|
7321
|
+
import { mkdtempSync, readFileSync as readFileSync19, unlinkSync as unlinkSync6, writeFileSync as writeFileSync19 } from "fs";
|
|
7249
7322
|
import { tmpdir } from "os";
|
|
7250
|
-
import { join as
|
|
7323
|
+
import { join as join23 } from "path";
|
|
7251
7324
|
import enquirer6 from "enquirer";
|
|
7252
7325
|
async function promptType() {
|
|
7253
7326
|
const { type } = await enquirer6.prompt({
|
|
@@ -7287,15 +7360,15 @@ async function promptDescription() {
|
|
|
7287
7360
|
}
|
|
7288
7361
|
function openEditor() {
|
|
7289
7362
|
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
7290
|
-
const dir = mkdtempSync(
|
|
7291
|
-
const filePath =
|
|
7363
|
+
const dir = mkdtempSync(join23(tmpdir(), "assist-"));
|
|
7364
|
+
const filePath = join23(dir, "description.md");
|
|
7292
7365
|
writeFileSync19(filePath, "");
|
|
7293
7366
|
const result = spawnSync2(editor, [filePath], { stdio: "inherit" });
|
|
7294
7367
|
if (result.status !== 0) {
|
|
7295
7368
|
unlinkSync6(filePath);
|
|
7296
7369
|
return void 0;
|
|
7297
7370
|
}
|
|
7298
|
-
const content =
|
|
7371
|
+
const content = readFileSync19(filePath, "utf8").trim();
|
|
7299
7372
|
unlinkSync6(filePath);
|
|
7300
7373
|
return content || void 0;
|
|
7301
7374
|
}
|
|
@@ -7786,7 +7859,7 @@ async function launchMode(slashCommand, options2) {
|
|
|
7786
7859
|
claudeSessionId
|
|
7787
7860
|
});
|
|
7788
7861
|
const { child, done: done2 } = spawnClaude(
|
|
7789
|
-
resumeSessionId ?
|
|
7862
|
+
resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description),
|
|
7790
7863
|
{ allowEdits: true, sessionId: claudeSessionId, resumeSessionId }
|
|
7791
7864
|
);
|
|
7792
7865
|
watchForMarker(child, { actOnDone: options2?.once });
|
|
@@ -8444,7 +8517,7 @@ function registerBacklog(program2) {
|
|
|
8444
8517
|
}
|
|
8445
8518
|
|
|
8446
8519
|
// src/commands/cliHook/index.ts
|
|
8447
|
-
import { basename as
|
|
8520
|
+
import { basename as basename4 } from "path";
|
|
8448
8521
|
|
|
8449
8522
|
// src/shared/splitCompound.ts
|
|
8450
8523
|
import { parse } from "shell-quote";
|
|
@@ -8614,12 +8687,12 @@ function findBuiltinDenyRaw(rawCommand) {
|
|
|
8614
8687
|
|
|
8615
8688
|
// src/commands/cliHook/logDeniedToolCall.ts
|
|
8616
8689
|
import { mkdirSync as mkdirSync10 } from "fs";
|
|
8617
|
-
import { homedir as
|
|
8618
|
-
import { join as
|
|
8690
|
+
import { homedir as homedir10 } from "os";
|
|
8691
|
+
import { join as join24 } from "path";
|
|
8619
8692
|
import Database from "better-sqlite3";
|
|
8620
8693
|
var _db;
|
|
8621
8694
|
function getDbDir() {
|
|
8622
|
-
return
|
|
8695
|
+
return join24(homedir10(), ".assist");
|
|
8623
8696
|
}
|
|
8624
8697
|
function initSchema2(db) {
|
|
8625
8698
|
db.exec(`
|
|
@@ -8638,7 +8711,7 @@ function openPromptsDb(dir) {
|
|
|
8638
8711
|
if (_db) return _db;
|
|
8639
8712
|
const dbDir = dir ?? getDbDir();
|
|
8640
8713
|
mkdirSync10(dbDir, { recursive: true });
|
|
8641
|
-
const db = new Database(
|
|
8714
|
+
const db = new Database(join24(dbDir, "assist.db"));
|
|
8642
8715
|
db.pragma("journal_mode = WAL");
|
|
8643
8716
|
initSchema2(db);
|
|
8644
8717
|
_db = db;
|
|
@@ -8740,17 +8813,17 @@ function extractGraphqlQuery(args) {
|
|
|
8740
8813
|
}
|
|
8741
8814
|
|
|
8742
8815
|
// src/shared/loadCliReads.ts
|
|
8743
|
-
import { existsSync as
|
|
8744
|
-
import { dirname as
|
|
8816
|
+
import { existsSync as existsSync25, readFileSync as readFileSync20, writeFileSync as writeFileSync20 } from "fs";
|
|
8817
|
+
import { dirname as dirname19, resolve as resolve8 } from "path";
|
|
8745
8818
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8746
8819
|
var __filename3 = fileURLToPath4(import.meta.url);
|
|
8747
|
-
var __dirname4 =
|
|
8820
|
+
var __dirname4 = dirname19(__filename3);
|
|
8748
8821
|
function packageRoot() {
|
|
8749
8822
|
return __dirname4;
|
|
8750
8823
|
}
|
|
8751
8824
|
function readLines(path57) {
|
|
8752
|
-
if (!
|
|
8753
|
-
return
|
|
8825
|
+
if (!existsSync25(path57)) return [];
|
|
8826
|
+
return readFileSync20(path57, "utf8").split("\n").filter((line) => line.trim() !== "");
|
|
8754
8827
|
}
|
|
8755
8828
|
var cachedReads;
|
|
8756
8829
|
var cachedWrites;
|
|
@@ -8796,14 +8869,14 @@ function findCliWrite(command) {
|
|
|
8796
8869
|
}
|
|
8797
8870
|
|
|
8798
8871
|
// src/shared/readSettingsPerms.ts
|
|
8799
|
-
import { existsSync as
|
|
8800
|
-
import { homedir as
|
|
8801
|
-
import { join as
|
|
8872
|
+
import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
|
|
8873
|
+
import { homedir as homedir11 } from "os";
|
|
8874
|
+
import { join as join25 } from "path";
|
|
8802
8875
|
function readSettingsPerms(key) {
|
|
8803
8876
|
const paths = [
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8877
|
+
join25(homedir11(), ".claude", "settings.json"),
|
|
8878
|
+
join25(process.cwd(), ".claude", "settings.json"),
|
|
8879
|
+
join25(process.cwd(), ".claude", "settings.local.json")
|
|
8807
8880
|
];
|
|
8808
8881
|
const entries = [];
|
|
8809
8882
|
for (const p of paths) {
|
|
@@ -8812,9 +8885,9 @@ function readSettingsPerms(key) {
|
|
|
8812
8885
|
return entries;
|
|
8813
8886
|
}
|
|
8814
8887
|
function readPermissionArray(filePath, key) {
|
|
8815
|
-
if (!
|
|
8888
|
+
if (!existsSync26(filePath)) return [];
|
|
8816
8889
|
try {
|
|
8817
|
-
const data = JSON.parse(
|
|
8890
|
+
const data = JSON.parse(readFileSync21(filePath, "utf8"));
|
|
8818
8891
|
const arr = data?.permissions?.[key];
|
|
8819
8892
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
8820
8893
|
} catch {
|
|
@@ -9030,7 +9103,7 @@ async function cliHook() {
|
|
|
9030
9103
|
logDeniedToolCall({
|
|
9031
9104
|
tool: input.toolName,
|
|
9032
9105
|
command: input.command,
|
|
9033
|
-
repo:
|
|
9106
|
+
repo: basename4(process.cwd()),
|
|
9034
9107
|
sessionId: process.env.CLAUDE_SESSION_ID,
|
|
9035
9108
|
denyReason: decision.permissionDecisionReason
|
|
9036
9109
|
});
|
|
@@ -9076,9 +9149,9 @@ ${reasons.join("\n")}`);
|
|
|
9076
9149
|
}
|
|
9077
9150
|
|
|
9078
9151
|
// src/commands/permitCliReads/index.ts
|
|
9079
|
-
import { existsSync as
|
|
9080
|
-
import { homedir as
|
|
9081
|
-
import { join as
|
|
9152
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync21 } from "fs";
|
|
9153
|
+
import { homedir as homedir12 } from "os";
|
|
9154
|
+
import { join as join26 } from "path";
|
|
9082
9155
|
|
|
9083
9156
|
// src/shared/checkCliAvailable.ts
|
|
9084
9157
|
import { execSync as execSync23 } from "child_process";
|
|
@@ -9367,15 +9440,15 @@ function updateSettings(cli, commands) {
|
|
|
9367
9440
|
// src/commands/permitCliReads/index.ts
|
|
9368
9441
|
function logPath(cli) {
|
|
9369
9442
|
const safeName = cli.replace(/\s+/g, "-");
|
|
9370
|
-
return
|
|
9443
|
+
return join26(homedir12(), ".assist", `cli-discover-${safeName}.log`);
|
|
9371
9444
|
}
|
|
9372
9445
|
function readCache(cli) {
|
|
9373
9446
|
const path57 = logPath(cli);
|
|
9374
|
-
if (!
|
|
9375
|
-
return
|
|
9447
|
+
if (!existsSync27(path57)) return void 0;
|
|
9448
|
+
return readFileSync22(path57, "utf8");
|
|
9376
9449
|
}
|
|
9377
9450
|
function writeCache(cli, output) {
|
|
9378
|
-
const dir =
|
|
9451
|
+
const dir = join26(homedir12(), ".assist");
|
|
9379
9452
|
mkdirSync11(dir, { recursive: true });
|
|
9380
9453
|
writeFileSync21(logPath(cli), output);
|
|
9381
9454
|
}
|
|
@@ -9504,35 +9577,35 @@ function registerCliHook(program2) {
|
|
|
9504
9577
|
}
|
|
9505
9578
|
|
|
9506
9579
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9507
|
-
import { existsSync as
|
|
9580
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
9508
9581
|
import chalk94 from "chalk";
|
|
9509
9582
|
|
|
9510
9583
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
9511
|
-
import { homedir as
|
|
9512
|
-
import { join as
|
|
9584
|
+
import { homedir as homedir13 } from "os";
|
|
9585
|
+
import { join as join27 } from "path";
|
|
9513
9586
|
function getRestrictedDir() {
|
|
9514
|
-
return
|
|
9587
|
+
return join27(homedir13(), ".assist", "restricted");
|
|
9515
9588
|
}
|
|
9516
9589
|
function getPinStatePath(pin) {
|
|
9517
|
-
return
|
|
9590
|
+
return join27(getRestrictedDir(), `code-comment-${pin}.json`);
|
|
9518
9591
|
}
|
|
9519
9592
|
|
|
9520
9593
|
// src/commands/codeComment/sweepRestrictedDir.ts
|
|
9521
|
-
import { readdirSync, statSync as
|
|
9522
|
-
import { join as
|
|
9594
|
+
import { readdirSync as readdirSync2, statSync as statSync3, unlinkSync as unlinkSync7 } from "fs";
|
|
9595
|
+
import { join as join28 } from "path";
|
|
9523
9596
|
var STALE_AFTER_MS = 30 * 60 * 1e3;
|
|
9524
9597
|
function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
9525
9598
|
let entries;
|
|
9526
9599
|
try {
|
|
9527
|
-
entries =
|
|
9600
|
+
entries = readdirSync2(dir);
|
|
9528
9601
|
} catch {
|
|
9529
9602
|
return;
|
|
9530
9603
|
}
|
|
9531
9604
|
const cutoff = Date.now() - STALE_AFTER_MS;
|
|
9532
9605
|
for (const entry of entries) {
|
|
9533
|
-
const path57 =
|
|
9606
|
+
const path57 = join28(dir, entry);
|
|
9534
9607
|
try {
|
|
9535
|
-
if (
|
|
9608
|
+
if (statSync3(path57).mtimeMs < cutoff) unlinkSync7(path57);
|
|
9536
9609
|
} catch {
|
|
9537
9610
|
continue;
|
|
9538
9611
|
}
|
|
@@ -9542,9 +9615,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
9542
9615
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
9543
9616
|
function readPinState(pin) {
|
|
9544
9617
|
const path57 = getPinStatePath(pin);
|
|
9545
|
-
if (!
|
|
9618
|
+
if (!existsSync28(path57)) return void 0;
|
|
9546
9619
|
try {
|
|
9547
|
-
const state = JSON.parse(
|
|
9620
|
+
const state = JSON.parse(readFileSync23(path57, "utf8"));
|
|
9548
9621
|
if (state.pin !== pin) return void 0;
|
|
9549
9622
|
return state;
|
|
9550
9623
|
} catch {
|
|
@@ -9559,12 +9632,12 @@ function codeCommentConfirm(pin) {
|
|
|
9559
9632
|
process.exitCode = 1;
|
|
9560
9633
|
return;
|
|
9561
9634
|
}
|
|
9562
|
-
if (!
|
|
9635
|
+
if (!existsSync28(state.file)) {
|
|
9563
9636
|
console.error(chalk94.red(`Target file no longer exists: ${state.file}`));
|
|
9564
9637
|
process.exitCode = 1;
|
|
9565
9638
|
return;
|
|
9566
9639
|
}
|
|
9567
|
-
const original =
|
|
9640
|
+
const original = readFileSync23(state.file, "utf8");
|
|
9568
9641
|
const lines = original.split("\n");
|
|
9569
9642
|
const index3 = state.line - 1;
|
|
9570
9643
|
if (index3 > lines.length) {
|
|
@@ -10410,7 +10483,7 @@ function registerConfig(program2) {
|
|
|
10410
10483
|
}
|
|
10411
10484
|
|
|
10412
10485
|
// src/commands/deploy/redirect.ts
|
|
10413
|
-
import { existsSync as
|
|
10486
|
+
import { existsSync as existsSync29, readFileSync as readFileSync24, writeFileSync as writeFileSync24 } from "fs";
|
|
10414
10487
|
import chalk107 from "chalk";
|
|
10415
10488
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
10416
10489
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -10419,11 +10492,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
10419
10492
|
</script>`;
|
|
10420
10493
|
function redirect() {
|
|
10421
10494
|
const indexPath = "index.html";
|
|
10422
|
-
if (!
|
|
10495
|
+
if (!existsSync29(indexPath)) {
|
|
10423
10496
|
console.log(chalk107.yellow("No index.html found"));
|
|
10424
10497
|
return;
|
|
10425
10498
|
}
|
|
10426
|
-
const content =
|
|
10499
|
+
const content = readFileSync24(indexPath, "utf8");
|
|
10427
10500
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
10428
10501
|
console.log(chalk107.dim("Trailing slash script already present"));
|
|
10429
10502
|
return;
|
|
@@ -10448,14 +10521,14 @@ function registerDeploy(program2) {
|
|
|
10448
10521
|
|
|
10449
10522
|
// src/commands/devlog/list/index.ts
|
|
10450
10523
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
10451
|
-
import { basename as
|
|
10524
|
+
import { basename as basename6 } from "path";
|
|
10452
10525
|
|
|
10453
10526
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
10454
|
-
import { homedir as
|
|
10455
|
-
import { join as
|
|
10456
|
-
var BLOG_REPO_ROOT =
|
|
10527
|
+
import { homedir as homedir14 } from "os";
|
|
10528
|
+
import { join as join29 } from "path";
|
|
10529
|
+
var BLOG_REPO_ROOT = join29(homedir14(), "git/blog");
|
|
10457
10530
|
function loadBlogSkipDays(repoName) {
|
|
10458
|
-
const config = loadRawYaml(
|
|
10531
|
+
const config = loadRawYaml(join29(BLOG_REPO_ROOT, "assist.yml"));
|
|
10459
10532
|
const devlog = config.devlog;
|
|
10460
10533
|
const skip2 = devlog?.skip;
|
|
10461
10534
|
return new Set(skip2?.[repoName]);
|
|
@@ -10466,17 +10539,17 @@ import { execSync as execSync24 } from "child_process";
|
|
|
10466
10539
|
import chalk108 from "chalk";
|
|
10467
10540
|
|
|
10468
10541
|
// src/shared/getRepoName.ts
|
|
10469
|
-
import { existsSync as
|
|
10470
|
-
import { basename as
|
|
10542
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
|
|
10543
|
+
import { basename as basename5, join as join30 } from "path";
|
|
10471
10544
|
function getRepoName() {
|
|
10472
10545
|
const config = loadConfig();
|
|
10473
10546
|
if (config.devlog?.name) {
|
|
10474
10547
|
return config.devlog.name;
|
|
10475
10548
|
}
|
|
10476
|
-
const packageJsonPath =
|
|
10477
|
-
if (
|
|
10549
|
+
const packageJsonPath = join30(process.cwd(), "package.json");
|
|
10550
|
+
if (existsSync30(packageJsonPath)) {
|
|
10478
10551
|
try {
|
|
10479
|
-
const content =
|
|
10552
|
+
const content = readFileSync25(packageJsonPath, "utf8");
|
|
10480
10553
|
const pkg = JSON.parse(content);
|
|
10481
10554
|
if (pkg.name) {
|
|
10482
10555
|
return pkg.name;
|
|
@@ -10484,13 +10557,13 @@ function getRepoName() {
|
|
|
10484
10557
|
} catch {
|
|
10485
10558
|
}
|
|
10486
10559
|
}
|
|
10487
|
-
return
|
|
10560
|
+
return basename5(process.cwd());
|
|
10488
10561
|
}
|
|
10489
10562
|
|
|
10490
10563
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
10491
|
-
import { readdirSync as
|
|
10492
|
-
import { join as
|
|
10493
|
-
var DEVLOG_DIR =
|
|
10564
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync26 } from "fs";
|
|
10565
|
+
import { join as join31 } from "path";
|
|
10566
|
+
var DEVLOG_DIR = join31(BLOG_REPO_ROOT, "src/content/devlog");
|
|
10494
10567
|
function extractFrontmatter(content) {
|
|
10495
10568
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
10496
10569
|
return fm?.[1] ?? null;
|
|
@@ -10516,9 +10589,9 @@ function parseFrontmatter(content, filename) {
|
|
|
10516
10589
|
}
|
|
10517
10590
|
function readDevlogFiles(callback) {
|
|
10518
10591
|
try {
|
|
10519
|
-
const files =
|
|
10592
|
+
const files = readdirSync3(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
10520
10593
|
for (const file of files) {
|
|
10521
|
-
const content =
|
|
10594
|
+
const content = readFileSync26(join31(DEVLOG_DIR, file), "utf8");
|
|
10522
10595
|
const parsed = parseFrontmatter(content, file);
|
|
10523
10596
|
if (parsed) callback(parsed);
|
|
10524
10597
|
}
|
|
@@ -10620,7 +10693,7 @@ function list3(options2) {
|
|
|
10620
10693
|
const config = loadConfig();
|
|
10621
10694
|
const days = options2.days ?? 30;
|
|
10622
10695
|
const ignore2 = options2.ignore ?? config.devlog?.ignore ?? [];
|
|
10623
|
-
const repoName =
|
|
10696
|
+
const repoName = basename6(process.cwd());
|
|
10624
10697
|
const skipDays = loadBlogSkipDays(repoName);
|
|
10625
10698
|
const devlogEntries = loadDevlogEntries(repoName);
|
|
10626
10699
|
const args = ["log"];
|
|
@@ -10906,11 +10979,11 @@ function repos(options2) {
|
|
|
10906
10979
|
|
|
10907
10980
|
// src/commands/devlog/skip.ts
|
|
10908
10981
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
10909
|
-
import { join as
|
|
10982
|
+
import { join as join32 } from "path";
|
|
10910
10983
|
import chalk113 from "chalk";
|
|
10911
10984
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
10912
10985
|
function getBlogConfigPath() {
|
|
10913
|
-
return
|
|
10986
|
+
return join32(BLOG_REPO_ROOT, "assist.yml");
|
|
10914
10987
|
}
|
|
10915
10988
|
function skip(date) {
|
|
10916
10989
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -10970,17 +11043,17 @@ function registerDevlog(program2) {
|
|
|
10970
11043
|
}
|
|
10971
11044
|
|
|
10972
11045
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
10973
|
-
import { closeSync as closeSync2, openSync as openSync2, readdirSync as
|
|
10974
|
-
import { join as
|
|
11046
|
+
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync4 } from "fs";
|
|
11047
|
+
import { join as join33 } from "path";
|
|
10975
11048
|
import chalk115 from "chalk";
|
|
10976
11049
|
|
|
10977
11050
|
// src/shared/findRepoRoot.ts
|
|
10978
|
-
import { existsSync as
|
|
11051
|
+
import { existsSync as existsSync31 } from "fs";
|
|
10979
11052
|
import path22 from "path";
|
|
10980
11053
|
function findRepoRoot(dir) {
|
|
10981
11054
|
let current = dir;
|
|
10982
11055
|
while (current !== path22.dirname(current)) {
|
|
10983
|
-
if (
|
|
11056
|
+
if (existsSync31(path22.join(current, ".git"))) {
|
|
10984
11057
|
return current;
|
|
10985
11058
|
}
|
|
10986
11059
|
current = path22.dirname(current);
|
|
@@ -10993,13 +11066,13 @@ var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
|
|
|
10993
11066
|
function isLockedDll(debugDir) {
|
|
10994
11067
|
let files;
|
|
10995
11068
|
try {
|
|
10996
|
-
files =
|
|
11069
|
+
files = readdirSync4(debugDir, { recursive: true });
|
|
10997
11070
|
} catch {
|
|
10998
11071
|
return null;
|
|
10999
11072
|
}
|
|
11000
11073
|
for (const file of files) {
|
|
11001
11074
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
11002
|
-
const dllPath =
|
|
11075
|
+
const dllPath = join33(debugDir, file);
|
|
11003
11076
|
try {
|
|
11004
11077
|
const fd = openSync2(dllPath, "r+");
|
|
11005
11078
|
closeSync2(fd);
|
|
@@ -11012,18 +11085,18 @@ function isLockedDll(debugDir) {
|
|
|
11012
11085
|
function findFirstLockedDll(dir) {
|
|
11013
11086
|
let entries;
|
|
11014
11087
|
try {
|
|
11015
|
-
entries =
|
|
11088
|
+
entries = readdirSync4(dir);
|
|
11016
11089
|
} catch {
|
|
11017
11090
|
return null;
|
|
11018
11091
|
}
|
|
11019
11092
|
if (entries.includes("bin")) {
|
|
11020
|
-
const locked = isLockedDll(
|
|
11093
|
+
const locked = isLockedDll(join33(dir, "bin", "Debug"));
|
|
11021
11094
|
if (locked) return locked;
|
|
11022
11095
|
}
|
|
11023
11096
|
for (const entry of entries) {
|
|
11024
11097
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
11025
11098
|
continue;
|
|
11026
|
-
const found = findFirstLockedDll(
|
|
11099
|
+
const found = findFirstLockedDll(join33(dir, entry));
|
|
11027
11100
|
if (found) return found;
|
|
11028
11101
|
}
|
|
11029
11102
|
return null;
|
|
@@ -11046,11 +11119,11 @@ async function checkBuildLocksCommand() {
|
|
|
11046
11119
|
}
|
|
11047
11120
|
|
|
11048
11121
|
// src/commands/dotnet/buildTree.ts
|
|
11049
|
-
import { readFileSync as
|
|
11122
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
11050
11123
|
import path23 from "path";
|
|
11051
11124
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
11052
11125
|
function getProjectRefs(csprojPath) {
|
|
11053
|
-
const content =
|
|
11126
|
+
const content = readFileSync27(csprojPath, "utf8");
|
|
11054
11127
|
const refs = [];
|
|
11055
11128
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
11056
11129
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -11067,7 +11140,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
11067
11140
|
for (const ref of getProjectRefs(abs)) {
|
|
11068
11141
|
const childAbs = path23.resolve(dir, ref);
|
|
11069
11142
|
try {
|
|
11070
|
-
|
|
11143
|
+
readFileSync27(childAbs);
|
|
11071
11144
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
11072
11145
|
} catch {
|
|
11073
11146
|
node.children.push({
|
|
@@ -11092,14 +11165,14 @@ function collectAllDeps(node) {
|
|
|
11092
11165
|
}
|
|
11093
11166
|
|
|
11094
11167
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
11095
|
-
import { readdirSync as
|
|
11168
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync28, statSync as statSync4 } from "fs";
|
|
11096
11169
|
import path24 from "path";
|
|
11097
11170
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
11098
11171
|
if (depth > maxDepth) return [];
|
|
11099
11172
|
const results = [];
|
|
11100
11173
|
let entries;
|
|
11101
11174
|
try {
|
|
11102
|
-
entries =
|
|
11175
|
+
entries = readdirSync5(dir);
|
|
11103
11176
|
} catch {
|
|
11104
11177
|
return results;
|
|
11105
11178
|
}
|
|
@@ -11108,7 +11181,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
|
11108
11181
|
continue;
|
|
11109
11182
|
const full = path24.join(dir, entry);
|
|
11110
11183
|
try {
|
|
11111
|
-
const stat2 =
|
|
11184
|
+
const stat2 = statSync4(full);
|
|
11112
11185
|
if (stat2.isFile() && entry.endsWith(".sln")) {
|
|
11113
11186
|
results.push(full);
|
|
11114
11187
|
} else if (stat2.isDirectory()) {
|
|
@@ -11127,7 +11200,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
11127
11200
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
11128
11201
|
for (const sln of slnFiles) {
|
|
11129
11202
|
try {
|
|
11130
|
-
const content =
|
|
11203
|
+
const content = readFileSync28(sln, "utf8");
|
|
11131
11204
|
if (pattern2.test(content)) {
|
|
11132
11205
|
matches.push(path24.relative(repoRoot, sln));
|
|
11133
11206
|
}
|
|
@@ -11191,12 +11264,12 @@ function printJson(tree, totalCount, solutions) {
|
|
|
11191
11264
|
}
|
|
11192
11265
|
|
|
11193
11266
|
// src/commands/dotnet/resolveCsproj.ts
|
|
11194
|
-
import { existsSync as
|
|
11267
|
+
import { existsSync as existsSync32 } from "fs";
|
|
11195
11268
|
import path25 from "path";
|
|
11196
11269
|
import chalk117 from "chalk";
|
|
11197
11270
|
function resolveCsproj(csprojPath) {
|
|
11198
11271
|
const resolved = path25.resolve(csprojPath);
|
|
11199
|
-
if (!
|
|
11272
|
+
if (!existsSync32(resolved)) {
|
|
11200
11273
|
console.error(chalk117.red(`File not found: ${resolved}`));
|
|
11201
11274
|
process.exit(1);
|
|
11202
11275
|
}
|
|
@@ -11364,17 +11437,17 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11364
11437
|
}
|
|
11365
11438
|
|
|
11366
11439
|
// src/commands/dotnet/resolveSolution.ts
|
|
11367
|
-
import { existsSync as
|
|
11440
|
+
import { existsSync as existsSync33 } from "fs";
|
|
11368
11441
|
import path26 from "path";
|
|
11369
11442
|
import chalk121 from "chalk";
|
|
11370
11443
|
|
|
11371
11444
|
// src/commands/dotnet/findSolution.ts
|
|
11372
|
-
import { readdirSync as
|
|
11373
|
-
import { dirname as
|
|
11445
|
+
import { readdirSync as readdirSync6 } from "fs";
|
|
11446
|
+
import { dirname as dirname20, join as join34 } from "path";
|
|
11374
11447
|
import chalk120 from "chalk";
|
|
11375
11448
|
function findSlnInDir(dir) {
|
|
11376
11449
|
try {
|
|
11377
|
-
return
|
|
11450
|
+
return readdirSync6(dir).filter((f) => f.endsWith(".sln")).map((f) => join34(dir, f));
|
|
11378
11451
|
} catch {
|
|
11379
11452
|
return [];
|
|
11380
11453
|
}
|
|
@@ -11395,7 +11468,7 @@ function findSolution() {
|
|
|
11395
11468
|
process.exit(1);
|
|
11396
11469
|
}
|
|
11397
11470
|
if (current === ceiling) break;
|
|
11398
|
-
current =
|
|
11471
|
+
current = dirname20(current);
|
|
11399
11472
|
}
|
|
11400
11473
|
console.error(chalk120.red("No .sln file found between cwd and repo root"));
|
|
11401
11474
|
process.exit(1);
|
|
@@ -11405,7 +11478,7 @@ function findSolution() {
|
|
|
11405
11478
|
function resolveSolution(sln) {
|
|
11406
11479
|
if (sln) {
|
|
11407
11480
|
const resolved = path26.resolve(sln);
|
|
11408
|
-
if (!
|
|
11481
|
+
if (!existsSync33(resolved)) {
|
|
11409
11482
|
console.error(chalk121.red(`Solution file not found: ${resolved}`));
|
|
11410
11483
|
process.exit(1);
|
|
11411
11484
|
}
|
|
@@ -11445,7 +11518,7 @@ function parseInspectReport(json) {
|
|
|
11445
11518
|
|
|
11446
11519
|
// src/commands/dotnet/runInspectCode.ts
|
|
11447
11520
|
import { execSync as execSync28 } from "child_process";
|
|
11448
|
-
import { existsSync as
|
|
11521
|
+
import { existsSync as existsSync34, readFileSync as readFileSync29, unlinkSync as unlinkSync9 } from "fs";
|
|
11449
11522
|
import { tmpdir as tmpdir3 } from "os";
|
|
11450
11523
|
import path27 from "path";
|
|
11451
11524
|
import chalk122 from "chalk";
|
|
@@ -11476,11 +11549,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
11476
11549
|
console.error(chalk122.red("jb inspectcode failed"));
|
|
11477
11550
|
process.exit(1);
|
|
11478
11551
|
}
|
|
11479
|
-
if (!
|
|
11552
|
+
if (!existsSync34(reportPath)) {
|
|
11480
11553
|
console.error(chalk122.red("Report file not generated"));
|
|
11481
11554
|
process.exit(1);
|
|
11482
11555
|
}
|
|
11483
|
-
const xml =
|
|
11556
|
+
const xml = readFileSync29(reportPath, "utf8");
|
|
11484
11557
|
unlinkSync9(reportPath);
|
|
11485
11558
|
return xml;
|
|
11486
11559
|
}
|
|
@@ -11783,7 +11856,7 @@ function aggregateCommitters(authorLists) {
|
|
|
11783
11856
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
11784
11857
|
import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync26 } from "fs";
|
|
11785
11858
|
import { tmpdir as tmpdir4 } from "os";
|
|
11786
|
-
import { join as
|
|
11859
|
+
import { join as join35 } from "path";
|
|
11787
11860
|
function buildArgs2(queryFile, vars) {
|
|
11788
11861
|
const args = ["api", "graphql", "-F", `query=@${queryFile}`];
|
|
11789
11862
|
for (const [key, value] of Object.entries(vars)) {
|
|
@@ -11808,7 +11881,7 @@ function throwOnGraphqlErrors(stdout) {
|
|
|
11808
11881
|
throw new Error(messages || "GraphQL request returned errors");
|
|
11809
11882
|
}
|
|
11810
11883
|
function runGhGraphql(mutation, vars) {
|
|
11811
|
-
const queryFile =
|
|
11884
|
+
const queryFile = join35(tmpdir4(), `gh-query-${Date.now()}.graphql`);
|
|
11812
11885
|
writeFileSync26(queryFile, mutation);
|
|
11813
11886
|
try {
|
|
11814
11887
|
const result = spawnSync3("gh", buildArgs2(queryFile, vars), {
|
|
@@ -11995,24 +12068,24 @@ async function countPendingHandovers(orm, origin) {
|
|
|
11995
12068
|
|
|
11996
12069
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
11997
12070
|
import {
|
|
11998
|
-
existsSync as
|
|
11999
|
-
readdirSync as
|
|
12000
|
-
readFileSync as
|
|
12071
|
+
existsSync as existsSync35,
|
|
12072
|
+
readdirSync as readdirSync7,
|
|
12073
|
+
readFileSync as readFileSync30,
|
|
12001
12074
|
rmSync as rmSync2,
|
|
12002
|
-
statSync as
|
|
12075
|
+
statSync as statSync5
|
|
12003
12076
|
} from "fs";
|
|
12004
|
-
import { basename as
|
|
12077
|
+
import { basename as basename7, join as join38 } from "path";
|
|
12005
12078
|
|
|
12006
12079
|
// src/commands/handover/getHandoverPath.ts
|
|
12007
|
-
import { join as
|
|
12080
|
+
import { join as join36 } from "path";
|
|
12008
12081
|
function getHandoverPath(cwd = process.cwd()) {
|
|
12009
|
-
return
|
|
12082
|
+
return join36(cwd, ".assist", "HANDOVER.md");
|
|
12010
12083
|
}
|
|
12011
12084
|
|
|
12012
12085
|
// src/commands/handover/getHandoversDir.ts
|
|
12013
|
-
import { join as
|
|
12086
|
+
import { join as join37 } from "path";
|
|
12014
12087
|
function getHandoversDir(cwd = process.cwd()) {
|
|
12015
|
-
return
|
|
12088
|
+
return join37(cwd, ".assist", "handovers");
|
|
12016
12089
|
}
|
|
12017
12090
|
|
|
12018
12091
|
// src/commands/handover/parseArchiveTimestamp.ts
|
|
@@ -12050,17 +12123,17 @@ function summariseHandoverContent(content) {
|
|
|
12050
12123
|
|
|
12051
12124
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
12052
12125
|
function collectMarkdown(dir) {
|
|
12053
|
-
if (!
|
|
12126
|
+
if (!existsSync35(dir)) return [];
|
|
12054
12127
|
const out = [];
|
|
12055
|
-
for (const entry of
|
|
12056
|
-
const full =
|
|
12128
|
+
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
12129
|
+
const full = join38(dir, entry.name);
|
|
12057
12130
|
if (entry.isDirectory()) out.push(...collectMarkdown(full));
|
|
12058
12131
|
else if (entry.isFile() && entry.name.endsWith(".md")) out.push(full);
|
|
12059
12132
|
}
|
|
12060
12133
|
return out;
|
|
12061
12134
|
}
|
|
12062
12135
|
async function migrateFile(orm, origin, file, createdAt) {
|
|
12063
|
-
const content =
|
|
12136
|
+
const content = readFileSync30(file, "utf8");
|
|
12064
12137
|
await saveHandover(orm, {
|
|
12065
12138
|
origin,
|
|
12066
12139
|
summary: summariseHandoverContent(content),
|
|
@@ -12072,13 +12145,13 @@ async function migrateFile(orm, origin, file, createdAt) {
|
|
|
12072
12145
|
async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
|
|
12073
12146
|
let migrated = 0;
|
|
12074
12147
|
for (const file of collectMarkdown(getHandoversDir(cwd))) {
|
|
12075
|
-
const createdAt = parseArchiveTimestamp(
|
|
12148
|
+
const createdAt = parseArchiveTimestamp(basename7(file)) ?? statSync5(file).mtime;
|
|
12076
12149
|
await migrateFile(orm, origin, file, createdAt);
|
|
12077
12150
|
migrated++;
|
|
12078
12151
|
}
|
|
12079
12152
|
const handoverPath = getHandoverPath(cwd);
|
|
12080
|
-
if (
|
|
12081
|
-
await migrateFile(orm, origin, handoverPath,
|
|
12153
|
+
if (existsSync35(handoverPath)) {
|
|
12154
|
+
await migrateFile(orm, origin, handoverPath, statSync5(handoverPath).mtime);
|
|
12082
12155
|
migrated++;
|
|
12083
12156
|
}
|
|
12084
12157
|
return migrated;
|
|
@@ -12293,20 +12366,20 @@ function acceptanceCriteria(issueKey) {
|
|
|
12293
12366
|
import { execSync as execSync30 } from "child_process";
|
|
12294
12367
|
|
|
12295
12368
|
// src/shared/loadJson.ts
|
|
12296
|
-
import { existsSync as
|
|
12297
|
-
import { homedir as
|
|
12298
|
-
import { join as
|
|
12369
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync13, readFileSync as readFileSync31, writeFileSync as writeFileSync27 } from "fs";
|
|
12370
|
+
import { homedir as homedir15 } from "os";
|
|
12371
|
+
import { join as join39 } from "path";
|
|
12299
12372
|
function getStoreDir() {
|
|
12300
|
-
return
|
|
12373
|
+
return join39(homedir15(), ".assist");
|
|
12301
12374
|
}
|
|
12302
12375
|
function getStorePath(filename) {
|
|
12303
|
-
return
|
|
12376
|
+
return join39(getStoreDir(), filename);
|
|
12304
12377
|
}
|
|
12305
12378
|
function loadJson(filename) {
|
|
12306
12379
|
const path57 = getStorePath(filename);
|
|
12307
|
-
if (
|
|
12380
|
+
if (existsSync36(path57)) {
|
|
12308
12381
|
try {
|
|
12309
|
-
return JSON.parse(
|
|
12382
|
+
return JSON.parse(readFileSync31(path57, "utf8"));
|
|
12310
12383
|
} catch {
|
|
12311
12384
|
return {};
|
|
12312
12385
|
}
|
|
@@ -12315,7 +12388,7 @@ function loadJson(filename) {
|
|
|
12315
12388
|
}
|
|
12316
12389
|
function saveJson(filename, data) {
|
|
12317
12390
|
const dir = getStoreDir();
|
|
12318
|
-
if (!
|
|
12391
|
+
if (!existsSync36(dir)) {
|
|
12319
12392
|
mkdirSync13(dir, { recursive: true });
|
|
12320
12393
|
}
|
|
12321
12394
|
writeFileSync27(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -12485,13 +12558,13 @@ function registerList(program2) {
|
|
|
12485
12558
|
}
|
|
12486
12559
|
|
|
12487
12560
|
// src/commands/mermaid/index.ts
|
|
12488
|
-
import { mkdirSync as mkdirSync14, readdirSync as
|
|
12561
|
+
import { mkdirSync as mkdirSync14, readdirSync as readdirSync8 } from "fs";
|
|
12489
12562
|
import { resolve as resolve11 } from "path";
|
|
12490
12563
|
import chalk132 from "chalk";
|
|
12491
12564
|
|
|
12492
12565
|
// src/commands/mermaid/exportFile.ts
|
|
12493
|
-
import { readFileSync as
|
|
12494
|
-
import { basename as
|
|
12566
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync28 } from "fs";
|
|
12567
|
+
import { basename as basename8, extname, resolve as resolve10 } from "path";
|
|
12495
12568
|
import chalk131 from "chalk";
|
|
12496
12569
|
|
|
12497
12570
|
// src/commands/mermaid/renderBlock.ts
|
|
@@ -12516,9 +12589,9 @@ async function renderBlock(krokiUrl, source) {
|
|
|
12516
12589
|
|
|
12517
12590
|
// src/commands/mermaid/exportFile.ts
|
|
12518
12591
|
async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
12519
|
-
const content =
|
|
12592
|
+
const content = readFileSync32(file, "utf8");
|
|
12520
12593
|
const blocks = extractMermaidBlocks(content);
|
|
12521
|
-
const stem =
|
|
12594
|
+
const stem = basename8(file, extname(file));
|
|
12522
12595
|
if (onlyIndex !== void 0) {
|
|
12523
12596
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
12524
12597
|
console.error(
|
|
@@ -12567,7 +12640,7 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
12567
12640
|
process.exit(1);
|
|
12568
12641
|
}
|
|
12569
12642
|
}
|
|
12570
|
-
const files = file ? [file] :
|
|
12643
|
+
const files = file ? [file] : readdirSync8(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
12571
12644
|
if (files.length === 0) {
|
|
12572
12645
|
console.log(chalk132.gray("No markdown files found in current directory."));
|
|
12573
12646
|
return;
|
|
@@ -12594,7 +12667,7 @@ function registerMermaid(program2) {
|
|
|
12594
12667
|
// src/commands/netcap/netcap.ts
|
|
12595
12668
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
12596
12669
|
import { createServer as createServer2 } from "http";
|
|
12597
|
-
import { dirname as
|
|
12670
|
+
import { dirname as dirname22 } from "path";
|
|
12598
12671
|
import chalk134 from "chalk";
|
|
12599
12672
|
|
|
12600
12673
|
// src/commands/netcap/corsHeaders.ts
|
|
@@ -12673,15 +12746,15 @@ function createNetcapHandler(options2) {
|
|
|
12673
12746
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
12674
12747
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
12675
12748
|
import { networkInterfaces } from "os";
|
|
12676
|
-
import { join as
|
|
12749
|
+
import { join as join41 } from "path";
|
|
12677
12750
|
import chalk133 from "chalk";
|
|
12678
12751
|
|
|
12679
12752
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
12680
|
-
import { dirname as
|
|
12753
|
+
import { dirname as dirname21, join as join40 } from "path";
|
|
12681
12754
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12682
|
-
var moduleDir =
|
|
12755
|
+
var moduleDir = dirname21(fileURLToPath5(import.meta.url));
|
|
12683
12756
|
function netcapExtensionDir() {
|
|
12684
|
-
return
|
|
12757
|
+
return join40(moduleDir, "commands", "netcap", "netcap-extension");
|
|
12685
12758
|
}
|
|
12686
12759
|
|
|
12687
12760
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
@@ -12696,7 +12769,7 @@ function lanIPv4() {
|
|
|
12696
12769
|
return void 0;
|
|
12697
12770
|
}
|
|
12698
12771
|
async function configureBackground(dir, host, port, filter) {
|
|
12699
|
-
const file =
|
|
12772
|
+
const file = join41(dir, "background.js");
|
|
12700
12773
|
const source = await readFile2(file, "utf8");
|
|
12701
12774
|
await writeFile2(
|
|
12702
12775
|
file,
|
|
@@ -12736,20 +12809,20 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
12736
12809
|
}
|
|
12737
12810
|
|
|
12738
12811
|
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
12739
|
-
import { isAbsolute, join as
|
|
12812
|
+
import { isAbsolute, join as join43, resolve as resolve12 } from "path";
|
|
12740
12813
|
|
|
12741
12814
|
// src/commands/netcap/defaultCapturePath.ts
|
|
12742
|
-
import { homedir as
|
|
12743
|
-
import { join as
|
|
12815
|
+
import { homedir as homedir16 } from "os";
|
|
12816
|
+
import { join as join42 } from "path";
|
|
12744
12817
|
function defaultCapturePath() {
|
|
12745
|
-
return
|
|
12818
|
+
return join42(homedir16(), ".assist", "netcap", "capture.jsonl");
|
|
12746
12819
|
}
|
|
12747
12820
|
|
|
12748
12821
|
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
12749
12822
|
function resolveNetcapOutPath(out) {
|
|
12750
12823
|
if (!out) return defaultCapturePath();
|
|
12751
12824
|
const dir = isAbsolute(out) ? out : resolve12(process.cwd(), out);
|
|
12752
|
-
return
|
|
12825
|
+
return join43(dir, "capture.jsonl");
|
|
12753
12826
|
}
|
|
12754
12827
|
|
|
12755
12828
|
// src/commands/netcap/netcap.ts
|
|
@@ -12757,7 +12830,7 @@ async function netcap(options2) {
|
|
|
12757
12830
|
const port = Number(options2.port);
|
|
12758
12831
|
const outPath = resolveNetcapOutPath(options2.out);
|
|
12759
12832
|
const filter = options2.filter ?? "";
|
|
12760
|
-
await mkdir3(
|
|
12833
|
+
await mkdir3(dirname22(outPath), { recursive: true });
|
|
12761
12834
|
const extensionPath = await prepareExtensionForLoad(port, filter);
|
|
12762
12835
|
let count7 = 0;
|
|
12763
12836
|
const handler = createNetcapHandler({
|
|
@@ -12796,11 +12869,11 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
|
|
|
12796
12869
|
|
|
12797
12870
|
// src/commands/netcap/netcapExtract.ts
|
|
12798
12871
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
12799
|
-
import { join as
|
|
12872
|
+
import { join as join44 } from "path";
|
|
12800
12873
|
import chalk135 from "chalk";
|
|
12801
12874
|
|
|
12802
12875
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
12803
|
-
import { readFileSync as
|
|
12876
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
12804
12877
|
|
|
12805
12878
|
// src/commands/netcap/parseRscRows.ts
|
|
12806
12879
|
var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
|
|
@@ -13196,7 +13269,7 @@ function extractVoyagerPosts(body) {
|
|
|
13196
13269
|
|
|
13197
13270
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
13198
13271
|
function captureEntries(captureFile) {
|
|
13199
|
-
const lines =
|
|
13272
|
+
const lines = readFileSync33(captureFile, "utf8").split("\n").filter(Boolean);
|
|
13200
13273
|
const entries = [];
|
|
13201
13274
|
for (const line of lines) {
|
|
13202
13275
|
let entry;
|
|
@@ -13241,7 +13314,7 @@ function extractPostsFromCapture(captureFile) {
|
|
|
13241
13314
|
function netcapExtract(file) {
|
|
13242
13315
|
const captureFile = file ?? defaultCapturePath();
|
|
13243
13316
|
const posts = extractPostsFromCapture(captureFile);
|
|
13244
|
-
const outFile =
|
|
13317
|
+
const outFile = join44(captureFile, "..", "posts.json");
|
|
13245
13318
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13246
13319
|
`);
|
|
13247
13320
|
console.log(
|
|
@@ -13677,26 +13750,26 @@ import { execSync as execSync35 } from "child_process";
|
|
|
13677
13750
|
import { execSync as execSync34 } from "child_process";
|
|
13678
13751
|
import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
13679
13752
|
import { tmpdir as tmpdir5 } from "os";
|
|
13680
|
-
import { join as
|
|
13753
|
+
import { join as join46 } from "path";
|
|
13681
13754
|
|
|
13682
13755
|
// src/commands/prs/loadCommentsCache.ts
|
|
13683
|
-
import { existsSync as
|
|
13684
|
-
import { join as
|
|
13756
|
+
import { existsSync as existsSync37, readFileSync as readFileSync34, unlinkSync as unlinkSync11 } from "fs";
|
|
13757
|
+
import { join as join45 } from "path";
|
|
13685
13758
|
import { parse as parse2 } from "yaml";
|
|
13686
13759
|
function getCachePath(prNumber) {
|
|
13687
|
-
return
|
|
13760
|
+
return join45(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
13688
13761
|
}
|
|
13689
13762
|
function loadCommentsCache(prNumber) {
|
|
13690
13763
|
const cachePath = getCachePath(prNumber);
|
|
13691
|
-
if (!
|
|
13764
|
+
if (!existsSync37(cachePath)) {
|
|
13692
13765
|
return null;
|
|
13693
13766
|
}
|
|
13694
|
-
const content =
|
|
13767
|
+
const content = readFileSync34(cachePath, "utf8");
|
|
13695
13768
|
return parse2(content);
|
|
13696
13769
|
}
|
|
13697
13770
|
function deleteCommentsCache(prNumber) {
|
|
13698
13771
|
const cachePath = getCachePath(prNumber);
|
|
13699
|
-
if (
|
|
13772
|
+
if (existsSync37(cachePath)) {
|
|
13700
13773
|
unlinkSync11(cachePath);
|
|
13701
13774
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
13702
13775
|
}
|
|
@@ -13714,7 +13787,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
13714
13787
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
13715
13788
|
function resolveThread(threadId) {
|
|
13716
13789
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
13717
|
-
const queryFile =
|
|
13790
|
+
const queryFile = join46(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
13718
13791
|
writeFileSync30(queryFile, mutation);
|
|
13719
13792
|
try {
|
|
13720
13793
|
execSync34(
|
|
@@ -13796,18 +13869,18 @@ function fixed(commentId, sha) {
|
|
|
13796
13869
|
}
|
|
13797
13870
|
|
|
13798
13871
|
// src/commands/prs/listComments/index.ts
|
|
13799
|
-
import { existsSync as
|
|
13800
|
-
import { join as
|
|
13872
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync15, writeFileSync as writeFileSync32 } from "fs";
|
|
13873
|
+
import { join as join48 } from "path";
|
|
13801
13874
|
import { stringify } from "yaml";
|
|
13802
13875
|
|
|
13803
13876
|
// src/commands/prs/fetchThreadIds.ts
|
|
13804
13877
|
import { execSync as execSync36 } from "child_process";
|
|
13805
13878
|
import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync31 } from "fs";
|
|
13806
13879
|
import { tmpdir as tmpdir6 } from "os";
|
|
13807
|
-
import { join as
|
|
13880
|
+
import { join as join47 } from "path";
|
|
13808
13881
|
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 } } } } } } }`;
|
|
13809
13882
|
function fetchThreadIds(org, repo, prNumber) {
|
|
13810
|
-
const queryFile =
|
|
13883
|
+
const queryFile = join47(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
13811
13884
|
writeFileSync31(queryFile, THREAD_QUERY);
|
|
13812
13885
|
try {
|
|
13813
13886
|
const result = execSync36(
|
|
@@ -13921,8 +13994,8 @@ function printComments2(result) {
|
|
|
13921
13994
|
|
|
13922
13995
|
// src/commands/prs/listComments/index.ts
|
|
13923
13996
|
function writeCommentsCache(prNumber, comments3) {
|
|
13924
|
-
const assistDir =
|
|
13925
|
-
if (!
|
|
13997
|
+
const assistDir = join48(process.cwd(), ".assist");
|
|
13998
|
+
if (!existsSync38(assistDir)) {
|
|
13926
13999
|
mkdirSync15(assistDir, { recursive: true });
|
|
13927
14000
|
}
|
|
13928
14001
|
const cacheData = {
|
|
@@ -13930,7 +14003,7 @@ function writeCommentsCache(prNumber, comments3) {
|
|
|
13930
14003
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13931
14004
|
comments: comments3
|
|
13932
14005
|
};
|
|
13933
|
-
const cachePath =
|
|
14006
|
+
const cachePath = join48(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
13934
14007
|
writeFileSync32(cachePath, stringify(cacheData));
|
|
13935
14008
|
}
|
|
13936
14009
|
function handleKnownErrors(error) {
|
|
@@ -13963,7 +14036,7 @@ async function listComments() {
|
|
|
13963
14036
|
];
|
|
13964
14037
|
updateCache(prNumber, allComments);
|
|
13965
14038
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
13966
|
-
const cachePath = hasLineComments ?
|
|
14039
|
+
const cachePath = hasLineComments ? join48(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
13967
14040
|
return { comments: allComments, cachePath };
|
|
13968
14041
|
} catch (error) {
|
|
13969
14042
|
const handled = handleKnownErrors(error);
|
|
@@ -16055,8 +16128,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
16055
16128
|
function clusterFiles(graph) {
|
|
16056
16129
|
const clusters = /* @__PURE__ */ new Map();
|
|
16057
16130
|
for (const file of graph.files) {
|
|
16058
|
-
const
|
|
16059
|
-
if (
|
|
16131
|
+
const basename13 = path43.basename(file, path43.extname(file));
|
|
16132
|
+
if (basename13 === "index") continue;
|
|
16060
16133
|
const importers = graph.importedBy.get(file);
|
|
16061
16134
|
if (!importers || importers.size !== 1) continue;
|
|
16062
16135
|
const parent = [...importers][0];
|
|
@@ -16468,22 +16541,22 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
|
|
|
16468
16541
|
}
|
|
16469
16542
|
|
|
16470
16543
|
// src/commands/review/buildReviewPaths.ts
|
|
16471
|
-
import { homedir as
|
|
16472
|
-
import { basename as
|
|
16544
|
+
import { homedir as homedir17 } from "os";
|
|
16545
|
+
import { basename as basename9, join as join49 } from "path";
|
|
16473
16546
|
function buildReviewPaths(repoRoot, key) {
|
|
16474
|
-
const reviewDir =
|
|
16475
|
-
|
|
16547
|
+
const reviewDir = join49(
|
|
16548
|
+
homedir17(),
|
|
16476
16549
|
".assist",
|
|
16477
16550
|
"reviews",
|
|
16478
|
-
|
|
16551
|
+
basename9(repoRoot),
|
|
16479
16552
|
key
|
|
16480
16553
|
);
|
|
16481
16554
|
return {
|
|
16482
16555
|
reviewDir,
|
|
16483
|
-
requestPath:
|
|
16484
|
-
claudePath:
|
|
16485
|
-
codexPath:
|
|
16486
|
-
synthesisPath:
|
|
16556
|
+
requestPath: join49(reviewDir, "request.md"),
|
|
16557
|
+
claudePath: join49(reviewDir, "claude.md"),
|
|
16558
|
+
codexPath: join49(reviewDir, "codex.md"),
|
|
16559
|
+
synthesisPath: join49(reviewDir, "synthesis.md")
|
|
16487
16560
|
};
|
|
16488
16561
|
}
|
|
16489
16562
|
|
|
@@ -16626,7 +16699,7 @@ function gatherContext() {
|
|
|
16626
16699
|
}
|
|
16627
16700
|
|
|
16628
16701
|
// src/commands/review/postReviewToPr.ts
|
|
16629
|
-
import { readFileSync as
|
|
16702
|
+
import { readFileSync as readFileSync35 } from "fs";
|
|
16630
16703
|
|
|
16631
16704
|
// src/commands/review/parseFindings.ts
|
|
16632
16705
|
var SEVERITIES = ["blocker", "major", "minor", "nit"];
|
|
@@ -16941,7 +17014,7 @@ async function confirmPost(prNumber, count7, options2) {
|
|
|
16941
17014
|
async function postReviewToPr(synthesisPath, options2) {
|
|
16942
17015
|
const prInfo = fetchPrDiffInfo();
|
|
16943
17016
|
const prNumber = prInfo.prNumber;
|
|
16944
|
-
const markdown =
|
|
17017
|
+
const markdown = readFileSync35(synthesisPath, "utf8");
|
|
16945
17018
|
const findings = parseFindings(markdown);
|
|
16946
17019
|
if (findings.length === 0) {
|
|
16947
17020
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -17023,10 +17096,10 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
17023
17096
|
}
|
|
17024
17097
|
|
|
17025
17098
|
// src/commands/review/prepareReviewDir.ts
|
|
17026
|
-
import { existsSync as
|
|
17099
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync16, unlinkSync as unlinkSync14, writeFileSync as writeFileSync33 } from "fs";
|
|
17027
17100
|
function clearReviewFiles(paths) {
|
|
17028
17101
|
for (const path57 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
17029
|
-
if (
|
|
17102
|
+
if (existsSync39(path57)) unlinkSync14(path57);
|
|
17030
17103
|
}
|
|
17031
17104
|
}
|
|
17032
17105
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -17094,11 +17167,11 @@ async function runBacklogSession(synthesisPath) {
|
|
|
17094
17167
|
}
|
|
17095
17168
|
|
|
17096
17169
|
// src/commands/review/cachedReviewerResult.ts
|
|
17097
|
-
import { statSync as
|
|
17170
|
+
import { statSync as statSync6 } from "fs";
|
|
17098
17171
|
function cachedReviewerResult(name, outputPath) {
|
|
17099
17172
|
let size;
|
|
17100
17173
|
try {
|
|
17101
|
-
size =
|
|
17174
|
+
size = statSync6(outputPath).size;
|
|
17102
17175
|
} catch {
|
|
17103
17176
|
return null;
|
|
17104
17177
|
}
|
|
@@ -17311,7 +17384,7 @@ function printReviewerFailures(results) {
|
|
|
17311
17384
|
}
|
|
17312
17385
|
|
|
17313
17386
|
// src/commands/review/runAndSynthesise.ts
|
|
17314
|
-
import { existsSync as
|
|
17387
|
+
import { existsSync as existsSync41, unlinkSync as unlinkSync16 } from "fs";
|
|
17315
17388
|
|
|
17316
17389
|
// src/commands/review/buildReviewerStdin.ts
|
|
17317
17390
|
var REVIEW_PROMPT = `You are acting as a reviewer for a proposed code change made by another engineer. The full review request \u2014 branch, base, changed files, and unified diff \u2014 is in the request file whose absolute path is given below.
|
|
@@ -17731,7 +17804,7 @@ function resolveClaude(args) {
|
|
|
17731
17804
|
}
|
|
17732
17805
|
|
|
17733
17806
|
// src/commands/review/runCodexReviewer.ts
|
|
17734
|
-
import { existsSync as
|
|
17807
|
+
import { existsSync as existsSync40, unlinkSync as unlinkSync15 } from "fs";
|
|
17735
17808
|
|
|
17736
17809
|
// src/commands/review/parseCodexEvent.ts
|
|
17737
17810
|
function isItemStarted(value) {
|
|
@@ -17783,7 +17856,7 @@ async function runCodexReviewer(spec) {
|
|
|
17783
17856
|
reportReviewerToolUse(spec.name, event, spinner);
|
|
17784
17857
|
}
|
|
17785
17858
|
});
|
|
17786
|
-
if (result.exitCode !== 0 &&
|
|
17859
|
+
if (result.exitCode !== 0 && existsSync40(spec.outputPath)) {
|
|
17787
17860
|
unlinkSync15(spec.outputPath);
|
|
17788
17861
|
}
|
|
17789
17862
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
@@ -17825,7 +17898,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
17825
17898
|
}
|
|
17826
17899
|
|
|
17827
17900
|
// src/commands/review/synthesise.ts
|
|
17828
|
-
import { readFileSync as
|
|
17901
|
+
import { readFileSync as readFileSync36 } from "fs";
|
|
17829
17902
|
|
|
17830
17903
|
// src/commands/review/buildSynthesisStdin.ts
|
|
17831
17904
|
var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
|
|
@@ -17881,7 +17954,7 @@ Files:
|
|
|
17881
17954
|
|
|
17882
17955
|
// src/commands/review/synthesise.ts
|
|
17883
17956
|
function printSummary2(synthesisPath) {
|
|
17884
|
-
const markdown =
|
|
17957
|
+
const markdown = readFileSync36(synthesisPath, "utf8");
|
|
17885
17958
|
console.log("");
|
|
17886
17959
|
console.log(buildReviewSummary(markdown));
|
|
17887
17960
|
console.log("");
|
|
@@ -17929,7 +18002,7 @@ async function runAndSynthesise(args) {
|
|
|
17929
18002
|
console.error("Both reviewers failed; skipping synthesis.");
|
|
17930
18003
|
return { ok: false, failures };
|
|
17931
18004
|
}
|
|
17932
|
-
if (anyFresh &&
|
|
18005
|
+
if (anyFresh && existsSync41(paths.synthesisPath)) {
|
|
17933
18006
|
unlinkSync16(paths.synthesisPath);
|
|
17934
18007
|
}
|
|
17935
18008
|
const synthesisResult = await synthesise(paths, { multi });
|
|
@@ -18779,27 +18852,27 @@ async function configure() {
|
|
|
18779
18852
|
}
|
|
18780
18853
|
|
|
18781
18854
|
// src/commands/transcript/list.ts
|
|
18782
|
-
import { existsSync as
|
|
18783
|
-
import { join as
|
|
18855
|
+
import { existsSync as existsSync42, readdirSync as readdirSync9, statSync as statSync7 } from "fs";
|
|
18856
|
+
import { join as join50 } from "path";
|
|
18784
18857
|
function list4() {
|
|
18785
18858
|
const { vttDir } = getTranscriptConfig();
|
|
18786
|
-
if (!
|
|
18787
|
-
for (const entry of
|
|
18859
|
+
if (!existsSync42(vttDir)) return;
|
|
18860
|
+
for (const entry of readdirSync9(vttDir)) {
|
|
18788
18861
|
if (!entry.endsWith(".vtt")) continue;
|
|
18789
|
-
if (
|
|
18862
|
+
if (statSync7(join50(vttDir, entry)).isDirectory()) continue;
|
|
18790
18863
|
console.log(entry);
|
|
18791
18864
|
}
|
|
18792
18865
|
}
|
|
18793
18866
|
|
|
18794
18867
|
// src/commands/transcript/move.ts
|
|
18795
18868
|
import {
|
|
18796
|
-
existsSync as
|
|
18869
|
+
existsSync as existsSync43,
|
|
18797
18870
|
mkdirSync as mkdirSync17,
|
|
18798
|
-
readFileSync as
|
|
18871
|
+
readFileSync as readFileSync37,
|
|
18799
18872
|
renameSync as renameSync2,
|
|
18800
18873
|
writeFileSync as writeFileSync35
|
|
18801
18874
|
} from "fs";
|
|
18802
|
-
import { basename as
|
|
18875
|
+
import { basename as basename10, join as join51 } from "path";
|
|
18803
18876
|
|
|
18804
18877
|
// src/commands/transcript/cleanText.ts
|
|
18805
18878
|
function cleanText(text6) {
|
|
@@ -19007,14 +19080,14 @@ function formatChatLog(messages) {
|
|
|
19007
19080
|
// src/commands/transcript/move.ts
|
|
19008
19081
|
var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
19009
19082
|
function convertVttToMarkdown(inputPath) {
|
|
19010
|
-
const cues = parseVtt(
|
|
19083
|
+
const cues = parseVtt(readFileSync37(inputPath, "utf8"));
|
|
19011
19084
|
const messages = cuesToChatMessages(deduplicateCues(cues));
|
|
19012
19085
|
return formatChatLog(messages);
|
|
19013
19086
|
}
|
|
19014
19087
|
function archiveRawVtt(vttDir, sourcePath, filename) {
|
|
19015
|
-
const processedDir =
|
|
19088
|
+
const processedDir = join51(vttDir, "processed");
|
|
19016
19089
|
mkdirSync17(processedDir, { recursive: true });
|
|
19017
|
-
renameSync2(sourcePath,
|
|
19090
|
+
renameSync2(sourcePath, join51(processedDir, filename));
|
|
19018
19091
|
}
|
|
19019
19092
|
function move(file, options2) {
|
|
19020
19093
|
const { date, client } = options2;
|
|
@@ -19023,20 +19096,20 @@ function move(file, options2) {
|
|
|
19023
19096
|
process.exit(1);
|
|
19024
19097
|
}
|
|
19025
19098
|
const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
19026
|
-
const filename =
|
|
19027
|
-
const sourcePath =
|
|
19028
|
-
if (!
|
|
19099
|
+
const filename = basename10(file);
|
|
19100
|
+
const sourcePath = join51(vttDir, filename);
|
|
19101
|
+
if (!existsSync43(sourcePath)) {
|
|
19029
19102
|
console.error(`Error: VTT file not found: ${sourcePath}`);
|
|
19030
19103
|
process.exit(1);
|
|
19031
19104
|
}
|
|
19032
|
-
const base =
|
|
19105
|
+
const base = basename10(filename, ".vtt").replace(/ Transcription$/, "");
|
|
19033
19106
|
const outputName = `${date} ${base}.md`;
|
|
19034
|
-
const formattedDir =
|
|
19107
|
+
const formattedDir = join51(transcriptsDir, client);
|
|
19035
19108
|
mkdirSync17(formattedDir, { recursive: true });
|
|
19036
|
-
const formattedPath =
|
|
19109
|
+
const formattedPath = join51(formattedDir, outputName);
|
|
19037
19110
|
writeFileSync35(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
|
|
19038
19111
|
archiveRawVtt(vttDir, sourcePath, filename);
|
|
19039
|
-
const summaryPath =
|
|
19112
|
+
const summaryPath = join51(summaryDir, client, outputName);
|
|
19040
19113
|
console.log(`Formatted transcript: ${formattedPath}`);
|
|
19041
19114
|
console.log(`Summary target: ${summaryPath}`);
|
|
19042
19115
|
}
|
|
@@ -19084,50 +19157,50 @@ function registerVerify(program2) {
|
|
|
19084
19157
|
|
|
19085
19158
|
// src/commands/voice/devices.ts
|
|
19086
19159
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
19087
|
-
import { join as
|
|
19160
|
+
import { join as join53 } from "path";
|
|
19088
19161
|
|
|
19089
19162
|
// src/commands/voice/shared.ts
|
|
19090
|
-
import { homedir as
|
|
19091
|
-
import { dirname as
|
|
19163
|
+
import { homedir as homedir18 } from "os";
|
|
19164
|
+
import { dirname as dirname24, join as join52 } from "path";
|
|
19092
19165
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
19093
|
-
var __dirname5 =
|
|
19094
|
-
var VOICE_DIR =
|
|
19166
|
+
var __dirname5 = dirname24(fileURLToPath6(import.meta.url));
|
|
19167
|
+
var VOICE_DIR = join52(homedir18(), ".assist", "voice");
|
|
19095
19168
|
var voicePaths = {
|
|
19096
19169
|
dir: VOICE_DIR,
|
|
19097
|
-
pid:
|
|
19098
|
-
log:
|
|
19099
|
-
venv:
|
|
19100
|
-
lock:
|
|
19170
|
+
pid: join52(VOICE_DIR, "voice.pid"),
|
|
19171
|
+
log: join52(VOICE_DIR, "voice.log"),
|
|
19172
|
+
venv: join52(VOICE_DIR, ".venv"),
|
|
19173
|
+
lock: join52(VOICE_DIR, "voice.lock")
|
|
19101
19174
|
};
|
|
19102
19175
|
function getPythonDir() {
|
|
19103
|
-
return
|
|
19176
|
+
return join52(__dirname5, "commands", "voice", "python");
|
|
19104
19177
|
}
|
|
19105
19178
|
function getVenvPython() {
|
|
19106
|
-
return process.platform === "win32" ?
|
|
19179
|
+
return process.platform === "win32" ? join52(voicePaths.venv, "Scripts", "python.exe") : join52(voicePaths.venv, "bin", "python");
|
|
19107
19180
|
}
|
|
19108
19181
|
function getLockDir() {
|
|
19109
19182
|
const config = loadConfig();
|
|
19110
19183
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
19111
19184
|
}
|
|
19112
19185
|
function getLockFile() {
|
|
19113
|
-
return
|
|
19186
|
+
return join52(getLockDir(), "voice.lock");
|
|
19114
19187
|
}
|
|
19115
19188
|
|
|
19116
19189
|
// src/commands/voice/devices.ts
|
|
19117
19190
|
function devices() {
|
|
19118
|
-
const script =
|
|
19191
|
+
const script = join53(getPythonDir(), "list_devices.py");
|
|
19119
19192
|
spawnSync5(getVenvPython(), [script], { stdio: "inherit" });
|
|
19120
19193
|
}
|
|
19121
19194
|
|
|
19122
19195
|
// src/commands/voice/logs.ts
|
|
19123
|
-
import { existsSync as
|
|
19196
|
+
import { existsSync as existsSync44, readFileSync as readFileSync38 } from "fs";
|
|
19124
19197
|
function logs(options2) {
|
|
19125
|
-
if (!
|
|
19198
|
+
if (!existsSync44(voicePaths.log)) {
|
|
19126
19199
|
console.log("No voice log file found");
|
|
19127
19200
|
return;
|
|
19128
19201
|
}
|
|
19129
19202
|
const count7 = Number.parseInt(options2.lines ?? "150", 10);
|
|
19130
|
-
const content =
|
|
19203
|
+
const content = readFileSync38(voicePaths.log, "utf8").trim();
|
|
19131
19204
|
if (!content) {
|
|
19132
19205
|
console.log("Voice log is empty");
|
|
19133
19206
|
return;
|
|
@@ -19150,12 +19223,12 @@ function logs(options2) {
|
|
|
19150
19223
|
// src/commands/voice/setup.ts
|
|
19151
19224
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
19152
19225
|
import { mkdirSync as mkdirSync19 } from "fs";
|
|
19153
|
-
import { join as
|
|
19226
|
+
import { join as join55 } from "path";
|
|
19154
19227
|
|
|
19155
19228
|
// src/commands/voice/checkLockFile.ts
|
|
19156
19229
|
import { execSync as execSync48 } from "child_process";
|
|
19157
|
-
import { existsSync as
|
|
19158
|
-
import { join as
|
|
19230
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync18, readFileSync as readFileSync39, writeFileSync as writeFileSync36 } from "fs";
|
|
19231
|
+
import { join as join54 } from "path";
|
|
19159
19232
|
function isProcessAlive2(pid) {
|
|
19160
19233
|
try {
|
|
19161
19234
|
process.kill(pid, 0);
|
|
@@ -19166,9 +19239,9 @@ function isProcessAlive2(pid) {
|
|
|
19166
19239
|
}
|
|
19167
19240
|
function checkLockFile() {
|
|
19168
19241
|
const lockFile = getLockFile();
|
|
19169
|
-
if (!
|
|
19242
|
+
if (!existsSync45(lockFile)) return;
|
|
19170
19243
|
try {
|
|
19171
|
-
const lock2 = JSON.parse(
|
|
19244
|
+
const lock2 = JSON.parse(readFileSync39(lockFile, "utf8"));
|
|
19172
19245
|
if (lock2.pid && isProcessAlive2(lock2.pid)) {
|
|
19173
19246
|
console.error(
|
|
19174
19247
|
`Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
|
|
@@ -19179,7 +19252,7 @@ function checkLockFile() {
|
|
|
19179
19252
|
}
|
|
19180
19253
|
}
|
|
19181
19254
|
function bootstrapVenv() {
|
|
19182
|
-
if (
|
|
19255
|
+
if (existsSync45(getVenvPython())) return;
|
|
19183
19256
|
console.log("Setting up Python environment...");
|
|
19184
19257
|
const pythonDir = getPythonDir();
|
|
19185
19258
|
execSync48(
|
|
@@ -19192,7 +19265,7 @@ function bootstrapVenv() {
|
|
|
19192
19265
|
}
|
|
19193
19266
|
function writeLockFile(pid) {
|
|
19194
19267
|
const lockFile = getLockFile();
|
|
19195
|
-
mkdirSync18(
|
|
19268
|
+
mkdirSync18(join54(lockFile, ".."), { recursive: true });
|
|
19196
19269
|
writeFileSync36(
|
|
19197
19270
|
lockFile,
|
|
19198
19271
|
JSON.stringify({
|
|
@@ -19208,7 +19281,7 @@ function setup() {
|
|
|
19208
19281
|
mkdirSync19(voicePaths.dir, { recursive: true });
|
|
19209
19282
|
bootstrapVenv();
|
|
19210
19283
|
console.log("\nDownloading models...\n");
|
|
19211
|
-
const script =
|
|
19284
|
+
const script = join55(getPythonDir(), "setup_models.py");
|
|
19212
19285
|
const result = spawnSync6(getVenvPython(), [script], {
|
|
19213
19286
|
stdio: "inherit",
|
|
19214
19287
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -19222,7 +19295,7 @@ function setup() {
|
|
|
19222
19295
|
// src/commands/voice/start.ts
|
|
19223
19296
|
import { spawn as spawn7 } from "child_process";
|
|
19224
19297
|
import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync37 } from "fs";
|
|
19225
|
-
import { join as
|
|
19298
|
+
import { join as join56 } from "path";
|
|
19226
19299
|
|
|
19227
19300
|
// src/commands/voice/buildDaemonEnv.ts
|
|
19228
19301
|
function buildDaemonEnv(options2) {
|
|
@@ -19260,7 +19333,7 @@ function start2(options2) {
|
|
|
19260
19333
|
bootstrapVenv();
|
|
19261
19334
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
19262
19335
|
const env = buildDaemonEnv({ debug });
|
|
19263
|
-
const script =
|
|
19336
|
+
const script = join56(getPythonDir(), "voice_daemon.py");
|
|
19264
19337
|
const python = getVenvPython();
|
|
19265
19338
|
if (options2.foreground) {
|
|
19266
19339
|
spawnForeground(python, script, env);
|
|
@@ -19270,7 +19343,7 @@ function start2(options2) {
|
|
|
19270
19343
|
}
|
|
19271
19344
|
|
|
19272
19345
|
// src/commands/voice/status.ts
|
|
19273
|
-
import { existsSync as
|
|
19346
|
+
import { existsSync as existsSync46, readFileSync as readFileSync40 } from "fs";
|
|
19274
19347
|
function isProcessAlive3(pid) {
|
|
19275
19348
|
try {
|
|
19276
19349
|
process.kill(pid, 0);
|
|
@@ -19280,16 +19353,16 @@ function isProcessAlive3(pid) {
|
|
|
19280
19353
|
}
|
|
19281
19354
|
}
|
|
19282
19355
|
function readRecentLogs(count7) {
|
|
19283
|
-
if (!
|
|
19284
|
-
const lines =
|
|
19356
|
+
if (!existsSync46(voicePaths.log)) return [];
|
|
19357
|
+
const lines = readFileSync40(voicePaths.log, "utf8").trim().split("\n");
|
|
19285
19358
|
return lines.slice(-count7);
|
|
19286
19359
|
}
|
|
19287
19360
|
function status() {
|
|
19288
|
-
if (!
|
|
19361
|
+
if (!existsSync46(voicePaths.pid)) {
|
|
19289
19362
|
console.log("Voice daemon: not running (no PID file)");
|
|
19290
19363
|
return;
|
|
19291
19364
|
}
|
|
19292
|
-
const pid = Number.parseInt(
|
|
19365
|
+
const pid = Number.parseInt(readFileSync40(voicePaths.pid, "utf8").trim(), 10);
|
|
19293
19366
|
const alive = isProcessAlive3(pid);
|
|
19294
19367
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
19295
19368
|
const recent = readRecentLogs(5);
|
|
@@ -19308,13 +19381,13 @@ function status() {
|
|
|
19308
19381
|
}
|
|
19309
19382
|
|
|
19310
19383
|
// src/commands/voice/stop.ts
|
|
19311
|
-
import { existsSync as
|
|
19384
|
+
import { existsSync as existsSync47, readFileSync as readFileSync41, unlinkSync as unlinkSync17 } from "fs";
|
|
19312
19385
|
function stop2() {
|
|
19313
|
-
if (!
|
|
19386
|
+
if (!existsSync47(voicePaths.pid)) {
|
|
19314
19387
|
console.log("Voice daemon is not running (no PID file)");
|
|
19315
19388
|
return;
|
|
19316
19389
|
}
|
|
19317
|
-
const pid = Number.parseInt(
|
|
19390
|
+
const pid = Number.parseInt(readFileSync41(voicePaths.pid, "utf8").trim(), 10);
|
|
19318
19391
|
try {
|
|
19319
19392
|
process.kill(pid, "SIGTERM");
|
|
19320
19393
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -19327,7 +19400,7 @@ function stop2() {
|
|
|
19327
19400
|
}
|
|
19328
19401
|
try {
|
|
19329
19402
|
const lockFile = getLockFile();
|
|
19330
|
-
if (
|
|
19403
|
+
if (existsSync47(lockFile)) unlinkSync17(lockFile);
|
|
19331
19404
|
} catch {
|
|
19332
19405
|
}
|
|
19333
19406
|
console.log("Voice daemon stopped");
|
|
@@ -19505,19 +19578,19 @@ async function auth() {
|
|
|
19505
19578
|
|
|
19506
19579
|
// src/commands/roam/postRoamActivity.ts
|
|
19507
19580
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
19508
|
-
import { readdirSync as
|
|
19509
|
-
import { join as
|
|
19581
|
+
import { readdirSync as readdirSync10, readFileSync as readFileSync42, statSync as statSync8 } from "fs";
|
|
19582
|
+
import { join as join57 } from "path";
|
|
19510
19583
|
function findPortFile(roamDir) {
|
|
19511
19584
|
let entries;
|
|
19512
19585
|
try {
|
|
19513
|
-
entries =
|
|
19586
|
+
entries = readdirSync10(roamDir);
|
|
19514
19587
|
} catch {
|
|
19515
19588
|
return void 0;
|
|
19516
19589
|
}
|
|
19517
19590
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
19518
|
-
const path57 =
|
|
19591
|
+
const path57 = join57(roamDir, name);
|
|
19519
19592
|
try {
|
|
19520
|
-
return { path: path57, mtimeMs:
|
|
19593
|
+
return { path: path57, mtimeMs: statSync8(path57).mtimeMs };
|
|
19521
19594
|
} catch {
|
|
19522
19595
|
return void 0;
|
|
19523
19596
|
}
|
|
@@ -19527,11 +19600,11 @@ function findPortFile(roamDir) {
|
|
|
19527
19600
|
function postRoamActivity(app, event) {
|
|
19528
19601
|
const appData = process.env.APPDATA;
|
|
19529
19602
|
if (!appData) return;
|
|
19530
|
-
const portFile = findPortFile(
|
|
19603
|
+
const portFile = findPortFile(join57(appData, "Roam"));
|
|
19531
19604
|
if (!portFile) return;
|
|
19532
19605
|
let port;
|
|
19533
19606
|
try {
|
|
19534
|
-
port =
|
|
19607
|
+
port = readFileSync42(portFile, "utf8").trim();
|
|
19535
19608
|
} catch {
|
|
19536
19609
|
return;
|
|
19537
19610
|
}
|
|
@@ -19673,15 +19746,15 @@ function runPreCommands(pre, cwd) {
|
|
|
19673
19746
|
|
|
19674
19747
|
// src/commands/run/spawnRunCommand.ts
|
|
19675
19748
|
import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
|
|
19676
|
-
import { existsSync as
|
|
19677
|
-
import { dirname as
|
|
19749
|
+
import { existsSync as existsSync48 } from "fs";
|
|
19750
|
+
import { dirname as dirname25, join as join58, resolve as resolve13 } from "path";
|
|
19678
19751
|
function resolveCommand2(command) {
|
|
19679
19752
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
19680
19753
|
try {
|
|
19681
19754
|
const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
19682
|
-
const gitRoot = resolve13(
|
|
19683
|
-
const gitBash =
|
|
19684
|
-
if (
|
|
19755
|
+
const gitRoot = resolve13(dirname25(gitPath), "..");
|
|
19756
|
+
const gitBash = join58(gitRoot, "bin", "bash.exe");
|
|
19757
|
+
if (existsSync48(gitBash)) return gitBash;
|
|
19685
19758
|
} catch {
|
|
19686
19759
|
}
|
|
19687
19760
|
return command;
|
|
@@ -19767,7 +19840,7 @@ async function run3(name, args) {
|
|
|
19767
19840
|
|
|
19768
19841
|
// src/commands/run/add.ts
|
|
19769
19842
|
import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync38 } from "fs";
|
|
19770
|
-
import { join as
|
|
19843
|
+
import { join as join59 } from "path";
|
|
19771
19844
|
|
|
19772
19845
|
// src/commands/run/extractOption.ts
|
|
19773
19846
|
function extractOption(args, flag) {
|
|
@@ -19828,7 +19901,7 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
19828
19901
|
saveConfig(config);
|
|
19829
19902
|
}
|
|
19830
19903
|
function createCommandFile(name) {
|
|
19831
|
-
const dir =
|
|
19904
|
+
const dir = join59(".claude", "commands");
|
|
19832
19905
|
mkdirSync21(dir, { recursive: true });
|
|
19833
19906
|
const content = `---
|
|
19834
19907
|
description: Run ${name}
|
|
@@ -19836,7 +19909,7 @@ description: Run ${name}
|
|
|
19836
19909
|
|
|
19837
19910
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
19838
19911
|
`;
|
|
19839
|
-
const filePath =
|
|
19912
|
+
const filePath = join59(dir, `${name}.md`);
|
|
19840
19913
|
writeFileSync38(filePath, content);
|
|
19841
19914
|
console.log(`Created command file: ${filePath}`);
|
|
19842
19915
|
}
|
|
@@ -19892,8 +19965,8 @@ function link2() {
|
|
|
19892
19965
|
}
|
|
19893
19966
|
|
|
19894
19967
|
// src/commands/run/remove.ts
|
|
19895
|
-
import { existsSync as
|
|
19896
|
-
import { join as
|
|
19968
|
+
import { existsSync as existsSync49, unlinkSync as unlinkSync18 } from "fs";
|
|
19969
|
+
import { join as join60 } from "path";
|
|
19897
19970
|
function findRemoveIndex() {
|
|
19898
19971
|
const idx = process.argv.indexOf("remove");
|
|
19899
19972
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -19908,8 +19981,8 @@ function parseRemoveName() {
|
|
|
19908
19981
|
return process.argv[idx + 1];
|
|
19909
19982
|
}
|
|
19910
19983
|
function deleteCommandFile(name) {
|
|
19911
|
-
const filePath =
|
|
19912
|
-
if (
|
|
19984
|
+
const filePath = join60(".claude", "commands", `${name}.md`);
|
|
19985
|
+
if (existsSync49(filePath)) {
|
|
19913
19986
|
unlinkSync18(filePath);
|
|
19914
19987
|
console.log(`Deleted command file: ${filePath}`);
|
|
19915
19988
|
}
|
|
@@ -19948,9 +20021,9 @@ function registerRun(program2) {
|
|
|
19948
20021
|
|
|
19949
20022
|
// src/commands/screenshot/index.ts
|
|
19950
20023
|
import { execSync as execSync50 } from "child_process";
|
|
19951
|
-
import { existsSync as
|
|
20024
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
19952
20025
|
import { tmpdir as tmpdir7 } from "os";
|
|
19953
|
-
import { join as
|
|
20026
|
+
import { join as join61, resolve as resolve15 } from "path";
|
|
19954
20027
|
import chalk179 from "chalk";
|
|
19955
20028
|
|
|
19956
20029
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -20080,14 +20153,14 @@ Write-Output $OutputPath
|
|
|
20080
20153
|
|
|
20081
20154
|
// src/commands/screenshot/index.ts
|
|
20082
20155
|
function buildOutputPath(outputDir, processName) {
|
|
20083
|
-
if (!
|
|
20156
|
+
if (!existsSync50(outputDir)) {
|
|
20084
20157
|
mkdirSync22(outputDir, { recursive: true });
|
|
20085
20158
|
}
|
|
20086
20159
|
const timestamp4 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
20087
20160
|
return resolve15(outputDir, `${processName}-${timestamp4}.png`);
|
|
20088
20161
|
}
|
|
20089
20162
|
function runPowerShellScript(processName, outputPath) {
|
|
20090
|
-
const scriptPath =
|
|
20163
|
+
const scriptPath = join61(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
20091
20164
|
writeFileSync39(scriptPath, captureWindowPs1, "utf8");
|
|
20092
20165
|
try {
|
|
20093
20166
|
execSync50(
|
|
@@ -20164,7 +20237,7 @@ function applyLine(result, pending, line) {
|
|
|
20164
20237
|
}
|
|
20165
20238
|
|
|
20166
20239
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
20167
|
-
import { readFileSync as
|
|
20240
|
+
import { readFileSync as readFileSync43 } from "fs";
|
|
20168
20241
|
function reportStolenSocket(socketPid) {
|
|
20169
20242
|
if (!socketPid) return;
|
|
20170
20243
|
const filePid = readPidFile();
|
|
@@ -20176,7 +20249,7 @@ function reportStolenSocket(socketPid) {
|
|
|
20176
20249
|
function readPidFile() {
|
|
20177
20250
|
try {
|
|
20178
20251
|
const pid = Number.parseInt(
|
|
20179
|
-
|
|
20252
|
+
readFileSync43(daemonPaths.pid, "utf8").trim(),
|
|
20180
20253
|
10
|
|
20181
20254
|
);
|
|
20182
20255
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -20252,6 +20325,7 @@ var persistedSessionSchema = z5.object({
|
|
|
20252
20325
|
title: z5.string().optional(),
|
|
20253
20326
|
subtitle: z5.string().optional(),
|
|
20254
20327
|
commandType: z5.enum(["claude", "run", "assist"]),
|
|
20328
|
+
status: z5.enum(["running", "waiting", "done", "error"]).optional(),
|
|
20255
20329
|
cwd: z5.string(),
|
|
20256
20330
|
startedAt: z5.number(),
|
|
20257
20331
|
runningMs: z5.number().optional(),
|
|
@@ -20294,6 +20368,7 @@ function toPersistedSession(session) {
|
|
|
20294
20368
|
title: session.title,
|
|
20295
20369
|
subtitle: session.subtitle,
|
|
20296
20370
|
commandType: session.commandType,
|
|
20371
|
+
status: session.status,
|
|
20297
20372
|
cwd: session.cwd ?? process.cwd(),
|
|
20298
20373
|
startedAt: session.startedAt,
|
|
20299
20374
|
runningMs: accumulatedRunningMs(session),
|
|
@@ -20528,7 +20603,7 @@ var ClientHub = class extends Set {
|
|
|
20528
20603
|
import * as pty from "node-pty";
|
|
20529
20604
|
|
|
20530
20605
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
20531
|
-
import { chmodSync, existsSync as
|
|
20606
|
+
import { chmodSync, existsSync as existsSync51, statSync as statSync9 } from "fs";
|
|
20532
20607
|
import { createRequire as createRequire3 } from "module";
|
|
20533
20608
|
import path49 from "path";
|
|
20534
20609
|
var require4 = createRequire3(import.meta.url);
|
|
@@ -20543,13 +20618,13 @@ function ensureSpawnHelperExecutable() {
|
|
|
20543
20618
|
`${process.platform}-${process.arch}`,
|
|
20544
20619
|
"spawn-helper"
|
|
20545
20620
|
);
|
|
20546
|
-
if (!
|
|
20547
|
-
const mode =
|
|
20621
|
+
if (!existsSync51(helper)) return;
|
|
20622
|
+
const mode = statSync9(helper).mode;
|
|
20548
20623
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
20549
20624
|
}
|
|
20550
20625
|
|
|
20551
20626
|
// src/commands/sessions/daemon/spawnPty.ts
|
|
20552
|
-
function spawnPty(args, cwd, sessionId) {
|
|
20627
|
+
function spawnPty(args, cwd, sessionId, extraEnv) {
|
|
20553
20628
|
ensureSpawnHelperExecutable();
|
|
20554
20629
|
const shell = process.platform === "win32" ? "cmd.exe" : process.env.SHELL ?? "bash";
|
|
20555
20630
|
const shellArgs = process.platform === "win32" ? ["/c", ...args] : ["-l", "-c", `exec ${args.map(shellEscape).join(" ")}`];
|
|
@@ -20565,7 +20640,8 @@ function spawnPty(args, cwd, sessionId) {
|
|
|
20565
20640
|
...sessionId && {
|
|
20566
20641
|
ASSIST_SESSION_ID: sessionId,
|
|
20567
20642
|
ASSIST_ACTIVITY_ID: sessionId
|
|
20568
|
-
}
|
|
20643
|
+
},
|
|
20644
|
+
...extraEnv
|
|
20569
20645
|
}
|
|
20570
20646
|
});
|
|
20571
20647
|
}
|
|
@@ -20819,13 +20895,19 @@ function assistResumeArgs(persisted) {
|
|
|
20819
20895
|
|
|
20820
20896
|
// src/commands/sessions/daemon/runningSession.ts
|
|
20821
20897
|
function runningSession(base, persisted, pty2) {
|
|
20898
|
+
return restoredSession(base, persisted, pty2, "running");
|
|
20899
|
+
}
|
|
20900
|
+
function waitingSession(base, persisted, pty2) {
|
|
20901
|
+
return restoredSession(base, persisted, pty2, "waiting");
|
|
20902
|
+
}
|
|
20903
|
+
function restoredSession(base, persisted, pty2, status2) {
|
|
20822
20904
|
const startedAt = Date.now();
|
|
20823
20905
|
return {
|
|
20824
20906
|
...base,
|
|
20825
|
-
status:
|
|
20907
|
+
status: status2,
|
|
20826
20908
|
startedAt,
|
|
20827
20909
|
runningMs: persisted.runningMs ?? 0,
|
|
20828
|
-
runningSince: startedAt,
|
|
20910
|
+
runningSince: status2 === "running" ? startedAt : null,
|
|
20829
20911
|
pty: pty2,
|
|
20830
20912
|
claudeSessionId: persisted.claudeSessionId,
|
|
20831
20913
|
restored: true,
|
|
@@ -20844,13 +20926,14 @@ function restoreInteractiveSession(id2, persisted, base) {
|
|
|
20844
20926
|
return notRestoredStub(base, persisted);
|
|
20845
20927
|
}
|
|
20846
20928
|
function resumeViaClaude(id2, persisted, base) {
|
|
20929
|
+
const idle = persisted.status === "waiting";
|
|
20847
20930
|
const pty2 = spawnClaude2({
|
|
20848
20931
|
resumeSessionId: persisted.claudeSessionId,
|
|
20849
|
-
prompt: buildResumePrompt(),
|
|
20932
|
+
prompt: idle ? void 0 : buildResumePrompt(),
|
|
20850
20933
|
cwd: persisted.cwd,
|
|
20851
20934
|
sessionId: id2
|
|
20852
20935
|
});
|
|
20853
|
-
return runningSession(base, persisted, pty2);
|
|
20936
|
+
return idle ? waitingSession(base, persisted, pty2) : runningSession(base, persisted, pty2);
|
|
20854
20937
|
}
|
|
20855
20938
|
function unrecoverableClaude(id2, persisted) {
|
|
20856
20939
|
return errorSession(
|
|
@@ -20893,8 +20976,14 @@ function restoreSession(id2, persisted) {
|
|
|
20893
20976
|
const base = restoreBase(id2, persisted);
|
|
20894
20977
|
if (isUpdate(persisted)) return updatedSession(id2, persisted);
|
|
20895
20978
|
if (needsWrapperRelaunch(persisted)) {
|
|
20896
|
-
const
|
|
20897
|
-
|
|
20979
|
+
const idle = persisted.status === "waiting";
|
|
20980
|
+
const pty2 = spawnPty(
|
|
20981
|
+
assistResumeArgs(persisted),
|
|
20982
|
+
persisted.cwd,
|
|
20983
|
+
id2,
|
|
20984
|
+
idle ? { ASSIST_RESUME_IDLE: "1" } : void 0
|
|
20985
|
+
);
|
|
20986
|
+
return idle ? waitingSession(base, persisted, pty2) : runningSession(base, persisted, pty2);
|
|
20898
20987
|
}
|
|
20899
20988
|
return restoreInteractiveSession(id2, persisted, base);
|
|
20900
20989
|
}
|
|
@@ -20988,8 +21077,8 @@ function resumeSession(id2, sessionId, cwd, name) {
|
|
|
20988
21077
|
}
|
|
20989
21078
|
|
|
20990
21079
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
20991
|
-
import { existsSync as
|
|
20992
|
-
import { dirname as
|
|
21080
|
+
import { existsSync as existsSync52, mkdirSync as mkdirSync23, watch } from "fs";
|
|
21081
|
+
import { dirname as dirname26 } from "path";
|
|
20993
21082
|
|
|
20994
21083
|
// src/commands/sessions/daemon/applyReviewPause.ts
|
|
20995
21084
|
function applyReviewPause(session, activity2) {
|
|
@@ -21007,7 +21096,7 @@ var DEBOUNCE_MS = 50;
|
|
|
21007
21096
|
function watchActivity(session, notify2) {
|
|
21008
21097
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
21009
21098
|
const path57 = activityPath(session.id);
|
|
21010
|
-
const dir =
|
|
21099
|
+
const dir = dirname26(path57);
|
|
21011
21100
|
try {
|
|
21012
21101
|
mkdirSync23(dir, { recursive: true });
|
|
21013
21102
|
} catch {
|
|
@@ -21030,7 +21119,7 @@ function watchActivity(session, notify2) {
|
|
|
21030
21119
|
if (timer) clearTimeout(timer);
|
|
21031
21120
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
21032
21121
|
});
|
|
21033
|
-
if (
|
|
21122
|
+
if (existsSync52(path57)) read();
|
|
21034
21123
|
}
|
|
21035
21124
|
function refreshActivity(session) {
|
|
21036
21125
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -22307,7 +22396,7 @@ function handleConnection(socket, manager) {
|
|
|
22307
22396
|
import { unlinkSync as unlinkSync20, writeFileSync as writeFileSync40 } from "fs";
|
|
22308
22397
|
|
|
22309
22398
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
22310
|
-
import { readFileSync as
|
|
22399
|
+
import { readFileSync as readFileSync44 } from "fs";
|
|
22311
22400
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
22312
22401
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
22313
22402
|
const timer = setInterval(() => {
|
|
@@ -22318,7 +22407,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
22318
22407
|
}
|
|
22319
22408
|
function ownsPidFile() {
|
|
22320
22409
|
try {
|
|
22321
|
-
return
|
|
22410
|
+
return readFileSync44(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
22322
22411
|
} catch {
|
|
22323
22412
|
return false;
|
|
22324
22413
|
}
|