@staff0rd/assist 0.488.4 → 0.489.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/allowed.cli-reads +1 -0
- package/dist/allowed.cli-reads +1 -0
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +862 -525
- 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.489.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -2415,8 +2415,8 @@ function printDiff(oldContent, newContent) {
|
|
|
2415
2415
|
normalizeJson(newContent)
|
|
2416
2416
|
);
|
|
2417
2417
|
for (const change of changes) {
|
|
2418
|
-
const
|
|
2419
|
-
for (const line of
|
|
2418
|
+
const lines2 = change.value.replace(/\n$/, "").split("\n");
|
|
2419
|
+
for (const line of lines2) {
|
|
2420
2420
|
if (change.added) {
|
|
2421
2421
|
console.log(chalk12.green(`+ ${line}`));
|
|
2422
2422
|
} else if (change.removed) {
|
|
@@ -2863,11 +2863,11 @@ function removeVscodeFromGitignore() {
|
|
|
2863
2863
|
return;
|
|
2864
2864
|
}
|
|
2865
2865
|
const content = fs3.readFileSync(gitignorePath, "utf8");
|
|
2866
|
-
const
|
|
2867
|
-
const filteredLines =
|
|
2866
|
+
const lines2 = content.split("\n");
|
|
2867
|
+
const filteredLines = lines2.filter(
|
|
2868
2868
|
(line) => !line.trim().toLowerCase().includes(".vscode")
|
|
2869
2869
|
);
|
|
2870
|
-
if (filteredLines.length !==
|
|
2870
|
+
if (filteredLines.length !== lines2.length) {
|
|
2871
2871
|
fs3.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
2872
2872
|
console.log(chalk20.dim("Removed .vscode references from .gitignore"));
|
|
2873
2873
|
}
|
|
@@ -3269,11 +3269,11 @@ ${checkName} failed:
|
|
|
3269
3269
|
// src/commands/lint/lint/runImportExtensionCheck.ts
|
|
3270
3270
|
function checkForImportExtensions(filePath) {
|
|
3271
3271
|
const content = fs12.readFileSync(filePath, "utf8");
|
|
3272
|
-
const
|
|
3272
|
+
const lines2 = content.split("\n");
|
|
3273
3273
|
const violations = [];
|
|
3274
3274
|
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
3275
|
-
for (let i = 0; i <
|
|
3276
|
-
const line =
|
|
3275
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
3276
|
+
const line = lines2[i];
|
|
3277
3277
|
if (importExtensionPattern.test(line)) {
|
|
3278
3278
|
violations.push({
|
|
3279
3279
|
filePath,
|
|
@@ -3305,12 +3305,12 @@ function runImportExtensionCheck() {
|
|
|
3305
3305
|
import fs13 from "fs";
|
|
3306
3306
|
function checkForDynamicImports(filePath) {
|
|
3307
3307
|
const content = fs13.readFileSync(filePath, "utf8");
|
|
3308
|
-
const
|
|
3308
|
+
const lines2 = content.split("\n");
|
|
3309
3309
|
const violations = [];
|
|
3310
3310
|
const requirePattern = /\brequire\s*\(/;
|
|
3311
3311
|
const dynamicImportPattern = /\bimport\s*\(/;
|
|
3312
|
-
for (let i = 0; i <
|
|
3313
|
-
const line =
|
|
3312
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
3313
|
+
const line = lines2[i];
|
|
3314
3314
|
if (requirePattern.test(line) || dynamicImportPattern.test(line)) {
|
|
3315
3315
|
violations.push({
|
|
3316
3316
|
filePath,
|
|
@@ -3412,9 +3412,9 @@ function collectBicepComments(content) {
|
|
|
3412
3412
|
comments3.push({ line, text: match });
|
|
3413
3413
|
return blankNonNewline(match);
|
|
3414
3414
|
});
|
|
3415
|
-
const
|
|
3416
|
-
for (let i = 0; i <
|
|
3417
|
-
const match =
|
|
3415
|
+
const lines2 = work.split("\n");
|
|
3416
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
3417
|
+
const match = lines2[i].match(LINE_COMMENT);
|
|
3418
3418
|
if (match) comments3.push({ line: i + 1, text: match[0] });
|
|
3419
3419
|
}
|
|
3420
3420
|
return comments3;
|
|
@@ -3429,14 +3429,14 @@ function isHeaderLine(line) {
|
|
|
3429
3429
|
return trimmed === "" || trimmed.startsWith("#");
|
|
3430
3430
|
}
|
|
3431
3431
|
function collectHashComments(content, options2) {
|
|
3432
|
-
const
|
|
3432
|
+
const lines2 = content.split("\n");
|
|
3433
3433
|
let start3 = 0;
|
|
3434
3434
|
if (options2.skipHeader) {
|
|
3435
|
-
while (start3 <
|
|
3435
|
+
while (start3 < lines2.length && isHeaderLine(lines2[start3])) start3++;
|
|
3436
3436
|
}
|
|
3437
3437
|
const comments3 = [];
|
|
3438
|
-
for (let i = start3; i <
|
|
3439
|
-
const work =
|
|
3438
|
+
for (let i = start3; i < lines2.length; i++) {
|
|
3439
|
+
const work = lines2[i].replace(
|
|
3440
3440
|
/"(?:[^"\\]|\\.)*"|'(?:[^']|'')*'/g,
|
|
3441
3441
|
blankNonNewline2
|
|
3442
3442
|
);
|
|
@@ -3470,8 +3470,8 @@ function collectComments(sourceFile) {
|
|
|
3470
3470
|
var MAINTAINABILITY_OVERRIDE_MARKER = "assist-maintainability-override";
|
|
3471
3471
|
var OVERRIDE_MARKER = /^\s*\/\/\s*assist-maintainability-override:?\s*(-?\d+)\s*$/;
|
|
3472
3472
|
function parseMaintainabilityOverride(content) {
|
|
3473
|
-
const
|
|
3474
|
-
for (const line of
|
|
3473
|
+
const lines2 = content.split("\n").slice(0, 10);
|
|
3474
|
+
for (const line of lines2) {
|
|
3475
3475
|
const match = line.match(OVERRIDE_MARKER);
|
|
3476
3476
|
if (!match) continue;
|
|
3477
3477
|
const value = Number(match[1]);
|
|
@@ -3508,12 +3508,12 @@ function isCommentExempt(text17) {
|
|
|
3508
3508
|
function toSingleLine(text17) {
|
|
3509
3509
|
return text17.replace(/\s+/g, " ").trim();
|
|
3510
3510
|
}
|
|
3511
|
-
function collectSourceFindings(file,
|
|
3511
|
+
function collectSourceFindings(file, lines2, project) {
|
|
3512
3512
|
const findings = [];
|
|
3513
3513
|
const sourceFile = project.addSourceFileAtPath(file);
|
|
3514
3514
|
for (const { pos, text: text17 } of collectComments(sourceFile)) {
|
|
3515
3515
|
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
3516
|
-
if (!
|
|
3516
|
+
if (!lines2.has(line)) continue;
|
|
3517
3517
|
if (isCommentExempt(text17)) continue;
|
|
3518
3518
|
findings.push({ file, line, text: toSingleLine(text17) });
|
|
3519
3519
|
}
|
|
@@ -3533,29 +3533,29 @@ function collectYamlComments(content) {
|
|
|
3533
3533
|
}
|
|
3534
3534
|
|
|
3535
3535
|
// src/commands/verify/blockCodeComments/collectFileComments.ts
|
|
3536
|
-
function toFindings(file,
|
|
3536
|
+
function toFindings(file, lines2, raw, exempt) {
|
|
3537
3537
|
const findings = [];
|
|
3538
3538
|
for (const { line, text: text17 } of raw) {
|
|
3539
|
-
if (!
|
|
3539
|
+
if (!lines2.has(line)) continue;
|
|
3540
3540
|
if (exempt && isCommentExempt(text17)) continue;
|
|
3541
3541
|
findings.push({ file, line, text: text17.replace(/\s+/g, " ").trim() });
|
|
3542
3542
|
}
|
|
3543
3543
|
return findings;
|
|
3544
3544
|
}
|
|
3545
|
-
function collectFileComments(file,
|
|
3545
|
+
function collectFileComments(file, lines2, project) {
|
|
3546
3546
|
const read = () => fs14.readFileSync(file, "utf8");
|
|
3547
3547
|
if (isYamlFile(file))
|
|
3548
|
-
return toFindings(file,
|
|
3548
|
+
return toFindings(file, lines2, collectYamlComments(read()), false);
|
|
3549
3549
|
if (isDockerfile(file) || isEnvFile(file) || isShellFile(file))
|
|
3550
3550
|
return toFindings(
|
|
3551
3551
|
file,
|
|
3552
|
-
|
|
3552
|
+
lines2,
|
|
3553
3553
|
collectHashComments(read(), { skipHeader: isShellFile(file) }),
|
|
3554
3554
|
true
|
|
3555
3555
|
);
|
|
3556
3556
|
if (isBicepFile(file))
|
|
3557
|
-
return toFindings(file,
|
|
3558
|
-
return collectSourceFindings(file,
|
|
3557
|
+
return toFindings(file, lines2, collectBicepComments(read()), true);
|
|
3558
|
+
return collectSourceFindings(file, lines2, project);
|
|
3559
3559
|
}
|
|
3560
3560
|
|
|
3561
3561
|
// src/commands/verify/blockCodeComments/parseDiffAddedLines.ts
|
|
@@ -3623,9 +3623,9 @@ function findComments(options2) {
|
|
|
3623
3623
|
compilerOptions: { allowJs: true }
|
|
3624
3624
|
});
|
|
3625
3625
|
const findings = [];
|
|
3626
|
-
for (const [file,
|
|
3626
|
+
for (const [file, lines2] of addedLines) {
|
|
3627
3627
|
if (!shouldScan(file, options2.ignoreGlobs)) continue;
|
|
3628
|
-
findings.push(...collectFileComments(file,
|
|
3628
|
+
findings.push(...collectFileComments(file, lines2, project));
|
|
3629
3629
|
}
|
|
3630
3630
|
findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
3631
3631
|
return findings;
|
|
@@ -3658,10 +3658,10 @@ function getDocumentedConfigKeys() {
|
|
|
3658
3658
|
}
|
|
3659
3659
|
function renderConfigHelp(entries, preamble) {
|
|
3660
3660
|
const width = Math.max(...entries.map((entry) => entry.setter.length));
|
|
3661
|
-
const
|
|
3661
|
+
const lines2 = entries.map(
|
|
3662
3662
|
(entry) => ` ${entry.setter.padEnd(width)} # ${entry.note}`
|
|
3663
3663
|
);
|
|
3664
|
-
const body = preamble ? ["", preamble, "", "Config:", ...
|
|
3664
|
+
const body = preamble ? ["", preamble, "", "Config:", ...lines2] : ["", "Config:", ...lines2];
|
|
3665
3665
|
return body.join("\n");
|
|
3666
3666
|
}
|
|
3667
3667
|
function configHelp(command, entries, preamble) {
|
|
@@ -3960,14 +3960,14 @@ function findRuleViolations(data, rule) {
|
|
|
3960
3960
|
}
|
|
3961
3961
|
return violations;
|
|
3962
3962
|
}
|
|
3963
|
-
function findForbiddenStrings(
|
|
3964
|
-
return
|
|
3963
|
+
function findForbiddenStrings(rules2, readJson) {
|
|
3964
|
+
return rules2.flatMap((rule) => findRuleViolations(readJson(rule.file), rule));
|
|
3965
3965
|
}
|
|
3966
3966
|
|
|
3967
3967
|
// src/commands/verify/forbiddenStrings/index.ts
|
|
3968
3968
|
function forbiddenStrings() {
|
|
3969
|
-
const
|
|
3970
|
-
if (
|
|
3969
|
+
const rules2 = loadConfig().forbiddenStrings ?? [];
|
|
3970
|
+
if (rules2.length === 0) {
|
|
3971
3971
|
console.log("No forbidden-strings rules configured.");
|
|
3972
3972
|
process.exit(0);
|
|
3973
3973
|
}
|
|
@@ -3988,7 +3988,7 @@ function forbiddenStrings() {
|
|
|
3988
3988
|
cache4.set(file, parsed);
|
|
3989
3989
|
return parsed;
|
|
3990
3990
|
};
|
|
3991
|
-
const violations = findForbiddenStrings(
|
|
3991
|
+
const violations = findForbiddenStrings(rules2, readJson);
|
|
3992
3992
|
if (violations.length === 0) {
|
|
3993
3993
|
console.log("No forbidden strings found.");
|
|
3994
3994
|
process.exit(0);
|
|
@@ -4015,18 +4015,18 @@ function hardcodedColors() {
|
|
|
4015
4015
|
const output = execSync13(`grep -rEnH '${pattern}' src/`, {
|
|
4016
4016
|
encoding: "utf8"
|
|
4017
4017
|
});
|
|
4018
|
-
const
|
|
4018
|
+
const lines2 = output.trim().split("\n").filter((line) => {
|
|
4019
4019
|
const match = line.match(/^(.+?):\d+:/);
|
|
4020
4020
|
if (!match) return true;
|
|
4021
4021
|
const file = match[1];
|
|
4022
4022
|
return !ignoreGlobs.some((glob) => minimatch3(file, glob));
|
|
4023
4023
|
});
|
|
4024
|
-
if (
|
|
4024
|
+
if (lines2.length === 0) {
|
|
4025
4025
|
console.log("No hardcoded colors found.");
|
|
4026
4026
|
process.exit(0);
|
|
4027
4027
|
}
|
|
4028
4028
|
console.log("Hardcoded colors found:\n");
|
|
4029
|
-
for (const line of
|
|
4029
|
+
for (const line of lines2) {
|
|
4030
4030
|
const match = line.match(/^(.+):(\d+):(.+)$/);
|
|
4031
4031
|
if (match) {
|
|
4032
4032
|
const [, file, lineNum, content] = match;
|
|
@@ -4036,7 +4036,7 @@ function hardcodedColors() {
|
|
|
4036
4036
|
}
|
|
4037
4037
|
}
|
|
4038
4038
|
console.log(`
|
|
4039
|
-
Total: ${
|
|
4039
|
+
Total: ${lines2.length} hardcoded color(s)`);
|
|
4040
4040
|
console.log("\nUse colors from the 'open-color' (oc) library instead.");
|
|
4041
4041
|
console.log("\nExample fix:");
|
|
4042
4042
|
console.log(" Before: color: '#228be6'");
|
|
@@ -4523,7 +4523,7 @@ ${failed2.length} script(s) failed:`);
|
|
|
4523
4523
|
}
|
|
4524
4524
|
}
|
|
4525
4525
|
function runEntry(entry) {
|
|
4526
|
-
return new Promise((
|
|
4526
|
+
return new Promise((resolve22) => {
|
|
4527
4527
|
const startTime = Date.now();
|
|
4528
4528
|
const child = spawnCommand(
|
|
4529
4529
|
entry.fullCommand,
|
|
@@ -4535,7 +4535,7 @@ function runEntry(entry) {
|
|
|
4535
4535
|
child.on("close", (code) => {
|
|
4536
4536
|
const exitCode = code ?? 1;
|
|
4537
4537
|
flushIfFailed(exitCode, chunks);
|
|
4538
|
-
|
|
4538
|
+
resolve22({
|
|
4539
4539
|
script: entry.name,
|
|
4540
4540
|
code: exitCode,
|
|
4541
4541
|
durationMs: Date.now() - startTime
|
|
@@ -5158,38 +5158,38 @@ var END_MARKER = "# <<< assist backup schedule <<<";
|
|
|
5158
5158
|
function buildBlock(every, cronLine) {
|
|
5159
5159
|
return [BEGIN_MARKER, `# every ${every}`, cronLine, END_MARKER];
|
|
5160
5160
|
}
|
|
5161
|
-
function findBlockRange(
|
|
5162
|
-
const start3 =
|
|
5161
|
+
function findBlockRange(lines2) {
|
|
5162
|
+
const start3 = lines2.indexOf(BEGIN_MARKER);
|
|
5163
5163
|
if (start3 === -1) return void 0;
|
|
5164
|
-
const end =
|
|
5164
|
+
const end = lines2.indexOf(END_MARKER, start3);
|
|
5165
5165
|
if (end === -1) return void 0;
|
|
5166
5166
|
return { start: start3, end };
|
|
5167
5167
|
}
|
|
5168
5168
|
function upsertScheduleBlock(crontab, every, cronLine) {
|
|
5169
|
-
const
|
|
5169
|
+
const lines2 = crontab.length === 0 ? [] : crontab.replace(/\n$/, "").split("\n");
|
|
5170
5170
|
const block = buildBlock(every, cronLine);
|
|
5171
|
-
const range = findBlockRange(
|
|
5172
|
-
const next3 = range === void 0 ? [...
|
|
5173
|
-
...
|
|
5171
|
+
const range = findBlockRange(lines2);
|
|
5172
|
+
const next3 = range === void 0 ? [...lines2, ...block] : [
|
|
5173
|
+
...lines2.slice(0, range.start),
|
|
5174
5174
|
...block,
|
|
5175
|
-
...
|
|
5175
|
+
...lines2.slice(range.end + 1)
|
|
5176
5176
|
];
|
|
5177
5177
|
return `${next3.join("\n")}
|
|
5178
5178
|
`;
|
|
5179
5179
|
}
|
|
5180
5180
|
function removeScheduleBlock(crontab) {
|
|
5181
|
-
const
|
|
5182
|
-
const range = findBlockRange(
|
|
5181
|
+
const lines2 = crontab.length === 0 ? [] : crontab.replace(/\n$/, "").split("\n");
|
|
5182
|
+
const range = findBlockRange(lines2);
|
|
5183
5183
|
if (range === void 0) return crontab;
|
|
5184
|
-
const next3 = [...
|
|
5184
|
+
const next3 = [...lines2.slice(0, range.start), ...lines2.slice(range.end + 1)];
|
|
5185
5185
|
return next3.length === 0 ? "" : `${next3.join("\n")}
|
|
5186
5186
|
`;
|
|
5187
5187
|
}
|
|
5188
5188
|
function readScheduleBlock(crontab) {
|
|
5189
|
-
const
|
|
5190
|
-
const range = findBlockRange(
|
|
5189
|
+
const lines2 = crontab.length === 0 ? [] : crontab.split("\n");
|
|
5190
|
+
const range = findBlockRange(lines2);
|
|
5191
5191
|
if (range === void 0) return void 0;
|
|
5192
|
-
const body =
|
|
5192
|
+
const body = lines2.slice(range.start + 1, range.end);
|
|
5193
5193
|
const everyLine = body.find((line) => line.startsWith("# every "));
|
|
5194
5194
|
const cronLine = body.find(
|
|
5195
5195
|
(line) => !line.startsWith("#") && line.trim() !== ""
|
|
@@ -5705,8 +5705,8 @@ function spawnInherit(command, args, options2 = {}) {
|
|
|
5705
5705
|
env,
|
|
5706
5706
|
cwd: options2.cwd
|
|
5707
5707
|
});
|
|
5708
|
-
const done2 = new Promise((
|
|
5709
|
-
child.on("close", (code) =>
|
|
5708
|
+
const done2 = new Promise((resolve22, reject) => {
|
|
5709
|
+
child.on("close", (code) => resolve22(code ?? 0));
|
|
5710
5710
|
child.on("error", reject);
|
|
5711
5711
|
});
|
|
5712
5712
|
return { child, done: done2 };
|
|
@@ -6851,9 +6851,9 @@ Failed to launch Claude for ${context}: ${message3}`)
|
|
|
6851
6851
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
6852
6852
|
import * as net from "net";
|
|
6853
6853
|
function connectToDaemon() {
|
|
6854
|
-
return new Promise((
|
|
6854
|
+
return new Promise((resolve22, reject) => {
|
|
6855
6855
|
const socket = net.connect(daemonPaths.socket);
|
|
6856
|
-
socket.once("connect", () =>
|
|
6856
|
+
socket.once("connect", () => resolve22(socket));
|
|
6857
6857
|
socket.once("error", reject);
|
|
6858
6858
|
});
|
|
6859
6859
|
}
|
|
@@ -6869,7 +6869,7 @@ async function isDaemonRunning() {
|
|
|
6869
6869
|
// src/commands/sessions/daemon/sendToDaemon.ts
|
|
6870
6870
|
var WRITE_TIMEOUT_MS = 500;
|
|
6871
6871
|
function sendToDaemon(message3) {
|
|
6872
|
-
return new Promise((
|
|
6872
|
+
return new Promise((resolve22, reject) => {
|
|
6873
6873
|
connectToDaemon().then((socket) => {
|
|
6874
6874
|
const timer = setTimeout(() => {
|
|
6875
6875
|
socket.destroy();
|
|
@@ -6883,7 +6883,7 @@ function sendToDaemon(message3) {
|
|
|
6883
6883
|
`, () => {
|
|
6884
6884
|
clearTimeout(timer);
|
|
6885
6885
|
socket.end();
|
|
6886
|
-
|
|
6886
|
+
resolve22();
|
|
6887
6887
|
});
|
|
6888
6888
|
}, reject);
|
|
6889
6889
|
});
|
|
@@ -6906,7 +6906,7 @@ function readSocketLines(socket, onLine) {
|
|
|
6906
6906
|
// src/commands/sessions/daemon/sendToDaemonAwaitAck.ts
|
|
6907
6907
|
var ACK_TIMEOUT_MS = 1e3;
|
|
6908
6908
|
function sendToDaemonAwaitAck(message3) {
|
|
6909
|
-
return new Promise((
|
|
6909
|
+
return new Promise((resolve22, reject) => {
|
|
6910
6910
|
connectToDaemon().then((socket) => {
|
|
6911
6911
|
let settled = false;
|
|
6912
6912
|
const finish = (error) => {
|
|
@@ -6915,7 +6915,7 @@ function sendToDaemonAwaitAck(message3) {
|
|
|
6915
6915
|
clearTimeout(timer);
|
|
6916
6916
|
socket.destroy();
|
|
6917
6917
|
if (error) reject(error);
|
|
6918
|
-
else
|
|
6918
|
+
else resolve22();
|
|
6919
6919
|
};
|
|
6920
6920
|
const timer = setTimeout(
|
|
6921
6921
|
() => finish(new Error("timed out awaiting daemon ack")),
|
|
@@ -6989,7 +6989,7 @@ async function deliverReliably(sessionId, status3, payload) {
|
|
|
6989
6989
|
}
|
|
6990
6990
|
}
|
|
6991
6991
|
function sleep(ms) {
|
|
6992
|
-
return new Promise((
|
|
6992
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
6993
6993
|
}
|
|
6994
6994
|
function describeError(error) {
|
|
6995
6995
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -7631,14 +7631,14 @@ function backlogRunMarkers(text17) {
|
|
|
7631
7631
|
}
|
|
7632
7632
|
|
|
7633
7633
|
// src/commands/sessions/shared/extractSessionMeta.ts
|
|
7634
|
-
function extractSessionMeta(
|
|
7634
|
+
function extractSessionMeta(lines2) {
|
|
7635
7635
|
let sessionId = "";
|
|
7636
7636
|
let cwd = "";
|
|
7637
7637
|
let timestamp6 = "";
|
|
7638
7638
|
let name = "";
|
|
7639
7639
|
let commandName = "";
|
|
7640
7640
|
let commandArgs = "";
|
|
7641
|
-
for (const line of
|
|
7641
|
+
for (const line of lines2) {
|
|
7642
7642
|
const entry = safeParse(line);
|
|
7643
7643
|
if (!entry) continue;
|
|
7644
7644
|
sessionId ||= strField(entry, "sessionId");
|
|
@@ -8645,7 +8645,7 @@ function spawnDaemon(reason4) {
|
|
|
8645
8645
|
child.unref();
|
|
8646
8646
|
}
|
|
8647
8647
|
function delay(ms) {
|
|
8648
|
-
return new Promise((
|
|
8648
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
8649
8649
|
}
|
|
8650
8650
|
|
|
8651
8651
|
// src/commands/sessions/daemon/isWindowsCwd.ts
|
|
@@ -8682,10 +8682,10 @@ function gitInvocation(cwd, args) {
|
|
|
8682
8682
|
}
|
|
8683
8683
|
function git2(cwd, args) {
|
|
8684
8684
|
const { file, argv, options: options2 } = gitInvocation(cwd, args);
|
|
8685
|
-
return new Promise((
|
|
8685
|
+
return new Promise((resolve22, reject) => {
|
|
8686
8686
|
execFile2(file, argv, options2, (error, stdout) => {
|
|
8687
8687
|
if (error) reject(error);
|
|
8688
|
-
else
|
|
8688
|
+
else resolve22(stdout.toString());
|
|
8689
8689
|
});
|
|
8690
8690
|
});
|
|
8691
8691
|
}
|
|
@@ -9097,12 +9097,12 @@ async function loadVisibleItems(req) {
|
|
|
9097
9097
|
|
|
9098
9098
|
// src/commands/backlog/web/parseStatusBody.ts
|
|
9099
9099
|
function readBody(req) {
|
|
9100
|
-
return new Promise((
|
|
9100
|
+
return new Promise((resolve22, reject) => {
|
|
9101
9101
|
let body = "";
|
|
9102
9102
|
req.on("data", (chunk) => {
|
|
9103
9103
|
body += chunk.toString();
|
|
9104
9104
|
});
|
|
9105
|
-
req.on("end", () =>
|
|
9105
|
+
req.on("end", () => resolve22(body));
|
|
9106
9106
|
req.on("error", reject);
|
|
9107
9107
|
});
|
|
9108
9108
|
}
|
|
@@ -10586,17 +10586,17 @@ async function stopDaemon() {
|
|
|
10586
10586
|
}
|
|
10587
10587
|
}
|
|
10588
10588
|
function closedBeforeTimeout(socket) {
|
|
10589
|
-
return new Promise((
|
|
10589
|
+
return new Promise((resolve22) => {
|
|
10590
10590
|
const timer = setTimeout(() => {
|
|
10591
10591
|
socket.destroy();
|
|
10592
|
-
|
|
10592
|
+
resolve22(false);
|
|
10593
10593
|
}, STOP_TIMEOUT_MS);
|
|
10594
10594
|
socket.resume();
|
|
10595
10595
|
socket.on("error", () => {
|
|
10596
10596
|
});
|
|
10597
10597
|
socket.once("close", () => {
|
|
10598
10598
|
clearTimeout(timer);
|
|
10599
|
-
|
|
10599
|
+
resolve22(true);
|
|
10600
10600
|
});
|
|
10601
10601
|
});
|
|
10602
10602
|
}
|
|
@@ -10647,8 +10647,8 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
10647
10647
|
respondJson(res, 400, { error: "Invalid target" });
|
|
10648
10648
|
return;
|
|
10649
10649
|
}
|
|
10650
|
-
await new Promise((
|
|
10651
|
-
res.once("finish",
|
|
10650
|
+
await new Promise((resolve22) => {
|
|
10651
|
+
res.once("finish", resolve22);
|
|
10652
10652
|
respondJson(res, 200, { ok: true });
|
|
10653
10653
|
});
|
|
10654
10654
|
if (target === "daemon" || target === "both") {
|
|
@@ -11185,8 +11185,8 @@ async function runGhImage(filePath, cwd) {
|
|
|
11185
11185
|
`gh image failed: ${stderr.trim() || err.message || "unknown error"}`
|
|
11186
11186
|
);
|
|
11187
11187
|
}
|
|
11188
|
-
const
|
|
11189
|
-
const markdown =
|
|
11188
|
+
const lines2 = stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
11189
|
+
const markdown = lines2.find((line) => /^!\[.*]\(.+\)$/.test(line)) ?? lines2.find((line) => line.includes("http")) ?? lines2[0];
|
|
11190
11190
|
if (!markdown) throw new Error("gh image produced no output");
|
|
11191
11191
|
return markdown;
|
|
11192
11192
|
}
|
|
@@ -11377,10 +11377,10 @@ async function openDaemonConnection(ws, ctx) {
|
|
|
11377
11377
|
}
|
|
11378
11378
|
}
|
|
11379
11379
|
function relayDaemonLines(conn, ws, repoCwd) {
|
|
11380
|
-
const
|
|
11381
|
-
|
|
11380
|
+
const lines2 = createInterface2({ input: conn });
|
|
11381
|
+
lines2.on("error", () => {
|
|
11382
11382
|
});
|
|
11383
|
-
|
|
11383
|
+
lines2.on("line", (line) => {
|
|
11384
11384
|
if (ws.readyState === ws.OPEN) ws.send(withRepoCwd(line, repoCwd));
|
|
11385
11385
|
});
|
|
11386
11386
|
conn.on("error", () => {
|
|
@@ -11522,7 +11522,7 @@ function firstEnabledIndex(items2) {
|
|
|
11522
11522
|
// src/commands/sessions/web/restartMenu/renderRestartMenu.ts
|
|
11523
11523
|
import chalk59 from "chalk";
|
|
11524
11524
|
function renderRestartMenu(items2, selected) {
|
|
11525
|
-
const
|
|
11525
|
+
const lines2 = [chalk59.bold.cyan("assist \u2014 restart menu")];
|
|
11526
11526
|
items2.forEach((item, i) => {
|
|
11527
11527
|
const active = i === selected;
|
|
11528
11528
|
const pointer = active ? chalk59.cyan("\u276F ") : " ";
|
|
@@ -11531,10 +11531,10 @@ function renderRestartMenu(items2, selected) {
|
|
|
11531
11531
|
let label2 = item.label;
|
|
11532
11532
|
if (item.disabled) label2 = chalk59.dim(label2);
|
|
11533
11533
|
else if (active) label2 = chalk59.cyan.bold(label2);
|
|
11534
|
-
|
|
11534
|
+
lines2.push(`${pointer}${number}${label2}${note}`);
|
|
11535
11535
|
});
|
|
11536
|
-
|
|
11537
|
-
return
|
|
11536
|
+
lines2.push(chalk59.dim("\u2191/\u2193 move \xB7 1-3 jump \xB7 enter select \xB7 esc close"));
|
|
11537
|
+
return lines2.join("\n");
|
|
11538
11538
|
}
|
|
11539
11539
|
|
|
11540
11540
|
// src/commands/sessions/web/restartMenu/createMenuState.ts
|
|
@@ -11660,10 +11660,10 @@ async function connect2() {
|
|
|
11660
11660
|
}
|
|
11661
11661
|
}
|
|
11662
11662
|
function wire(socket) {
|
|
11663
|
-
const
|
|
11664
|
-
|
|
11663
|
+
const lines2 = createInterface3({ input: socket });
|
|
11664
|
+
lines2.on("error", () => {
|
|
11665
11665
|
});
|
|
11666
|
-
|
|
11666
|
+
lines2.on("line", emit);
|
|
11667
11667
|
socket.on("error", () => {
|
|
11668
11668
|
});
|
|
11669
11669
|
socket.on("close", scheduleReconnect);
|
|
@@ -12203,11 +12203,11 @@ async function countRows(client, table) {
|
|
|
12203
12203
|
return rows[0].n;
|
|
12204
12204
|
}
|
|
12205
12205
|
function printSummary(tables, current, incoming) {
|
|
12206
|
-
const
|
|
12206
|
+
const lines2 = tables.map(
|
|
12207
12207
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
12208
12208
|
);
|
|
12209
12209
|
console.error(chalk71.bold("\nThis will REPLACE all backlog data:"));
|
|
12210
|
-
console.error(`${
|
|
12210
|
+
console.error(`${lines2.join("\n")}
|
|
12211
12211
|
`);
|
|
12212
12212
|
}
|
|
12213
12213
|
async function confirmReplace(client, tables, incoming, fromStdin) {
|
|
@@ -12600,7 +12600,7 @@ function parsePreviewDecision(line, requestId) {
|
|
|
12600
12600
|
|
|
12601
12601
|
// src/commands/sessions/shared/requestPreviewDecision.ts
|
|
12602
12602
|
function requestPreviewDecision(request) {
|
|
12603
|
-
return new Promise((
|
|
12603
|
+
return new Promise((resolve22, reject) => {
|
|
12604
12604
|
connectToDaemon().then((socket) => {
|
|
12605
12605
|
let settled = false;
|
|
12606
12606
|
const finish = (error, decision) => {
|
|
@@ -12608,7 +12608,7 @@ function requestPreviewDecision(request) {
|
|
|
12608
12608
|
settled = true;
|
|
12609
12609
|
socket.destroy();
|
|
12610
12610
|
if (error) reject(error);
|
|
12611
|
-
else
|
|
12611
|
+
else resolve22(decision);
|
|
12612
12612
|
};
|
|
12613
12613
|
readSocketLines(socket, (line) => {
|
|
12614
12614
|
const incoming = parsePreviewDecision(line, request.requestId);
|
|
@@ -14859,13 +14859,13 @@ function saveCliReads(commands) {
|
|
|
14859
14859
|
);
|
|
14860
14860
|
cachedReads = void 0;
|
|
14861
14861
|
}
|
|
14862
|
-
function findMatch(command,
|
|
14862
|
+
function findMatch(command, lines2) {
|
|
14863
14863
|
const words = command.split(/\s+/);
|
|
14864
14864
|
if (words.length === 0) return void 0;
|
|
14865
|
-
if (
|
|
14865
|
+
if (lines2.includes(words[0])) return words[0];
|
|
14866
14866
|
if (words.length < 2) return void 0;
|
|
14867
14867
|
const prefix2 = `${words[0]} ${words[1]}`;
|
|
14868
|
-
const candidates =
|
|
14868
|
+
const candidates = lines2.filter(
|
|
14869
14869
|
(line) => line === prefix2 || line.startsWith(`${prefix2} `)
|
|
14870
14870
|
);
|
|
14871
14871
|
return candidates.sort((a, b) => b.length - a.length).find((rc) => command === rc || command.startsWith(`${rc} `));
|
|
@@ -15299,12 +15299,12 @@ function hasSubcommands(helpText) {
|
|
|
15299
15299
|
// src/commands/permitCliReads/runHelp.ts
|
|
15300
15300
|
import { exec as exec2 } from "child_process";
|
|
15301
15301
|
function runHelp(args) {
|
|
15302
|
-
return new Promise((
|
|
15302
|
+
return new Promise((resolve22) => {
|
|
15303
15303
|
exec2(
|
|
15304
15304
|
`${args.join(" ")} --help`,
|
|
15305
15305
|
{ encoding: "utf8", timeout: 3e4 },
|
|
15306
15306
|
(_err, stdout, stderr) => {
|
|
15307
|
-
|
|
15307
|
+
resolve22(stdout || stderr || "");
|
|
15308
15308
|
}
|
|
15309
15309
|
);
|
|
15310
15310
|
});
|
|
@@ -15432,14 +15432,14 @@ function formatHuman(cli, commands) {
|
|
|
15432
15432
|
const sorted = [...commands].sort(
|
|
15433
15433
|
(a, b) => a.path.join(" ").localeCompare(b.path.join(" "))
|
|
15434
15434
|
);
|
|
15435
|
-
const
|
|
15435
|
+
const lines2 = [`Discovered ${commands.length} commands for "${cli}":
|
|
15436
15436
|
`];
|
|
15437
15437
|
for (const cmd of sorted) {
|
|
15438
15438
|
const full = `${cli} ${cmd.path.join(" ")}`;
|
|
15439
15439
|
const text17 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
|
|
15440
|
-
|
|
15440
|
+
lines2.push(`${prefix(classifyVerb(cmd.path))}${text17}`);
|
|
15441
15441
|
}
|
|
15442
|
-
return
|
|
15442
|
+
return lines2.join("\n");
|
|
15443
15443
|
}
|
|
15444
15444
|
|
|
15445
15445
|
// src/commands/permitCliReads/parseCached.ts
|
|
@@ -15686,22 +15686,22 @@ function codeCommentConfirm(pin) {
|
|
|
15686
15686
|
return;
|
|
15687
15687
|
}
|
|
15688
15688
|
const original = readFileSync29(state.file, "utf8");
|
|
15689
|
-
const
|
|
15689
|
+
const lines2 = original.split("\n");
|
|
15690
15690
|
const index3 = state.line - 1;
|
|
15691
|
-
if (index3 >
|
|
15691
|
+
if (index3 > lines2.length) {
|
|
15692
15692
|
console.error(
|
|
15693
15693
|
chalk118.red(
|
|
15694
|
-
`Line ${state.line} is beyond the end of ${state.file} (${
|
|
15694
|
+
`Line ${state.line} is beyond the end of ${state.file} (${lines2.length} lines).`
|
|
15695
15695
|
)
|
|
15696
15696
|
);
|
|
15697
15697
|
process.exitCode = 1;
|
|
15698
15698
|
return;
|
|
15699
15699
|
}
|
|
15700
15700
|
const marker = isHashCommentFile(state.file) ? "#" : "//";
|
|
15701
|
-
const indentSource =
|
|
15701
|
+
const indentSource = lines2[index3] ?? "";
|
|
15702
15702
|
const indent2 = indentSource.match(/^\s*/)?.[0] ?? "";
|
|
15703
|
-
|
|
15704
|
-
writeFileSync24(state.file,
|
|
15703
|
+
lines2.splice(index3, 0, `${indent2}${marker} ${state.text}`);
|
|
15704
|
+
writeFileSync24(state.file, lines2.join("\n"));
|
|
15705
15705
|
unlinkSync8(getPinStatePath(pin));
|
|
15706
15706
|
console.log(
|
|
15707
15707
|
chalk118.green(
|
|
@@ -16413,17 +16413,17 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
16413
16413
|
let hasViolation = false;
|
|
16414
16414
|
for (const file of files) {
|
|
16415
16415
|
const content = fs22.readFileSync(file, "utf8");
|
|
16416
|
-
const
|
|
16417
|
-
results.push({ file, lines });
|
|
16418
|
-
if (options2.threshold !== void 0 &&
|
|
16416
|
+
const lines2 = countSloc(content);
|
|
16417
|
+
results.push({ file, lines: lines2 });
|
|
16418
|
+
if (options2.threshold !== void 0 && lines2 > options2.threshold) {
|
|
16419
16419
|
hasViolation = true;
|
|
16420
16420
|
}
|
|
16421
16421
|
}
|
|
16422
16422
|
results.sort((a, b) => b.lines - a.lines);
|
|
16423
|
-
for (const { file, lines } of results) {
|
|
16424
|
-
const exceedsThreshold = options2.threshold !== void 0 &&
|
|
16423
|
+
for (const { file, lines: lines2 } of results) {
|
|
16424
|
+
const exceedsThreshold = options2.threshold !== void 0 && lines2 > options2.threshold;
|
|
16425
16425
|
const color = exceedsThreshold ? chalk127.red : chalk127.white;
|
|
16426
|
-
console.log(`${color(file)} \u2192 ${chalk127.cyan(
|
|
16426
|
+
console.log(`${color(file)} \u2192 ${chalk127.cyan(lines2)} lines`);
|
|
16427
16427
|
}
|
|
16428
16428
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
16429
16429
|
console.log(
|
|
@@ -17010,9 +17010,9 @@ function printCommitsWithFiles(commits2, ignore3, verbose) {
|
|
|
17010
17010
|
}
|
|
17011
17011
|
}
|
|
17012
17012
|
function parseGitLogCommits(output, ignore3, afterDate) {
|
|
17013
|
-
const
|
|
17013
|
+
const lines2 = output.trim().split("\n");
|
|
17014
17014
|
const commitsByDate = /* @__PURE__ */ new Map();
|
|
17015
|
-
for (const line of
|
|
17015
|
+
for (const line of lines2) {
|
|
17016
17016
|
const [date, hash, ...messageParts] = line.split("|");
|
|
17017
17017
|
const message3 = messageParts.join("|");
|
|
17018
17018
|
if (afterDate && date <= afterDate) {
|
|
@@ -18108,12 +18108,12 @@ function isHeaderLine2(line) {
|
|
|
18108
18108
|
return trimmed === "" || trimmed.startsWith("#");
|
|
18109
18109
|
}
|
|
18110
18110
|
function extractShellComments(text17) {
|
|
18111
|
-
const
|
|
18111
|
+
const lines2 = text17.split("\n");
|
|
18112
18112
|
let firstCodeLine = 0;
|
|
18113
|
-
while (firstCodeLine <
|
|
18113
|
+
while (firstCodeLine < lines2.length && isHeaderLine2(lines2[firstCodeLine])) {
|
|
18114
18114
|
firstCodeLine++;
|
|
18115
18115
|
}
|
|
18116
|
-
return extractYamlComments(
|
|
18116
|
+
return extractYamlComments(lines2.slice(firstCodeLine).join("\n"));
|
|
18117
18117
|
}
|
|
18118
18118
|
|
|
18119
18119
|
// src/commands/editHook/introducedComments.ts
|
|
@@ -19159,9 +19159,28 @@ function keptInPlace(cwd) {
|
|
|
19159
19159
|
return { cwd, kind: "primary", created: false };
|
|
19160
19160
|
}
|
|
19161
19161
|
|
|
19162
|
+
// src/commands/sessions/daemon/describePersistedSession.ts
|
|
19163
|
+
function describePersistedSession(entry) {
|
|
19164
|
+
const { id, name, cwd } = readDescribed(entry);
|
|
19165
|
+
return `id=${id ?? "?"} name=${JSON.stringify(name ?? "?")} cwd=${cwd ?? "?"}`;
|
|
19166
|
+
}
|
|
19167
|
+
function readDescribed(entry) {
|
|
19168
|
+
if (typeof entry !== "object" || entry === null) return {};
|
|
19169
|
+
const record = entry;
|
|
19170
|
+
return {
|
|
19171
|
+
id: stringOrUndefined(record.id),
|
|
19172
|
+
name: stringOrUndefined(record.name),
|
|
19173
|
+
cwd: stringOrUndefined(record.cwd)
|
|
19174
|
+
};
|
|
19175
|
+
}
|
|
19176
|
+
function stringOrUndefined(value) {
|
|
19177
|
+
return typeof value === "string" ? value : void 0;
|
|
19178
|
+
}
|
|
19179
|
+
|
|
19162
19180
|
// src/commands/sessions/daemon/persistedSessionSchema.ts
|
|
19163
19181
|
import { z as z7 } from "zod";
|
|
19164
19182
|
var persistedSessionSchema = z7.object({
|
|
19183
|
+
id: z7.string().optional(),
|
|
19165
19184
|
name: z7.string(),
|
|
19166
19185
|
title: z7.string().optional(),
|
|
19167
19186
|
generatedTitle: z7.string().optional(),
|
|
@@ -19185,6 +19204,7 @@ var persistedSessionSchema = z7.object({
|
|
|
19185
19204
|
// src/commands/sessions/daemon/toPersistedSession.ts
|
|
19186
19205
|
function toPersistedSession(session) {
|
|
19187
19206
|
return {
|
|
19207
|
+
id: session.id,
|
|
19188
19208
|
name: session.name,
|
|
19189
19209
|
title: session.title,
|
|
19190
19210
|
generatedTitle: session.generatedTitle,
|
|
@@ -19214,10 +19234,25 @@ var SESSIONS_FILE = "sessions.json";
|
|
|
19214
19234
|
function loadPersistedSessions() {
|
|
19215
19235
|
const data = loadJson(SESSIONS_FILE);
|
|
19216
19236
|
if (!Array.isArray(data)) return [];
|
|
19217
|
-
|
|
19237
|
+
const rejected = [];
|
|
19238
|
+
const loaded = data.flatMap((entry) => {
|
|
19218
19239
|
const parsed = persistedSessionSchema.safeParse(entry);
|
|
19219
|
-
|
|
19240
|
+
if (parsed.success) return [parsed.data];
|
|
19241
|
+
rejected.push(
|
|
19242
|
+
`${describePersistedSession(entry)}: ${parsed.error.issues.map((i) => `${i.path.join(".")} ${i.message}`).join("; ")}`
|
|
19243
|
+
);
|
|
19244
|
+
return [];
|
|
19220
19245
|
});
|
|
19246
|
+
logRejected(rejected);
|
|
19247
|
+
return loaded;
|
|
19248
|
+
}
|
|
19249
|
+
var lastRejectedSignature = "";
|
|
19250
|
+
function logRejected(rejected) {
|
|
19251
|
+
const signature = rejected.join("|");
|
|
19252
|
+
if (signature === lastRejectedSignature) return;
|
|
19253
|
+
lastRejectedSignature = signature;
|
|
19254
|
+
for (const entry of rejected)
|
|
19255
|
+
daemonLog(`unreadable persisted session dropped \u2014 ${entry}`);
|
|
19221
19256
|
}
|
|
19222
19257
|
function savePersistedSessions(sessions) {
|
|
19223
19258
|
saveJson(SESSIONS_FILE, sessions);
|
|
@@ -19389,7 +19424,7 @@ function placedByDaemon() {
|
|
|
19389
19424
|
function seed(worktreePath, clone) {
|
|
19390
19425
|
console.log(`Preparing ${worktreePath}\u2026`);
|
|
19391
19426
|
return new Promise(
|
|
19392
|
-
(
|
|
19427
|
+
(resolve22) => seedWorktree(worktreePath, clone, resolve22)
|
|
19393
19428
|
);
|
|
19394
19429
|
}
|
|
19395
19430
|
async function moveToPrCheckoutTree() {
|
|
@@ -19896,25 +19931,25 @@ function isVisibleText(t) {
|
|
|
19896
19931
|
return /[a-zA-Z]{3,}/.test(t);
|
|
19897
19932
|
}
|
|
19898
19933
|
var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
|
|
19899
|
-
function collectRscText(v,
|
|
19934
|
+
function collectRscText(v, resolve22, sink2, seen) {
|
|
19900
19935
|
if (v == null) return;
|
|
19901
19936
|
if (typeof v === "string") {
|
|
19902
19937
|
if (isRscRef(v)) {
|
|
19903
19938
|
if (!seen.has(v)) {
|
|
19904
19939
|
seen.add(v);
|
|
19905
|
-
collectRscText(
|
|
19940
|
+
collectRscText(resolve22(v), resolve22, sink2, seen);
|
|
19906
19941
|
}
|
|
19907
19942
|
} else if (isHashtag(v)) sink2.hashtags.push(v);
|
|
19908
19943
|
else if (isVisibleText(v)) sink2.text.push(v);
|
|
19909
19944
|
return;
|
|
19910
19945
|
}
|
|
19911
19946
|
if (Array.isArray(v)) {
|
|
19912
|
-
for (const x of v) collectRscText(x,
|
|
19947
|
+
for (const x of v) collectRscText(x, resolve22, sink2, seen);
|
|
19913
19948
|
return;
|
|
19914
19949
|
}
|
|
19915
19950
|
if (typeof v === "object") {
|
|
19916
19951
|
for (const val of Object.values(v)) {
|
|
19917
|
-
collectRscText(val,
|
|
19952
|
+
collectRscText(val, resolve22, sink2, seen);
|
|
19918
19953
|
}
|
|
19919
19954
|
}
|
|
19920
19955
|
}
|
|
@@ -19946,7 +19981,7 @@ function visitObjects(root, fn) {
|
|
|
19946
19981
|
}
|
|
19947
19982
|
}
|
|
19948
19983
|
}
|
|
19949
|
-
function buildMentionMap(rows,
|
|
19984
|
+
function buildMentionMap(rows, resolve22) {
|
|
19950
19985
|
const map = /* @__PURE__ */ new Map();
|
|
19951
19986
|
visitObjects(rows, (o) => {
|
|
19952
19987
|
const url = profileActionUrl(o);
|
|
@@ -19954,7 +19989,7 @@ function buildMentionMap(rows, resolve21) {
|
|
|
19954
19989
|
const slug = slugFromProfileUrl(url);
|
|
19955
19990
|
if (!slug || map.has(slug)) return;
|
|
19956
19991
|
const sink2 = { text: [], hashtags: [] };
|
|
19957
|
-
collectRscText(o.children,
|
|
19992
|
+
collectRscText(o.children, resolve22, sink2, /* @__PURE__ */ new Set());
|
|
19958
19993
|
const name = sink2.text.join(" ").replace(/\s+/g, " ").trim();
|
|
19959
19994
|
map.set(slug, name ? { slug, name, url } : { slug, url });
|
|
19960
19995
|
});
|
|
@@ -20040,10 +20075,10 @@ function buildPost(raw, mentionMap, author) {
|
|
|
20040
20075
|
|
|
20041
20076
|
// src/commands/netcap/walkPostRow.ts
|
|
20042
20077
|
var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
|
|
20043
|
-
function walkPostRow(v,
|
|
20078
|
+
function walkPostRow(v, resolve22, raw) {
|
|
20044
20079
|
if (v == null || typeof v !== "object") return;
|
|
20045
20080
|
if (Array.isArray(v)) {
|
|
20046
|
-
for (const x of v) walkPostRow(x,
|
|
20081
|
+
for (const x of v) walkPostRow(x, resolve22, raw);
|
|
20047
20082
|
return;
|
|
20048
20083
|
}
|
|
20049
20084
|
const o = v;
|
|
@@ -20057,9 +20092,9 @@ function walkPostRow(v, resolve21, raw) {
|
|
|
20057
20092
|
}
|
|
20058
20093
|
if (isCommentary(o)) {
|
|
20059
20094
|
const sink2 = { text: raw.text, hashtags: raw.hashtags };
|
|
20060
|
-
collectRscText(o.children,
|
|
20095
|
+
collectRscText(o.children, resolve22, sink2, /* @__PURE__ */ new Set());
|
|
20061
20096
|
}
|
|
20062
|
-
for (const val of Object.values(o)) walkPostRow(val,
|
|
20097
|
+
for (const val of Object.values(o)) walkPostRow(val, resolve22, raw);
|
|
20063
20098
|
}
|
|
20064
20099
|
|
|
20065
20100
|
// src/commands/netcap/extractLinkedInPosts.ts
|
|
@@ -20073,8 +20108,8 @@ function findCommentaryRows(rows) {
|
|
|
20073
20108
|
}
|
|
20074
20109
|
function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
20075
20110
|
const rows = parseRscRows(flight);
|
|
20076
|
-
const
|
|
20077
|
-
const mentionMap = buildMentionMap(rows,
|
|
20111
|
+
const resolve22 = makeRscResolver(rows);
|
|
20112
|
+
const mentionMap = buildMentionMap(rows, resolve22);
|
|
20078
20113
|
const posts = [];
|
|
20079
20114
|
for (const id of findCommentaryRows(rows)) {
|
|
20080
20115
|
const raw = {
|
|
@@ -20084,7 +20119,7 @@ function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
|
20084
20119
|
links: [],
|
|
20085
20120
|
related: []
|
|
20086
20121
|
};
|
|
20087
|
-
walkPostRow(rows[id],
|
|
20122
|
+
walkPostRow(rows[id], resolve22, raw);
|
|
20088
20123
|
const post = buildPost(raw, mentionMap, author);
|
|
20089
20124
|
if (post) posts.push(post);
|
|
20090
20125
|
}
|
|
@@ -20253,9 +20288,9 @@ function extractVoyagerPosts(body) {
|
|
|
20253
20288
|
|
|
20254
20289
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
20255
20290
|
function captureEntries(captureFile) {
|
|
20256
|
-
const
|
|
20291
|
+
const lines2 = readFileSync39(captureFile, "utf8").split("\n").filter(Boolean);
|
|
20257
20292
|
const entries = [];
|
|
20258
|
-
for (const line of
|
|
20293
|
+
for (const line of lines2) {
|
|
20259
20294
|
let entry;
|
|
20260
20295
|
try {
|
|
20261
20296
|
entry = JSON.parse(line);
|
|
@@ -20695,11 +20730,11 @@ function findWallOfText(body) {
|
|
|
20695
20730
|
function splitParagraphs(body) {
|
|
20696
20731
|
const paragraphs = [];
|
|
20697
20732
|
let section3 = "(intro)";
|
|
20698
|
-
let
|
|
20733
|
+
let lines2 = [];
|
|
20699
20734
|
const flush = () => {
|
|
20700
|
-
if (
|
|
20701
|
-
paragraphs.push({ section: section3, lines });
|
|
20702
|
-
|
|
20735
|
+
if (lines2.length > 0) {
|
|
20736
|
+
paragraphs.push({ section: section3, lines: lines2 });
|
|
20737
|
+
lines2 = [];
|
|
20703
20738
|
}
|
|
20704
20739
|
};
|
|
20705
20740
|
for (const line of body.split("\n")) {
|
|
@@ -20710,17 +20745,17 @@ function splitParagraphs(body) {
|
|
|
20710
20745
|
} else if (line.trim() === "") {
|
|
20711
20746
|
flush();
|
|
20712
20747
|
} else {
|
|
20713
|
-
|
|
20748
|
+
lines2.push(line);
|
|
20714
20749
|
}
|
|
20715
20750
|
}
|
|
20716
20751
|
flush();
|
|
20717
20752
|
return paragraphs;
|
|
20718
20753
|
}
|
|
20719
|
-
function isWallOfText(
|
|
20720
|
-
if (
|
|
20754
|
+
function isWallOfText(lines2) {
|
|
20755
|
+
if (lines2.some(isListLine)) {
|
|
20721
20756
|
return false;
|
|
20722
20757
|
}
|
|
20723
|
-
const text17 =
|
|
20758
|
+
const text17 = lines2.join(" ").trim();
|
|
20724
20759
|
return text17.length > MAX_PARAGRAPH_CHARS || countSentences(text17) > MAX_PARAGRAPH_SENTENCES;
|
|
20725
20760
|
}
|
|
20726
20761
|
function countSentences(paragraph) {
|
|
@@ -22163,9 +22198,9 @@ function parseRefactorYml() {
|
|
|
22163
22198
|
}
|
|
22164
22199
|
const content = fs24.readFileSync(REFACTOR_YML_PATH, "utf8");
|
|
22165
22200
|
const entries = [];
|
|
22166
|
-
const
|
|
22201
|
+
const lines2 = content.split("\n");
|
|
22167
22202
|
let currentEntry = {};
|
|
22168
|
-
for (const line of
|
|
22203
|
+
for (const line of lines2) {
|
|
22169
22204
|
const trimmed = line.trim();
|
|
22170
22205
|
if (trimmed.startsWith("- file:")) {
|
|
22171
22206
|
if (currentEntry.file) {
|
|
@@ -22238,7 +22273,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
22238
22273
|
|
|
22239
22274
|
// src/commands/refactor/check/index.ts
|
|
22240
22275
|
function runScript(script, cwd) {
|
|
22241
|
-
return new Promise((
|
|
22276
|
+
return new Promise((resolve22) => {
|
|
22242
22277
|
const child = spawn6("npm", ["run", script], {
|
|
22243
22278
|
stdio: "pipe",
|
|
22244
22279
|
shell: true,
|
|
@@ -22252,7 +22287,7 @@ function runScript(script, cwd) {
|
|
|
22252
22287
|
output += data.toString();
|
|
22253
22288
|
});
|
|
22254
22289
|
child.on("close", (code) => {
|
|
22255
|
-
|
|
22290
|
+
resolve22({ script, code: code ?? 1, output });
|
|
22256
22291
|
});
|
|
22257
22292
|
});
|
|
22258
22293
|
}
|
|
@@ -22753,22 +22788,22 @@ function formatImportLine(imp) {
|
|
|
22753
22788
|
|
|
22754
22789
|
// src/commands/refactor/extract/buildDestinationContent.ts
|
|
22755
22790
|
function buildDestinationContent(functionTexts, imports, sourceRelativePath, sourceImportNames) {
|
|
22756
|
-
const
|
|
22791
|
+
const lines2 = [];
|
|
22757
22792
|
for (const imp of imports) {
|
|
22758
|
-
|
|
22793
|
+
lines2.push(formatImportLine(imp));
|
|
22759
22794
|
}
|
|
22760
22795
|
if (sourceImportNames.length > 0) {
|
|
22761
|
-
|
|
22796
|
+
lines2.push(
|
|
22762
22797
|
`import { ${sourceImportNames.join(", ")} } from "${sourceRelativePath}";`
|
|
22763
22798
|
);
|
|
22764
22799
|
}
|
|
22765
|
-
if (
|
|
22800
|
+
if (lines2.length > 0) lines2.push("");
|
|
22766
22801
|
for (let i = 0; i < functionTexts.length; i++) {
|
|
22767
|
-
if (i > 0)
|
|
22768
|
-
|
|
22802
|
+
if (i > 0) lines2.push("");
|
|
22803
|
+
lines2.push(functionTexts[i]);
|
|
22769
22804
|
}
|
|
22770
|
-
|
|
22771
|
-
return
|
|
22805
|
+
lines2.push("");
|
|
22806
|
+
return lines2.join("\n");
|
|
22772
22807
|
}
|
|
22773
22808
|
|
|
22774
22809
|
// src/commands/refactor/extract/getRelativeImportPath.ts
|
|
@@ -23379,9 +23414,9 @@ function groupReferences(symbol, cwd) {
|
|
|
23379
23414
|
const grouped = /* @__PURE__ */ new Map();
|
|
23380
23415
|
for (const ref of refs) {
|
|
23381
23416
|
const refFile = path50.relative(cwd, ref.getSourceFile().getFilePath());
|
|
23382
|
-
const
|
|
23383
|
-
if (!grouped.has(refFile)) grouped.set(refFile,
|
|
23384
|
-
|
|
23417
|
+
const lines2 = grouped.get(refFile) ?? [];
|
|
23418
|
+
if (!grouped.has(refFile)) grouped.set(refFile, lines2);
|
|
23419
|
+
lines2.push(ref.getStartLineNumber());
|
|
23385
23420
|
}
|
|
23386
23421
|
return grouped;
|
|
23387
23422
|
}
|
|
@@ -23401,9 +23436,9 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
23401
23436
|
chalk189.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
23402
23437
|
`)
|
|
23403
23438
|
);
|
|
23404
|
-
for (const [refFile,
|
|
23439
|
+
for (const [refFile, lines2] of grouped) {
|
|
23405
23440
|
console.log(
|
|
23406
|
-
` ${chalk189.dim(refFile)}: lines ${chalk189.cyan(
|
|
23441
|
+
` ${chalk189.dim(refFile)}: lines ${chalk189.cyan(lines2.join(", "))}`
|
|
23407
23442
|
);
|
|
23408
23443
|
}
|
|
23409
23444
|
if (options2.apply) {
|
|
@@ -23844,12 +23879,12 @@ function headerFor(c) {
|
|
|
23844
23879
|
return tags ? `### ${location} [${tags}]` : `### ${location}`;
|
|
23845
23880
|
}
|
|
23846
23881
|
function formatThread(thread) {
|
|
23847
|
-
const
|
|
23882
|
+
const lines2 = [
|
|
23848
23883
|
headerFor(thread.root),
|
|
23849
23884
|
`**${thread.root.author}**: ${thread.root.body.trim()}`,
|
|
23850
23885
|
...thread.replies.map((r) => `**${r.author}** (reply): ${r.body.trim()}`)
|
|
23851
23886
|
];
|
|
23852
|
-
return
|
|
23887
|
+
return lines2.join("\n\n");
|
|
23853
23888
|
}
|
|
23854
23889
|
var INTRO = `The PR already has the review comments below (including resolved and outdated threads). Avoid re-raising findings that a prior comment substantively covers.`;
|
|
23855
23890
|
function formatPriorComments(comments3) {
|
|
@@ -24156,13 +24191,13 @@ function summariseSynthesis(markdown) {
|
|
|
24156
24191
|
return { summary: extractSummary(markdown), totals, findingCount };
|
|
24157
24192
|
}
|
|
24158
24193
|
function formatSynthesisSummary(summary) {
|
|
24159
|
-
const
|
|
24194
|
+
const lines2 = [];
|
|
24160
24195
|
const { totals, findingCount } = summary;
|
|
24161
|
-
|
|
24196
|
+
lines2.push(
|
|
24162
24197
|
`Findings: ${findingCount} (blocker ${totals.blocker}, major ${totals.major}, minor ${totals.minor}, nit ${totals.nit})`
|
|
24163
24198
|
);
|
|
24164
|
-
if (summary.summary)
|
|
24165
|
-
return
|
|
24199
|
+
if (summary.summary) lines2.push("", summary.summary);
|
|
24200
|
+
return lines2.join("\n");
|
|
24166
24201
|
}
|
|
24167
24202
|
|
|
24168
24203
|
// src/commands/review/buildReviewSummary.ts
|
|
@@ -24173,12 +24208,12 @@ function formatFindingLine(finding) {
|
|
|
24173
24208
|
function buildReviewSummary(markdown) {
|
|
24174
24209
|
const summary = summariseSynthesis(markdown);
|
|
24175
24210
|
const findings = parseFindings(markdown);
|
|
24176
|
-
const
|
|
24211
|
+
const lines2 = ["## Code review summary", "", formatSynthesisSummary(summary)];
|
|
24177
24212
|
if (findings.length > 0) {
|
|
24178
|
-
|
|
24179
|
-
for (const finding of findings)
|
|
24213
|
+
lines2.push("", "### Findings", "");
|
|
24214
|
+
for (const finding of findings) lines2.push(formatFindingLine(finding));
|
|
24180
24215
|
}
|
|
24181
|
-
return
|
|
24216
|
+
return lines2.join("\n");
|
|
24182
24217
|
}
|
|
24183
24218
|
|
|
24184
24219
|
// src/commands/review/sanitiseReviewerNames.ts
|
|
@@ -24189,13 +24224,13 @@ function sanitiseReviewerNames(value) {
|
|
|
24189
24224
|
|
|
24190
24225
|
// src/commands/review/postFindings.ts
|
|
24191
24226
|
function buildCommentBody(finding) {
|
|
24192
|
-
const
|
|
24227
|
+
const lines2 = [];
|
|
24193
24228
|
const severityLabel = finding.severity ?? "finding";
|
|
24194
|
-
|
|
24195
|
-
if (finding.impact)
|
|
24229
|
+
lines2.push(`**${severityLabel}: ${finding.title}**`);
|
|
24230
|
+
if (finding.impact) lines2.push("", `Impact: ${finding.impact}`);
|
|
24196
24231
|
if (finding.recommendation)
|
|
24197
|
-
|
|
24198
|
-
return sanitiseReviewerNames(
|
|
24232
|
+
lines2.push("", `Recommendation: ${finding.recommendation}`);
|
|
24233
|
+
return sanitiseReviewerNames(lines2.join("\n"));
|
|
24199
24234
|
}
|
|
24200
24235
|
function postFindings(findings) {
|
|
24201
24236
|
let posted = 0;
|
|
@@ -24294,10 +24329,10 @@ function buildDiffLineIndex(diff3) {
|
|
|
24294
24329
|
|
|
24295
24330
|
// src/commands/review/partitionFindingsByDiff.ts
|
|
24296
24331
|
function isWithinDiff(finding, index3) {
|
|
24297
|
-
const
|
|
24298
|
-
if (!
|
|
24299
|
-
if (!
|
|
24300
|
-
if (finding.startLine !== void 0 && !
|
|
24332
|
+
const lines2 = index3.get(finding.file);
|
|
24333
|
+
if (!lines2) return false;
|
|
24334
|
+
if (!lines2.has(finding.line)) return false;
|
|
24335
|
+
if (finding.startLine !== void 0 && !lines2.has(finding.startLine)) {
|
|
24301
24336
|
return false;
|
|
24302
24337
|
}
|
|
24303
24338
|
return true;
|
|
@@ -24688,8 +24723,8 @@ function indent(text17) {
|
|
|
24688
24723
|
return text17.split(/\r?\n/).map((line) => ` ${line}`);
|
|
24689
24724
|
}
|
|
24690
24725
|
function tailLines(text17, maxLines) {
|
|
24691
|
-
const
|
|
24692
|
-
return
|
|
24726
|
+
const lines2 = text17.split(/\r?\n/);
|
|
24727
|
+
return lines2.length <= maxLines ? text17 : lines2.slice(-maxLines).join("\n");
|
|
24693
24728
|
}
|
|
24694
24729
|
function isFastFail(input) {
|
|
24695
24730
|
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
@@ -25061,12 +25096,12 @@ function onCloseResult(ctx, code) {
|
|
|
25061
25096
|
return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
|
|
25062
25097
|
}
|
|
25063
25098
|
function waitForChildExit(ctx) {
|
|
25064
|
-
return new Promise((
|
|
25099
|
+
return new Promise((resolve22) => {
|
|
25065
25100
|
let settled = false;
|
|
25066
25101
|
const settle = (result) => {
|
|
25067
25102
|
if (settled) return;
|
|
25068
25103
|
settled = true;
|
|
25069
|
-
|
|
25104
|
+
resolve22(result);
|
|
25070
25105
|
};
|
|
25071
25106
|
ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
|
|
25072
25107
|
ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
|
|
@@ -25721,13 +25756,13 @@ function formatEvent(event) {
|
|
|
25721
25756
|
const abbrev = levelAbbrev(event.Level);
|
|
25722
25757
|
const ts8 = chalk198.dim(formatTimestamp(event.Timestamp));
|
|
25723
25758
|
const msg = renderMessage(event);
|
|
25724
|
-
const
|
|
25759
|
+
const lines2 = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
25725
25760
|
if (event.Exception) {
|
|
25726
25761
|
for (const line of event.Exception.split("\n")) {
|
|
25727
|
-
|
|
25762
|
+
lines2.push(chalk198.red(` ${line}`));
|
|
25728
25763
|
}
|
|
25729
25764
|
}
|
|
25730
|
-
return
|
|
25765
|
+
return lines2.join("\n");
|
|
25731
25766
|
}
|
|
25732
25767
|
|
|
25733
25768
|
// src/commands/seq/parseRelativeTime.ts
|
|
@@ -26166,9 +26201,9 @@ function createReadlineInterface() {
|
|
|
26166
26201
|
});
|
|
26167
26202
|
}
|
|
26168
26203
|
function askQuestion(rl, question) {
|
|
26169
|
-
return new Promise((
|
|
26204
|
+
return new Promise((resolve22) => {
|
|
26170
26205
|
rl.question(question, (answer) => {
|
|
26171
|
-
|
|
26206
|
+
resolve22(answer.trim());
|
|
26172
26207
|
});
|
|
26173
26208
|
});
|
|
26174
26209
|
}
|
|
@@ -26388,13 +26423,13 @@ function extractSpeaker(fullText) {
|
|
|
26388
26423
|
function isTextLine(line) {
|
|
26389
26424
|
return !!line.trim() && !line.includes("-->");
|
|
26390
26425
|
}
|
|
26391
|
-
function scanTextLines(
|
|
26426
|
+
function scanTextLines(lines2, start3) {
|
|
26392
26427
|
let i = start3;
|
|
26393
|
-
while (i <
|
|
26394
|
-
return { texts:
|
|
26428
|
+
while (i < lines2.length && isTextLine(lines2[i])) i++;
|
|
26429
|
+
return { texts: lines2.slice(start3, i).map((l) => l.trim()), end: i };
|
|
26395
26430
|
}
|
|
26396
|
-
function collectTextLines(
|
|
26397
|
-
const { texts, end } = scanTextLines(
|
|
26431
|
+
function collectTextLines(lines2, startIndex) {
|
|
26432
|
+
const { texts, end } = scanTextLines(lines2, startIndex);
|
|
26398
26433
|
return { text: texts.join(" "), nextIndex: end };
|
|
26399
26434
|
}
|
|
26400
26435
|
function parseTimestampLine(line) {
|
|
@@ -26405,30 +26440,30 @@ function buildCue(startMs, endMs, fullText) {
|
|
|
26405
26440
|
const { speaker, text: text17 } = extractSpeaker(fullText);
|
|
26406
26441
|
return text17 ? { startMs, endMs, speaker, text: text17 } : null;
|
|
26407
26442
|
}
|
|
26408
|
-
function parseCueLine(
|
|
26409
|
-
const { startMs, endMs } = parseTimestampLine(
|
|
26410
|
-
const { text: text17, nextIndex: nextIndex2 } = collectTextLines(
|
|
26443
|
+
function parseCueLine(lines2, i) {
|
|
26444
|
+
const { startMs, endMs } = parseTimestampLine(lines2[i]);
|
|
26445
|
+
const { text: text17, nextIndex: nextIndex2 } = collectTextLines(lines2, i + 1);
|
|
26411
26446
|
return { cue: buildCue(startMs, endMs, text17), nextIndex: nextIndex2 };
|
|
26412
26447
|
}
|
|
26413
26448
|
function isCueSeparator(line) {
|
|
26414
26449
|
return line.trim().includes("-->");
|
|
26415
26450
|
}
|
|
26416
|
-
function skipHeader(
|
|
26451
|
+
function skipHeader(lines2) {
|
|
26417
26452
|
let i = 0;
|
|
26418
|
-
while (i <
|
|
26453
|
+
while (i < lines2.length && !isCueSeparator(lines2[i])) i++;
|
|
26419
26454
|
return i;
|
|
26420
26455
|
}
|
|
26421
|
-
function processLine(cues,
|
|
26422
|
-
if (!isCueSeparator(
|
|
26423
|
-
const { cue, nextIndex: nextIndex2 } = parseCueLine(
|
|
26456
|
+
function processLine(cues, lines2, i) {
|
|
26457
|
+
if (!isCueSeparator(lines2[i])) return i + 1;
|
|
26458
|
+
const { cue, nextIndex: nextIndex2 } = parseCueLine(lines2, i);
|
|
26424
26459
|
if (cue) cues.push(cue);
|
|
26425
26460
|
return nextIndex2;
|
|
26426
26461
|
}
|
|
26427
26462
|
function parseVtt(content) {
|
|
26428
26463
|
const cues = [];
|
|
26429
|
-
const
|
|
26430
|
-
let i = skipHeader(
|
|
26431
|
-
while (i <
|
|
26464
|
+
const lines2 = content.split(/\r?\n/);
|
|
26465
|
+
let i = skipHeader(lines2);
|
|
26466
|
+
while (i < lines2.length) i = processLine(cues, lines2, i);
|
|
26432
26467
|
return cues;
|
|
26433
26468
|
}
|
|
26434
26469
|
|
|
@@ -26653,8 +26688,8 @@ function logs(options2) {
|
|
|
26653
26688
|
console.log("Voice log is empty");
|
|
26654
26689
|
return;
|
|
26655
26690
|
}
|
|
26656
|
-
const
|
|
26657
|
-
for (const line of
|
|
26691
|
+
const lines2 = content.split("\n").slice(-count8);
|
|
26692
|
+
for (const line of lines2) {
|
|
26658
26693
|
try {
|
|
26659
26694
|
const event = JSON.parse(line);
|
|
26660
26695
|
const time = event.timestamp?.slice(11, 19) ?? "";
|
|
@@ -26802,8 +26837,8 @@ function isProcessAlive3(pid) {
|
|
|
26802
26837
|
}
|
|
26803
26838
|
function readRecentLogs(count8) {
|
|
26804
26839
|
if (!existsSync56(voicePaths.log)) return [];
|
|
26805
|
-
const
|
|
26806
|
-
return
|
|
26840
|
+
const lines2 = readFileSync46(voicePaths.log, "utf8").trim().split("\n");
|
|
26841
|
+
return lines2.slice(-count8);
|
|
26807
26842
|
}
|
|
26808
26843
|
function status2() {
|
|
26809
26844
|
if (!existsSync56(voicePaths.pid)) {
|
|
@@ -26910,6 +26945,152 @@ function registerVoice(program2) {
|
|
|
26910
26945
|
configHelp(voiceCommand, voiceConfigHelp);
|
|
26911
26946
|
}
|
|
26912
26947
|
|
|
26948
|
+
// src/commands/watch/readBuiltVersion.ts
|
|
26949
|
+
import { join as join67 } from "path";
|
|
26950
|
+
|
|
26951
|
+
// src/commands/watch/resolveUpstream.ts
|
|
26952
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
26953
|
+
function runGit2(args, cwd) {
|
|
26954
|
+
return execFileSync10("git", args, {
|
|
26955
|
+
encoding: "utf8",
|
|
26956
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
26957
|
+
cwd
|
|
26958
|
+
}).trim();
|
|
26959
|
+
}
|
|
26960
|
+
function resolveUpstream(cwd) {
|
|
26961
|
+
try {
|
|
26962
|
+
runGit2(["rev-parse", "--is-inside-work-tree"], cwd);
|
|
26963
|
+
} catch {
|
|
26964
|
+
throw new Error(
|
|
26965
|
+
"not a git repository \u2014 run assist watch wait from inside a repo"
|
|
26966
|
+
);
|
|
26967
|
+
}
|
|
26968
|
+
let branch2;
|
|
26969
|
+
try {
|
|
26970
|
+
branch2 = runGit2(["symbolic-ref", "--quiet", "--short", "HEAD"], cwd);
|
|
26971
|
+
} catch {
|
|
26972
|
+
throw new Error(
|
|
26973
|
+
"HEAD is detached \u2014 check out a branch before waiting on its upstream"
|
|
26974
|
+
);
|
|
26975
|
+
}
|
|
26976
|
+
try {
|
|
26977
|
+
return {
|
|
26978
|
+
branch: branch2,
|
|
26979
|
+
upstream: runGit2(
|
|
26980
|
+
["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"],
|
|
26981
|
+
cwd
|
|
26982
|
+
)
|
|
26983
|
+
};
|
|
26984
|
+
} catch {
|
|
26985
|
+
throw new Error(
|
|
26986
|
+
`branch "${branch2}" has no upstream \u2014 set one with: git push -u origin ${branch2}`
|
|
26987
|
+
);
|
|
26988
|
+
}
|
|
26989
|
+
}
|
|
26990
|
+
|
|
26991
|
+
// src/commands/watch/readBuiltVersion.ts
|
|
26992
|
+
function readBuiltVersion(cwd) {
|
|
26993
|
+
try {
|
|
26994
|
+
const root = runGit2(["rev-parse", "--show-toplevel"], cwd);
|
|
26995
|
+
return readPackageJson(join67(root, "package.json")).version ?? "unknown";
|
|
26996
|
+
} catch {
|
|
26997
|
+
return "unknown";
|
|
26998
|
+
}
|
|
26999
|
+
}
|
|
27000
|
+
|
|
27001
|
+
// src/commands/watch/readRecentCommits.ts
|
|
27002
|
+
function readRecentCommits(count8 = 10, cwd) {
|
|
27003
|
+
const output = runGit2(
|
|
27004
|
+
["log", `-${count8}`, "--pretty=format:%H%x09%h%x09%ar%x09%s"],
|
|
27005
|
+
cwd
|
|
27006
|
+
);
|
|
27007
|
+
if (!output) return [];
|
|
27008
|
+
return output.split("\n").map((line) => {
|
|
27009
|
+
const [sha, short2, when, ...subject] = line.split(" ");
|
|
27010
|
+
return { sha, short: short2, when, subject: subject.join(" ") };
|
|
27011
|
+
});
|
|
27012
|
+
}
|
|
27013
|
+
|
|
27014
|
+
// src/commands/watch/renderWatchReport.ts
|
|
27015
|
+
var escapeCell = (text17) => text17.replaceAll("|", String.raw`\|`);
|
|
27016
|
+
function renderWatchReport({
|
|
27017
|
+
version: version2,
|
|
27018
|
+
commits: commits2,
|
|
27019
|
+
newShas,
|
|
27020
|
+
restarts
|
|
27021
|
+
}) {
|
|
27022
|
+
const isNew = new Set(newShas);
|
|
27023
|
+
const lines2 = [`**Version** ${version2}`, ""];
|
|
27024
|
+
if (commits2.length === 0) {
|
|
27025
|
+
lines2.push("_no commits_");
|
|
27026
|
+
} else {
|
|
27027
|
+
lines2.push("| SHA | When | Subject |", "| --- | --- | --- |");
|
|
27028
|
+
for (const commit2 of commits2) {
|
|
27029
|
+
const marker = isNew.has(commit2.sha) ? " \u2190 new" : "";
|
|
27030
|
+
lines2.push(
|
|
27031
|
+
`| \`${commit2.short}\` | ${commit2.when} | ${escapeCell(commit2.subject)}${marker} |`
|
|
27032
|
+
);
|
|
27033
|
+
}
|
|
27034
|
+
}
|
|
27035
|
+
lines2.push("", "**Restarts**", "");
|
|
27036
|
+
lines2.push(
|
|
27037
|
+
...restarts.length === 0 ? ["- none needed"] : restarts.map((restart) => `- ${restart}`)
|
|
27038
|
+
);
|
|
27039
|
+
return lines2.join("\n");
|
|
27040
|
+
}
|
|
27041
|
+
|
|
27042
|
+
// src/commands/watch/restartAdvice.ts
|
|
27043
|
+
var webUiPrefix = "src/commands/sessions/web/ui/";
|
|
27044
|
+
var sessionsPrefix = "src/commands/sessions/";
|
|
27045
|
+
var rules = [
|
|
27046
|
+
{
|
|
27047
|
+
matches: (path71) => path71.startsWith(webUiPrefix),
|
|
27048
|
+
advice: "restart the web server, then hard-reload the browser tab"
|
|
27049
|
+
},
|
|
27050
|
+
{
|
|
27051
|
+
matches: (path71) => path71.startsWith(sessionsPrefix) && !path71.startsWith(webUiPrefix),
|
|
27052
|
+
advice: "restart the daemon"
|
|
27053
|
+
}
|
|
27054
|
+
];
|
|
27055
|
+
function restartAdvice(paths) {
|
|
27056
|
+
return rules.filter((rule) => paths.some(rule.matches)).map((rule) => rule.advice);
|
|
27057
|
+
}
|
|
27058
|
+
|
|
27059
|
+
// src/commands/watch/buildWatchReport.ts
|
|
27060
|
+
var lines = (output) => output.split("\n").filter((line) => line.length > 0);
|
|
27061
|
+
function buildWatchReport(from, cwd) {
|
|
27062
|
+
const range = from ? `${from}..HEAD` : void 0;
|
|
27063
|
+
return renderWatchReport({
|
|
27064
|
+
version: readBuiltVersion(cwd),
|
|
27065
|
+
commits: readRecentCommits(10, cwd),
|
|
27066
|
+
newShas: range ? lines(runGit2(["rev-list", range], cwd)) : [],
|
|
27067
|
+
restarts: restartAdvice(
|
|
27068
|
+
range ? lines(runGit2(["diff", "--name-only", range], cwd)) : []
|
|
27069
|
+
)
|
|
27070
|
+
});
|
|
27071
|
+
}
|
|
27072
|
+
|
|
27073
|
+
// src/commands/watch/gitFailureReason.ts
|
|
27074
|
+
function gitFailureReason(error) {
|
|
27075
|
+
const streams = error;
|
|
27076
|
+
for (const stream of [streams?.stderr, streams?.stdout]) {
|
|
27077
|
+
const text17 = stream == null ? "" : String(stream).trim();
|
|
27078
|
+
if (text17) return text17;
|
|
27079
|
+
}
|
|
27080
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
27081
|
+
return message3.trim() || "git failed without reporting a reason";
|
|
27082
|
+
}
|
|
27083
|
+
|
|
27084
|
+
// src/commands/watch/watchReport.ts
|
|
27085
|
+
function watchReport(options2) {
|
|
27086
|
+
try {
|
|
27087
|
+
console.log(buildWatchReport(options2.from));
|
|
27088
|
+
} catch (error) {
|
|
27089
|
+
console.error(`cannot build the report: ${gitFailureReason(error)}`);
|
|
27090
|
+
process.exit(1);
|
|
27091
|
+
}
|
|
27092
|
+
}
|
|
27093
|
+
|
|
26913
27094
|
// src/commands/watch/describeOutcome.ts
|
|
26914
27095
|
var short = (sha) => sha.slice(0, 7);
|
|
26915
27096
|
function describeOutcome(outcome) {
|
|
@@ -26962,72 +27143,248 @@ function parseDuration(value) {
|
|
|
26962
27143
|
return amount * UNIT_MS[match[2]];
|
|
26963
27144
|
}
|
|
26964
27145
|
|
|
26965
|
-
// src/commands/watch/
|
|
26966
|
-
function
|
|
26967
|
-
|
|
26968
|
-
|
|
26969
|
-
|
|
26970
|
-
|
|
27146
|
+
// src/commands/watch/parseWatchDurations.ts
|
|
27147
|
+
function parseOrExit(value) {
|
|
27148
|
+
try {
|
|
27149
|
+
return parseDuration(value);
|
|
27150
|
+
} catch (error) {
|
|
27151
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
27152
|
+
return process.exit(1);
|
|
26971
27153
|
}
|
|
26972
|
-
|
|
26973
|
-
|
|
27154
|
+
}
|
|
27155
|
+
function parseWatchDurations(interval, timeout) {
|
|
27156
|
+
return {
|
|
27157
|
+
intervalMs: parseOrExit(interval),
|
|
27158
|
+
timeoutMs: timeout.trim() === "none" ? void 0 : parseOrExit(timeout)
|
|
27159
|
+
};
|
|
26974
27160
|
}
|
|
26975
27161
|
|
|
26976
|
-
// src/commands/watch/
|
|
26977
|
-
|
|
26978
|
-
function
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
27162
|
+
// src/commands/watch/pullFastForward.ts
|
|
27163
|
+
var STASH_MESSAGE = "assist watch";
|
|
27164
|
+
function attemptGit(args, cwd) {
|
|
27165
|
+
try {
|
|
27166
|
+
runGit2(args, cwd);
|
|
27167
|
+
return { ok: true };
|
|
27168
|
+
} catch (error) {
|
|
27169
|
+
return { ok: false, reason: gitFailureReason(error) };
|
|
27170
|
+
}
|
|
26984
27171
|
}
|
|
26985
|
-
function
|
|
27172
|
+
function fastForwarded(cwd) {
|
|
27173
|
+
return { kind: "fast-forwarded", sha: runGit2(["rev-parse", "@"], cwd) };
|
|
27174
|
+
}
|
|
27175
|
+
function operationInProgress(cwd) {
|
|
27176
|
+
return ["MERGE_HEAD", "REBASE_HEAD"].some(
|
|
27177
|
+
(ref) => attemptGit(["rev-parse", "--verify", "--quiet", ref], cwd).ok
|
|
27178
|
+
);
|
|
27179
|
+
}
|
|
27180
|
+
function headMatchesUpstream(cwd) {
|
|
26986
27181
|
try {
|
|
26987
|
-
runGit2(["rev-parse", "
|
|
27182
|
+
return runGit2(["rev-parse", "@"], cwd) === runGit2(["rev-parse", "@{u}"], cwd);
|
|
26988
27183
|
} catch {
|
|
26989
|
-
|
|
26990
|
-
"not a git repository \u2014 run assist watch wait from inside a repo"
|
|
26991
|
-
);
|
|
27184
|
+
return false;
|
|
26992
27185
|
}
|
|
26993
|
-
|
|
27186
|
+
}
|
|
27187
|
+
function behindUpstream(cwd) {
|
|
27188
|
+
return attemptGit(["merge-base", "--is-ancestor", "@", "@{u}"], cwd).ok;
|
|
27189
|
+
}
|
|
27190
|
+
function stashDirtyTree(cwd) {
|
|
27191
|
+
let dirty;
|
|
26994
27192
|
try {
|
|
26995
|
-
|
|
26996
|
-
} catch {
|
|
26997
|
-
|
|
26998
|
-
|
|
26999
|
-
|
|
27193
|
+
dirty = runGit2(["status", "--porcelain"], cwd) !== "";
|
|
27194
|
+
} catch (error) {
|
|
27195
|
+
return { ok: false, reason: gitFailureReason(error) };
|
|
27196
|
+
}
|
|
27197
|
+
if (!dirty) return { ok: true, stashed: false };
|
|
27198
|
+
const push = attemptGit(
|
|
27199
|
+
["stash", "push", "--include-untracked", "--message", STASH_MESSAGE],
|
|
27200
|
+
cwd
|
|
27201
|
+
);
|
|
27202
|
+
return push.ok ? { ok: true, stashed: true } : push;
|
|
27203
|
+
}
|
|
27204
|
+
function mergeBehindBranch(cwd) {
|
|
27205
|
+
const stash = stashDirtyTree(cwd);
|
|
27206
|
+
if (!stash.ok) return { kind: "blocked", reason: stash.reason };
|
|
27207
|
+
const merge = attemptGit(["merge", "--ff-only", "@{u}"], cwd);
|
|
27208
|
+
const restore2 = stash.stashed ? attemptGit(["stash", "pop"], cwd) : { ok: true };
|
|
27209
|
+
if (!merge.ok) return { kind: "blocked", reason: merge.reason };
|
|
27210
|
+
if (!restore2.ok) return { kind: "blocked", reason: restore2.reason };
|
|
27211
|
+
return fastForwarded(cwd);
|
|
27212
|
+
}
|
|
27213
|
+
function pullFastForward(cwd) {
|
|
27214
|
+
const pull = attemptGit(["pull", "--ff-only"], cwd);
|
|
27215
|
+
if (pull.ok) return fastForwarded(cwd);
|
|
27216
|
+
if (operationInProgress(cwd)) return { kind: "blocked", reason: pull.reason };
|
|
27217
|
+
if (headMatchesUpstream(cwd)) return fastForwarded(cwd);
|
|
27218
|
+
if (!behindUpstream(cwd)) return { kind: "blocked", reason: pull.reason };
|
|
27219
|
+
return mergeBehindBranch(cwd);
|
|
27220
|
+
}
|
|
27221
|
+
|
|
27222
|
+
// src/commands/watch/runWatchBuild.ts
|
|
27223
|
+
import { resolve as resolve17 } from "path";
|
|
27224
|
+
|
|
27225
|
+
// src/commands/run/findRunConfig.ts
|
|
27226
|
+
function exitNoRunConfigs() {
|
|
27227
|
+
console.error("No run configurations found in assist.yml");
|
|
27228
|
+
process.exit(1);
|
|
27229
|
+
}
|
|
27230
|
+
function exitWithConfigNotFound(name, configs) {
|
|
27231
|
+
console.error(`No run configuration found with name: ${name}`);
|
|
27232
|
+
console.error("Available configurations:");
|
|
27233
|
+
for (const r of configs) {
|
|
27234
|
+
console.error(` - ${r.name}`);
|
|
27235
|
+
}
|
|
27236
|
+
process.exit(1);
|
|
27237
|
+
}
|
|
27238
|
+
function exitWithAmbiguousConfig(name, matches) {
|
|
27239
|
+
console.error(`Ambiguous run configuration: ${name}`);
|
|
27240
|
+
console.error("Did you mean:");
|
|
27241
|
+
for (const r of matches) {
|
|
27242
|
+
console.error(` - ${r.name}`);
|
|
27243
|
+
}
|
|
27244
|
+
process.exit(1);
|
|
27245
|
+
}
|
|
27246
|
+
function requireRunConfigs() {
|
|
27247
|
+
const { run: run4 } = loadConfig();
|
|
27248
|
+
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
27249
|
+
if (configs.length === 0) return exitNoRunConfigs();
|
|
27250
|
+
return configs;
|
|
27251
|
+
}
|
|
27252
|
+
function lookupRunConfig(name) {
|
|
27253
|
+
const configs = requireRunConfigs();
|
|
27254
|
+
const exact = configs.find((r) => r.name === name);
|
|
27255
|
+
if (exact) return { kind: "match", config: exact };
|
|
27256
|
+
const suffixMatches = configs.filter((r) => r.name.endsWith(`:${name}`));
|
|
27257
|
+
if (suffixMatches.length === 1)
|
|
27258
|
+
return { kind: "match", config: suffixMatches[0] };
|
|
27259
|
+
if (suffixMatches.length > 1)
|
|
27260
|
+
return { kind: "ambiguous", matches: suffixMatches };
|
|
27261
|
+
return { kind: "not-found" };
|
|
27262
|
+
}
|
|
27263
|
+
function findRunConfig(name) {
|
|
27264
|
+
const result = lookupRunConfig(name);
|
|
27265
|
+
if (result.kind === "match") return result.config;
|
|
27266
|
+
if (result.kind === "ambiguous")
|
|
27267
|
+
return exitWithAmbiguousConfig(name, result.matches);
|
|
27268
|
+
return exitWithConfigNotFound(name, requireRunConfigs());
|
|
27269
|
+
}
|
|
27270
|
+
|
|
27271
|
+
// src/commands/run/resolveParams.ts
|
|
27272
|
+
function resolveParams(params, cliArgs) {
|
|
27273
|
+
if (!params || params.length === 0) return cliArgs;
|
|
27274
|
+
const resolved = [];
|
|
27275
|
+
const missing = [];
|
|
27276
|
+
for (let i = 0; i < params.length; i++) {
|
|
27277
|
+
const param = params[i];
|
|
27278
|
+
const value = cliArgs[i] ?? param.default;
|
|
27279
|
+
if (value !== void 0) {
|
|
27280
|
+
resolved.push(value);
|
|
27281
|
+
} else if (param.required) {
|
|
27282
|
+
missing.push(param.name);
|
|
27283
|
+
}
|
|
27284
|
+
}
|
|
27285
|
+
if (missing.length > 0) {
|
|
27286
|
+
const s = missing.length > 1 ? "s" : "";
|
|
27287
|
+
const names = missing.map((n) => `"${n}"`).join(", ");
|
|
27288
|
+
console.error(`Missing required param${s}: ${names}`);
|
|
27289
|
+
process.exit(1);
|
|
27000
27290
|
}
|
|
27291
|
+
resolved.push(...cliArgs.slice(params.length));
|
|
27292
|
+
return resolved;
|
|
27293
|
+
}
|
|
27294
|
+
|
|
27295
|
+
// src/commands/run/runCommandToCompletion.ts
|
|
27296
|
+
import { execFileSync as execFileSync11, spawn as spawn9 } from "child_process";
|
|
27297
|
+
import { existsSync as existsSync58 } from "fs";
|
|
27298
|
+
import { dirname as dirname31, join as join68, resolve as resolve16 } from "path";
|
|
27299
|
+
function resolveCommand2(command) {
|
|
27300
|
+
if (process.platform !== "win32" || command !== "bash") return command;
|
|
27001
27301
|
try {
|
|
27002
|
-
|
|
27003
|
-
|
|
27004
|
-
|
|
27005
|
-
|
|
27006
|
-
cwd
|
|
27007
|
-
)
|
|
27008
|
-
};
|
|
27302
|
+
const gitPath = execFileSync11("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
27303
|
+
const gitRoot = resolve16(dirname31(gitPath), "..");
|
|
27304
|
+
const gitBash = join68(gitRoot, "bin", "bash.exe");
|
|
27305
|
+
if (existsSync58(gitBash)) return gitBash;
|
|
27009
27306
|
} catch {
|
|
27010
|
-
|
|
27011
|
-
`branch "${branch2}" has no upstream \u2014 set one with: git push -u origin ${branch2}`
|
|
27012
|
-
);
|
|
27307
|
+
return command;
|
|
27013
27308
|
}
|
|
27309
|
+
return command;
|
|
27310
|
+
}
|
|
27311
|
+
function runCommandToCompletion(command, args, env, cwd, quiet) {
|
|
27312
|
+
return new Promise((resolveResult) => {
|
|
27313
|
+
const child = spawn9(resolveCommand2(command), args, {
|
|
27314
|
+
stdio: quiet ? "pipe" : "inherit",
|
|
27315
|
+
env: env ? { ...process.env, ...expandEnv(env) } : void 0,
|
|
27316
|
+
cwd
|
|
27317
|
+
});
|
|
27318
|
+
const chunks = [];
|
|
27319
|
+
if (quiet) {
|
|
27320
|
+
child.stdout?.on("data", (data) => chunks.push(data));
|
|
27321
|
+
child.stderr?.on("data", (data) => chunks.push(data));
|
|
27322
|
+
}
|
|
27323
|
+
child.on("close", (code) => {
|
|
27324
|
+
resolveResult({
|
|
27325
|
+
kind: "completed",
|
|
27326
|
+
exitCode: code ?? 0,
|
|
27327
|
+
output: Buffer.concat(chunks).toString()
|
|
27328
|
+
});
|
|
27329
|
+
});
|
|
27330
|
+
child.on("error", (err) => {
|
|
27331
|
+
resolveResult({
|
|
27332
|
+
kind: "failed",
|
|
27333
|
+
message: `Failed to execute command: ${err.message}`
|
|
27334
|
+
});
|
|
27335
|
+
});
|
|
27336
|
+
});
|
|
27014
27337
|
}
|
|
27015
27338
|
|
|
27016
|
-
// src/commands/
|
|
27017
|
-
|
|
27018
|
-
|
|
27019
|
-
|
|
27020
|
-
|
|
27021
|
-
|
|
27022
|
-
|
|
27339
|
+
// src/commands/run/runPreCommands.ts
|
|
27340
|
+
import { execSync as execSync60 } from "child_process";
|
|
27341
|
+
function runPreCommands(pre, cwd) {
|
|
27342
|
+
for (const cmd of pre) {
|
|
27343
|
+
try {
|
|
27344
|
+
execSync60(cmd, { stdio: "inherit", cwd });
|
|
27345
|
+
} catch (error) {
|
|
27346
|
+
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
27347
|
+
process.exit(code);
|
|
27348
|
+
}
|
|
27349
|
+
}
|
|
27350
|
+
}
|
|
27351
|
+
|
|
27352
|
+
// src/commands/watch/runWatchBuild.ts
|
|
27353
|
+
async function runWatchBuild(entry) {
|
|
27354
|
+
const config = findRunConfig(entry);
|
|
27355
|
+
const cwd = config.cwd ? resolve17(getConfigDir(), config.cwd) : void 0;
|
|
27356
|
+
if (config.pre) runPreCommands(config.pre, cwd);
|
|
27357
|
+
const result = await runCommandToCompletion(
|
|
27358
|
+
config.command,
|
|
27359
|
+
[...config.args ?? [], ...resolveParams(config.params, [])],
|
|
27360
|
+
config.env,
|
|
27361
|
+
cwd,
|
|
27362
|
+
config.quiet
|
|
27363
|
+
);
|
|
27364
|
+
if (result.kind === "failed")
|
|
27365
|
+
return { kind: "failed", exitCode: 1, output: result.message };
|
|
27366
|
+
if (result.exitCode !== 0)
|
|
27367
|
+
return { kind: "failed", exitCode: result.exitCode, output: result.output };
|
|
27368
|
+
return { kind: "built" };
|
|
27369
|
+
}
|
|
27370
|
+
|
|
27371
|
+
// src/commands/watch/reportBuildOrExit.ts
|
|
27372
|
+
async function reportBuildOrExit(entry) {
|
|
27373
|
+
const outcome = await runWatchBuild(entry);
|
|
27374
|
+
if (outcome.kind === "built") {
|
|
27375
|
+
console.log(`built with "${entry}"`);
|
|
27376
|
+
return;
|
|
27023
27377
|
}
|
|
27378
|
+
if (outcome.output.length > 0) process.stdout.write(outcome.output);
|
|
27379
|
+
console.error(`build "${entry}" failed with exit code ${outcome.exitCode}`);
|
|
27380
|
+
process.exit(4);
|
|
27024
27381
|
}
|
|
27025
27382
|
|
|
27026
27383
|
// src/commands/watch/fetchQuietly.ts
|
|
27027
|
-
import { execFileSync as
|
|
27384
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
27028
27385
|
function fetchQuietly(cwd, timeoutMs) {
|
|
27029
27386
|
try {
|
|
27030
|
-
|
|
27387
|
+
execFileSync12("git", ["fetch", "--quiet"], {
|
|
27031
27388
|
stdio: ["pipe", "pipe", "pipe"],
|
|
27032
27389
|
cwd,
|
|
27033
27390
|
timeout: timeoutMs
|
|
@@ -27055,26 +27412,12 @@ function readMovement(cwd) {
|
|
|
27055
27412
|
}
|
|
27056
27413
|
}
|
|
27057
27414
|
|
|
27058
|
-
// src/commands/watch/
|
|
27415
|
+
// src/commands/watch/pollForMovement.ts
|
|
27059
27416
|
var MIN_FETCH_TIMEOUT_MS = 6e4;
|
|
27060
|
-
function
|
|
27061
|
-
const { intervalMs, timeoutMs, timeout, cwd
|
|
27062
|
-
let upstream;
|
|
27063
|
-
try {
|
|
27064
|
-
upstream = resolveUpstream(cwd).upstream;
|
|
27065
|
-
} catch (error) {
|
|
27066
|
-
return Promise.resolve({
|
|
27067
|
-
kind: "unavailable",
|
|
27068
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
27069
|
-
});
|
|
27070
|
-
}
|
|
27071
|
-
onStart?.(upstream);
|
|
27072
|
-
const moved = readMovement(cwd);
|
|
27073
|
-
if (moved) {
|
|
27074
|
-
return Promise.resolve({ kind: "moved", upstream, ...moved });
|
|
27075
|
-
}
|
|
27417
|
+
function pollForMovement(options2) {
|
|
27418
|
+
const { upstream, intervalMs, timeoutMs, timeout, cwd } = options2;
|
|
27076
27419
|
const fetchTimeoutMs = Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS);
|
|
27077
|
-
return new Promise((
|
|
27420
|
+
return new Promise((resolve22) => {
|
|
27078
27421
|
let settled = false;
|
|
27079
27422
|
const finish = (outcome) => {
|
|
27080
27423
|
if (settled) return;
|
|
@@ -27082,7 +27425,7 @@ function waitForUpstream(options2) {
|
|
|
27082
27425
|
clearInterval(ticker);
|
|
27083
27426
|
clearTimeout(deadline);
|
|
27084
27427
|
process.off("SIGINT", onInterrupt);
|
|
27085
|
-
|
|
27428
|
+
resolve22(outcome);
|
|
27086
27429
|
};
|
|
27087
27430
|
const onInterrupt = () => finish({ kind: "interrupted" });
|
|
27088
27431
|
const ticker = setInterval(() => {
|
|
@@ -27090,7 +27433,7 @@ function waitForUpstream(options2) {
|
|
|
27090
27433
|
const found = readMovement(cwd);
|
|
27091
27434
|
if (found) finish({ kind: "moved", upstream, ...found });
|
|
27092
27435
|
}, intervalMs);
|
|
27093
|
-
const deadline = setTimeout(
|
|
27436
|
+
const deadline = timeoutMs === void 0 ? void 0 : setTimeout(
|
|
27094
27437
|
() => finish({ kind: "timeout", upstream, timeout }),
|
|
27095
27438
|
timeoutMs
|
|
27096
27439
|
);
|
|
@@ -27098,22 +27441,35 @@ function waitForUpstream(options2) {
|
|
|
27098
27441
|
});
|
|
27099
27442
|
}
|
|
27100
27443
|
|
|
27101
|
-
// src/commands/watch/
|
|
27102
|
-
function
|
|
27444
|
+
// src/commands/watch/waitForUpstream.ts
|
|
27445
|
+
function waitForUpstream(options2) {
|
|
27446
|
+
const { intervalMs, timeoutMs, timeout, cwd, onStart } = options2;
|
|
27447
|
+
let upstream;
|
|
27103
27448
|
try {
|
|
27104
|
-
|
|
27449
|
+
upstream = resolveUpstream(cwd).upstream;
|
|
27105
27450
|
} catch (error) {
|
|
27106
|
-
|
|
27107
|
-
|
|
27451
|
+
return Promise.resolve({
|
|
27452
|
+
kind: "unavailable",
|
|
27453
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
27454
|
+
});
|
|
27108
27455
|
}
|
|
27456
|
+
onStart?.(upstream);
|
|
27457
|
+
const moved = readMovement(cwd);
|
|
27458
|
+
if (moved) return Promise.resolve({ kind: "moved", upstream, ...moved });
|
|
27459
|
+
return pollForMovement({ upstream, intervalMs, timeoutMs, timeout, cwd });
|
|
27109
27460
|
}
|
|
27461
|
+
|
|
27462
|
+
// src/commands/watch/watchWait.ts
|
|
27463
|
+
var DEFAULT_BUILD_ENTRY = "auto-build";
|
|
27110
27464
|
function report({ exitCode, message: message3 }) {
|
|
27111
27465
|
if (exitCode === 0) console.log(message3);
|
|
27112
27466
|
else console.error(message3);
|
|
27113
27467
|
}
|
|
27114
27468
|
async function watchWait(options2) {
|
|
27115
|
-
const intervalMs =
|
|
27116
|
-
|
|
27469
|
+
const { intervalMs, timeoutMs } = parseWatchDurations(
|
|
27470
|
+
options2.interval,
|
|
27471
|
+
options2.timeout
|
|
27472
|
+
);
|
|
27117
27473
|
const outcome = await waitForUpstream({
|
|
27118
27474
|
intervalMs,
|
|
27119
27475
|
timeoutMs,
|
|
@@ -27122,29 +27478,47 @@ async function watchWait(options2) {
|
|
|
27122
27478
|
});
|
|
27123
27479
|
const waitReport = describeOutcome(outcome);
|
|
27124
27480
|
report(waitReport);
|
|
27125
|
-
if (outcome.kind
|
|
27126
|
-
|
|
27127
|
-
|
|
27128
|
-
|
|
27481
|
+
if (outcome.kind !== "moved" || !options2.pull)
|
|
27482
|
+
return process.exit(waitReport.exitCode);
|
|
27483
|
+
const pullResult = pullFastForward();
|
|
27484
|
+
const pullReport = describePull(pullResult);
|
|
27485
|
+
report(pullReport);
|
|
27486
|
+
if (pullResult.kind !== "fast-forwarded")
|
|
27487
|
+
return process.exit(pullReport.exitCode);
|
|
27488
|
+
console.log(`
|
|
27489
|
+
${buildWatchReport(outcome.from)}`);
|
|
27490
|
+
if (options2.build) {
|
|
27491
|
+
await reportBuildOrExit(
|
|
27492
|
+
typeof options2.build === "string" ? options2.build : DEFAULT_BUILD_ENTRY
|
|
27493
|
+
);
|
|
27129
27494
|
}
|
|
27130
|
-
process.exit(
|
|
27495
|
+
process.exit(0);
|
|
27131
27496
|
}
|
|
27132
27497
|
|
|
27133
27498
|
// src/commands/registerWatch.ts
|
|
27134
27499
|
function registerWatch(program2) {
|
|
27135
27500
|
const watchCommand = program2.command("watch").description("Wait on upstream movement for the current branch");
|
|
27136
27501
|
watchCommand.command("wait").description(
|
|
27137
|
-
"Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull
|
|
27502
|
+
"Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull hits genuine divergence, 4 when --build fails, 1 when waiting is impossible, 130 on interrupt)"
|
|
27138
27503
|
).option("--interval <duration>", "How often to fetch (e.g. 30s, 2m)", "30s").option(
|
|
27139
27504
|
"--timeout <duration>",
|
|
27140
|
-
"Give up and exit 2 after this long (e.g. 60m, 2h)",
|
|
27141
|
-
"
|
|
27505
|
+
"Give up and exit 2 after this long (e.g. 60m, 2h), or none to wait indefinitely",
|
|
27506
|
+
"none"
|
|
27142
27507
|
).option(
|
|
27143
27508
|
"--pull",
|
|
27144
|
-
"On movement, fast-forward with git pull --ff-only; exit 3 with git's reason
|
|
27509
|
+
"On movement, fast-forward with git pull --ff-only, recovering a dirty tree or a merely-behind branch; exit 3 with git's reason on genuine divergence"
|
|
27510
|
+
).option(
|
|
27511
|
+
"--build [entry]",
|
|
27512
|
+
"After a successful pull, run this run entry (default auto-build); exit 4 with its output when it fails"
|
|
27145
27513
|
).action(
|
|
27146
27514
|
(options2) => watchWait(options2)
|
|
27147
27515
|
);
|
|
27516
|
+
watchCommand.command("report").description(
|
|
27517
|
+
"Print the built version, the last 10 commits as a markdown table, and the restarts the new commits make necessary"
|
|
27518
|
+
).option(
|
|
27519
|
+
"--from <sha>",
|
|
27520
|
+
"Mark commits reachable from HEAD but not <sha> as new, and derive restart advice from the files they changed"
|
|
27521
|
+
).action((options2) => watchReport(options2));
|
|
27148
27522
|
}
|
|
27149
27523
|
|
|
27150
27524
|
// src/commands/roam/auth.ts
|
|
@@ -27170,7 +27544,7 @@ function extractCode(url, expectedState) {
|
|
|
27170
27544
|
return code;
|
|
27171
27545
|
}
|
|
27172
27546
|
function waitForCallback(port, expectedState) {
|
|
27173
|
-
return new Promise((
|
|
27547
|
+
return new Promise((resolve22, reject) => {
|
|
27174
27548
|
const timeout = setTimeout(() => {
|
|
27175
27549
|
server.close();
|
|
27176
27550
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -27187,7 +27561,7 @@ function waitForCallback(port, expectedState) {
|
|
|
27187
27561
|
const code = extractCode(url, expectedState);
|
|
27188
27562
|
respondHtml(res, 200, "Authorization successful!");
|
|
27189
27563
|
server.close();
|
|
27190
|
-
|
|
27564
|
+
resolve22(code);
|
|
27191
27565
|
} catch (error) {
|
|
27192
27566
|
respondHtml(res, 400, error.message);
|
|
27193
27567
|
server.close();
|
|
@@ -27307,9 +27681,9 @@ async function auth() {
|
|
|
27307
27681
|
}
|
|
27308
27682
|
|
|
27309
27683
|
// src/commands/roam/postRoamActivity.ts
|
|
27310
|
-
import { execFileSync as
|
|
27684
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
27311
27685
|
import { readdirSync as readdirSync12, readFileSync as readFileSync48, statSync as statSync10 } from "fs";
|
|
27312
|
-
import { join as
|
|
27686
|
+
import { join as join69 } from "path";
|
|
27313
27687
|
function findPortFile(roamDir) {
|
|
27314
27688
|
let entries;
|
|
27315
27689
|
try {
|
|
@@ -27318,7 +27692,7 @@ function findPortFile(roamDir) {
|
|
|
27318
27692
|
return void 0;
|
|
27319
27693
|
}
|
|
27320
27694
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
27321
|
-
const path71 =
|
|
27695
|
+
const path71 = join69(roamDir, name);
|
|
27322
27696
|
try {
|
|
27323
27697
|
return { path: path71, mtimeMs: statSync10(path71).mtimeMs };
|
|
27324
27698
|
} catch {
|
|
@@ -27330,7 +27704,7 @@ function findPortFile(roamDir) {
|
|
|
27330
27704
|
function postRoamActivity(app, event) {
|
|
27331
27705
|
const appData = process.env.APPDATA;
|
|
27332
27706
|
if (!appData) return;
|
|
27333
|
-
const portFile = findPortFile(
|
|
27707
|
+
const portFile = findPortFile(join69(appData, "Roam"));
|
|
27334
27708
|
if (!portFile) return;
|
|
27335
27709
|
let port;
|
|
27336
27710
|
try {
|
|
@@ -27340,7 +27714,7 @@ function postRoamActivity(app, event) {
|
|
|
27340
27714
|
}
|
|
27341
27715
|
const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${app === "codex" ? 99998 : 99999}`;
|
|
27342
27716
|
try {
|
|
27343
|
-
|
|
27717
|
+
execFileSync13("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
|
|
27344
27718
|
stdio: "ignore"
|
|
27345
27719
|
});
|
|
27346
27720
|
} catch {
|
|
@@ -27464,53 +27838,7 @@ var rootConfigHelp = {
|
|
|
27464
27838
|
};
|
|
27465
27839
|
|
|
27466
27840
|
// src/commands/run/index.ts
|
|
27467
|
-
import { resolve as
|
|
27468
|
-
|
|
27469
|
-
// src/commands/run/findRunConfig.ts
|
|
27470
|
-
function exitNoRunConfigs() {
|
|
27471
|
-
console.error("No run configurations found in assist.yml");
|
|
27472
|
-
process.exit(1);
|
|
27473
|
-
}
|
|
27474
|
-
function exitWithConfigNotFound(name, configs) {
|
|
27475
|
-
console.error(`No run configuration found with name: ${name}`);
|
|
27476
|
-
console.error("Available configurations:");
|
|
27477
|
-
for (const r of configs) {
|
|
27478
|
-
console.error(` - ${r.name}`);
|
|
27479
|
-
}
|
|
27480
|
-
process.exit(1);
|
|
27481
|
-
}
|
|
27482
|
-
function exitWithAmbiguousConfig(name, matches) {
|
|
27483
|
-
console.error(`Ambiguous run configuration: ${name}`);
|
|
27484
|
-
console.error("Did you mean:");
|
|
27485
|
-
for (const r of matches) {
|
|
27486
|
-
console.error(` - ${r.name}`);
|
|
27487
|
-
}
|
|
27488
|
-
process.exit(1);
|
|
27489
|
-
}
|
|
27490
|
-
function requireRunConfigs() {
|
|
27491
|
-
const { run: run4 } = loadConfig();
|
|
27492
|
-
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
27493
|
-
if (configs.length === 0) return exitNoRunConfigs();
|
|
27494
|
-
return configs;
|
|
27495
|
-
}
|
|
27496
|
-
function lookupRunConfig(name) {
|
|
27497
|
-
const configs = requireRunConfigs();
|
|
27498
|
-
const exact = configs.find((r) => r.name === name);
|
|
27499
|
-
if (exact) return { kind: "match", config: exact };
|
|
27500
|
-
const suffixMatches = configs.filter((r) => r.name.endsWith(`:${name}`));
|
|
27501
|
-
if (suffixMatches.length === 1)
|
|
27502
|
-
return { kind: "match", config: suffixMatches[0] };
|
|
27503
|
-
if (suffixMatches.length > 1)
|
|
27504
|
-
return { kind: "ambiguous", matches: suffixMatches };
|
|
27505
|
-
return { kind: "not-found" };
|
|
27506
|
-
}
|
|
27507
|
-
function findRunConfig(name) {
|
|
27508
|
-
const result = lookupRunConfig(name);
|
|
27509
|
-
if (result.kind === "match") return result.config;
|
|
27510
|
-
if (result.kind === "ambiguous")
|
|
27511
|
-
return exitWithAmbiguousConfig(name, result.matches);
|
|
27512
|
-
return exitWithConfigNotFound(name, requireRunConfigs());
|
|
27513
|
-
}
|
|
27841
|
+
import { resolve as resolve18 } from "path";
|
|
27514
27842
|
|
|
27515
27843
|
// src/commands/run/formatConfiguredCommands.ts
|
|
27516
27844
|
function formatConfiguredCommands() {
|
|
@@ -27523,84 +27851,23 @@ Configured commands:
|
|
|
27523
27851
|
${names}`;
|
|
27524
27852
|
}
|
|
27525
27853
|
|
|
27526
|
-
// src/commands/run/resolveParams.ts
|
|
27527
|
-
function resolveParams(params, cliArgs) {
|
|
27528
|
-
if (!params || params.length === 0) return cliArgs;
|
|
27529
|
-
const resolved = [];
|
|
27530
|
-
const missing = [];
|
|
27531
|
-
for (let i = 0; i < params.length; i++) {
|
|
27532
|
-
const param = params[i];
|
|
27533
|
-
const value = cliArgs[i] ?? param.default;
|
|
27534
|
-
if (value !== void 0) {
|
|
27535
|
-
resolved.push(value);
|
|
27536
|
-
} else if (param.required) {
|
|
27537
|
-
missing.push(param.name);
|
|
27538
|
-
}
|
|
27539
|
-
}
|
|
27540
|
-
if (missing.length > 0) {
|
|
27541
|
-
const s = missing.length > 1 ? "s" : "";
|
|
27542
|
-
const names = missing.map((n) => `"${n}"`).join(", ");
|
|
27543
|
-
console.error(`Missing required param${s}: ${names}`);
|
|
27544
|
-
process.exit(1);
|
|
27545
|
-
}
|
|
27546
|
-
resolved.push(...cliArgs.slice(params.length));
|
|
27547
|
-
return resolved;
|
|
27548
|
-
}
|
|
27549
|
-
|
|
27550
|
-
// src/commands/run/runPreCommands.ts
|
|
27551
|
-
import { execSync as execSync60 } from "child_process";
|
|
27552
|
-
function runPreCommands(pre, cwd) {
|
|
27553
|
-
for (const cmd of pre) {
|
|
27554
|
-
try {
|
|
27555
|
-
execSync60(cmd, { stdio: "inherit", cwd });
|
|
27556
|
-
} catch (error) {
|
|
27557
|
-
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
27558
|
-
process.exit(code);
|
|
27559
|
-
}
|
|
27560
|
-
}
|
|
27561
|
-
}
|
|
27562
|
-
|
|
27563
27854
|
// src/commands/run/spawnRunCommand.ts
|
|
27564
|
-
import { execFileSync as execFileSync13, spawn as spawn9 } from "child_process";
|
|
27565
|
-
import { existsSync as existsSync58 } from "fs";
|
|
27566
|
-
import { dirname as dirname31, join as join68, resolve as resolve16 } from "path";
|
|
27567
|
-
function resolveCommand2(command) {
|
|
27568
|
-
if (process.platform !== "win32" || command !== "bash") return command;
|
|
27569
|
-
try {
|
|
27570
|
-
const gitPath = execFileSync13("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
27571
|
-
const gitRoot = resolve16(dirname31(gitPath), "..");
|
|
27572
|
-
const gitBash = join68(gitRoot, "bin", "bash.exe");
|
|
27573
|
-
if (existsSync58(gitBash)) return gitBash;
|
|
27574
|
-
} catch {
|
|
27575
|
-
}
|
|
27576
|
-
return command;
|
|
27577
|
-
}
|
|
27578
27855
|
function spawnRunCommand(command, args, env, cwd, quiet) {
|
|
27579
27856
|
const start3 = Date.now();
|
|
27580
|
-
|
|
27581
|
-
|
|
27582
|
-
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27586
|
-
|
|
27587
|
-
|
|
27588
|
-
child.stderr?.on("data", (data) => chunks.push(data));
|
|
27589
|
-
}
|
|
27590
|
-
child.on("close", (code) => {
|
|
27591
|
-
const exitCode = code ?? 0;
|
|
27592
|
-
if (quiet && exitCode !== 0 && chunks.length > 0) {
|
|
27593
|
-
process.stdout.write(Buffer.concat(chunks));
|
|
27857
|
+
void runCommandToCompletion(command, args, env, cwd, quiet).then((result) => {
|
|
27858
|
+
if (result.kind === "failed") {
|
|
27859
|
+
console.error(result.message);
|
|
27860
|
+
process.exit(1);
|
|
27861
|
+
}
|
|
27862
|
+
const { exitCode, output } = result;
|
|
27863
|
+
if (quiet && exitCode !== 0 && output.length > 0) {
|
|
27864
|
+
process.stdout.write(output);
|
|
27594
27865
|
}
|
|
27595
27866
|
const elapsed = formatElapsed(Date.now() - start3);
|
|
27596
27867
|
if (!quiet || exitCode !== 0) console.log(`
|
|
27597
27868
|
Done in ${elapsed}`);
|
|
27598
27869
|
process.exit(exitCode);
|
|
27599
27870
|
});
|
|
27600
|
-
child.on("error", (err) => {
|
|
27601
|
-
console.error(`Failed to execute command: ${err.message}`);
|
|
27602
|
-
process.exit(1);
|
|
27603
|
-
});
|
|
27604
27871
|
}
|
|
27605
27872
|
|
|
27606
27873
|
// src/commands/run/index.ts
|
|
@@ -27616,7 +27883,7 @@ function listRunConfigs(verbose) {
|
|
|
27616
27883
|
}
|
|
27617
27884
|
}
|
|
27618
27885
|
function execRunConfig(config, args) {
|
|
27619
|
-
const cwd = config.cwd ?
|
|
27886
|
+
const cwd = config.cwd ? resolve18(getConfigDir(), config.cwd) : void 0;
|
|
27620
27887
|
if (config.pre) runPreCommands(config.pre, cwd);
|
|
27621
27888
|
const resolved = resolveParams(config.params, args);
|
|
27622
27889
|
spawnRunCommand(
|
|
@@ -27658,7 +27925,7 @@ async function run3(name, args) {
|
|
|
27658
27925
|
|
|
27659
27926
|
// src/commands/run/add.ts
|
|
27660
27927
|
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync41 } from "fs";
|
|
27661
|
-
import { join as
|
|
27928
|
+
import { join as join70 } from "path";
|
|
27662
27929
|
|
|
27663
27930
|
// src/commands/run/extractOption.ts
|
|
27664
27931
|
function extractOption(args, flag) {
|
|
@@ -27719,7 +27986,7 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
27719
27986
|
saveConfig(config);
|
|
27720
27987
|
}
|
|
27721
27988
|
function createCommandFile(name) {
|
|
27722
|
-
const dir =
|
|
27989
|
+
const dir = join70(".claude", "commands");
|
|
27723
27990
|
mkdirSync24(dir, { recursive: true });
|
|
27724
27991
|
const content = `---
|
|
27725
27992
|
description: Run ${name}
|
|
@@ -27727,7 +27994,7 @@ description: Run ${name}
|
|
|
27727
27994
|
|
|
27728
27995
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
27729
27996
|
`;
|
|
27730
|
-
const filePath =
|
|
27997
|
+
const filePath = join70(dir, `${name}.md`);
|
|
27731
27998
|
writeFileSync41(filePath, content);
|
|
27732
27999
|
console.log(`Created command file: ${filePath}`);
|
|
27733
28000
|
}
|
|
@@ -27784,7 +28051,7 @@ function link2() {
|
|
|
27784
28051
|
|
|
27785
28052
|
// src/commands/run/remove.ts
|
|
27786
28053
|
import { existsSync as existsSync59, unlinkSync as unlinkSync21 } from "fs";
|
|
27787
|
-
import { join as
|
|
28054
|
+
import { join as join71 } from "path";
|
|
27788
28055
|
function findRemoveIndex() {
|
|
27789
28056
|
const idx = process.argv.indexOf("remove");
|
|
27790
28057
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -27799,7 +28066,7 @@ function parseRemoveName() {
|
|
|
27799
28066
|
return process.argv[idx + 1];
|
|
27800
28067
|
}
|
|
27801
28068
|
function deleteCommandFile(name) {
|
|
27802
|
-
const filePath =
|
|
28069
|
+
const filePath = join71(".claude", "commands", `${name}.md`);
|
|
27803
28070
|
if (existsSync59(filePath)) {
|
|
27804
28071
|
unlinkSync21(filePath);
|
|
27805
28072
|
console.log(`Deleted command file: ${filePath}`);
|
|
@@ -27856,7 +28123,7 @@ function registerRun(program2) {
|
|
|
27856
28123
|
import { execSync as execSync61 } from "child_process";
|
|
27857
28124
|
import { existsSync as existsSync60, mkdirSync as mkdirSync25, unlinkSync as unlinkSync22, writeFileSync as writeFileSync42 } from "fs";
|
|
27858
28125
|
import { tmpdir as tmpdir8 } from "os";
|
|
27859
|
-
import { join as
|
|
28126
|
+
import { join as join72, resolve as resolve19 } from "path";
|
|
27860
28127
|
import chalk209 from "chalk";
|
|
27861
28128
|
|
|
27862
28129
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -27990,10 +28257,10 @@ function buildOutputPath(outputDir, processName) {
|
|
|
27990
28257
|
mkdirSync25(outputDir, { recursive: true });
|
|
27991
28258
|
}
|
|
27992
28259
|
const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27993
|
-
return
|
|
28260
|
+
return resolve19(outputDir, `${processName}-${timestamp6}.png`);
|
|
27994
28261
|
}
|
|
27995
28262
|
function runPowerShellScript(processName, outputPath) {
|
|
27996
|
-
const scriptPath =
|
|
28263
|
+
const scriptPath = join72(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
|
|
27997
28264
|
writeFileSync42(scriptPath, captureWindowPs1, "utf8");
|
|
27998
28265
|
try {
|
|
27999
28266
|
execSync61(
|
|
@@ -28006,7 +28273,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
28006
28273
|
}
|
|
28007
28274
|
function screenshot(processName) {
|
|
28008
28275
|
const config = loadConfig();
|
|
28009
|
-
const outputDir =
|
|
28276
|
+
const outputDir = resolve19(config.screenshot.outputDir);
|
|
28010
28277
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
28011
28278
|
console.log(chalk209.gray(`Capturing window for process "${processName}" ...`));
|
|
28012
28279
|
try {
|
|
@@ -28039,18 +28306,18 @@ var STATUS_TIMEOUT_MS = 5e3;
|
|
|
28039
28306
|
function queryDaemon(socket) {
|
|
28040
28307
|
socket.write(`${JSON.stringify({ type: "ping" })}
|
|
28041
28308
|
`);
|
|
28042
|
-
return new Promise((
|
|
28309
|
+
return new Promise((resolve22) => {
|
|
28043
28310
|
const result = { sessions: [] };
|
|
28044
28311
|
const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
|
|
28045
|
-
const timer = setTimeout(() =>
|
|
28046
|
-
const
|
|
28047
|
-
|
|
28312
|
+
const timer = setTimeout(() => resolve22(result), STATUS_TIMEOUT_MS);
|
|
28313
|
+
const lines2 = createInterface5({ input: socket });
|
|
28314
|
+
lines2.on("error", () => {
|
|
28048
28315
|
});
|
|
28049
|
-
|
|
28316
|
+
lines2.on("line", (line) => {
|
|
28050
28317
|
applyLine(result, pending, line);
|
|
28051
28318
|
if (pending.size === 0) {
|
|
28052
28319
|
clearTimeout(timer);
|
|
28053
|
-
|
|
28320
|
+
resolve22(result);
|
|
28054
28321
|
}
|
|
28055
28322
|
});
|
|
28056
28323
|
});
|
|
@@ -28135,12 +28402,12 @@ function clearPersistedSessionsOnDrain() {
|
|
|
28135
28402
|
}
|
|
28136
28403
|
|
|
28137
28404
|
// src/commands/sessions/daemon/readDaemonMessage.ts
|
|
28138
|
-
function readDaemonMessage(
|
|
28139
|
-
return new Promise((
|
|
28405
|
+
function readDaemonMessage(lines2, timeoutMs, fallback, match) {
|
|
28406
|
+
return new Promise((resolve22) => {
|
|
28140
28407
|
const finish = (value) => {
|
|
28141
28408
|
clearTimeout(timer);
|
|
28142
|
-
|
|
28143
|
-
|
|
28409
|
+
lines2.off("line", onLine);
|
|
28410
|
+
resolve22(value);
|
|
28144
28411
|
};
|
|
28145
28412
|
const timer = setTimeout(() => finish(fallback), timeoutMs);
|
|
28146
28413
|
const onLine = (line) => {
|
|
@@ -28150,7 +28417,7 @@ function readDaemonMessage(lines, timeoutMs, fallback, match) {
|
|
|
28150
28417
|
} catch {
|
|
28151
28418
|
}
|
|
28152
28419
|
};
|
|
28153
|
-
|
|
28420
|
+
lines2.on("line", onLine);
|
|
28154
28421
|
});
|
|
28155
28422
|
}
|
|
28156
28423
|
|
|
@@ -28165,10 +28432,10 @@ async function drainDaemon(options2 = {}) {
|
|
|
28165
28432
|
clearPersistedSessionsOnDrain();
|
|
28166
28433
|
return;
|
|
28167
28434
|
}
|
|
28168
|
-
const
|
|
28169
|
-
|
|
28435
|
+
const lines2 = createInterface6({ input: socket });
|
|
28436
|
+
lines2.on("error", () => {
|
|
28170
28437
|
});
|
|
28171
|
-
const live = await liveSessions(
|
|
28438
|
+
const live = await liveSessions(lines2);
|
|
28172
28439
|
if (live.length > 0 && options2.yes !== true) {
|
|
28173
28440
|
reportLive(live);
|
|
28174
28441
|
if (!await confirmDrain()) {
|
|
@@ -28176,7 +28443,7 @@ async function drainDaemon(options2 = {}) {
|
|
|
28176
28443
|
return;
|
|
28177
28444
|
}
|
|
28178
28445
|
}
|
|
28179
|
-
const count8 = await requestDrain(socket,
|
|
28446
|
+
const count8 = await requestDrain(socket, lines2);
|
|
28180
28447
|
socket.destroy();
|
|
28181
28448
|
console.log(`Drained ${count8} session(s)`);
|
|
28182
28449
|
}
|
|
@@ -28195,9 +28462,9 @@ async function confirmDrain() {
|
|
|
28195
28462
|
console.log("Drain cancelled");
|
|
28196
28463
|
return false;
|
|
28197
28464
|
}
|
|
28198
|
-
function liveSessions(
|
|
28465
|
+
function liveSessions(lines2) {
|
|
28199
28466
|
return readDaemonMessage(
|
|
28200
|
-
|
|
28467
|
+
lines2,
|
|
28201
28468
|
LIST_TIMEOUT_MS,
|
|
28202
28469
|
[],
|
|
28203
28470
|
(data) => data.type === "sessions" ? (data.sessions ?? []).filter(
|
|
@@ -28205,11 +28472,11 @@ function liveSessions(lines) {
|
|
|
28205
28472
|
) : void 0
|
|
28206
28473
|
);
|
|
28207
28474
|
}
|
|
28208
|
-
function requestDrain(socket,
|
|
28475
|
+
function requestDrain(socket, lines2) {
|
|
28209
28476
|
socket.write(`${JSON.stringify({ type: "drain" })}
|
|
28210
28477
|
`);
|
|
28211
28478
|
return readDaemonMessage(
|
|
28212
|
-
|
|
28479
|
+
lines2,
|
|
28213
28480
|
DRAIN_TIMEOUT_MS,
|
|
28214
28481
|
0,
|
|
28215
28482
|
(data) => data.type === "drained" ? data.count ?? 0 : void 0
|
|
@@ -28674,12 +28941,12 @@ import { basename as basename18 } from "path";
|
|
|
28674
28941
|
|
|
28675
28942
|
// src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
|
|
28676
28943
|
import { existsSync as existsSync63 } from "fs";
|
|
28677
|
-
import { join as
|
|
28944
|
+
import { join as join75 } from "path";
|
|
28678
28945
|
|
|
28679
28946
|
// src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
|
|
28680
28947
|
import { statSync as statSync12 } from "fs";
|
|
28681
28948
|
import { rm as rm2 } from "fs/promises";
|
|
28682
|
-
import { join as
|
|
28949
|
+
import { join as join74 } from "path";
|
|
28683
28950
|
async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
28684
28951
|
if (holdsAGitDirectoryRatherThanALink(worktreePath)) {
|
|
28685
28952
|
daemonLog(
|
|
@@ -28706,7 +28973,7 @@ async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
|
28706
28973
|
return true;
|
|
28707
28974
|
}
|
|
28708
28975
|
function holdsAGitDirectoryRatherThanALink(worktreePath) {
|
|
28709
|
-
return statSync12(
|
|
28976
|
+
return statSync12(join74(worktreePath, ".git"), {
|
|
28710
28977
|
throwIfNoEntry: false
|
|
28711
28978
|
})?.isDirectory() === true;
|
|
28712
28979
|
}
|
|
@@ -28742,7 +29009,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
|
|
|
28742
29009
|
);
|
|
28743
29010
|
}
|
|
28744
29011
|
function strandedReason(worktreePath, cause) {
|
|
28745
|
-
if (!existsSync63(
|
|
29012
|
+
if (!existsSync63(join75(worktreePath, ".git")))
|
|
28746
29013
|
return "its .git link is already gone";
|
|
28747
29014
|
if (/not a working tree|not a git repository/i.test(reason2(cause)))
|
|
28748
29015
|
return "git no longer recognises it as a working tree";
|
|
@@ -29836,6 +30103,40 @@ function registerSpawnedSession(session, sessions, clients, onStatusChange, noti
|
|
|
29836
30103
|
return session.id;
|
|
29837
30104
|
}
|
|
29838
30105
|
|
|
30106
|
+
// src/commands/sessions/daemon/sessionLimits.ts
|
|
30107
|
+
var MAX_LIVE = 12;
|
|
30108
|
+
var sessionLimits = {
|
|
30109
|
+
maxRestore: MAX_LIVE,
|
|
30110
|
+
/** Allocate the next session id from counter, refusing past the absolute
|
|
30111
|
+
* ceiling regardless of caller (restore, web create, retry) so no trigger
|
|
30112
|
+
* can fan out without bound. The counter advances only when allowed. */
|
|
30113
|
+
nextId(liveCount, counter) {
|
|
30114
|
+
if (liveCount >= MAX_LIVE) {
|
|
30115
|
+
daemonLog(`refusing to spawn: at ceiling of ${MAX_LIVE} live sessions`);
|
|
30116
|
+
throw new Error(`session ceiling of ${MAX_LIVE} reached`);
|
|
30117
|
+
}
|
|
30118
|
+
return String(counter.next++);
|
|
30119
|
+
},
|
|
30120
|
+
recoveryCardId(counter) {
|
|
30121
|
+
return String(counter.next++);
|
|
30122
|
+
}
|
|
30123
|
+
};
|
|
30124
|
+
|
|
30125
|
+
// src/commands/sessions/daemon/makeSessionSpawner.ts
|
|
30126
|
+
function makeSessionSpawner(sessions, clients, counter, onStatusChange, notify2) {
|
|
30127
|
+
const register = (allocateId) => (create) => registerSpawnedSession(
|
|
30128
|
+
create(allocateId()),
|
|
30129
|
+
sessions,
|
|
30130
|
+
clients,
|
|
30131
|
+
onStatusChange(),
|
|
30132
|
+
notify2
|
|
30133
|
+
);
|
|
30134
|
+
return {
|
|
30135
|
+
spawn: register(() => sessionLimits.nextId(sessions.size, counter)),
|
|
30136
|
+
recoveryCard: register(() => sessionLimits.recoveryCardId(counter))
|
|
30137
|
+
};
|
|
30138
|
+
}
|
|
30139
|
+
|
|
29839
30140
|
// src/commands/sessions/daemon/applySetStatus.ts
|
|
29840
30141
|
function applySetStatus(sessions, id, status3, source, onStatusChange) {
|
|
29841
30142
|
const session = sessions.get(id);
|
|
@@ -29931,9 +30232,9 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
|
29931
30232
|
|
|
29932
30233
|
// src/commands/sessions/shared/transcriptUsage.ts
|
|
29933
30234
|
import * as fs38 from "fs";
|
|
29934
|
-
function transcriptUsage(
|
|
30235
|
+
function transcriptUsage(lines2) {
|
|
29935
30236
|
const byId = /* @__PURE__ */ new Map();
|
|
29936
|
-
for (const line of
|
|
30237
|
+
for (const line of lines2) {
|
|
29937
30238
|
if (!line.trim()) continue;
|
|
29938
30239
|
let entry;
|
|
29939
30240
|
try {
|
|
@@ -30298,6 +30599,43 @@ function restoreBase(id, persisted) {
|
|
|
30298
30599
|
};
|
|
30299
30600
|
}
|
|
30300
30601
|
|
|
30602
|
+
// src/commands/sessions/daemon/deferredSession.ts
|
|
30603
|
+
function deferredSession(id, persisted, cap) {
|
|
30604
|
+
return {
|
|
30605
|
+
...restoreBase(id, persisted),
|
|
30606
|
+
status: "stopped",
|
|
30607
|
+
startedAt: persisted.startedAt,
|
|
30608
|
+
runningMs: persisted.runningMs ?? 0,
|
|
30609
|
+
runningSince: null,
|
|
30610
|
+
waitingSince: null,
|
|
30611
|
+
pty: null,
|
|
30612
|
+
claudeSessionId: persisted.claudeSessionId,
|
|
30613
|
+
runName: persisted.runName,
|
|
30614
|
+
runArgs: persisted.runArgs,
|
|
30615
|
+
activity: persisted.activity,
|
|
30616
|
+
restored: false,
|
|
30617
|
+
scrollback: deferralNotice(persisted, cap)
|
|
30618
|
+
};
|
|
30619
|
+
}
|
|
30620
|
+
function deferralNotice(persisted, cap) {
|
|
30621
|
+
return [
|
|
30622
|
+
`\r
|
|
30623
|
+
\x1B[33mNot resumed: restore was already at its cap of ${cap} session(s)\x1B[0m\r
|
|
30624
|
+
`,
|
|
30625
|
+
`This card is the handle for it. Its command, working directory (${persisted.cwd})\r
|
|
30626
|
+
`,
|
|
30627
|
+
"and transcript are intact \u2014 restart to put an agent back in it, or dismiss it.\r\n"
|
|
30628
|
+
].join("");
|
|
30629
|
+
}
|
|
30630
|
+
|
|
30631
|
+
// src/commands/sessions/daemon/logDroppedSession.ts
|
|
30632
|
+
function logDroppedSession(persisted, error) {
|
|
30633
|
+
const reason4 = error instanceof Error ? error.message : String(error);
|
|
30634
|
+
daemonLog(
|
|
30635
|
+
`dropped persisted session ${describePersistedSession(persisted)}: ${reason4}`
|
|
30636
|
+
);
|
|
30637
|
+
}
|
|
30638
|
+
|
|
30301
30639
|
// src/commands/sessions/daemon/errorSession.ts
|
|
30302
30640
|
function errorSession(id, persisted, error) {
|
|
30303
30641
|
return {
|
|
@@ -30460,16 +30798,20 @@ function restoreSession(id, persisted) {
|
|
|
30460
30798
|
}
|
|
30461
30799
|
|
|
30462
30800
|
// src/commands/sessions/daemon/restoreOne.ts
|
|
30463
|
-
function restoreOne(persisted,
|
|
30801
|
+
function restoreOne(persisted, spawner, sessions) {
|
|
30464
30802
|
try {
|
|
30465
|
-
const id =
|
|
30803
|
+
const id = spawner.spawn((sid) => restoreSession(sid, persisted));
|
|
30466
30804
|
logUnresumable(persisted.name, id, sessions.get(id));
|
|
30467
30805
|
} catch (error) {
|
|
30468
|
-
const reason4 = logRestoreError(persisted
|
|
30469
|
-
|
|
30470
|
-
|
|
30471
|
-
|
|
30472
|
-
|
|
30806
|
+
const reason4 = logRestoreError(persisted, error);
|
|
30807
|
+
spawnErrorCard(persisted, spawner, reason4);
|
|
30808
|
+
}
|
|
30809
|
+
}
|
|
30810
|
+
function spawnErrorCard(persisted, spawner, reason4) {
|
|
30811
|
+
try {
|
|
30812
|
+
spawner.recoveryCard((id) => errorSession(id, persisted, reason4));
|
|
30813
|
+
} catch (cardError) {
|
|
30814
|
+
logDroppedSession(persisted, cardError);
|
|
30473
30815
|
}
|
|
30474
30816
|
}
|
|
30475
30817
|
function logUnresumable(name, id, session) {
|
|
@@ -30478,42 +30820,36 @@ function logUnresumable(name, id, session) {
|
|
|
30478
30820
|
`could not resume restored session "${name}" (id ${id}): ${session.error}`
|
|
30479
30821
|
);
|
|
30480
30822
|
}
|
|
30481
|
-
function logRestoreError(
|
|
30823
|
+
function logRestoreError(persisted, error) {
|
|
30482
30824
|
const reason4 = error instanceof Error ? error.message : String(error);
|
|
30483
|
-
daemonLog(
|
|
30825
|
+
daemonLog(
|
|
30826
|
+
`failed to restore session ${describePersistedSession(persisted)}: ${reason4}`
|
|
30827
|
+
);
|
|
30484
30828
|
return reason4;
|
|
30485
30829
|
}
|
|
30486
30830
|
|
|
30487
|
-
// src/commands/sessions/daemon/sessionLimits.ts
|
|
30488
|
-
var MAX_LIVE = 12;
|
|
30489
|
-
var MAX_RESTORE = 10;
|
|
30490
|
-
var sessionLimits = {
|
|
30491
|
-
maxRestore: MAX_RESTORE,
|
|
30492
|
-
/** Allocate the next session id from counter, refusing past the absolute
|
|
30493
|
-
* ceiling regardless of caller (restore, web create, retry) so no trigger
|
|
30494
|
-
* can fan out without bound. The counter advances only when allowed. */
|
|
30495
|
-
nextId(liveCount, counter) {
|
|
30496
|
-
if (liveCount >= MAX_LIVE) {
|
|
30497
|
-
daemonLog(`refusing to spawn: at ceiling of ${MAX_LIVE} live sessions`);
|
|
30498
|
-
throw new Error(`session ceiling of ${MAX_LIVE} reached`);
|
|
30499
|
-
}
|
|
30500
|
-
return String(counter.next++);
|
|
30501
|
-
}
|
|
30502
|
-
};
|
|
30503
|
-
|
|
30504
30831
|
// src/commands/sessions/daemon/restoreAll.ts
|
|
30505
|
-
function restoreAll(
|
|
30832
|
+
function restoreAll(spawner, sessions) {
|
|
30506
30833
|
const persisted = loadPersistedSessions();
|
|
30507
|
-
const
|
|
30508
|
-
|
|
30509
|
-
|
|
30834
|
+
const names = persisted.slice(0, sessionLimits.maxRestore).map((entry) => {
|
|
30835
|
+
restoreOne(entry, spawner, sessions);
|
|
30836
|
+
return entry.name;
|
|
30837
|
+
});
|
|
30838
|
+
for (const over of persisted.slice(sessionLimits.maxRestore))
|
|
30839
|
+
deferOne(over, spawner.recoveryCard);
|
|
30840
|
+
return names;
|
|
30841
|
+
}
|
|
30842
|
+
function deferOne(persisted, spawnRecoveryCard) {
|
|
30843
|
+
try {
|
|
30844
|
+
const id = spawnRecoveryCard(
|
|
30845
|
+
(sid) => deferredSession(sid, persisted, sessionLimits.maxRestore)
|
|
30846
|
+
);
|
|
30510
30847
|
daemonLog(
|
|
30511
|
-
`restore capped at ${sessionLimits.maxRestore}
|
|
30848
|
+
`restore capped at ${sessionLimits.maxRestore}: ${describePersistedSession(persisted)} deferred to stopped card ${id}`
|
|
30512
30849
|
);
|
|
30513
|
-
|
|
30514
|
-
|
|
30515
|
-
|
|
30516
|
-
});
|
|
30850
|
+
} catch (error) {
|
|
30851
|
+
logDroppedSession(persisted, error);
|
|
30852
|
+
}
|
|
30517
30853
|
}
|
|
30518
30854
|
|
|
30519
30855
|
// src/commands/sessions/daemon/worktree/rearmStoppedSessions.ts
|
|
@@ -30597,29 +30933,29 @@ async function describeHeldWork(path71, reason4) {
|
|
|
30597
30933
|
}
|
|
30598
30934
|
async function changedFiles(path71) {
|
|
30599
30935
|
const status3 = await gitResult(path71, ["status", "--porcelain"]);
|
|
30600
|
-
const
|
|
30936
|
+
const lines2 = status3.ok ? nonEmptyLines(status3.out) : [];
|
|
30601
30937
|
return {
|
|
30602
|
-
summary: `${
|
|
30603
|
-
items: capped(
|
|
30938
|
+
summary: `${lines2.length} uncommitted ${lines2.length === 1 ? "file" : "files"}`,
|
|
30939
|
+
items: capped(lines2)
|
|
30604
30940
|
};
|
|
30605
30941
|
}
|
|
30606
30942
|
async function unpushedCommits(path71, reason4) {
|
|
30607
30943
|
const log2 = await gitResult(path71, ["log", "--oneline", "@{upstream}..HEAD"]);
|
|
30608
30944
|
if (!log2.ok) return { summary: reason4, items: [] };
|
|
30609
|
-
const
|
|
30945
|
+
const lines2 = nonEmptyLines(log2.out);
|
|
30610
30946
|
return {
|
|
30611
|
-
summary: `${
|
|
30612
|
-
items: capped(
|
|
30947
|
+
summary: `${lines2.length} unpushed ${lines2.length === 1 ? "commit" : "commits"}`,
|
|
30948
|
+
items: capped(lines2)
|
|
30613
30949
|
};
|
|
30614
30950
|
}
|
|
30615
30951
|
function nonEmptyLines(out) {
|
|
30616
30952
|
return out.split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
30617
30953
|
}
|
|
30618
|
-
function capped(
|
|
30619
|
-
if (
|
|
30954
|
+
function capped(lines2) {
|
|
30955
|
+
if (lines2.length <= MAX_ITEMS) return lines2;
|
|
30620
30956
|
return [
|
|
30621
|
-
...
|
|
30622
|
-
`\u2026 and ${
|
|
30957
|
+
...lines2.slice(0, MAX_ITEMS),
|
|
30958
|
+
`\u2026 and ${lines2.length - MAX_ITEMS} more`
|
|
30623
30959
|
];
|
|
30624
30960
|
}
|
|
30625
30961
|
|
|
@@ -30764,9 +31100,9 @@ async function recoverOrphan(sessions, spawnWith, orphan, notify2) {
|
|
|
30764
31100
|
}
|
|
30765
31101
|
|
|
30766
31102
|
// src/commands/sessions/daemon/restoreAllSessions.ts
|
|
30767
|
-
function restoreAllSessions(
|
|
30768
|
-
const names = restoreAll(
|
|
30769
|
-
reconcileWorktreesOnRestore(sessions,
|
|
31103
|
+
function restoreAllSessions(spawner, sessions, notify2) {
|
|
31104
|
+
const names = restoreAll(spawner, sessions);
|
|
31105
|
+
reconcileWorktreesOnRestore(sessions, spawner.recoveryCard, notify2);
|
|
30770
31106
|
rearmStoppedSessions(sessions, notify2);
|
|
30771
31107
|
return names;
|
|
30772
31108
|
}
|
|
@@ -31100,7 +31436,7 @@ function windowsDaemonHost() {
|
|
|
31100
31436
|
var CONNECT_TIMEOUT_MS = 2e3;
|
|
31101
31437
|
var KEEPALIVE_PROBE_MS = 1e4;
|
|
31102
31438
|
function connectToWindowsDaemon() {
|
|
31103
|
-
return new Promise((
|
|
31439
|
+
return new Promise((resolve22, reject) => {
|
|
31104
31440
|
const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
|
|
31105
31441
|
socket.setTimeout(CONNECT_TIMEOUT_MS);
|
|
31106
31442
|
socket.once("timeout", () => {
|
|
@@ -31110,7 +31446,7 @@ function connectToWindowsDaemon() {
|
|
|
31110
31446
|
socket.once("connect", () => {
|
|
31111
31447
|
socket.setTimeout(0);
|
|
31112
31448
|
socket.setKeepAlive(true, KEEPALIVE_PROBE_MS);
|
|
31113
|
-
|
|
31449
|
+
resolve22(socket);
|
|
31114
31450
|
});
|
|
31115
31451
|
socket.once("error", reject);
|
|
31116
31452
|
});
|
|
@@ -31131,9 +31467,9 @@ import { spawn as spawn11 } from "child_process";
|
|
|
31131
31467
|
import { createInterface as createInterface7 } from "readline";
|
|
31132
31468
|
function logChildStream(stream, label2) {
|
|
31133
31469
|
if (!stream) return;
|
|
31134
|
-
const
|
|
31135
|
-
|
|
31136
|
-
|
|
31470
|
+
const lines2 = createInterface7({ input: stream });
|
|
31471
|
+
lines2.on("line", (line) => daemonLog(`[${label2}] ${line}`));
|
|
31472
|
+
lines2.on("error", () => {
|
|
31137
31473
|
});
|
|
31138
31474
|
}
|
|
31139
31475
|
|
|
@@ -31188,7 +31524,7 @@ async function waitForWindowsDaemon() {
|
|
|
31188
31524
|
);
|
|
31189
31525
|
}
|
|
31190
31526
|
function delay2(ms) {
|
|
31191
|
-
return new Promise((
|
|
31527
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
31192
31528
|
}
|
|
31193
31529
|
|
|
31194
31530
|
// src/commands/sessions/daemon/defaultConnect.ts
|
|
@@ -31472,7 +31808,7 @@ async function healWindowsDaemon() {
|
|
|
31472
31808
|
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
31473
31809
|
}
|
|
31474
31810
|
function runOnWindowsHost(command, timeoutMs) {
|
|
31475
|
-
return new Promise((
|
|
31811
|
+
return new Promise((resolve22, reject) => {
|
|
31476
31812
|
const child = spawn12("pwsh.exe", ["-Command", command], {
|
|
31477
31813
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31478
31814
|
});
|
|
@@ -31492,7 +31828,7 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
31492
31828
|
});
|
|
31493
31829
|
child.on("exit", (code) => {
|
|
31494
31830
|
clearTimeout(timer);
|
|
31495
|
-
if (code === 0)
|
|
31831
|
+
if (code === 0) resolve22();
|
|
31496
31832
|
else
|
|
31497
31833
|
reject(
|
|
31498
31834
|
new Error(
|
|
@@ -31603,10 +31939,10 @@ var WindowsConnection = class {
|
|
|
31603
31939
|
return socket;
|
|
31604
31940
|
}
|
|
31605
31941
|
wire(socket) {
|
|
31606
|
-
const
|
|
31607
|
-
|
|
31942
|
+
const lines2 = createInterface8({ input: socket });
|
|
31943
|
+
lines2.on("error", () => {
|
|
31608
31944
|
});
|
|
31609
|
-
|
|
31945
|
+
lines2.on("line", (line) => this.deps.onLine(line));
|
|
31610
31946
|
socket.on("error", () => {
|
|
31611
31947
|
});
|
|
31612
31948
|
socket.on("close", () => {
|
|
@@ -31961,16 +32297,17 @@ var SessionManager = class {
|
|
|
31961
32297
|
);
|
|
31962
32298
|
}
|
|
31963
32299
|
restore() {
|
|
31964
|
-
return restoreAllSessions(this.
|
|
32300
|
+
return restoreAllSessions(this.spawner, this.sessions, this.notify);
|
|
31965
32301
|
}
|
|
31966
32302
|
drain = () => drainSessions(this.sessions, this.notify);
|
|
31967
|
-
|
|
31968
|
-
create(sessionLimits.nextId(this.sessions.size, this.idCounter)),
|
|
32303
|
+
spawner = makeSessionSpawner(
|
|
31969
32304
|
this.sessions,
|
|
31970
32305
|
this.clients,
|
|
31971
|
-
this.
|
|
31972
|
-
this.
|
|
32306
|
+
this.idCounter,
|
|
32307
|
+
() => this.onStatusChange,
|
|
32308
|
+
() => this.notify()
|
|
31973
32309
|
);
|
|
32310
|
+
spawnWith = this.spawner.spawn;
|
|
31974
32311
|
treeCtx() {
|
|
31975
32312
|
return treeSpawnContext(
|
|
31976
32313
|
this.sessions,
|
|
@@ -32204,9 +32541,9 @@ async function parseTranscript(sessionId) {
|
|
|
32204
32541
|
return [];
|
|
32205
32542
|
}
|
|
32206
32543
|
}
|
|
32207
|
-
function parseTranscriptLines(
|
|
32544
|
+
function parseTranscriptLines(lines2) {
|
|
32208
32545
|
const messages = [];
|
|
32209
|
-
for (const line of
|
|
32546
|
+
for (const line of lines2) {
|
|
32210
32547
|
const entry = line.trim() ? safeParse2(line) : null;
|
|
32211
32548
|
if (!entry || entry.isSidechain || entry.isMeta) continue;
|
|
32212
32549
|
messages.push(...entryMessages(entry));
|
|
@@ -32388,10 +32725,10 @@ function handleConnection(socket, manager) {
|
|
|
32388
32725
|
};
|
|
32389
32726
|
manager.addClient(client);
|
|
32390
32727
|
manager.clients.greet(client);
|
|
32391
|
-
const
|
|
32392
|
-
|
|
32728
|
+
const lines2 = createInterface9({ input: socket });
|
|
32729
|
+
lines2.on("error", () => {
|
|
32393
32730
|
});
|
|
32394
|
-
|
|
32731
|
+
lines2.on("line", (line) => {
|
|
32395
32732
|
let data;
|
|
32396
32733
|
try {
|
|
32397
32734
|
data = JSON.parse(line);
|
|
@@ -32852,9 +33189,9 @@ function buildLimitsSegment(rateLimits) {
|
|
|
32852
33189
|
|
|
32853
33190
|
// src/commands/readGitBranch.ts
|
|
32854
33191
|
import { readFileSync as readFileSync54, statSync as statSync14 } from "fs";
|
|
32855
|
-
import { isAbsolute as isAbsolute4, join as
|
|
33192
|
+
import { isAbsolute as isAbsolute4, join as join77, resolve as resolve20 } from "path";
|
|
32856
33193
|
function resolveGitDir(cwd) {
|
|
32857
|
-
const dotGit =
|
|
33194
|
+
const dotGit = join77(cwd, ".git");
|
|
32858
33195
|
let stat3;
|
|
32859
33196
|
try {
|
|
32860
33197
|
stat3 = statSync14(dotGit);
|
|
@@ -32875,7 +33212,7 @@ function resolveGitDir(cwd) {
|
|
|
32875
33212
|
return null;
|
|
32876
33213
|
}
|
|
32877
33214
|
const gitDir = match[1].trim();
|
|
32878
|
-
return isAbsolute4(gitDir) ? gitDir :
|
|
33215
|
+
return isAbsolute4(gitDir) ? gitDir : resolve20(cwd, gitDir);
|
|
32879
33216
|
}
|
|
32880
33217
|
function readGitBranch(cwd) {
|
|
32881
33218
|
const gitDir = resolveGitDir(cwd);
|
|
@@ -32884,7 +33221,7 @@ function readGitBranch(cwd) {
|
|
|
32884
33221
|
}
|
|
32885
33222
|
let head;
|
|
32886
33223
|
try {
|
|
32887
|
-
head = readFileSync54(
|
|
33224
|
+
head = readFileSync54(join77(gitDir, "HEAD"), "utf8");
|
|
32888
33225
|
} catch {
|
|
32889
33226
|
return null;
|
|
32890
33227
|
}
|