@staff0rd/assist 0.485.0 → 0.485.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +871 -745
- 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.485.
|
|
9
|
+
version: "0.485.2",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -142,9 +142,9 @@ import chalk from "chalk";
|
|
|
142
142
|
import { stringify as stringifyYaml } from "yaml";
|
|
143
143
|
|
|
144
144
|
// src/shared/loadConfigFrom.ts
|
|
145
|
-
import { existsSync as
|
|
145
|
+
import { existsSync as existsSync3 } from "fs";
|
|
146
146
|
import { homedir } from "os";
|
|
147
|
-
import { dirname, join } from "path";
|
|
147
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
148
148
|
|
|
149
149
|
// src/commands/backlog/getCurrentOrigin.ts
|
|
150
150
|
import { execFileSync } from "child_process";
|
|
@@ -201,13 +201,68 @@ function getCurrentOrigin(cwd) {
|
|
|
201
201
|
return `local:${root ?? cwd}`;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
// src/shared/linkedWorktree.ts
|
|
205
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
206
|
+
import { basename, dirname, isAbsolute, join, resolve } from "path";
|
|
207
|
+
function linkedWorktree(dir) {
|
|
208
|
+
const root = findGitLink(dir);
|
|
209
|
+
if (!root) return null;
|
|
210
|
+
const gitDir = readGitDirPointer(root);
|
|
211
|
+
if (!gitDir) return null;
|
|
212
|
+
const commonDir = resolveCommonDir(gitDir);
|
|
213
|
+
if (!commonDir || basename(commonDir) !== ".git") return null;
|
|
214
|
+
const clone = dirname(commonDir);
|
|
215
|
+
return existsSync(clone) ? { root, clone } : null;
|
|
216
|
+
}
|
|
217
|
+
function findGitLink(dir) {
|
|
218
|
+
let current = resolve(dir);
|
|
219
|
+
while (current !== dirname(current)) {
|
|
220
|
+
const entry = join(current, ".git");
|
|
221
|
+
if (existsSync(entry)) return isFile(entry) ? current : null;
|
|
222
|
+
current = dirname(current);
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
function isFile(path71) {
|
|
227
|
+
try {
|
|
228
|
+
return statSync(path71).isFile();
|
|
229
|
+
} catch {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function readGitDirPointer(root) {
|
|
234
|
+
const target = readTrimmed(join(root, ".git"));
|
|
235
|
+
if (!target?.startsWith("gitdir:")) return null;
|
|
236
|
+
return absolute(target.slice("gitdir:".length).trim(), root);
|
|
237
|
+
}
|
|
238
|
+
function resolveCommonDir(gitDir) {
|
|
239
|
+
const recorded = readTrimmed(join(gitDir, "commondir"));
|
|
240
|
+
if (recorded) return absolute(recorded, gitDir);
|
|
241
|
+
return linkedGitDirParent(gitDir);
|
|
242
|
+
}
|
|
243
|
+
function linkedGitDirParent(gitDir) {
|
|
244
|
+
const match = /^(.*)[/\\]worktrees[/\\][^/\\]+[/\\]?$/.exec(gitDir);
|
|
245
|
+
return match ? match[1] : null;
|
|
246
|
+
}
|
|
247
|
+
function readTrimmed(path71) {
|
|
248
|
+
try {
|
|
249
|
+
const content = readFileSync(path71, "utf8").trim();
|
|
250
|
+
return content === "" ? null : content;
|
|
251
|
+
} catch {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function absolute(target, from) {
|
|
256
|
+
return isAbsolute(target) ? target : resolve(from, target);
|
|
257
|
+
}
|
|
258
|
+
|
|
204
259
|
// src/shared/loadRawYaml.ts
|
|
205
|
-
import { existsSync, readFileSync } from "fs";
|
|
260
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
206
261
|
import { parse as parseYaml } from "yaml";
|
|
207
262
|
function loadRawYaml(path71) {
|
|
208
|
-
if (!
|
|
263
|
+
if (!existsSync2(path71)) return {};
|
|
209
264
|
try {
|
|
210
|
-
const content =
|
|
265
|
+
const content = readFileSync2(path71, "utf8");
|
|
211
266
|
return parseYaml(content) || {};
|
|
212
267
|
} catch {
|
|
213
268
|
return {};
|
|
@@ -580,30 +635,35 @@ var assistConfigSchema = z2.strictObject({
|
|
|
580
635
|
// src/shared/loadConfigFrom.ts
|
|
581
636
|
function findConfigUp(startDir) {
|
|
582
637
|
let current = startDir;
|
|
583
|
-
while (current !==
|
|
584
|
-
const claudePath =
|
|
585
|
-
if (
|
|
638
|
+
while (current !== dirname2(current)) {
|
|
639
|
+
const claudePath = join2(current, ".claude", "assist.yml");
|
|
640
|
+
if (existsSync3(claudePath))
|
|
586
641
|
return { configPath: claudePath, rootDir: current };
|
|
587
|
-
const rootPath =
|
|
588
|
-
if (
|
|
589
|
-
current =
|
|
642
|
+
const rootPath = join2(current, "assist.yml");
|
|
643
|
+
if (existsSync3(rootPath)) return { configPath: rootPath, rootDir: current };
|
|
644
|
+
current = dirname2(current);
|
|
590
645
|
}
|
|
591
646
|
return null;
|
|
592
647
|
}
|
|
593
648
|
function getConfigPathFrom(cwd) {
|
|
594
649
|
const found = findConfigUp(cwd);
|
|
595
650
|
if (found) return found.configPath;
|
|
596
|
-
return
|
|
651
|
+
return join2(cwd, "assist.yml");
|
|
597
652
|
}
|
|
598
653
|
function getGlobalConfigPath() {
|
|
599
|
-
return
|
|
654
|
+
return join2(homedir(), ".assist.yml");
|
|
600
655
|
}
|
|
601
656
|
function getConfigDirFrom(cwd) {
|
|
602
|
-
return
|
|
657
|
+
return dirname2(getConfigPathFrom(cwd));
|
|
658
|
+
}
|
|
659
|
+
function projectConfigPathFrom(cwd) {
|
|
660
|
+
if (findConfigUp(cwd)) return getConfigPathFrom(cwd);
|
|
661
|
+
const clone = linkedWorktree(cwd)?.clone;
|
|
662
|
+
return getConfigPathFrom(clone ?? cwd);
|
|
603
663
|
}
|
|
604
664
|
function loadConfigFrom(cwd) {
|
|
605
665
|
const globalRaw = loadRawYaml(getGlobalConfigPath());
|
|
606
|
-
const projectRaw = loadRawYaml(
|
|
666
|
+
const projectRaw = loadRawYaml(projectConfigPathFrom(cwd));
|
|
607
667
|
const repoOverride = globalRaw.repos ? resolveRepoOverride(globalRaw, getCurrentOrigin(cwd)) : {};
|
|
608
668
|
const globalWithRepo = mergeRawConfigs(globalRaw, repoOverride);
|
|
609
669
|
const merged = mergeRawConfigs(globalWithRepo, projectRaw);
|
|
@@ -624,7 +684,7 @@ function loadConfig() {
|
|
|
624
684
|
return loadConfigFrom(process.cwd());
|
|
625
685
|
}
|
|
626
686
|
function loadProjectConfig(cwd = process.cwd()) {
|
|
627
|
-
return loadRawYaml(
|
|
687
|
+
return loadRawYaml(projectConfigPathFrom(cwd));
|
|
628
688
|
}
|
|
629
689
|
function loadGlobalConfigRaw() {
|
|
630
690
|
return loadRawYaml(getGlobalConfigPath());
|
|
@@ -633,7 +693,7 @@ function saveGlobalConfig(config) {
|
|
|
633
693
|
writeFileSync(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
|
|
634
694
|
}
|
|
635
695
|
function saveConfig(config, cwd = process.cwd()) {
|
|
636
|
-
const configPath =
|
|
696
|
+
const configPath = projectConfigPathFrom(cwd);
|
|
637
697
|
writeFileSync(configPath, stringifyYaml(config, { lineWidth: 0 }));
|
|
638
698
|
}
|
|
639
699
|
function getTranscriptConfig() {
|
|
@@ -1781,7 +1841,7 @@ function gitRefUrl(kind, ref, cwd) {
|
|
|
1781
1841
|
}
|
|
1782
1842
|
|
|
1783
1843
|
// src/commands/commit/collectCommitRefs.ts
|
|
1784
|
-
function collectCommitRefs(
|
|
1844
|
+
function collectCommitRefs(message3) {
|
|
1785
1845
|
const refs = [];
|
|
1786
1846
|
const branch2 = git("rev-parse --abbrev-ref HEAD");
|
|
1787
1847
|
if (branch2 && branch2 !== "HEAD") {
|
|
@@ -1798,7 +1858,7 @@ function collectCommitRefs(message2) {
|
|
|
1798
1858
|
ref: sha,
|
|
1799
1859
|
url: gitRefUrl("commit", sha)
|
|
1800
1860
|
};
|
|
1801
|
-
const subject =
|
|
1861
|
+
const subject = message3.split("\n", 1)[0];
|
|
1802
1862
|
if (subject) ref.title = subject;
|
|
1803
1863
|
refs.push(ref);
|
|
1804
1864
|
const parent = git("rev-parse HEAD^");
|
|
@@ -1866,16 +1926,16 @@ function shouldPull(config) {
|
|
|
1866
1926
|
|
|
1867
1927
|
// src/commands/commit/stageAndCommit.ts
|
|
1868
1928
|
import { execSync as execSync7 } from "child_process";
|
|
1869
|
-
function commitStaged(
|
|
1870
|
-
execSync7(`git commit -m ${shellQuote(
|
|
1929
|
+
function commitStaged(message3) {
|
|
1930
|
+
execSync7(`git commit -m ${shellQuote(message3)}`, { stdio: "inherit" });
|
|
1871
1931
|
return execSync7("git rev-parse --short=7 HEAD", {
|
|
1872
1932
|
encoding: "utf8"
|
|
1873
1933
|
}).trim();
|
|
1874
1934
|
}
|
|
1875
|
-
function stageAndCommit(files,
|
|
1935
|
+
function stageAndCommit(files, message3) {
|
|
1876
1936
|
const escaped = files.map(shellQuote).join(" ");
|
|
1877
1937
|
execSync7(`git add ${escaped}`, { stdio: "inherit" });
|
|
1878
|
-
return commitStaged(
|
|
1938
|
+
return commitStaged(message3);
|
|
1879
1939
|
}
|
|
1880
1940
|
|
|
1881
1941
|
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
@@ -1970,34 +2030,34 @@ function backlogRefError(subject, context, ids) {
|
|
|
1970
2030
|
// src/commands/commit/validateMessage.ts
|
|
1971
2031
|
var MAX_MESSAGE_LENGTH = 50;
|
|
1972
2032
|
var CONVENTIONAL_COMMIT_REGEX = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(!)?(\(.+\))?!?: .+$/;
|
|
1973
|
-
function validateMessage(
|
|
1974
|
-
if (
|
|
2033
|
+
function validateMessage(message3, config) {
|
|
2034
|
+
if (message3.toLowerCase().includes("claude")) {
|
|
1975
2035
|
console.error("Error: Commit message must not reference Claude");
|
|
1976
2036
|
process.exit(1);
|
|
1977
2037
|
}
|
|
1978
|
-
const backlogIds = findBacklogRefs(
|
|
2038
|
+
const backlogIds = findBacklogRefs(message3);
|
|
1979
2039
|
if (backlogIds.length > 0) {
|
|
1980
2040
|
console.error(
|
|
1981
2041
|
backlogRefError("Commit message", "commit messages", backlogIds)
|
|
1982
2042
|
);
|
|
1983
2043
|
process.exit(1);
|
|
1984
2044
|
}
|
|
1985
|
-
if (config.commit?.conventional && !CONVENTIONAL_COMMIT_REGEX.test(
|
|
2045
|
+
if (config.commit?.conventional && !CONVENTIONAL_COMMIT_REGEX.test(message3)) {
|
|
1986
2046
|
console.error(
|
|
1987
2047
|
"Error: Commit message must follow conventional commit format (e.g., 'feat: add feature', 'fix(scope): fix bug')"
|
|
1988
2048
|
);
|
|
1989
2049
|
process.exit(1);
|
|
1990
2050
|
}
|
|
1991
|
-
if (
|
|
2051
|
+
if (message3.length > MAX_MESSAGE_LENGTH) {
|
|
1992
2052
|
console.error(
|
|
1993
|
-
`Error: Commit message must be ${MAX_MESSAGE_LENGTH} characters or less (current: ${
|
|
2053
|
+
`Error: Commit message must be ${MAX_MESSAGE_LENGTH} characters or less (current: ${message3.length})`
|
|
1994
2054
|
);
|
|
1995
2055
|
process.exit(1);
|
|
1996
2056
|
}
|
|
1997
2057
|
}
|
|
1998
2058
|
|
|
1999
2059
|
// src/commands/commit.ts
|
|
2000
|
-
async function execCommit(files,
|
|
2060
|
+
async function execCommit(files, message3, config) {
|
|
2001
2061
|
try {
|
|
2002
2062
|
warnIfUnexpectedBranch(config);
|
|
2003
2063
|
const pulled = shouldPull(config);
|
|
@@ -2005,21 +2065,21 @@ async function execCommit(files, message2, config) {
|
|
|
2005
2065
|
execSync8("git pull --autostash", { stdio: "inherit" });
|
|
2006
2066
|
}
|
|
2007
2067
|
abortOnConflicts(files, pulled);
|
|
2008
|
-
const sha = files.length > 0 ? stageAndCommit(files,
|
|
2068
|
+
const sha = files.length > 0 ? stageAndCommit(files, message3) : commitStaged(message3);
|
|
2009
2069
|
console.log(`Committed: ${sha}`);
|
|
2010
2070
|
if (config.commit?.push) {
|
|
2011
2071
|
pushCommit(config.worktree?.trunk === true);
|
|
2012
2072
|
console.log("Pushed to remote");
|
|
2013
2073
|
}
|
|
2014
|
-
await recordCommitActivity(
|
|
2074
|
+
await recordCommitActivity(message3);
|
|
2015
2075
|
process.exit(0);
|
|
2016
2076
|
} catch {
|
|
2017
2077
|
process.exit(1);
|
|
2018
2078
|
}
|
|
2019
2079
|
}
|
|
2020
|
-
async function recordCommitActivity(
|
|
2080
|
+
async function recordCommitActivity(message3) {
|
|
2021
2081
|
if (resolveSessionItemId() === null) return;
|
|
2022
|
-
await recordSessionRefs(collectCommitRefs(
|
|
2082
|
+
await recordSessionRefs(collectCommitRefs(message3));
|
|
2023
2083
|
}
|
|
2024
2084
|
async function commit(args) {
|
|
2025
2085
|
if (args[0] === "status") {
|
|
@@ -2032,11 +2092,11 @@ async function commit(args) {
|
|
|
2032
2092
|
console.error("Usage: assist commit <message> [files...]");
|
|
2033
2093
|
process.exit(1);
|
|
2034
2094
|
}
|
|
2035
|
-
const
|
|
2095
|
+
const message3 = args[0];
|
|
2036
2096
|
const files = args.slice(1);
|
|
2037
2097
|
const config = loadConfig();
|
|
2038
|
-
validateMessage(
|
|
2039
|
-
await execCommit(files,
|
|
2098
|
+
validateMessage(message3, config);
|
|
2099
|
+
await execCommit(files, message3, config);
|
|
2040
2100
|
}
|
|
2041
2101
|
|
|
2042
2102
|
// src/commands/coverage.ts
|
|
@@ -2074,12 +2134,12 @@ async function exitOnCancel(promise) {
|
|
|
2074
2134
|
}
|
|
2075
2135
|
|
|
2076
2136
|
// src/shared/promptMultiselect.ts
|
|
2077
|
-
async function promptMultiselect(
|
|
2137
|
+
async function promptMultiselect(message3, options2) {
|
|
2078
2138
|
const { selected } = await exitOnCancel(
|
|
2079
2139
|
enquirer.prompt({
|
|
2080
2140
|
type: "multiselect",
|
|
2081
2141
|
name: "selected",
|
|
2082
|
-
message:
|
|
2142
|
+
message: message3,
|
|
2083
2143
|
choices: options2.map((opt) => ({
|
|
2084
2144
|
name: opt.value,
|
|
2085
2145
|
message: `${opt.name} - ${chalk4.dim(opt.description)}`
|
|
@@ -2259,17 +2319,17 @@ import * as path3 from "path";
|
|
|
2259
2319
|
import chalk10 from "chalk";
|
|
2260
2320
|
|
|
2261
2321
|
// src/commands/verify/addToKnipIgnoreBinaries.ts
|
|
2262
|
-
import { existsSync as
|
|
2263
|
-
import { join as
|
|
2322
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
2323
|
+
import { join as join4 } from "path";
|
|
2264
2324
|
import chalk9 from "chalk";
|
|
2265
2325
|
function loadKnipConfig(knipJsonPath) {
|
|
2266
|
-
if (
|
|
2267
|
-
return JSON.parse(
|
|
2326
|
+
if (existsSync5(knipJsonPath)) {
|
|
2327
|
+
return JSON.parse(readFileSync4(knipJsonPath, "utf8"));
|
|
2268
2328
|
}
|
|
2269
2329
|
return { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
2270
2330
|
}
|
|
2271
2331
|
function addToKnipIgnoreBinaries(cwd, binary) {
|
|
2272
|
-
const knipJsonPath =
|
|
2332
|
+
const knipJsonPath = join4(cwd, "knip.json");
|
|
2273
2333
|
try {
|
|
2274
2334
|
const knipConfig = loadKnipConfig(knipJsonPath);
|
|
2275
2335
|
const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
|
|
@@ -2316,17 +2376,17 @@ import * as path5 from "path";
|
|
|
2316
2376
|
import chalk15 from "chalk";
|
|
2317
2377
|
|
|
2318
2378
|
// src/commands/format/init.ts
|
|
2319
|
-
import { existsSync as
|
|
2379
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
2320
2380
|
import chalk13 from "chalk";
|
|
2321
2381
|
|
|
2322
2382
|
// src/shared/promptConfirm.ts
|
|
2323
2383
|
import enquirer2 from "enquirer";
|
|
2324
|
-
async function promptConfirm(
|
|
2384
|
+
async function promptConfirm(message3, initial = true) {
|
|
2325
2385
|
const { confirmed } = await exitOnCancel(
|
|
2326
2386
|
enquirer2.prompt({
|
|
2327
2387
|
type: "confirm",
|
|
2328
2388
|
name: "confirmed",
|
|
2329
|
-
message:
|
|
2389
|
+
message: message3,
|
|
2330
2390
|
initial,
|
|
2331
2391
|
// @ts-expect-error - enquirer types don't include symbols but it's supported
|
|
2332
2392
|
symbols: {
|
|
@@ -2378,7 +2438,7 @@ async function init() {
|
|
|
2378
2438
|
const newContent = `${JSON.stringify(oxfmtrc_template_default, null, " ")}
|
|
2379
2439
|
`;
|
|
2380
2440
|
const configPath = ".oxfmtrc.json";
|
|
2381
|
-
const oldContent =
|
|
2441
|
+
const oldContent = existsSync6(configPath) ? readFileSync5(configPath, "utf8") : "";
|
|
2382
2442
|
if (oldContent === newContent) {
|
|
2383
2443
|
console.log(".oxfmtrc.json already has the baseline formatter config");
|
|
2384
2444
|
return;
|
|
@@ -2401,15 +2461,15 @@ async function init() {
|
|
|
2401
2461
|
}
|
|
2402
2462
|
|
|
2403
2463
|
// src/commands/lint/init.ts
|
|
2404
|
-
import { existsSync as
|
|
2464
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
2405
2465
|
import chalk14 from "chalk";
|
|
2406
2466
|
|
|
2407
2467
|
// src/shared/removeEslint/index.ts
|
|
2408
2468
|
import { execSync as execSync11 } from "child_process";
|
|
2409
|
-
import { existsSync as
|
|
2469
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
2410
2470
|
|
|
2411
2471
|
// src/shared/removeEslint/removeEslintConfigFiles.ts
|
|
2412
|
-
import { existsSync as
|
|
2472
|
+
import { existsSync as existsSync7, unlinkSync } from "fs";
|
|
2413
2473
|
var ESLINT_CONFIG_FILES = [
|
|
2414
2474
|
"eslint.config.js",
|
|
2415
2475
|
"eslint.config.mjs",
|
|
@@ -2425,7 +2485,7 @@ var ESLINT_CONFIG_FILES = [
|
|
|
2425
2485
|
function removeEslintConfigFiles() {
|
|
2426
2486
|
let removed = false;
|
|
2427
2487
|
for (const configFile of ESLINT_CONFIG_FILES) {
|
|
2428
|
-
if (
|
|
2488
|
+
if (existsSync7(configFile)) {
|
|
2429
2489
|
unlinkSync(configFile);
|
|
2430
2490
|
console.log(`Removed ${configFile}`);
|
|
2431
2491
|
removed = true;
|
|
@@ -2447,10 +2507,10 @@ function removeEslint(options2 = {}) {
|
|
|
2447
2507
|
}
|
|
2448
2508
|
function removeEslintFromPackageJson(options2) {
|
|
2449
2509
|
const packageJsonPath = "package.json";
|
|
2450
|
-
if (!
|
|
2510
|
+
if (!existsSync8(packageJsonPath)) {
|
|
2451
2511
|
return false;
|
|
2452
2512
|
}
|
|
2453
|
-
const packageJson = JSON.parse(
|
|
2513
|
+
const packageJson = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
2454
2514
|
let modified = false;
|
|
2455
2515
|
modified = removeEslintDeps(packageJson.dependencies) || modified;
|
|
2456
2516
|
modified = removeEslintDeps(packageJson.devDependencies) || modified;
|
|
@@ -2514,7 +2574,7 @@ async function writeOxlintConfig() {
|
|
|
2514
2574
|
const newContent = `${JSON.stringify(oxlintrc_template_default, null, " ")}
|
|
2515
2575
|
`;
|
|
2516
2576
|
const configPath = ".oxlintrc.json";
|
|
2517
|
-
const oldContent =
|
|
2577
|
+
const oldContent = existsSync9(configPath) ? readFileSync7(configPath, "utf8") : "";
|
|
2518
2578
|
if (oldContent === newContent) {
|
|
2519
2579
|
console.log(".oxlintrc.json already has the baseline linter config");
|
|
2520
2580
|
return;
|
|
@@ -3289,7 +3349,7 @@ function lint(options2 = {}) {
|
|
|
3289
3349
|
|
|
3290
3350
|
// src/commands/new/registerNew/newCli/index.ts
|
|
3291
3351
|
import { execSync as execSync20 } from "child_process";
|
|
3292
|
-
import { basename as
|
|
3352
|
+
import { basename as basename3, resolve as resolve6 } from "path";
|
|
3293
3353
|
|
|
3294
3354
|
// src/commands/verify/blockCodeComments/findComments.ts
|
|
3295
3355
|
import { execSync as execSync12 } from "child_process";
|
|
@@ -3872,7 +3932,7 @@ function configKeys() {
|
|
|
3872
3932
|
}
|
|
3873
3933
|
|
|
3874
3934
|
// src/commands/verify/forbiddenStrings/index.ts
|
|
3875
|
-
import { existsSync as
|
|
3935
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
|
|
3876
3936
|
|
|
3877
3937
|
// src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
|
|
3878
3938
|
import { minimatch as minimatch2 } from "minimatch";
|
|
@@ -3913,13 +3973,13 @@ function forbiddenStrings() {
|
|
|
3913
3973
|
const cache4 = /* @__PURE__ */ new Map();
|
|
3914
3974
|
const readJson = (file) => {
|
|
3915
3975
|
if (cache4.has(file)) return cache4.get(file);
|
|
3916
|
-
if (!
|
|
3976
|
+
if (!existsSync13(file)) {
|
|
3917
3977
|
console.log(`Forbidden-strings file not found: ${file}`);
|
|
3918
3978
|
process.exit(1);
|
|
3919
3979
|
}
|
|
3920
3980
|
let parsed;
|
|
3921
3981
|
try {
|
|
3922
|
-
parsed = JSON.parse(
|
|
3982
|
+
parsed = JSON.parse(readFileSync10(file, "utf8"));
|
|
3923
3983
|
} catch (error) {
|
|
3924
3984
|
console.log(`Could not parse ${file}: ${error.message}`);
|
|
3925
3985
|
process.exit(1);
|
|
@@ -3992,7 +4052,7 @@ Total: ${lines.length} hardcoded color(s)`);
|
|
|
3992
4052
|
import * as path19 from "path";
|
|
3993
4053
|
|
|
3994
4054
|
// src/shared/resolveRunConfigs.ts
|
|
3995
|
-
import { dirname as
|
|
4055
|
+
import { dirname as dirname10, relative, resolve as resolve4 } from "path";
|
|
3996
4056
|
|
|
3997
4057
|
// src/shared/assertNoDuplicateRunNames.ts
|
|
3998
4058
|
function findDuplicateNames(configs) {
|
|
@@ -4014,14 +4074,14 @@ function assertNoDuplicateRunNames(configs) {
|
|
|
4014
4074
|
}
|
|
4015
4075
|
|
|
4016
4076
|
// src/shared/findLinkedConfigPath.ts
|
|
4017
|
-
import { existsSync as
|
|
4018
|
-
import { join as
|
|
4077
|
+
import { existsSync as existsSync14 } from "fs";
|
|
4078
|
+
import { join as join9, resolve as resolve2 } from "path";
|
|
4019
4079
|
function findLinkedConfigPath(linkPath, fromDir) {
|
|
4020
|
-
const resolved =
|
|
4021
|
-
const claudePath =
|
|
4022
|
-
if (
|
|
4023
|
-
const rootPath =
|
|
4024
|
-
if (
|
|
4080
|
+
const resolved = resolve2(fromDir, linkPath);
|
|
4081
|
+
const claudePath = join9(resolved, ".claude", "assist.yml");
|
|
4082
|
+
if (existsSync14(claudePath)) return claudePath;
|
|
4083
|
+
const rootPath = join9(resolved, "assist.yml");
|
|
4084
|
+
if (existsSync14(rootPath)) return rootPath;
|
|
4025
4085
|
throw new Error(`No assist.yml found in linked project: ${resolved}`);
|
|
4026
4086
|
}
|
|
4027
4087
|
|
|
@@ -4031,9 +4091,9 @@ function isRunLink(entry) {
|
|
|
4031
4091
|
}
|
|
4032
4092
|
|
|
4033
4093
|
// src/shared/loadLinkedEntries.ts
|
|
4034
|
-
import { resolve as
|
|
4094
|
+
import { resolve as resolve3 } from "path";
|
|
4035
4095
|
function loadLinkedEntries(configPath, visited) {
|
|
4036
|
-
const canonical =
|
|
4096
|
+
const canonical = resolve3(configPath);
|
|
4037
4097
|
if (visited.has(canonical)) {
|
|
4038
4098
|
throw new Error(
|
|
4039
4099
|
`Circular link detected: ${canonical} has already been visited`
|
|
@@ -4055,15 +4115,15 @@ function applyPrefix(configs, prefix2) {
|
|
|
4055
4115
|
function setDefaultCwd(configs, defaultCwd) {
|
|
4056
4116
|
return configs.map((c) => c.cwd ? c : { ...c, cwd: defaultCwd });
|
|
4057
4117
|
}
|
|
4058
|
-
function relativeToRoot(ctx,
|
|
4059
|
-
return relative(ctx.rootConfigDir,
|
|
4118
|
+
function relativeToRoot(ctx, absolute2) {
|
|
4119
|
+
return relative(ctx.rootConfigDir, absolute2);
|
|
4060
4120
|
}
|
|
4061
4121
|
function loadAndResolveLink(linkPath, configDir, ctx) {
|
|
4062
4122
|
const configPath = findLinkedConfigPath(linkPath, configDir);
|
|
4063
4123
|
const entries = loadLinkedEntries(configPath, ctx.visited);
|
|
4064
|
-
const defaultCwd = relativeToRoot(ctx,
|
|
4124
|
+
const defaultCwd = relativeToRoot(ctx, resolve4(configDir, linkPath));
|
|
4065
4125
|
return setDefaultCwd(
|
|
4066
|
-
resolveRecursive(entries,
|
|
4126
|
+
resolveRecursive(entries, dirname10(configPath), ctx),
|
|
4067
4127
|
defaultCwd
|
|
4068
4128
|
);
|
|
4069
4129
|
}
|
|
@@ -4085,7 +4145,7 @@ function resolveLocalCwd(config, configDir, ctx) {
|
|
|
4085
4145
|
if (!config.cwd || configDir === ctx.rootConfigDir) return config;
|
|
4086
4146
|
return {
|
|
4087
4147
|
...config,
|
|
4088
|
-
cwd: relativeToRoot(ctx,
|
|
4148
|
+
cwd: relativeToRoot(ctx, resolve4(configDir, config.cwd))
|
|
4089
4149
|
};
|
|
4090
4150
|
}
|
|
4091
4151
|
|
|
@@ -4132,7 +4192,7 @@ function list() {
|
|
|
4132
4192
|
}
|
|
4133
4193
|
|
|
4134
4194
|
// src/commands/verify/migrations/index.ts
|
|
4135
|
-
import { readFileSync as
|
|
4195
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
4136
4196
|
import path20 from "path";
|
|
4137
4197
|
import { fileURLToPath } from "url";
|
|
4138
4198
|
|
|
@@ -4213,7 +4273,7 @@ function listMigrationFiles(dir) {
|
|
|
4213
4273
|
|
|
4214
4274
|
// src/commands/verify/migrations/readBaselineMigrations.ts
|
|
4215
4275
|
import { execSync as execSync14 } from "child_process";
|
|
4216
|
-
import { basename } from "path";
|
|
4276
|
+
import { basename as basename2 } from "path";
|
|
4217
4277
|
var MIGRATION_FILE3 = /^migration\d+[A-Za-z0-9]*\.ts$/;
|
|
4218
4278
|
function readBaselineMigrations(repoRelativeDir, ref) {
|
|
4219
4279
|
const baseline = /* @__PURE__ */ new Map();
|
|
@@ -4226,7 +4286,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
4226
4286
|
} catch {
|
|
4227
4287
|
return baseline;
|
|
4228
4288
|
}
|
|
4229
|
-
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path71) => MIGRATION_FILE3.test(
|
|
4289
|
+
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path71) => MIGRATION_FILE3.test(basename2(path71)));
|
|
4230
4290
|
for (const path71 of paths) {
|
|
4231
4291
|
try {
|
|
4232
4292
|
const content = execSync14(`git show "${ref}:${path71}"`, {
|
|
@@ -4234,7 +4294,7 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
4234
4294
|
maxBuffer: 16 * 1024 * 1024,
|
|
4235
4295
|
stdio: ["pipe", "pipe", "pipe"]
|
|
4236
4296
|
});
|
|
4237
|
-
baseline.set(
|
|
4297
|
+
baseline.set(basename2(path71), content);
|
|
4238
4298
|
} catch {
|
|
4239
4299
|
}
|
|
4240
4300
|
}
|
|
@@ -4294,7 +4354,7 @@ function migrations2() {
|
|
|
4294
4354
|
if (ref) {
|
|
4295
4355
|
const baseline = readBaselineMigrations(REPO_RELATIVE_DIR, ref);
|
|
4296
4356
|
const current = new Map(
|
|
4297
|
-
files.map((file) => [file,
|
|
4357
|
+
files.map((file) => [file, readFileSync11(path20.join(dir, file), "utf8")])
|
|
4298
4358
|
);
|
|
4299
4359
|
for (const finding of checkAppendOnly(baseline, current)) {
|
|
4300
4360
|
problems.push(
|
|
@@ -4462,7 +4522,7 @@ ${failed2.length} script(s) failed:`);
|
|
|
4462
4522
|
}
|
|
4463
4523
|
}
|
|
4464
4524
|
function runEntry(entry) {
|
|
4465
|
-
return new Promise((
|
|
4525
|
+
return new Promise((resolve21) => {
|
|
4466
4526
|
const startTime = Date.now();
|
|
4467
4527
|
const child = spawnCommand(
|
|
4468
4528
|
entry.fullCommand,
|
|
@@ -4474,7 +4534,7 @@ function runEntry(entry) {
|
|
|
4474
4534
|
child.on("close", (code) => {
|
|
4475
4535
|
const exitCode = code ?? 1;
|
|
4476
4536
|
flushIfFailed(exitCode, chunks);
|
|
4477
|
-
|
|
4537
|
+
resolve21({
|
|
4478
4538
|
script: entry.name,
|
|
4479
4539
|
code: exitCode,
|
|
4480
4540
|
durationMs: Date.now() - startTime
|
|
@@ -4605,7 +4665,7 @@ program.parse();
|
|
|
4605
4665
|
|
|
4606
4666
|
// src/commands/new/registerNew/newCli/index.ts
|
|
4607
4667
|
async function newCli() {
|
|
4608
|
-
const name =
|
|
4668
|
+
const name = basename3(resolve6("."));
|
|
4609
4669
|
initGit();
|
|
4610
4670
|
initPackageJson(name);
|
|
4611
4671
|
console.log("Installing dependencies...");
|
|
@@ -4620,7 +4680,7 @@ async function newCli() {
|
|
|
4620
4680
|
|
|
4621
4681
|
// src/commands/new/registerNew/newProject.ts
|
|
4622
4682
|
import { execSync as execSync22 } from "child_process";
|
|
4623
|
-
import { existsSync as
|
|
4683
|
+
import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
|
|
4624
4684
|
|
|
4625
4685
|
// src/commands/deploy/init/index.ts
|
|
4626
4686
|
import { execSync as execSync21 } from "child_process";
|
|
@@ -4628,33 +4688,33 @@ import chalk28 from "chalk";
|
|
|
4628
4688
|
import enquirer3 from "enquirer";
|
|
4629
4689
|
|
|
4630
4690
|
// src/commands/deploy/init/updateWorkflow.ts
|
|
4631
|
-
import { existsSync as
|
|
4632
|
-
import { dirname as
|
|
4691
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
4692
|
+
import { dirname as dirname12, join as join10 } from "path";
|
|
4633
4693
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4634
4694
|
import chalk27 from "chalk";
|
|
4635
4695
|
var WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
4636
|
-
var __dirname2 =
|
|
4696
|
+
var __dirname2 = dirname12(fileURLToPath2(import.meta.url));
|
|
4637
4697
|
function getExistingSiteId() {
|
|
4638
|
-
if (!
|
|
4698
|
+
if (!existsSync15(WORKFLOW_PATH)) {
|
|
4639
4699
|
return null;
|
|
4640
4700
|
}
|
|
4641
|
-
const content =
|
|
4701
|
+
const content = readFileSync12(WORKFLOW_PATH, "utf8");
|
|
4642
4702
|
const match = content.match(/-s\s+([a-f0-9-]{36})/);
|
|
4643
4703
|
return match ? match[1] : null;
|
|
4644
4704
|
}
|
|
4645
4705
|
function getTemplateContent(siteId) {
|
|
4646
|
-
const templatePath =
|
|
4647
|
-
const template =
|
|
4706
|
+
const templatePath = join10(__dirname2, "commands/deploy/build.yml");
|
|
4707
|
+
const template = readFileSync12(templatePath, "utf8");
|
|
4648
4708
|
return template.replace("{{NETLIFY_SITE_ID}}", siteId);
|
|
4649
4709
|
}
|
|
4650
4710
|
async function updateWorkflow(siteId) {
|
|
4651
4711
|
const newContent = getTemplateContent(siteId);
|
|
4652
4712
|
const workflowDir = ".github/workflows";
|
|
4653
|
-
if (!
|
|
4713
|
+
if (!existsSync15(workflowDir)) {
|
|
4654
4714
|
mkdirSync3(workflowDir, { recursive: true });
|
|
4655
4715
|
}
|
|
4656
|
-
if (
|
|
4657
|
-
const oldContent =
|
|
4716
|
+
if (existsSync15(WORKFLOW_PATH)) {
|
|
4717
|
+
const oldContent = readFileSync12(WORKFLOW_PATH, "utf8");
|
|
4658
4718
|
if (oldContent === newContent) {
|
|
4659
4719
|
console.log(chalk27.green("build.yml is already up to date"));
|
|
4660
4720
|
return;
|
|
@@ -4748,11 +4808,11 @@ async function newProject() {
|
|
|
4748
4808
|
}
|
|
4749
4809
|
function addViteBaseConfig() {
|
|
4750
4810
|
const viteConfigPath = "vite.config.ts";
|
|
4751
|
-
if (!
|
|
4811
|
+
if (!existsSync16(viteConfigPath)) {
|
|
4752
4812
|
console.log("No vite.config.ts found, skipping base config");
|
|
4753
4813
|
return;
|
|
4754
4814
|
}
|
|
4755
|
-
const content =
|
|
4815
|
+
const content = readFileSync13(viteConfigPath, "utf8");
|
|
4756
4816
|
if (content.includes("base:")) {
|
|
4757
4817
|
console.log("vite.config.ts already has base config");
|
|
4758
4818
|
return;
|
|
@@ -4819,13 +4879,13 @@ function getSnoreToastPath() {
|
|
|
4819
4879
|
return path21.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
|
|
4820
4880
|
}
|
|
4821
4881
|
function showWindowsNotificationFromWsl(options2) {
|
|
4822
|
-
const { title, message:
|
|
4882
|
+
const { title, message: message3, sound } = options2;
|
|
4823
4883
|
const snoreToastPath = getSnoreToastPath();
|
|
4824
4884
|
try {
|
|
4825
4885
|
fs16.chmodSync(snoreToastPath, 493);
|
|
4826
4886
|
} catch {
|
|
4827
4887
|
}
|
|
4828
|
-
const args = ["-t", title, "-m",
|
|
4888
|
+
const args = ["-t", title, "-m", message3];
|
|
4829
4889
|
if (sound) {
|
|
4830
4890
|
args.push("-s", "ms-winsoundevent:Notification.Default");
|
|
4831
4891
|
}
|
|
@@ -4839,14 +4899,14 @@ function showWindowsNotificationFromWsl(options2) {
|
|
|
4839
4899
|
|
|
4840
4900
|
// src/commands/notify/showNotification/index.ts
|
|
4841
4901
|
function showNotification(options2) {
|
|
4842
|
-
const { title, message:
|
|
4902
|
+
const { title, message: message3, sound } = options2;
|
|
4843
4903
|
const platform = detectPlatform();
|
|
4844
4904
|
if (platform === "wsl") {
|
|
4845
|
-
return showWindowsNotificationFromWsl({ title, message:
|
|
4905
|
+
return showWindowsNotificationFromWsl({ title, message: message3, sound });
|
|
4846
4906
|
}
|
|
4847
4907
|
const notificationOptions = {
|
|
4848
4908
|
title,
|
|
4849
|
-
message:
|
|
4909
|
+
message: message3,
|
|
4850
4910
|
wait: false
|
|
4851
4911
|
};
|
|
4852
4912
|
if (platform === "windows") {
|
|
@@ -4868,7 +4928,7 @@ async function notify() {
|
|
|
4868
4928
|
}
|
|
4869
4929
|
const inputData = await readStdin();
|
|
4870
4930
|
const data = JSON.parse(inputData);
|
|
4871
|
-
const { notification_type, cwd, message:
|
|
4931
|
+
const { notification_type, cwd, message: message3 } = data;
|
|
4872
4932
|
const projectName = cwd?.split(/[/\\]/).pop() ?? "Unknown Project";
|
|
4873
4933
|
let title;
|
|
4874
4934
|
let body;
|
|
@@ -4876,7 +4936,7 @@ async function notify() {
|
|
|
4876
4936
|
switch (notification_type) {
|
|
4877
4937
|
case "permission_prompt":
|
|
4878
4938
|
title = "Claude needs permission";
|
|
4879
|
-
body = `${projectName} - ${
|
|
4939
|
+
body = `${projectName} - ${message3 || "Permission required"}`;
|
|
4880
4940
|
sound = "Alarm";
|
|
4881
4941
|
break;
|
|
4882
4942
|
case "idle_prompt":
|
|
@@ -4886,7 +4946,7 @@ async function notify() {
|
|
|
4886
4946
|
break;
|
|
4887
4947
|
default:
|
|
4888
4948
|
title = "Claude Code";
|
|
4889
|
-
body =
|
|
4949
|
+
body = message3 ? `${projectName} - ${message3}` : projectName;
|
|
4890
4950
|
sound = "Default";
|
|
4891
4951
|
}
|
|
4892
4952
|
showNotification({ title, message: body, sound });
|
|
@@ -4994,7 +5054,7 @@ function registerActivity(program2) {
|
|
|
4994
5054
|
|
|
4995
5055
|
// src/commands/registerBackup.ts
|
|
4996
5056
|
import { mkdir as mkdir2, stat } from "fs/promises";
|
|
4997
|
-
import { join as
|
|
5057
|
+
import { join as join12, resolve as resolve7 } from "path";
|
|
4998
5058
|
import chalk31 from "chalk";
|
|
4999
5059
|
|
|
5000
5060
|
// src/shared/db/recordBackup.ts
|
|
@@ -5014,7 +5074,7 @@ function expandTilde2(value) {
|
|
|
5014
5074
|
|
|
5015
5075
|
// src/commands/backup/scheduleBackup.ts
|
|
5016
5076
|
import { mkdir } from "fs/promises";
|
|
5017
|
-
import { join as
|
|
5077
|
+
import { join as join11 } from "path";
|
|
5018
5078
|
import chalk29 from "chalk";
|
|
5019
5079
|
|
|
5020
5080
|
// src/commands/backup/readCrontab.ts
|
|
@@ -5140,8 +5200,8 @@ function readScheduleBlock(crontab) {
|
|
|
5140
5200
|
}
|
|
5141
5201
|
|
|
5142
5202
|
// src/commands/backup/scheduleBackup.ts
|
|
5143
|
-
function fail(
|
|
5144
|
-
console.error(chalk29.red(
|
|
5203
|
+
function fail(message3) {
|
|
5204
|
+
console.error(chalk29.red(message3));
|
|
5145
5205
|
process.exit(1);
|
|
5146
5206
|
}
|
|
5147
5207
|
async function scheduleBackup({
|
|
@@ -5156,7 +5216,7 @@ async function scheduleBackup({
|
|
|
5156
5216
|
const cronExpr = durationToCron(every);
|
|
5157
5217
|
const dir = expandTilde2(loadConfig().backup.dir);
|
|
5158
5218
|
await mkdir(dir, { recursive: true });
|
|
5159
|
-
const logPath2 =
|
|
5219
|
+
const logPath2 = join11(dir, "cron.log");
|
|
5160
5220
|
const cronLine = `${cronExpr} ${resolveAssistCommand()} backup >> ${logPath2} 2>&1`;
|
|
5161
5221
|
writeCrontab(upsertScheduleBlock(readCrontab(), every, cronLine));
|
|
5162
5222
|
console.error(
|
|
@@ -5335,7 +5395,7 @@ async function backup({ out }) {
|
|
|
5335
5395
|
await mkdir2(dir, { recursive: true });
|
|
5336
5396
|
const start3 = Date.now();
|
|
5337
5397
|
const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
5338
|
-
const filePath =
|
|
5398
|
+
const filePath = resolve7(join12(dir, `backup-${timestamp6}.dump`));
|
|
5339
5399
|
await exportBacklog(filePath);
|
|
5340
5400
|
const { size } = await stat(filePath);
|
|
5341
5401
|
const durationMs = Date.now() - start3;
|
|
@@ -5442,19 +5502,19 @@ function parseItemId(input) {
|
|
|
5442
5502
|
|
|
5443
5503
|
// src/commands/backlog/acquireLock.ts
|
|
5444
5504
|
import {
|
|
5445
|
-
existsSync as
|
|
5505
|
+
existsSync as existsSync17,
|
|
5446
5506
|
mkdirSync as mkdirSync4,
|
|
5447
|
-
readFileSync as
|
|
5507
|
+
readFileSync as readFileSync14,
|
|
5448
5508
|
unlinkSync as unlinkSync2,
|
|
5449
5509
|
writeFileSync as writeFileSync14
|
|
5450
5510
|
} from "fs";
|
|
5451
5511
|
import { homedir as homedir4 } from "os";
|
|
5452
|
-
import { join as
|
|
5512
|
+
import { join as join13 } from "path";
|
|
5453
5513
|
function getLocksDir() {
|
|
5454
|
-
return
|
|
5514
|
+
return join13(homedir4(), ".assist", "locks");
|
|
5455
5515
|
}
|
|
5456
5516
|
function getLockPath(itemId2) {
|
|
5457
|
-
return
|
|
5517
|
+
return join13(getLocksDir(), `lock-${itemId2}.json`);
|
|
5458
5518
|
}
|
|
5459
5519
|
function isProcessAlive(pid) {
|
|
5460
5520
|
try {
|
|
@@ -5466,9 +5526,9 @@ function isProcessAlive(pid) {
|
|
|
5466
5526
|
}
|
|
5467
5527
|
function foreignLockHolder(itemId2) {
|
|
5468
5528
|
const lockPath = getLockPath(itemId2);
|
|
5469
|
-
if (!
|
|
5529
|
+
if (!existsSync17(lockPath)) return null;
|
|
5470
5530
|
try {
|
|
5471
|
-
const lock2 = JSON.parse(
|
|
5531
|
+
const lock2 = JSON.parse(readFileSync14(lockPath, "utf8"));
|
|
5472
5532
|
if (typeof lock2.pid !== "number" || lock2.pid === process.pid) return null;
|
|
5473
5533
|
if (!isProcessAlive(lock2.pid)) return null;
|
|
5474
5534
|
return { pid: lock2.pid, timestamp: lock2.timestamp };
|
|
@@ -5579,19 +5639,19 @@ import chalk45 from "chalk";
|
|
|
5579
5639
|
|
|
5580
5640
|
// src/commands/sessions/daemon/ensureHooksSettings.ts
|
|
5581
5641
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync15 } from "fs";
|
|
5582
|
-
import { dirname as
|
|
5642
|
+
import { dirname as dirname13 } from "path";
|
|
5583
5643
|
|
|
5584
5644
|
// src/commands/sessions/daemon/daemonPaths.ts
|
|
5585
5645
|
import { homedir as homedir5 } from "os";
|
|
5586
|
-
import { join as
|
|
5587
|
-
var DAEMON_DIR =
|
|
5646
|
+
import { join as join14 } from "path";
|
|
5647
|
+
var DAEMON_DIR = join14(homedir5(), ".assist", "daemon");
|
|
5588
5648
|
var daemonPaths = {
|
|
5589
5649
|
dir: DAEMON_DIR,
|
|
5590
|
-
socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` :
|
|
5591
|
-
log:
|
|
5592
|
-
pid:
|
|
5593
|
-
spawnLock:
|
|
5594
|
-
hooksSettings:
|
|
5650
|
+
socket: process.platform === "win32" ? String.raw`\\.\pipe\assist-sessions-daemon` : join14(DAEMON_DIR, "daemon.sock"),
|
|
5651
|
+
log: join14(DAEMON_DIR, "daemon.log"),
|
|
5652
|
+
pid: join14(DAEMON_DIR, "daemon.pid"),
|
|
5653
|
+
spawnLock: join14(DAEMON_DIR, "spawn.lock"),
|
|
5654
|
+
hooksSettings: join14(DAEMON_DIR, "hooks-settings.json")
|
|
5595
5655
|
};
|
|
5596
5656
|
|
|
5597
5657
|
// src/commands/sessions/daemon/ensureHooksSettings.ts
|
|
@@ -5626,7 +5686,7 @@ var hooksSettings = {
|
|
|
5626
5686
|
};
|
|
5627
5687
|
function ensureHooksSettings() {
|
|
5628
5688
|
const path71 = daemonPaths.hooksSettings;
|
|
5629
|
-
mkdirSync5(
|
|
5689
|
+
mkdirSync5(dirname13(path71), { recursive: true });
|
|
5630
5690
|
writeFileSync15(path71, JSON.stringify(hooksSettings, null, 2));
|
|
5631
5691
|
return path71;
|
|
5632
5692
|
}
|
|
@@ -5644,8 +5704,8 @@ function spawnInherit(command, args, options2 = {}) {
|
|
|
5644
5704
|
env,
|
|
5645
5705
|
cwd: options2.cwd
|
|
5646
5706
|
});
|
|
5647
|
-
const done2 = new Promise((
|
|
5648
|
-
child.on("close", (code) =>
|
|
5707
|
+
const done2 = new Promise((resolve21, reject) => {
|
|
5708
|
+
child.on("close", (code) => resolve21(code ?? 0));
|
|
5649
5709
|
child.on("error", reject);
|
|
5650
5710
|
});
|
|
5651
5711
|
return { child, done: done2 };
|
|
@@ -5679,6 +5739,10 @@ function buildArgs(prompt, options2) {
|
|
|
5679
5739
|
return [prompt];
|
|
5680
5740
|
}
|
|
5681
5741
|
|
|
5742
|
+
// src/commands/backlog/ensureStoryBranch.ts
|
|
5743
|
+
import { execSync as execSync28 } from "child_process";
|
|
5744
|
+
import { basename as basename4 } from "path";
|
|
5745
|
+
|
|
5682
5746
|
// src/commands/branch/createBranch.ts
|
|
5683
5747
|
import { execSync as execSync27 } from "child_process";
|
|
5684
5748
|
|
|
@@ -5829,8 +5893,8 @@ function buildPrompt(description) {
|
|
|
5829
5893
|
|
|
5830
5894
|
// src/commands/sessions/daemon/appendDaemonLog.ts
|
|
5831
5895
|
import { appendFileSync } from "fs";
|
|
5832
|
-
function appendDaemonLog(
|
|
5833
|
-
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${
|
|
5896
|
+
function appendDaemonLog(message3) {
|
|
5897
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message3}`;
|
|
5834
5898
|
try {
|
|
5835
5899
|
appendFileSync(daemonPaths.log, `${line}
|
|
5836
5900
|
`);
|
|
@@ -5841,36 +5905,89 @@ function appendDaemonLog(message2) {
|
|
|
5841
5905
|
// src/commands/backlog/ensureStoryBranch.ts
|
|
5842
5906
|
async function ensureStoryBranch(item) {
|
|
5843
5907
|
const config = loadConfig();
|
|
5844
|
-
if (!config.prs?.required)
|
|
5845
|
-
|
|
5908
|
+
if (!config.prs?.required) {
|
|
5909
|
+
log(item, "prs.required not set; left the session on its current branch");
|
|
5910
|
+
return;
|
|
5911
|
+
}
|
|
5912
|
+
const recorded = recordedBranch(item);
|
|
5913
|
+
if (recorded) {
|
|
5914
|
+
adoptRecordedBranch(item, recorded);
|
|
5915
|
+
return;
|
|
5916
|
+
}
|
|
5846
5917
|
process.env.ASSIST_BACKLOG_ITEM_ID = String(item.id);
|
|
5847
5918
|
const slug = await generateBranchSlug(item.name);
|
|
5848
5919
|
const { branchName } = await createBranch({ slug, jira: item.jiraKey });
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5920
|
+
log(item, `prs.required set and no branch recorded; created ${branchName}`);
|
|
5921
|
+
}
|
|
5922
|
+
function recordedBranch(item) {
|
|
5923
|
+
return (item.gitRefs ?? []).find((ref) => ref.kind === "branch")?.ref;
|
|
5924
|
+
}
|
|
5925
|
+
function adoptRecordedBranch(item, branch2) {
|
|
5926
|
+
const parked = worktreeBranchInPlay();
|
|
5927
|
+
if (!parked) {
|
|
5928
|
+
log(
|
|
5929
|
+
item,
|
|
5930
|
+
`branch ${branch2} already recorded; left the session on its current branch`
|
|
5931
|
+
);
|
|
5932
|
+
return;
|
|
5933
|
+
}
|
|
5934
|
+
try {
|
|
5935
|
+
execSync28("git fetch", { stdio: "ignore" });
|
|
5936
|
+
} catch {
|
|
5937
|
+
}
|
|
5938
|
+
try {
|
|
5939
|
+
execSync28(`git switch ${shellQuote(branch2)}`, { stdio: "inherit" });
|
|
5940
|
+
log(
|
|
5941
|
+
item,
|
|
5942
|
+
`branch ${branch2} already recorded; switched off ${parked} onto it`
|
|
5943
|
+
);
|
|
5944
|
+
} catch (error) {
|
|
5945
|
+
log(
|
|
5946
|
+
item,
|
|
5947
|
+
`branch ${branch2} already recorded but the worktree stayed on ${parked}: ${message(error)}`
|
|
5948
|
+
);
|
|
5949
|
+
}
|
|
5950
|
+
}
|
|
5951
|
+
function worktreeBranchInPlay() {
|
|
5952
|
+
const tree = linkedWorktree(process.cwd());
|
|
5953
|
+
if (!tree) return null;
|
|
5954
|
+
const head = currentBranch2();
|
|
5955
|
+
return head === basename4(tree.root) ? head : null;
|
|
5956
|
+
}
|
|
5957
|
+
function currentBranch2() {
|
|
5958
|
+
try {
|
|
5959
|
+
return execSync28("git rev-parse --abbrev-ref HEAD", {
|
|
5960
|
+
encoding: "utf8",
|
|
5961
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5962
|
+
}).trim();
|
|
5963
|
+
} catch {
|
|
5964
|
+
return null;
|
|
5965
|
+
}
|
|
5852
5966
|
}
|
|
5853
|
-
function
|
|
5854
|
-
|
|
5967
|
+
function log(item, outcome) {
|
|
5968
|
+
appendDaemonLog(`backlog run ${item.id}: ${outcome}`);
|
|
5969
|
+
}
|
|
5970
|
+
function message(error) {
|
|
5971
|
+
return error instanceof Error ? error.message : String(error);
|
|
5855
5972
|
}
|
|
5856
5973
|
|
|
5857
5974
|
// src/commands/backlog/shared.ts
|
|
5858
5975
|
import chalk37 from "chalk";
|
|
5859
5976
|
|
|
5860
5977
|
// src/commands/backlog/migrateLocalBacklog.ts
|
|
5861
|
-
import { existsSync as
|
|
5862
|
-
import { join as
|
|
5978
|
+
import { existsSync as existsSync19 } from "fs";
|
|
5979
|
+
import { join as join16 } from "path";
|
|
5863
5980
|
import chalk36 from "chalk";
|
|
5864
5981
|
|
|
5865
5982
|
// src/commands/backlog/backupLocalBacklogFiles.ts
|
|
5866
|
-
import { existsSync as
|
|
5867
|
-
import { join as
|
|
5983
|
+
import { existsSync as existsSync18, renameSync } from "fs";
|
|
5984
|
+
import { join as join15 } from "path";
|
|
5868
5985
|
var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
|
|
5869
5986
|
function backupLocalBacklogFiles(dir) {
|
|
5870
5987
|
const moved = [];
|
|
5871
5988
|
for (const name of LOCAL_FILES) {
|
|
5872
|
-
const path71 =
|
|
5873
|
-
if (
|
|
5989
|
+
const path71 = join15(dir, ".assist", name);
|
|
5990
|
+
if (existsSync18(path71)) {
|
|
5874
5991
|
renameSync(path71, `${path71}.bak`);
|
|
5875
5992
|
moved.push(`${name} \u2192 ${name}.bak`);
|
|
5876
5993
|
}
|
|
@@ -5879,11 +5996,11 @@ function backupLocalBacklogFiles(dir) {
|
|
|
5879
5996
|
}
|
|
5880
5997
|
|
|
5881
5998
|
// src/commands/backlog/gitPullBacklog.ts
|
|
5882
|
-
import { execSync as
|
|
5999
|
+
import { execSync as execSync29 } from "child_process";
|
|
5883
6000
|
import chalk35 from "chalk";
|
|
5884
6001
|
function gitPullBacklog(dir) {
|
|
5885
6002
|
try {
|
|
5886
|
-
|
|
6003
|
+
execSync29("git pull --ff-only", {
|
|
5887
6004
|
cwd: dir,
|
|
5888
6005
|
stdio: ["pipe", "pipe", "pipe"]
|
|
5889
6006
|
});
|
|
@@ -6258,7 +6375,7 @@ async function loadAllItems(orm, origin) {
|
|
|
6258
6375
|
}
|
|
6259
6376
|
|
|
6260
6377
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
6261
|
-
import { readFileSync as
|
|
6378
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
6262
6379
|
|
|
6263
6380
|
// src/commands/backlog/types.ts
|
|
6264
6381
|
import { z as z3 } from "zod";
|
|
@@ -6350,14 +6467,14 @@ var backlogFileSchema = z3.array(backlogItemSchema);
|
|
|
6350
6467
|
|
|
6351
6468
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
6352
6469
|
function parseBacklogJsonl(path71) {
|
|
6353
|
-
const content =
|
|
6470
|
+
const content = readFileSync15(path71, "utf8").trim();
|
|
6354
6471
|
if (content.length === 0) return [];
|
|
6355
6472
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
6356
6473
|
}
|
|
6357
6474
|
|
|
6358
6475
|
// src/commands/backlog/migrateLocalBacklog.ts
|
|
6359
6476
|
function jsonlPath(dir) {
|
|
6360
|
-
return
|
|
6477
|
+
return join16(dir, ".assist", "backlog.jsonl");
|
|
6361
6478
|
}
|
|
6362
6479
|
async function verifyImport(orm, origin, items2, imported) {
|
|
6363
6480
|
const reloaded = await loadAllItems(orm, origin);
|
|
@@ -6373,7 +6490,7 @@ async function verifyImport(orm, origin, items2, imported) {
|
|
|
6373
6490
|
}
|
|
6374
6491
|
}
|
|
6375
6492
|
async function migrateLocalBacklog(orm, dir, origin) {
|
|
6376
|
-
if (!
|
|
6493
|
+
if (!existsSync19(jsonlPath(dir))) return;
|
|
6377
6494
|
const existing = (await loadAllItems(orm, origin)).length;
|
|
6378
6495
|
if (existing > 0) {
|
|
6379
6496
|
const moved2 = backupLocalBacklogFiles(dir);
|
|
@@ -6412,20 +6529,20 @@ async function deleteItem(orm, id) {
|
|
|
6412
6529
|
}
|
|
6413
6530
|
|
|
6414
6531
|
// src/commands/backlog/findBacklogUp.ts
|
|
6415
|
-
import { existsSync as
|
|
6416
|
-
import { dirname as
|
|
6532
|
+
import { existsSync as existsSync20 } from "fs";
|
|
6533
|
+
import { dirname as dirname14, join as join17 } from "path";
|
|
6417
6534
|
var BACKLOG_MARKERS = [
|
|
6418
|
-
|
|
6419
|
-
|
|
6535
|
+
join17(".assist", "backlog.db"),
|
|
6536
|
+
join17(".assist", "backlog.jsonl"),
|
|
6420
6537
|
"assist.backlog.yml"
|
|
6421
6538
|
];
|
|
6422
6539
|
function findBacklogUp(startDir) {
|
|
6423
6540
|
let current = startDir;
|
|
6424
|
-
while (current !==
|
|
6425
|
-
if (BACKLOG_MARKERS.some((marker) =>
|
|
6541
|
+
while (current !== dirname14(current)) {
|
|
6542
|
+
if (BACKLOG_MARKERS.some((marker) => existsSync20(join17(current, marker)))) {
|
|
6426
6543
|
return current;
|
|
6427
6544
|
}
|
|
6428
|
-
current =
|
|
6545
|
+
current = dirname14(current);
|
|
6429
6546
|
}
|
|
6430
6547
|
return null;
|
|
6431
6548
|
}
|
|
@@ -6610,10 +6727,10 @@ async function reconcileResumePhase(orm, item, startPhase, resumeSessionId) {
|
|
|
6610
6727
|
if (resumedPhaseIdx === void 0 || resumedPhaseIdx === startPhase) {
|
|
6611
6728
|
return startPhase;
|
|
6612
6729
|
}
|
|
6613
|
-
const
|
|
6614
|
-
appendDaemonLog(`backlog run ${item.id}: ${
|
|
6730
|
+
const message3 = `resume reconciliation: currentPhase implied phase ${startPhase + 1} but the resumed conversation ${resumeSessionId} ran phase ${resumedPhaseIdx + 1}; resuming phase ${resumedPhaseIdx + 1} to match the conversation`;
|
|
6731
|
+
appendDaemonLog(`backlog run ${item.id}: ${message3}`);
|
|
6615
6732
|
try {
|
|
6616
|
-
await appendComment(orm, item.id, `Resume reconciled \u2014 ${
|
|
6733
|
+
await appendComment(orm, item.id, `Resume reconciled \u2014 ${message3}`, {
|
|
6617
6734
|
phase: resumedPhaseIdx + 1
|
|
6618
6735
|
});
|
|
6619
6736
|
} catch {
|
|
@@ -6676,14 +6793,14 @@ function reportDuplicateRun(itemId2, holder) {
|
|
|
6676
6793
|
}
|
|
6677
6794
|
|
|
6678
6795
|
// src/commands/backlog/consumePause.ts
|
|
6679
|
-
import { existsSync as
|
|
6796
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "fs";
|
|
6680
6797
|
import { homedir as homedir6 } from "os";
|
|
6681
|
-
import { join as
|
|
6798
|
+
import { join as join18 } from "path";
|
|
6682
6799
|
function getControlsDir() {
|
|
6683
|
-
return
|
|
6800
|
+
return join18(homedir6(), ".assist", "controls");
|
|
6684
6801
|
}
|
|
6685
6802
|
function getPausePath(itemId2) {
|
|
6686
|
-
return
|
|
6803
|
+
return join18(getControlsDir(), `pause-${itemId2}.json`);
|
|
6687
6804
|
}
|
|
6688
6805
|
function requestPause(itemId2) {
|
|
6689
6806
|
mkdirSync6(getControlsDir(), { recursive: true });
|
|
@@ -6693,7 +6810,7 @@ function requestPause(itemId2) {
|
|
|
6693
6810
|
);
|
|
6694
6811
|
}
|
|
6695
6812
|
function isPausePending(itemId2) {
|
|
6696
|
-
return
|
|
6813
|
+
return existsSync21(getPausePath(itemId2));
|
|
6697
6814
|
}
|
|
6698
6815
|
function clearPause(itemId2) {
|
|
6699
6816
|
try {
|
|
@@ -6703,7 +6820,7 @@ function clearPause(itemId2) {
|
|
|
6703
6820
|
}
|
|
6704
6821
|
function consumePause(itemId2) {
|
|
6705
6822
|
const pausePath = getPausePath(itemId2);
|
|
6706
|
-
if (!
|
|
6823
|
+
if (!existsSync21(pausePath)) return false;
|
|
6707
6824
|
try {
|
|
6708
6825
|
unlinkSync3(pausePath);
|
|
6709
6826
|
} catch {
|
|
@@ -6722,10 +6839,10 @@ async function awaitClaude(done2, context) {
|
|
|
6722
6839
|
try {
|
|
6723
6840
|
return await done2;
|
|
6724
6841
|
} catch (error) {
|
|
6725
|
-
const
|
|
6842
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
6726
6843
|
console.error(
|
|
6727
6844
|
chalk40.red(`
|
|
6728
|
-
Failed to launch Claude for ${context}: ${
|
|
6845
|
+
Failed to launch Claude for ${context}: ${message3}`)
|
|
6729
6846
|
);
|
|
6730
6847
|
return CLAUDE_SPAWN_FAILED;
|
|
6731
6848
|
}
|
|
@@ -6734,9 +6851,9 @@ Failed to launch Claude for ${context}: ${message2}`)
|
|
|
6734
6851
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
6735
6852
|
import * as net from "net";
|
|
6736
6853
|
function connectToDaemon() {
|
|
6737
|
-
return new Promise((
|
|
6854
|
+
return new Promise((resolve21, reject) => {
|
|
6738
6855
|
const socket = net.connect(daemonPaths.socket);
|
|
6739
|
-
socket.once("connect", () =>
|
|
6856
|
+
socket.once("connect", () => resolve21(socket));
|
|
6740
6857
|
socket.once("error", reject);
|
|
6741
6858
|
});
|
|
6742
6859
|
}
|
|
@@ -6751,8 +6868,8 @@ async function isDaemonRunning() {
|
|
|
6751
6868
|
|
|
6752
6869
|
// src/commands/sessions/daemon/sendToDaemon.ts
|
|
6753
6870
|
var WRITE_TIMEOUT_MS = 500;
|
|
6754
|
-
function sendToDaemon(
|
|
6755
|
-
return new Promise((
|
|
6871
|
+
function sendToDaemon(message3) {
|
|
6872
|
+
return new Promise((resolve21, reject) => {
|
|
6756
6873
|
connectToDaemon().then((socket) => {
|
|
6757
6874
|
const timer = setTimeout(() => {
|
|
6758
6875
|
socket.destroy();
|
|
@@ -6762,11 +6879,11 @@ function sendToDaemon(message2) {
|
|
|
6762
6879
|
clearTimeout(timer);
|
|
6763
6880
|
reject(error);
|
|
6764
6881
|
});
|
|
6765
|
-
socket.write(`${JSON.stringify(
|
|
6882
|
+
socket.write(`${JSON.stringify(message3)}
|
|
6766
6883
|
`, () => {
|
|
6767
6884
|
clearTimeout(timer);
|
|
6768
6885
|
socket.end();
|
|
6769
|
-
|
|
6886
|
+
resolve21();
|
|
6770
6887
|
});
|
|
6771
6888
|
}, reject);
|
|
6772
6889
|
});
|
|
@@ -6788,8 +6905,8 @@ function readSocketLines(socket, onLine) {
|
|
|
6788
6905
|
|
|
6789
6906
|
// src/commands/sessions/daemon/sendToDaemonAwaitAck.ts
|
|
6790
6907
|
var ACK_TIMEOUT_MS = 1e3;
|
|
6791
|
-
function sendToDaemonAwaitAck(
|
|
6792
|
-
return new Promise((
|
|
6908
|
+
function sendToDaemonAwaitAck(message3) {
|
|
6909
|
+
return new Promise((resolve21, reject) => {
|
|
6793
6910
|
connectToDaemon().then((socket) => {
|
|
6794
6911
|
let settled = false;
|
|
6795
6912
|
const finish = (error) => {
|
|
@@ -6798,7 +6915,7 @@ function sendToDaemonAwaitAck(message2) {
|
|
|
6798
6915
|
clearTimeout(timer);
|
|
6799
6916
|
socket.destroy();
|
|
6800
6917
|
if (error) reject(error);
|
|
6801
|
-
else
|
|
6918
|
+
else resolve21();
|
|
6802
6919
|
};
|
|
6803
6920
|
const timer = setTimeout(
|
|
6804
6921
|
() => finish(new Error("timed out awaiting daemon ack")),
|
|
@@ -6812,7 +6929,7 @@ function sendToDaemonAwaitAck(message2) {
|
|
|
6812
6929
|
"close",
|
|
6813
6930
|
() => finish(new Error("daemon closed before acknowledging"))
|
|
6814
6931
|
);
|
|
6815
|
-
socket.write(`${JSON.stringify(
|
|
6932
|
+
socket.write(`${JSON.stringify(message3)}
|
|
6816
6933
|
`);
|
|
6817
6934
|
}, reject);
|
|
6818
6935
|
});
|
|
@@ -6872,7 +6989,7 @@ async function deliverReliably(sessionId, status3, payload) {
|
|
|
6872
6989
|
}
|
|
6873
6990
|
}
|
|
6874
6991
|
function sleep(ms) {
|
|
6875
|
-
return new Promise((
|
|
6992
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
6876
6993
|
}
|
|
6877
6994
|
function describeError(error) {
|
|
6878
6995
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -7026,42 +7143,42 @@ function buildPhasePrompt(item, phaseNumber, phase) {
|
|
|
7026
7143
|
}
|
|
7027
7144
|
|
|
7028
7145
|
// src/commands/backlog/watchForMarker.ts
|
|
7029
|
-
import { existsSync as
|
|
7146
|
+
import { existsSync as existsSync24, unwatchFile, watchFile } from "fs";
|
|
7030
7147
|
|
|
7031
7148
|
// src/commands/backlog/readSignal.ts
|
|
7032
|
-
import { existsSync as
|
|
7149
|
+
import { existsSync as existsSync23, readFileSync as readFileSync17 } from "fs";
|
|
7033
7150
|
|
|
7034
7151
|
// src/commands/backlog/writeSignal.ts
|
|
7035
7152
|
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync18 } from "fs";
|
|
7036
7153
|
import { homedir as homedir8 } from "os";
|
|
7037
|
-
import { dirname as
|
|
7154
|
+
import { dirname as dirname16, join as join20 } from "path";
|
|
7038
7155
|
import chalk41 from "chalk";
|
|
7039
7156
|
|
|
7040
7157
|
// src/commands/backlog/recordSignalOwner.ts
|
|
7041
7158
|
import {
|
|
7042
|
-
existsSync as
|
|
7159
|
+
existsSync as existsSync22,
|
|
7043
7160
|
mkdirSync as mkdirSync7,
|
|
7044
|
-
readFileSync as
|
|
7161
|
+
readFileSync as readFileSync16,
|
|
7045
7162
|
rmSync,
|
|
7046
7163
|
writeFileSync as writeFileSync17
|
|
7047
7164
|
} from "fs";
|
|
7048
7165
|
import { homedir as homedir7 } from "os";
|
|
7049
|
-
import { dirname as
|
|
7166
|
+
import { dirname as dirname15, join as join19 } from "path";
|
|
7050
7167
|
function getOwnerPath(itemId2) {
|
|
7051
|
-
return
|
|
7168
|
+
return join19(homedir7(), ".assist", "signals", `owner-${itemId2}.json`);
|
|
7052
7169
|
}
|
|
7053
7170
|
function recordSignalOwner(itemId2) {
|
|
7054
7171
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
7055
7172
|
if (!sessionId) return;
|
|
7056
7173
|
const path71 = getOwnerPath(itemId2);
|
|
7057
|
-
mkdirSync7(
|
|
7174
|
+
mkdirSync7(dirname15(path71), { recursive: true });
|
|
7058
7175
|
writeFileSync17(path71, JSON.stringify({ sessionId }));
|
|
7059
7176
|
}
|
|
7060
7177
|
function readSignalOwner(itemId2) {
|
|
7061
7178
|
const path71 = getOwnerPath(itemId2);
|
|
7062
|
-
if (!
|
|
7179
|
+
if (!existsSync22(path71)) return void 0;
|
|
7063
7180
|
try {
|
|
7064
|
-
const parsed = JSON.parse(
|
|
7181
|
+
const parsed = JSON.parse(readFileSync16(path71, "utf8"));
|
|
7065
7182
|
return parsed.sessionId;
|
|
7066
7183
|
} catch {
|
|
7067
7184
|
return void 0;
|
|
@@ -7078,7 +7195,7 @@ function clearSignalOwner(itemId2) {
|
|
|
7078
7195
|
// src/commands/backlog/writeSignal.ts
|
|
7079
7196
|
function getSignalPath(sessionId = process.env.ASSIST_SESSION_ID) {
|
|
7080
7197
|
if (!sessionId) return void 0;
|
|
7081
|
-
return
|
|
7198
|
+
return join20(homedir8(), ".assist", "signals", `signal-${sessionId}.json`);
|
|
7082
7199
|
}
|
|
7083
7200
|
function resolveSignalTarget(event, data) {
|
|
7084
7201
|
const caller = process.env.ASSIST_SESSION_ID;
|
|
@@ -7110,16 +7227,16 @@ function writeSignal(event, data) {
|
|
|
7110
7227
|
const path71 = getSignalPath(target);
|
|
7111
7228
|
if (!path71) return;
|
|
7112
7229
|
const signal = { event, sessionId: target, ...data };
|
|
7113
|
-
mkdirSync8(
|
|
7230
|
+
mkdirSync8(dirname16(path71), { recursive: true });
|
|
7114
7231
|
writeFileSync18(path71, JSON.stringify(signal));
|
|
7115
7232
|
}
|
|
7116
7233
|
|
|
7117
7234
|
// src/commands/backlog/readSignal.ts
|
|
7118
7235
|
function readSignal() {
|
|
7119
7236
|
const path71 = getSignalPath();
|
|
7120
|
-
if (!path71 || !
|
|
7237
|
+
if (!path71 || !existsSync23(path71)) return void 0;
|
|
7121
7238
|
try {
|
|
7122
|
-
return JSON.parse(
|
|
7239
|
+
return JSON.parse(readFileSync17(path71, "utf8"));
|
|
7123
7240
|
} catch {
|
|
7124
7241
|
return void 0;
|
|
7125
7242
|
}
|
|
@@ -7131,7 +7248,7 @@ function watchForMarker(child, options2) {
|
|
|
7131
7248
|
const statusPath = getSignalPath();
|
|
7132
7249
|
if (!statusPath) return { killedOnMarker: () => killed };
|
|
7133
7250
|
watchFile(statusPath, { interval: 1e3 }, () => {
|
|
7134
|
-
if (!
|
|
7251
|
+
if (!existsSync24(statusPath)) return;
|
|
7135
7252
|
const signal = readSignal();
|
|
7136
7253
|
if (!signal) return;
|
|
7137
7254
|
if (signal.event === "done" && !options2?.actOnDone) return;
|
|
@@ -7230,9 +7347,9 @@ async function persistPhaseSessionId(itemId2, phaseIdx, claudeSessionId) {
|
|
|
7230
7347
|
}
|
|
7231
7348
|
|
|
7232
7349
|
// src/shared/emitActivity.ts
|
|
7233
|
-
import { mkdirSync as mkdirSync9, readFileSync as
|
|
7350
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync18, rmSync as rmSync2, writeFileSync as writeFileSync19 } from "fs";
|
|
7234
7351
|
import { homedir as homedir9 } from "os";
|
|
7235
|
-
import { dirname as
|
|
7352
|
+
import { dirname as dirname17, join as join21 } from "path";
|
|
7236
7353
|
import { z as z4 } from "zod";
|
|
7237
7354
|
var activitySchema = z4.object({
|
|
7238
7355
|
kind: z4.enum(["command", "backlog"]),
|
|
@@ -7247,18 +7364,18 @@ var activitySchema = z4.object({
|
|
|
7247
7364
|
startedAt: z4.number()
|
|
7248
7365
|
});
|
|
7249
7366
|
function activityPath(sessionId) {
|
|
7250
|
-
return
|
|
7367
|
+
return join21(homedir9(), ".assist", "activity", `activity-${sessionId}.json`);
|
|
7251
7368
|
}
|
|
7252
7369
|
function emitActivity(activity2) {
|
|
7253
7370
|
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
7254
7371
|
if (!sessionId) return;
|
|
7255
7372
|
const path71 = activityPath(sessionId);
|
|
7256
|
-
mkdirSync9(
|
|
7373
|
+
mkdirSync9(dirname17(path71), { recursive: true });
|
|
7257
7374
|
writeFileSync19(path71, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
7258
7375
|
}
|
|
7259
7376
|
function readActivity(path71) {
|
|
7260
7377
|
try {
|
|
7261
|
-
return JSON.parse(
|
|
7378
|
+
return JSON.parse(readFileSync18(path71, "utf8"));
|
|
7262
7379
|
} catch {
|
|
7263
7380
|
return void 0;
|
|
7264
7381
|
}
|
|
@@ -7269,7 +7386,7 @@ function reconcileActivity(sessionId, activity2) {
|
|
|
7269
7386
|
return;
|
|
7270
7387
|
}
|
|
7271
7388
|
const path71 = activityPath(sessionId);
|
|
7272
|
-
mkdirSync9(
|
|
7389
|
+
mkdirSync9(dirname17(path71), { recursive: true });
|
|
7273
7390
|
writeFileSync19(path71, JSON.stringify(activity2));
|
|
7274
7391
|
}
|
|
7275
7392
|
function removeActivity(sessionId) {
|
|
@@ -7294,7 +7411,7 @@ function reportPhaseActivity(item, phaseNumber, totalPhases, phase, claudeSessio
|
|
|
7294
7411
|
}
|
|
7295
7412
|
|
|
7296
7413
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
7297
|
-
import { existsSync as
|
|
7414
|
+
import { existsSync as existsSync25, unlinkSync as unlinkSync4 } from "fs";
|
|
7298
7415
|
import chalk42 from "chalk";
|
|
7299
7416
|
|
|
7300
7417
|
// src/commands/backlog/handleIncompletePhase.ts
|
|
@@ -7316,7 +7433,7 @@ async function handleIncompletePhase() {
|
|
|
7316
7433
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
7317
7434
|
function cleanupSignal() {
|
|
7318
7435
|
const statusPath = getSignalPath();
|
|
7319
|
-
if (statusPath &&
|
|
7436
|
+
if (statusPath && existsSync25(statusPath)) {
|
|
7320
7437
|
unlinkSync4(statusPath);
|
|
7321
7438
|
}
|
|
7322
7439
|
}
|
|
@@ -7327,7 +7444,7 @@ async function isTerminalStatus(itemId2) {
|
|
|
7327
7444
|
}
|
|
7328
7445
|
async function resolvePhaseResult(phaseIndex, itemId2) {
|
|
7329
7446
|
const signalPath = getSignalPath();
|
|
7330
|
-
if (!signalPath || !
|
|
7447
|
+
if (!signalPath || !existsSync25(signalPath)) {
|
|
7331
7448
|
if (await isTerminalStatus(itemId2)) return { kind: "abort" };
|
|
7332
7449
|
const action = await handleIncompletePhase();
|
|
7333
7450
|
if (action === "abort") return { kind: "abort" };
|
|
@@ -7566,13 +7683,13 @@ async function findSessionJsonlPath(sessionId) {
|
|
|
7566
7683
|
// src/commands/backlog/verifyResumeConversation.ts
|
|
7567
7684
|
async function verifyResumeConversation(itemId2, resumeSessionId, phaseLabel2) {
|
|
7568
7685
|
if (await findSessionJsonlPath(resumeSessionId)) return true;
|
|
7569
|
-
const
|
|
7686
|
+
const message3 = `${phaseLabel2}: resume found no conversation for session ${resumeSessionId}; phase not advanced`;
|
|
7570
7687
|
console.error(chalk43.red(`
|
|
7571
|
-
${
|
|
7572
|
-
appendDaemonLog(`backlog run ${itemId2}: ${
|
|
7688
|
+
${message3}`));
|
|
7689
|
+
appendDaemonLog(`backlog run ${itemId2}: ${message3}`);
|
|
7573
7690
|
try {
|
|
7574
7691
|
const { orm } = await getReady();
|
|
7575
|
-
await appendComment(orm, itemId2, `Resume failed \u2014 ${
|
|
7692
|
+
await appendComment(orm, itemId2, `Resume failed \u2014 ${message3}`);
|
|
7576
7693
|
} catch {
|
|
7577
7694
|
}
|
|
7578
7695
|
return false;
|
|
@@ -8183,21 +8300,21 @@ import chalk61 from "chalk";
|
|
|
8183
8300
|
import { WebSocketServer } from "ws";
|
|
8184
8301
|
|
|
8185
8302
|
// src/shared/getInstallDir.ts
|
|
8186
|
-
import { execSync as
|
|
8187
|
-
import { dirname as
|
|
8303
|
+
import { execSync as execSync30 } from "child_process";
|
|
8304
|
+
import { dirname as dirname19, resolve as resolve8 } from "path";
|
|
8188
8305
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
8189
8306
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
8190
|
-
var __dirname3 =
|
|
8307
|
+
var __dirname3 = dirname19(__filename2);
|
|
8191
8308
|
function getInstallDir() {
|
|
8192
|
-
return
|
|
8309
|
+
return resolve8(__dirname3, "..");
|
|
8193
8310
|
}
|
|
8194
8311
|
function isGitRepo(dir) {
|
|
8195
8312
|
try {
|
|
8196
|
-
const result =
|
|
8313
|
+
const result = execSync30("git rev-parse --show-toplevel", {
|
|
8197
8314
|
cwd: dir,
|
|
8198
8315
|
stdio: "pipe"
|
|
8199
8316
|
}).toString().trim();
|
|
8200
|
-
return
|
|
8317
|
+
return resolve8(result) === resolve8(dir);
|
|
8201
8318
|
} catch {
|
|
8202
8319
|
return false;
|
|
8203
8320
|
}
|
|
@@ -8210,11 +8327,11 @@ import {
|
|
|
8210
8327
|
import chalk57 from "chalk";
|
|
8211
8328
|
|
|
8212
8329
|
// src/lib/openBrowser.ts
|
|
8213
|
-
import { execSync as
|
|
8330
|
+
import { execSync as execSync31 } from "child_process";
|
|
8214
8331
|
function tryExec(commands) {
|
|
8215
8332
|
for (const cmd of commands) {
|
|
8216
8333
|
try {
|
|
8217
|
-
|
|
8334
|
+
execSync31(cmd, { stdio: "ignore" });
|
|
8218
8335
|
return true;
|
|
8219
8336
|
} catch {
|
|
8220
8337
|
}
|
|
@@ -8332,7 +8449,7 @@ import {
|
|
|
8332
8449
|
closeSync as closeSync2,
|
|
8333
8450
|
mkdirSync as mkdirSync10,
|
|
8334
8451
|
openSync as openSync2,
|
|
8335
|
-
statSync,
|
|
8452
|
+
statSync as statSync2,
|
|
8336
8453
|
unlinkSync as unlinkSync5,
|
|
8337
8454
|
writeSync
|
|
8338
8455
|
} from "fs";
|
|
@@ -8381,7 +8498,7 @@ function tryCreateLock() {
|
|
|
8381
8498
|
}
|
|
8382
8499
|
function isLockStale() {
|
|
8383
8500
|
try {
|
|
8384
|
-
return Date.now() -
|
|
8501
|
+
return Date.now() - statSync2(daemonPaths.spawnLock).mtimeMs > STALE_LOCK_MS;
|
|
8385
8502
|
} catch {
|
|
8386
8503
|
return true;
|
|
8387
8504
|
}
|
|
@@ -8393,16 +8510,16 @@ function releaseSpawnLock() {
|
|
|
8393
8510
|
}
|
|
8394
8511
|
}
|
|
8395
8512
|
function spawnDaemon(reason4) {
|
|
8396
|
-
const
|
|
8513
|
+
const log2 = openSync2(daemonPaths.log, "a");
|
|
8397
8514
|
const child = spawn4(process.execPath, [process.argv[1], "daemon", "run"], {
|
|
8398
8515
|
detached: true,
|
|
8399
|
-
stdio: ["ignore",
|
|
8516
|
+
stdio: ["ignore", log2, log2],
|
|
8400
8517
|
env: { ...process.env, ASSIST_DAEMON_SPAWN_REASON: reason4 }
|
|
8401
8518
|
});
|
|
8402
8519
|
child.unref();
|
|
8403
8520
|
}
|
|
8404
8521
|
function delay(ms) {
|
|
8405
|
-
return new Promise((
|
|
8522
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
8406
8523
|
}
|
|
8407
8524
|
|
|
8408
8525
|
// src/commands/sessions/daemon/isWindowsCwd.ts
|
|
@@ -8439,10 +8556,10 @@ function gitInvocation(cwd, args) {
|
|
|
8439
8556
|
}
|
|
8440
8557
|
function git2(cwd, args) {
|
|
8441
8558
|
const { file, argv, options: options2 } = gitInvocation(cwd, args);
|
|
8442
|
-
return new Promise((
|
|
8559
|
+
return new Promise((resolve21, reject) => {
|
|
8443
8560
|
execFile2(file, argv, options2, (error, stdout) => {
|
|
8444
8561
|
if (error) reject(error);
|
|
8445
|
-
else
|
|
8562
|
+
else resolve21(stdout.toString());
|
|
8446
8563
|
});
|
|
8447
8564
|
});
|
|
8448
8565
|
}
|
|
@@ -8514,20 +8631,20 @@ function gitCommonDir(cwd) {
|
|
|
8514
8631
|
}
|
|
8515
8632
|
|
|
8516
8633
|
// src/shared/loadJson.ts
|
|
8517
|
-
import { existsSync as
|
|
8634
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync19, writeFileSync as writeFileSync20 } from "fs";
|
|
8518
8635
|
import { homedir as homedir11 } from "os";
|
|
8519
|
-
import { join as
|
|
8636
|
+
import { join as join23 } from "path";
|
|
8520
8637
|
function getStoreDir() {
|
|
8521
|
-
return
|
|
8638
|
+
return join23(homedir11(), ".assist");
|
|
8522
8639
|
}
|
|
8523
8640
|
function getStorePath(filename) {
|
|
8524
|
-
return
|
|
8641
|
+
return join23(getStoreDir(), filename);
|
|
8525
8642
|
}
|
|
8526
8643
|
function loadJson(filename) {
|
|
8527
8644
|
const path71 = getStorePath(filename);
|
|
8528
|
-
if (
|
|
8645
|
+
if (existsSync26(path71)) {
|
|
8529
8646
|
try {
|
|
8530
|
-
return JSON.parse(
|
|
8647
|
+
return JSON.parse(readFileSync19(path71, "utf8"));
|
|
8531
8648
|
} catch {
|
|
8532
8649
|
return {};
|
|
8533
8650
|
}
|
|
@@ -8536,7 +8653,7 @@ function loadJson(filename) {
|
|
|
8536
8653
|
}
|
|
8537
8654
|
function saveJson(filename, data) {
|
|
8538
8655
|
const dir = getStoreDir();
|
|
8539
|
-
if (!
|
|
8656
|
+
if (!existsSync26(dir)) {
|
|
8540
8657
|
mkdirSync11(dir, { recursive: true });
|
|
8541
8658
|
}
|
|
8542
8659
|
writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
@@ -8591,16 +8708,16 @@ function hostedGroup(cwd, origin, clone) {
|
|
|
8591
8708
|
|
|
8592
8709
|
// src/shared/createBundleHandler.ts
|
|
8593
8710
|
import { createHash } from "crypto";
|
|
8594
|
-
import { readFileSync as
|
|
8595
|
-
import { dirname as
|
|
8711
|
+
import { readFileSync as readFileSync20, statSync as statSync3 } from "fs";
|
|
8712
|
+
import { dirname as dirname20, join as join24 } from "path";
|
|
8596
8713
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8597
8714
|
function createBundleHandler(importMetaUrl, bundlePath, contentType = "application/javascript") {
|
|
8598
|
-
const file =
|
|
8715
|
+
const file = join24(dirname20(fileURLToPath4(importMetaUrl)), bundlePath);
|
|
8599
8716
|
let cache4;
|
|
8600
8717
|
return (req, res) => {
|
|
8601
|
-
const mtimeMs =
|
|
8718
|
+
const mtimeMs = statSync3(file).mtimeMs;
|
|
8602
8719
|
if (cache4?.mtimeMs !== mtimeMs) {
|
|
8603
|
-
const body =
|
|
8720
|
+
const body = readFileSync20(file, "utf8");
|
|
8604
8721
|
const etag = `"${createHash("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
8605
8722
|
cache4 = { body, etag, mtimeMs };
|
|
8606
8723
|
}
|
|
@@ -8729,15 +8846,15 @@ async function loadItemSummaries(orm, origin) {
|
|
|
8729
8846
|
}
|
|
8730
8847
|
|
|
8731
8848
|
// src/commands/backlog/resolveRepoLocation.ts
|
|
8732
|
-
import { existsSync as
|
|
8849
|
+
import { existsSync as existsSync27 } from "fs";
|
|
8733
8850
|
|
|
8734
8851
|
// src/commands/backlog/cloneTargetDir.ts
|
|
8735
|
-
import { join as
|
|
8852
|
+
import { join as join25, resolve as resolve9 } from "path";
|
|
8736
8853
|
function cloneTargetDir(origin, baseDir) {
|
|
8737
8854
|
if (origin.startsWith("local:")) return null;
|
|
8738
8855
|
const repoName = origin.split("/").filter(Boolean).pop();
|
|
8739
8856
|
if (!repoName) return null;
|
|
8740
|
-
return
|
|
8857
|
+
return resolve9(join25(baseDir, repoName));
|
|
8741
8858
|
}
|
|
8742
8859
|
|
|
8743
8860
|
// src/commands/backlog/resolveRepoLocation.ts
|
|
@@ -8745,7 +8862,7 @@ function resolveRepoLocation(origin, knownCwd, baseDir) {
|
|
|
8745
8862
|
if (knownCwd) return { cwd: knownCwd };
|
|
8746
8863
|
const target = cloneTargetDir(origin, baseDir);
|
|
8747
8864
|
if (!target) return {};
|
|
8748
|
-
if (
|
|
8865
|
+
if (existsSync27(target) && getCurrentOrigin(target) === origin)
|
|
8749
8866
|
return { cwd: target };
|
|
8750
8867
|
return { cloneTarget: target };
|
|
8751
8868
|
}
|
|
@@ -8854,12 +8971,12 @@ async function loadVisibleItems(req) {
|
|
|
8854
8971
|
|
|
8855
8972
|
// src/commands/backlog/web/parseStatusBody.ts
|
|
8856
8973
|
function readBody(req) {
|
|
8857
|
-
return new Promise((
|
|
8974
|
+
return new Promise((resolve21, reject) => {
|
|
8858
8975
|
let body = "";
|
|
8859
8976
|
req.on("data", (chunk) => {
|
|
8860
8977
|
body += chunk.toString();
|
|
8861
8978
|
});
|
|
8862
|
-
req.on("end", () =>
|
|
8979
|
+
req.on("end", () => resolve21(body));
|
|
8863
8980
|
req.on("error", reject);
|
|
8864
8981
|
});
|
|
8865
8982
|
}
|
|
@@ -9441,13 +9558,13 @@ async function diffScopes(req, res) {
|
|
|
9441
9558
|
|
|
9442
9559
|
// src/commands/sessions/web/fileContent.ts
|
|
9443
9560
|
import { readFile, stat as stat2 } from "fs/promises";
|
|
9444
|
-
import { isAbsolute, relative as relative2, resolve as
|
|
9561
|
+
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10 } from "path";
|
|
9445
9562
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
9446
9563
|
function resolveWithinCwd(cwd, path71) {
|
|
9447
|
-
const root =
|
|
9448
|
-
const target =
|
|
9564
|
+
const root = resolve10(toGitCwd(cwd));
|
|
9565
|
+
const target = resolve10(root, path71);
|
|
9449
9566
|
const rel = relative2(root, target);
|
|
9450
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
9567
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
9451
9568
|
return target;
|
|
9452
9569
|
}
|
|
9453
9570
|
async function fileContent(req, res) {
|
|
@@ -9516,13 +9633,13 @@ function readRawConfigLayers(cwd) {
|
|
|
9516
9633
|
const global = loadRawYaml(getGlobalConfigPath());
|
|
9517
9634
|
if (!global.repos)
|
|
9518
9635
|
return {
|
|
9519
|
-
project: loadRawYaml(
|
|
9636
|
+
project: loadRawYaml(projectConfigPathFrom(cwd)),
|
|
9520
9637
|
global,
|
|
9521
9638
|
repoOverride: {}
|
|
9522
9639
|
};
|
|
9523
9640
|
const origin = getCurrentOrigin(cwd);
|
|
9524
9641
|
return {
|
|
9525
|
-
project: loadRawYaml(
|
|
9642
|
+
project: loadRawYaml(projectConfigPathFrom(cwd)),
|
|
9526
9643
|
global,
|
|
9527
9644
|
repoOverride: resolveRepoOverride(global, origin),
|
|
9528
9645
|
repoKey: matchRepoConfigKey(global, origin)
|
|
@@ -9710,20 +9827,20 @@ function handleServerRuns(req, res) {
|
|
|
9710
9827
|
|
|
9711
9828
|
// src/commands/sessions/web/getReviewSynthesis.ts
|
|
9712
9829
|
import { execFile as execFile4 } from "child_process";
|
|
9713
|
-
import { readFileSync as
|
|
9830
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
9714
9831
|
import { homedir as homedir12 } from "os";
|
|
9715
|
-
import { basename as
|
|
9832
|
+
import { basename as basename8, join as join27 } from "path";
|
|
9716
9833
|
import { promisify as promisify3 } from "util";
|
|
9717
9834
|
|
|
9718
9835
|
// src/commands/sessions/web/findSynthesisForBranch.ts
|
|
9719
|
-
import { existsSync as
|
|
9720
|
-
import { basename as
|
|
9836
|
+
import { existsSync as existsSync28, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
|
|
9837
|
+
import { basename as basename7, dirname as dirname21, join as join26 } from "path";
|
|
9721
9838
|
function findSynthesisForBranch(repoReviewsDir, branch2) {
|
|
9722
|
-
const branchKeyPath =
|
|
9723
|
-
const parent =
|
|
9724
|
-
const branchPrefix =
|
|
9725
|
-
if (!
|
|
9726
|
-
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) =>
|
|
9839
|
+
const branchKeyPath = join26(repoReviewsDir, `${branch2}-`);
|
|
9840
|
+
const parent = dirname21(branchKeyPath);
|
|
9841
|
+
const branchPrefix = basename7(branchKeyPath);
|
|
9842
|
+
if (!existsSync28(parent)) return null;
|
|
9843
|
+
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join26(parent, name, "synthesis.md")).filter((path71) => existsSync28(path71)).map((path71) => ({ path: path71, mtime: statSync4(path71).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
9727
9844
|
return synthesisFiles[0]?.path ?? null;
|
|
9728
9845
|
}
|
|
9729
9846
|
|
|
@@ -9740,11 +9857,11 @@ async function resolveSynthesisPath(cwd) {
|
|
|
9740
9857
|
runGit(cwd, ["rev-parse", "--show-toplevel"]),
|
|
9741
9858
|
runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
|
|
9742
9859
|
]);
|
|
9743
|
-
const repoReviewsDir =
|
|
9860
|
+
const repoReviewsDir = join27(
|
|
9744
9861
|
homedir12(),
|
|
9745
9862
|
".assist",
|
|
9746
9863
|
"reviews",
|
|
9747
|
-
|
|
9864
|
+
basename8(repoRoot)
|
|
9748
9865
|
);
|
|
9749
9866
|
return findSynthesisForBranch(repoReviewsDir, branch2);
|
|
9750
9867
|
}
|
|
@@ -9757,7 +9874,7 @@ async function getReviewSynthesis(req, res) {
|
|
|
9757
9874
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
9758
9875
|
return;
|
|
9759
9876
|
}
|
|
9760
|
-
respondJson(res, 200, { synthesis:
|
|
9877
|
+
respondJson(res, 200, { synthesis: readFileSync21(path71, "utf8") });
|
|
9761
9878
|
} catch {
|
|
9762
9879
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
9763
9880
|
}
|
|
@@ -9888,7 +10005,7 @@ import * as os3 from "os";
|
|
|
9888
10005
|
import * as path25 from "path";
|
|
9889
10006
|
|
|
9890
10007
|
// src/shared/checkCliAvailable.ts
|
|
9891
|
-
import { execSync as
|
|
10008
|
+
import { execSync as execSync32 } from "child_process";
|
|
9892
10009
|
function checkCliAvailable(cli) {
|
|
9893
10010
|
const binary = cli.split(/\s+/)[0];
|
|
9894
10011
|
const opts = {
|
|
@@ -9896,11 +10013,11 @@ function checkCliAvailable(cli) {
|
|
|
9896
10013
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9897
10014
|
};
|
|
9898
10015
|
try {
|
|
9899
|
-
|
|
10016
|
+
execSync32(`command -v ${binary}`, opts);
|
|
9900
10017
|
return true;
|
|
9901
10018
|
} catch {
|
|
9902
10019
|
try {
|
|
9903
|
-
|
|
10020
|
+
execSync32(`where ${binary}`, opts);
|
|
9904
10021
|
return true;
|
|
9905
10022
|
} catch {
|
|
9906
10023
|
return false;
|
|
@@ -9991,8 +10108,8 @@ function subsequenceScore(text17, query) {
|
|
|
9991
10108
|
function scoreFilePath(path71, query) {
|
|
9992
10109
|
const needle = query.trim().toLowerCase();
|
|
9993
10110
|
if (!needle) return 0;
|
|
9994
|
-
const
|
|
9995
|
-
const inBasename = subsequenceScore(
|
|
10111
|
+
const basename21 = path71.slice(path71.lastIndexOf("/") + 1);
|
|
10112
|
+
const inBasename = subsequenceScore(basename21, needle);
|
|
9996
10113
|
if (inBasename !== null) return BASENAME_WEIGHT + inBasename;
|
|
9997
10114
|
return subsequenceScore(path71, needle);
|
|
9998
10115
|
}
|
|
@@ -10389,17 +10506,17 @@ async function stopDaemon() {
|
|
|
10389
10506
|
}
|
|
10390
10507
|
}
|
|
10391
10508
|
function closedBeforeTimeout(socket) {
|
|
10392
|
-
return new Promise((
|
|
10509
|
+
return new Promise((resolve21) => {
|
|
10393
10510
|
const timer = setTimeout(() => {
|
|
10394
10511
|
socket.destroy();
|
|
10395
|
-
|
|
10512
|
+
resolve21(false);
|
|
10396
10513
|
}, STOP_TIMEOUT_MS);
|
|
10397
10514
|
socket.resume();
|
|
10398
10515
|
socket.on("error", () => {
|
|
10399
10516
|
});
|
|
10400
10517
|
socket.once("close", () => {
|
|
10401
10518
|
clearTimeout(timer);
|
|
10402
|
-
|
|
10519
|
+
resolve21(true);
|
|
10403
10520
|
});
|
|
10404
10521
|
});
|
|
10405
10522
|
}
|
|
@@ -10450,8 +10567,8 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
10450
10567
|
respondJson(res, 400, { error: "Invalid target" });
|
|
10451
10568
|
return;
|
|
10452
10569
|
}
|
|
10453
|
-
await new Promise((
|
|
10454
|
-
res.once("finish",
|
|
10570
|
+
await new Promise((resolve21) => {
|
|
10571
|
+
res.once("finish", resolve21);
|
|
10455
10572
|
respondJson(res, 200, { ok: true });
|
|
10456
10573
|
});
|
|
10457
10574
|
if (target === "daemon" || target === "both") {
|
|
@@ -10966,7 +11083,7 @@ async function readRequestBuffer(req, limit) {
|
|
|
10966
11083
|
// src/commands/sessions/web/writeTempImage.ts
|
|
10967
11084
|
import { mkdtemp, writeFile as writeFile2 } from "fs/promises";
|
|
10968
11085
|
import { tmpdir } from "os";
|
|
10969
|
-
import { extname, join as
|
|
11086
|
+
import { extname, join as join29 } from "path";
|
|
10970
11087
|
var EXT_BY_MIME = {
|
|
10971
11088
|
"image/png": "png",
|
|
10972
11089
|
"image/jpeg": "jpg",
|
|
@@ -10986,8 +11103,8 @@ function safeBaseName(name) {
|
|
|
10986
11103
|
return base.replace(/^-+|-+$/g, "").slice(0, 60) || "screenshot";
|
|
10987
11104
|
}
|
|
10988
11105
|
async function writeTempImage(name, contentType, body) {
|
|
10989
|
-
const dir = await mkdtemp(
|
|
10990
|
-
const filePath =
|
|
11106
|
+
const dir = await mkdtemp(join29(tmpdir(), "assist-pr-img-"));
|
|
11107
|
+
const filePath = join29(
|
|
10991
11108
|
dir,
|
|
10992
11109
|
`${safeBaseName(name)}.${pickExtension(name, contentType)}`
|
|
10993
11110
|
);
|
|
@@ -11035,7 +11152,7 @@ async function uploadPrImage(req, res) {
|
|
|
11035
11152
|
|
|
11036
11153
|
// src/commands/sessions/web/createCssHandler.ts
|
|
11037
11154
|
import { createHash as createHash2 } from "crypto";
|
|
11038
|
-
import { readFileSync as
|
|
11155
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
11039
11156
|
import { createRequire as createRequire2 } from "module";
|
|
11040
11157
|
var require3 = createRequire2(import.meta.url);
|
|
11041
11158
|
function createCssHandler(packageEntry) {
|
|
@@ -11043,7 +11160,7 @@ function createCssHandler(packageEntry) {
|
|
|
11043
11160
|
return (req, res) => {
|
|
11044
11161
|
if (!cache4) {
|
|
11045
11162
|
const resolved = require3.resolve(packageEntry);
|
|
11046
|
-
const body =
|
|
11163
|
+
const body = readFileSync22(resolved, "utf8");
|
|
11047
11164
|
const etag = `"${createHash2("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
11048
11165
|
cache4 = { body, etag };
|
|
11049
11166
|
}
|
|
@@ -11193,8 +11310,8 @@ async function runRestartItem(item, { runRestartDaemon, reExec }) {
|
|
|
11193
11310
|
reExec();
|
|
11194
11311
|
}
|
|
11195
11312
|
} catch (error) {
|
|
11196
|
-
const
|
|
11197
|
-
console.error(chalk58.red(`Restart failed: ${
|
|
11313
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
11314
|
+
console.error(chalk58.red(`Restart failed: ${message3}`));
|
|
11198
11315
|
}
|
|
11199
11316
|
}
|
|
11200
11317
|
|
|
@@ -11294,10 +11411,10 @@ function renderRestartMenu(items2, selected) {
|
|
|
11294
11411
|
}
|
|
11295
11412
|
|
|
11296
11413
|
// src/commands/sessions/web/restartMenu/createMenuState.ts
|
|
11297
|
-
function createMenuState(items2,
|
|
11414
|
+
function createMenuState(items2, log2) {
|
|
11298
11415
|
let open = false;
|
|
11299
11416
|
let selected = firstEnabledIndex(items2);
|
|
11300
|
-
const render = () =>
|
|
11417
|
+
const render = () => log2(renderRestartMenu(items2, selected));
|
|
11301
11418
|
return {
|
|
11302
11419
|
isOpen: () => open,
|
|
11303
11420
|
open() {
|
|
@@ -11308,7 +11425,7 @@ function createMenuState(items2, log) {
|
|
|
11308
11425
|
close() {
|
|
11309
11426
|
if (!open) return;
|
|
11310
11427
|
open = false;
|
|
11311
|
-
|
|
11428
|
+
log2.clear();
|
|
11312
11429
|
},
|
|
11313
11430
|
move(direction) {
|
|
11314
11431
|
selected = nextIndex(items2, selected, direction);
|
|
@@ -11365,8 +11482,8 @@ function installRestartMenu(options2 = {}) {
|
|
|
11365
11482
|
const { stdin, out, toggleKey, exit, restartDaemonFn, reExecFn, items: items2 } = resolveOptions(options2);
|
|
11366
11483
|
if (!stdin.isTTY) return () => {
|
|
11367
11484
|
};
|
|
11368
|
-
const
|
|
11369
|
-
const menu = createMenuState(items2,
|
|
11485
|
+
const log2 = createLogUpdate(out);
|
|
11486
|
+
const menu = createMenuState(items2, log2);
|
|
11370
11487
|
const reExec = () => reExecFn({ beforeExec: () => cleanup(), exit });
|
|
11371
11488
|
const { isBusy, activate } = createActivate(menu, {
|
|
11372
11489
|
runRestartDaemon: restartDaemonFn,
|
|
@@ -11582,13 +11699,13 @@ async function beginAssociation(id, options2, clearPatch, label2) {
|
|
|
11582
11699
|
}
|
|
11583
11700
|
|
|
11584
11701
|
// src/commands/backlog/associate-github/fetchGithubIssueTitle.ts
|
|
11585
|
-
import { execSync as
|
|
11702
|
+
import { execSync as execSync33 } from "child_process";
|
|
11586
11703
|
function fetchGithubIssueTitle(issue) {
|
|
11587
11704
|
const match = /^([^/]+)\/([^#]+)#(\d+)$/.exec(issue);
|
|
11588
11705
|
if (!match) return void 0;
|
|
11589
11706
|
const [, owner, repo, number] = match;
|
|
11590
11707
|
try {
|
|
11591
|
-
const result =
|
|
11708
|
+
const result = execSync33(
|
|
11592
11709
|
`gh issue view ${number} -R ${owner}/${repo} --json title`,
|
|
11593
11710
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
11594
11711
|
);
|
|
@@ -11655,12 +11772,12 @@ import chalk66 from "chalk";
|
|
|
11655
11772
|
import { eq as eq22 } from "drizzle-orm";
|
|
11656
11773
|
|
|
11657
11774
|
// src/commands/jira/fetchIssue.ts
|
|
11658
|
-
import { execSync as
|
|
11775
|
+
import { execSync as execSync34 } from "child_process";
|
|
11659
11776
|
import chalk65 from "chalk";
|
|
11660
11777
|
function fetchIssue(issueKey, fields) {
|
|
11661
11778
|
let result;
|
|
11662
11779
|
try {
|
|
11663
|
-
result =
|
|
11780
|
+
result = execSync34(
|
|
11664
11781
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
11665
11782
|
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
11666
11783
|
);
|
|
@@ -11731,7 +11848,7 @@ function registerAssociateJiraCommand(cmd) {
|
|
|
11731
11848
|
|
|
11732
11849
|
// src/commands/backlog/cloneRepo.ts
|
|
11733
11850
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
11734
|
-
import { existsSync as
|
|
11851
|
+
import { existsSync as existsSync29 } from "fs";
|
|
11735
11852
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
11736
11853
|
import chalk67 from "chalk";
|
|
11737
11854
|
|
|
@@ -11747,8 +11864,8 @@ function originToSshUrl(origin) {
|
|
|
11747
11864
|
}
|
|
11748
11865
|
|
|
11749
11866
|
// src/commands/backlog/cloneRepo.ts
|
|
11750
|
-
function fail2(
|
|
11751
|
-
console.log(chalk67.red(
|
|
11867
|
+
function fail2(message3) {
|
|
11868
|
+
console.log(chalk67.red(message3));
|
|
11752
11869
|
process.exitCode = 1;
|
|
11753
11870
|
}
|
|
11754
11871
|
async function cloneRepo(originRaw) {
|
|
@@ -11767,7 +11884,7 @@ async function cloneRepo(originRaw) {
|
|
|
11767
11884
|
if (!target) {
|
|
11768
11885
|
return fail2(`Could not derive a repository name from "${origin}".`);
|
|
11769
11886
|
}
|
|
11770
|
-
if (
|
|
11887
|
+
if (existsSync29(target)) {
|
|
11771
11888
|
return fail2(`Clone target already exists: ${target}`);
|
|
11772
11889
|
}
|
|
11773
11890
|
await mkdir3(baseDir, { recursive: true });
|
|
@@ -12190,9 +12307,9 @@ function ensureRemoteOrigin() {
|
|
|
12190
12307
|
|
|
12191
12308
|
// src/commands/backlog/add/shared.ts
|
|
12192
12309
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
12193
|
-
import { mkdtempSync, readFileSync as
|
|
12310
|
+
import { mkdtempSync, readFileSync as readFileSync23, unlinkSync as unlinkSync6, writeFileSync as writeFileSync21 } from "fs";
|
|
12194
12311
|
import { tmpdir as tmpdir2 } from "os";
|
|
12195
|
-
import { join as
|
|
12312
|
+
import { join as join30 } from "path";
|
|
12196
12313
|
import enquirer6 from "enquirer";
|
|
12197
12314
|
async function promptType() {
|
|
12198
12315
|
const { type } = await enquirer6.prompt({
|
|
@@ -12232,15 +12349,15 @@ async function promptDescription() {
|
|
|
12232
12349
|
}
|
|
12233
12350
|
function openEditor() {
|
|
12234
12351
|
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
12235
|
-
const dir = mkdtempSync(
|
|
12236
|
-
const filePath =
|
|
12352
|
+
const dir = mkdtempSync(join30(tmpdir2(), "assist-"));
|
|
12353
|
+
const filePath = join30(dir, "description.md");
|
|
12237
12354
|
writeFileSync21(filePath, "");
|
|
12238
12355
|
const result = spawnSync3(editor, [filePath], { stdio: "inherit" });
|
|
12239
12356
|
if (result.status !== 0) {
|
|
12240
12357
|
unlinkSync6(filePath);
|
|
12241
12358
|
return void 0;
|
|
12242
12359
|
}
|
|
12243
|
-
const content =
|
|
12360
|
+
const content = readFileSync23(filePath, "utf8").trim();
|
|
12244
12361
|
unlinkSync6(filePath);
|
|
12245
12362
|
return content || void 0;
|
|
12246
12363
|
}
|
|
@@ -12356,7 +12473,7 @@ function parsePreviewDecision(line, requestId) {
|
|
|
12356
12473
|
|
|
12357
12474
|
// src/commands/sessions/shared/requestPreviewDecision.ts
|
|
12358
12475
|
function requestPreviewDecision(request) {
|
|
12359
|
-
return new Promise((
|
|
12476
|
+
return new Promise((resolve21, reject) => {
|
|
12360
12477
|
connectToDaemon().then((socket) => {
|
|
12361
12478
|
let settled = false;
|
|
12362
12479
|
const finish = (error, decision) => {
|
|
@@ -12364,7 +12481,7 @@ function requestPreviewDecision(request) {
|
|
|
12364
12481
|
settled = true;
|
|
12365
12482
|
socket.destroy();
|
|
12366
12483
|
if (error) reject(error);
|
|
12367
|
-
else
|
|
12484
|
+
else resolve21(decision);
|
|
12368
12485
|
};
|
|
12369
12486
|
readSocketLines(socket, (line) => {
|
|
12370
12487
|
const incoming = parsePreviewDecision(line, request.requestId);
|
|
@@ -12507,10 +12624,10 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
12507
12624
|
import chalk79 from "chalk";
|
|
12508
12625
|
|
|
12509
12626
|
// src/commands/backlog/readJsonPayload.ts
|
|
12510
|
-
import { readFileSync as
|
|
12627
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
12511
12628
|
import chalk78 from "chalk";
|
|
12512
|
-
function fail3(
|
|
12513
|
-
console.error(chalk78.red(
|
|
12629
|
+
function fail3(message3) {
|
|
12630
|
+
console.error(chalk78.red(message3));
|
|
12514
12631
|
process.exit(1);
|
|
12515
12632
|
}
|
|
12516
12633
|
function describe(error) {
|
|
@@ -12519,7 +12636,7 @@ function describe(error) {
|
|
|
12519
12636
|
async function readSource(source) {
|
|
12520
12637
|
try {
|
|
12521
12638
|
if (source === "-") return (await readStdinBuffer()).toString("utf8");
|
|
12522
|
-
return
|
|
12639
|
+
return readFileSync24(source, "utf8");
|
|
12523
12640
|
} catch (error) {
|
|
12524
12641
|
return fail3(
|
|
12525
12642
|
`Cannot read the payload from ${source === "-" ? "stdin" : source}: ${describe(error)}`
|
|
@@ -12679,8 +12796,8 @@ function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
|
12679
12796
|
}
|
|
12680
12797
|
|
|
12681
12798
|
// src/commands/backlog/link.ts
|
|
12682
|
-
function fail4(
|
|
12683
|
-
console.log(chalk81.red(
|
|
12799
|
+
function fail4(message3) {
|
|
12800
|
+
console.log(chalk81.red(message3));
|
|
12684
12801
|
return void 0;
|
|
12685
12802
|
}
|
|
12686
12803
|
function parseLinkType(type) {
|
|
@@ -12802,8 +12919,8 @@ Pass the full origin.`
|
|
|
12802
12919
|
}
|
|
12803
12920
|
|
|
12804
12921
|
// src/commands/backlog/move-repo/index.ts
|
|
12805
|
-
function fail5(
|
|
12806
|
-
console.log(chalk84.red(
|
|
12922
|
+
function fail5(message3) {
|
|
12923
|
+
console.log(chalk84.red(message3));
|
|
12807
12924
|
process.exitCode = 1;
|
|
12808
12925
|
}
|
|
12809
12926
|
async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
@@ -12958,11 +13075,11 @@ async function handleLaunchSignal(slashCommand, once) {
|
|
|
12958
13075
|
await next({ allowEdits: true, once });
|
|
12959
13076
|
}
|
|
12960
13077
|
} catch (error) {
|
|
12961
|
-
const
|
|
13078
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
12962
13079
|
console.error(
|
|
12963
13080
|
chalk86.yellow(
|
|
12964
13081
|
`
|
|
12965
|
-
Could not complete post-run step (${
|
|
13082
|
+
Could not complete post-run step (${message3}).
|
|
12966
13083
|
This is usually a transient database/network blip \u2014 the work is saved and the session is safe to resume.`
|
|
12967
13084
|
)
|
|
12968
13085
|
);
|
|
@@ -14334,7 +14451,7 @@ function registerBranch(program2) {
|
|
|
14334
14451
|
}
|
|
14335
14452
|
|
|
14336
14453
|
// src/commands/cliHook/index.ts
|
|
14337
|
-
import { basename as
|
|
14454
|
+
import { basename as basename9 } from "path";
|
|
14338
14455
|
|
|
14339
14456
|
// src/shared/splitCompound.ts
|
|
14340
14457
|
import { parse } from "shell-quote";
|
|
@@ -14520,7 +14637,7 @@ function findBuiltinDenyRaw(rawCommand) {
|
|
|
14520
14637
|
}
|
|
14521
14638
|
|
|
14522
14639
|
// src/shared/isApprovedRead.ts
|
|
14523
|
-
import { resolve as
|
|
14640
|
+
import { resolve as resolve12, sep } from "path";
|
|
14524
14641
|
|
|
14525
14642
|
// src/shared/tokenize.ts
|
|
14526
14643
|
function tokenize(command) {
|
|
@@ -14601,29 +14718,29 @@ function extractGraphqlQuery(args) {
|
|
|
14601
14718
|
}
|
|
14602
14719
|
|
|
14603
14720
|
// src/shared/loadCliReads.ts
|
|
14604
|
-
import { existsSync as
|
|
14605
|
-
import { dirname as
|
|
14721
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25, writeFileSync as writeFileSync22 } from "fs";
|
|
14722
|
+
import { dirname as dirname22, resolve as resolve11 } from "path";
|
|
14606
14723
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
14607
14724
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
14608
|
-
var __dirname4 =
|
|
14725
|
+
var __dirname4 = dirname22(__filename3);
|
|
14609
14726
|
function packageRoot() {
|
|
14610
14727
|
return __dirname4;
|
|
14611
14728
|
}
|
|
14612
14729
|
function readLines(path71) {
|
|
14613
|
-
if (!
|
|
14614
|
-
return
|
|
14730
|
+
if (!existsSync30(path71)) return [];
|
|
14731
|
+
return readFileSync25(path71, "utf8").split("\n").filter((line) => line.trim() !== "");
|
|
14615
14732
|
}
|
|
14616
14733
|
var cachedReads;
|
|
14617
14734
|
var cachedWrites;
|
|
14618
14735
|
function getCliReadsLines() {
|
|
14619
14736
|
if (!cachedReads) {
|
|
14620
|
-
cachedReads = readLines(
|
|
14737
|
+
cachedReads = readLines(resolve11(packageRoot(), "allowed.cli-reads"));
|
|
14621
14738
|
}
|
|
14622
14739
|
return cachedReads;
|
|
14623
14740
|
}
|
|
14624
14741
|
function getCliWritesLines() {
|
|
14625
14742
|
if (!cachedWrites) {
|
|
14626
|
-
cachedWrites = readLines(
|
|
14743
|
+
cachedWrites = readLines(resolve11(packageRoot(), "allowed.cli-writes"));
|
|
14627
14744
|
}
|
|
14628
14745
|
return cachedWrites;
|
|
14629
14746
|
}
|
|
@@ -14632,7 +14749,7 @@ function loadCliReads() {
|
|
|
14632
14749
|
}
|
|
14633
14750
|
function saveCliReads(commands) {
|
|
14634
14751
|
writeFileSync22(
|
|
14635
|
-
|
|
14752
|
+
resolve11(packageRoot(), "allowed.cli-reads"),
|
|
14636
14753
|
`${commands.join("\n")}
|
|
14637
14754
|
`
|
|
14638
14755
|
);
|
|
@@ -14657,14 +14774,14 @@ function findCliWrite(command) {
|
|
|
14657
14774
|
}
|
|
14658
14775
|
|
|
14659
14776
|
// src/shared/readSettingsPerms.ts
|
|
14660
|
-
import { existsSync as
|
|
14777
|
+
import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
|
|
14661
14778
|
import { homedir as homedir14 } from "os";
|
|
14662
|
-
import { join as
|
|
14779
|
+
import { join as join31 } from "path";
|
|
14663
14780
|
function readSettingsPerms(key) {
|
|
14664
14781
|
const paths = [
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
14782
|
+
join31(homedir14(), ".claude", "settings.json"),
|
|
14783
|
+
join31(process.cwd(), ".claude", "settings.json"),
|
|
14784
|
+
join31(process.cwd(), ".claude", "settings.local.json")
|
|
14668
14785
|
];
|
|
14669
14786
|
const entries = [];
|
|
14670
14787
|
for (const p of paths) {
|
|
@@ -14673,9 +14790,9 @@ function readSettingsPerms(key) {
|
|
|
14673
14790
|
return entries;
|
|
14674
14791
|
}
|
|
14675
14792
|
function readPermissionArray(filePath, key) {
|
|
14676
|
-
if (!
|
|
14793
|
+
if (!existsSync31(filePath)) return [];
|
|
14677
14794
|
try {
|
|
14678
|
-
const data = JSON.parse(
|
|
14795
|
+
const data = JSON.parse(readFileSync26(filePath, "utf8"));
|
|
14679
14796
|
const arr = data?.permissions?.[key];
|
|
14680
14797
|
return Array.isArray(arr) ? arr.filter((e) => typeof e === "string") : [];
|
|
14681
14798
|
} catch {
|
|
@@ -14754,19 +14871,19 @@ function isCdToCwd(command) {
|
|
|
14754
14871
|
const parts = command.split(/\s+/);
|
|
14755
14872
|
if (parts[0] !== "cd" || parts.length > 2) return false;
|
|
14756
14873
|
if (parts.length === 1) return false;
|
|
14757
|
-
const resolved =
|
|
14758
|
-
return resolved ===
|
|
14874
|
+
const resolved = resolve12(normalizeMsysPath(parts[1]));
|
|
14875
|
+
return resolved === resolve12(process.cwd());
|
|
14759
14876
|
}
|
|
14760
14877
|
function isCdToReadAllowedDir(command) {
|
|
14761
14878
|
const parts = command.split(/\s+/);
|
|
14762
14879
|
if (parts[0] !== "cd" || parts.length !== 2) return void 0;
|
|
14763
|
-
const target =
|
|
14880
|
+
const target = resolve12(normalizeMsysPath(parts[1]));
|
|
14764
14881
|
for (const entry of readSettingsPerms("allow")) {
|
|
14765
14882
|
const m = entry.match(READ_RE);
|
|
14766
14883
|
if (!m) continue;
|
|
14767
14884
|
const base = globBaseDir(m[1]);
|
|
14768
14885
|
if (!base) continue;
|
|
14769
|
-
const resolved =
|
|
14886
|
+
const resolved = resolve12(normalizeMsysPath(base));
|
|
14770
14887
|
if (target === resolved || target.startsWith(resolved + sep)) {
|
|
14771
14888
|
return `cd to Read-allowed directory: ${entry}`;
|
|
14772
14889
|
}
|
|
@@ -14866,11 +14983,11 @@ function decideCommand(toolName, rawCommand) {
|
|
|
14866
14983
|
// src/commands/cliHook/logDeniedToolCall.ts
|
|
14867
14984
|
import { mkdirSync as mkdirSync12 } from "fs";
|
|
14868
14985
|
import { homedir as homedir15 } from "os";
|
|
14869
|
-
import { join as
|
|
14986
|
+
import { join as join32 } from "path";
|
|
14870
14987
|
import Database from "better-sqlite3";
|
|
14871
14988
|
var _db;
|
|
14872
14989
|
function getDbDir() {
|
|
14873
|
-
return
|
|
14990
|
+
return join32(homedir15(), ".assist");
|
|
14874
14991
|
}
|
|
14875
14992
|
function initSchema(db) {
|
|
14876
14993
|
db.exec(`
|
|
@@ -14889,7 +15006,7 @@ function openPromptsDb(dir) {
|
|
|
14889
15006
|
if (_db) return _db;
|
|
14890
15007
|
const dbDir = dir ?? getDbDir();
|
|
14891
15008
|
mkdirSync12(dbDir, { recursive: true });
|
|
14892
|
-
const db = new Database(
|
|
15009
|
+
const db = new Database(join32(dbDir, "assist.db"));
|
|
14893
15010
|
db.pragma("journal_mode = WAL");
|
|
14894
15011
|
initSchema(db);
|
|
14895
15012
|
_db = db;
|
|
@@ -14939,7 +15056,7 @@ async function cliHook() {
|
|
|
14939
15056
|
logDeniedToolCall({
|
|
14940
15057
|
tool: input.toolName,
|
|
14941
15058
|
command: input.command,
|
|
14942
|
-
repo:
|
|
15059
|
+
repo: basename9(process.cwd()),
|
|
14943
15060
|
sessionId: process.env.CLAUDE_SESSION_ID,
|
|
14944
15061
|
denyReason: decision.permissionDecisionReason
|
|
14945
15062
|
});
|
|
@@ -14985,9 +15102,9 @@ ${reasons.join("\n")}`);
|
|
|
14985
15102
|
}
|
|
14986
15103
|
|
|
14987
15104
|
// src/commands/permitCliReads/index.ts
|
|
14988
|
-
import { existsSync as
|
|
15105
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync13, readFileSync as readFileSync27, writeFileSync as writeFileSync23 } from "fs";
|
|
14989
15106
|
import { homedir as homedir16 } from "os";
|
|
14990
|
-
import { join as
|
|
15107
|
+
import { join as join33 } from "path";
|
|
14991
15108
|
|
|
14992
15109
|
// src/commands/permitCliReads/assertCliExists.ts
|
|
14993
15110
|
function assertCliExists(cli) {
|
|
@@ -15078,12 +15195,12 @@ function hasSubcommands(helpText) {
|
|
|
15078
15195
|
// src/commands/permitCliReads/runHelp.ts
|
|
15079
15196
|
import { exec as exec2 } from "child_process";
|
|
15080
15197
|
function runHelp(args) {
|
|
15081
|
-
return new Promise((
|
|
15198
|
+
return new Promise((resolve21) => {
|
|
15082
15199
|
exec2(
|
|
15083
15200
|
`${args.join(" ")} --help`,
|
|
15084
15201
|
{ encoding: "utf8", timeout: 3e4 },
|
|
15085
15202
|
(_err, stdout, stderr) => {
|
|
15086
|
-
|
|
15203
|
+
resolve21(stdout || stderr || "");
|
|
15087
15204
|
}
|
|
15088
15205
|
);
|
|
15089
15206
|
});
|
|
@@ -15250,15 +15367,15 @@ function updateSettings(cli, commands) {
|
|
|
15250
15367
|
// src/commands/permitCliReads/index.ts
|
|
15251
15368
|
function logPath(cli) {
|
|
15252
15369
|
const safeName = cli.replace(/\s+/g, "-");
|
|
15253
|
-
return
|
|
15370
|
+
return join33(homedir16(), ".assist", `cli-discover-${safeName}.log`);
|
|
15254
15371
|
}
|
|
15255
15372
|
function readCache(cli) {
|
|
15256
15373
|
const path71 = logPath(cli);
|
|
15257
|
-
if (!
|
|
15258
|
-
return
|
|
15374
|
+
if (!existsSync32(path71)) return void 0;
|
|
15375
|
+
return readFileSync27(path71, "utf8");
|
|
15259
15376
|
}
|
|
15260
15377
|
function writeCache(cli, output) {
|
|
15261
|
-
const dir =
|
|
15378
|
+
const dir = join33(homedir16(), ".assist");
|
|
15262
15379
|
mkdirSync13(dir, { recursive: true });
|
|
15263
15380
|
writeFileSync23(logPath(cli), output);
|
|
15264
15381
|
}
|
|
@@ -15311,15 +15428,15 @@ function loadDenyConfig(global) {
|
|
|
15311
15428
|
}
|
|
15312
15429
|
|
|
15313
15430
|
// src/commands/deny/denyAdd.ts
|
|
15314
|
-
function denyAdd(pattern2,
|
|
15431
|
+
function denyAdd(pattern2, message3, options2) {
|
|
15315
15432
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
15316
15433
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
15317
15434
|
console.log(chalk115.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
15318
15435
|
return;
|
|
15319
15436
|
}
|
|
15320
|
-
deny.push({ pattern: pattern2, message:
|
|
15437
|
+
deny.push({ pattern: pattern2, message: message3 });
|
|
15321
15438
|
saveDeny(deny);
|
|
15322
|
-
console.log(chalk115.green(`Added deny rule: ${pattern2} \u2192 ${
|
|
15439
|
+
console.log(chalk115.green(`Added deny rule: ${pattern2} \u2192 ${message3}`));
|
|
15323
15440
|
}
|
|
15324
15441
|
|
|
15325
15442
|
// src/commands/deny/denyList.ts
|
|
@@ -15401,22 +15518,22 @@ function registerCliHook(program2) {
|
|
|
15401
15518
|
}
|
|
15402
15519
|
|
|
15403
15520
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
15404
|
-
import { existsSync as
|
|
15521
|
+
import { existsSync as existsSync34, readFileSync as readFileSync29, unlinkSync as unlinkSync8, writeFileSync as writeFileSync24 } from "fs";
|
|
15405
15522
|
import chalk118 from "chalk";
|
|
15406
15523
|
|
|
15407
15524
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
15408
15525
|
import { homedir as homedir17 } from "os";
|
|
15409
|
-
import { join as
|
|
15526
|
+
import { join as join34 } from "path";
|
|
15410
15527
|
function getRestrictedDir() {
|
|
15411
|
-
return
|
|
15528
|
+
return join34(homedir17(), ".assist", "restricted");
|
|
15412
15529
|
}
|
|
15413
15530
|
function getPinStatePath(pin) {
|
|
15414
|
-
return
|
|
15531
|
+
return join34(getRestrictedDir(), `code-comment-${pin}.json`);
|
|
15415
15532
|
}
|
|
15416
15533
|
|
|
15417
15534
|
// src/commands/codeComment/sweepRestrictedDir.ts
|
|
15418
|
-
import { readdirSync as readdirSync3, statSync as
|
|
15419
|
-
import { join as
|
|
15535
|
+
import { readdirSync as readdirSync3, statSync as statSync5, unlinkSync as unlinkSync7 } from "fs";
|
|
15536
|
+
import { join as join35 } from "path";
|
|
15420
15537
|
var STALE_AFTER_MS = 30 * 60 * 1e3;
|
|
15421
15538
|
function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
15422
15539
|
let entries;
|
|
@@ -15427,9 +15544,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
15427
15544
|
}
|
|
15428
15545
|
const cutoff = Date.now() - STALE_AFTER_MS;
|
|
15429
15546
|
for (const entry of entries) {
|
|
15430
|
-
const path71 =
|
|
15547
|
+
const path71 = join35(dir, entry);
|
|
15431
15548
|
try {
|
|
15432
|
-
if (
|
|
15549
|
+
if (statSync5(path71).mtimeMs < cutoff) unlinkSync7(path71);
|
|
15433
15550
|
} catch {
|
|
15434
15551
|
continue;
|
|
15435
15552
|
}
|
|
@@ -15437,12 +15554,12 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
15437
15554
|
}
|
|
15438
15555
|
|
|
15439
15556
|
// src/commands/codeComment/readPinState.ts
|
|
15440
|
-
import { existsSync as
|
|
15557
|
+
import { existsSync as existsSync33, readFileSync as readFileSync28 } from "fs";
|
|
15441
15558
|
function readPinState(pin) {
|
|
15442
15559
|
const path71 = getPinStatePath(pin);
|
|
15443
|
-
if (!
|
|
15560
|
+
if (!existsSync33(path71)) return void 0;
|
|
15444
15561
|
try {
|
|
15445
|
-
const state = JSON.parse(
|
|
15562
|
+
const state = JSON.parse(readFileSync28(path71, "utf8"));
|
|
15446
15563
|
if (state.pin !== pin) return void 0;
|
|
15447
15564
|
return state;
|
|
15448
15565
|
} catch {
|
|
@@ -15459,12 +15576,12 @@ function codeCommentConfirm(pin) {
|
|
|
15459
15576
|
process.exitCode = 1;
|
|
15460
15577
|
return;
|
|
15461
15578
|
}
|
|
15462
|
-
if (!
|
|
15579
|
+
if (!existsSync34(state.file)) {
|
|
15463
15580
|
console.error(chalk118.red(`Target file no longer exists: ${state.file}`));
|
|
15464
15581
|
process.exitCode = 1;
|
|
15465
15582
|
return;
|
|
15466
15583
|
}
|
|
15467
|
-
const original =
|
|
15584
|
+
const original = readFileSync29(state.file, "utf8");
|
|
15468
15585
|
const lines = original.split("\n");
|
|
15469
15586
|
const index3 = state.line - 1;
|
|
15470
15587
|
if (index3 > lines.length) {
|
|
@@ -16061,10 +16178,10 @@ function formatResultLine(entry, failing) {
|
|
|
16061
16178
|
}
|
|
16062
16179
|
|
|
16063
16180
|
// src/commands/complexity/maintainability/getMaintainabilityGitState.ts
|
|
16064
|
-
import { execSync as
|
|
16181
|
+
import { execSync as execSync35 } from "child_process";
|
|
16065
16182
|
import path28 from "path";
|
|
16066
16183
|
function git3(command) {
|
|
16067
|
-
return
|
|
16184
|
+
return execSync35(command, { encoding: "utf8" });
|
|
16068
16185
|
}
|
|
16069
16186
|
function toAbsolute(root, repoRelative) {
|
|
16070
16187
|
return path28.resolve(root, repoRelative);
|
|
@@ -16481,21 +16598,21 @@ import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync26 } from "fs"
|
|
|
16481
16598
|
import chalk134 from "chalk";
|
|
16482
16599
|
|
|
16483
16600
|
// src/commands/dbMigration/getMigrationPinPath.ts
|
|
16484
|
-
import { join as
|
|
16601
|
+
import { join as join36 } from "path";
|
|
16485
16602
|
function getMigrationPinPath(pin) {
|
|
16486
|
-
return
|
|
16603
|
+
return join36(getRestrictedDir(), `db-migration-pin-${pin}.json`);
|
|
16487
16604
|
}
|
|
16488
16605
|
function getMigrationApprovalPath(migrationId) {
|
|
16489
|
-
return
|
|
16606
|
+
return join36(getRestrictedDir(), `db-migration-approval-${migrationId}.json`);
|
|
16490
16607
|
}
|
|
16491
16608
|
|
|
16492
16609
|
// src/commands/dbMigration/readMigrationPinState.ts
|
|
16493
|
-
import { existsSync as
|
|
16610
|
+
import { existsSync as existsSync35, readFileSync as readFileSync30 } from "fs";
|
|
16494
16611
|
function readMigrationPinState(pin) {
|
|
16495
16612
|
const path71 = getMigrationPinPath(pin);
|
|
16496
|
-
if (!
|
|
16613
|
+
if (!existsSync35(path71)) return void 0;
|
|
16497
16614
|
try {
|
|
16498
|
-
const state = JSON.parse(
|
|
16615
|
+
const state = JSON.parse(readFileSync30(path71, "utf8"));
|
|
16499
16616
|
if (state.pin !== pin) return void 0;
|
|
16500
16617
|
if (!Number.isInteger(state.migrationId)) return void 0;
|
|
16501
16618
|
return state;
|
|
@@ -16582,7 +16699,7 @@ function registerDbMigration(parent) {
|
|
|
16582
16699
|
}
|
|
16583
16700
|
|
|
16584
16701
|
// src/commands/deploy/redirect.ts
|
|
16585
|
-
import { existsSync as
|
|
16702
|
+
import { existsSync as existsSync36, readFileSync as readFileSync31, writeFileSync as writeFileSync28 } from "fs";
|
|
16586
16703
|
import chalk136 from "chalk";
|
|
16587
16704
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
16588
16705
|
if (!window.location.pathname.endsWith('/')) {
|
|
@@ -16591,11 +16708,11 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
16591
16708
|
</script>`;
|
|
16592
16709
|
function redirect() {
|
|
16593
16710
|
const indexPath = "index.html";
|
|
16594
|
-
if (!
|
|
16711
|
+
if (!existsSync36(indexPath)) {
|
|
16595
16712
|
console.log(chalk136.yellow("No index.html found"));
|
|
16596
16713
|
return;
|
|
16597
16714
|
}
|
|
16598
|
-
const content =
|
|
16715
|
+
const content = readFileSync31(indexPath, "utf8");
|
|
16599
16716
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
16600
16717
|
console.log(chalk136.dim("Trailing slash script already present"));
|
|
16601
16718
|
return;
|
|
@@ -16620,35 +16737,35 @@ function registerDeploy(program2) {
|
|
|
16620
16737
|
|
|
16621
16738
|
// src/commands/devlog/list/index.ts
|
|
16622
16739
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
16623
|
-
import { basename as
|
|
16740
|
+
import { basename as basename11 } from "path";
|
|
16624
16741
|
|
|
16625
16742
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
16626
16743
|
import { homedir as homedir18 } from "os";
|
|
16627
|
-
import { join as
|
|
16628
|
-
var BLOG_REPO_ROOT =
|
|
16744
|
+
import { join as join37 } from "path";
|
|
16745
|
+
var BLOG_REPO_ROOT = join37(homedir18(), "git/blog");
|
|
16629
16746
|
function loadBlogSkipDays(repoName) {
|
|
16630
|
-
const config = loadRawYaml(
|
|
16747
|
+
const config = loadRawYaml(join37(BLOG_REPO_ROOT, "assist.yml"));
|
|
16631
16748
|
const devlog = config.devlog;
|
|
16632
16749
|
const skip2 = devlog?.skip;
|
|
16633
16750
|
return new Set(skip2?.[repoName]);
|
|
16634
16751
|
}
|
|
16635
16752
|
|
|
16636
16753
|
// src/commands/devlog/shared.ts
|
|
16637
|
-
import { execSync as
|
|
16754
|
+
import { execSync as execSync36 } from "child_process";
|
|
16638
16755
|
import chalk137 from "chalk";
|
|
16639
16756
|
|
|
16640
16757
|
// src/shared/getRepoName.ts
|
|
16641
|
-
import { existsSync as
|
|
16642
|
-
import { basename as
|
|
16758
|
+
import { existsSync as existsSync37, readFileSync as readFileSync32 } from "fs";
|
|
16759
|
+
import { basename as basename10, join as join38 } from "path";
|
|
16643
16760
|
function getRepoName() {
|
|
16644
16761
|
const config = loadConfig();
|
|
16645
16762
|
if (config.devlog?.name) {
|
|
16646
16763
|
return config.devlog.name;
|
|
16647
16764
|
}
|
|
16648
|
-
const packageJsonPath =
|
|
16649
|
-
if (
|
|
16765
|
+
const packageJsonPath = join38(process.cwd(), "package.json");
|
|
16766
|
+
if (existsSync37(packageJsonPath)) {
|
|
16650
16767
|
try {
|
|
16651
|
-
const content =
|
|
16768
|
+
const content = readFileSync32(packageJsonPath, "utf8");
|
|
16652
16769
|
const pkg = JSON.parse(content);
|
|
16653
16770
|
if (pkg.name) {
|
|
16654
16771
|
return pkg.name;
|
|
@@ -16656,13 +16773,13 @@ function getRepoName() {
|
|
|
16656
16773
|
} catch {
|
|
16657
16774
|
}
|
|
16658
16775
|
}
|
|
16659
|
-
return
|
|
16776
|
+
return basename10(process.cwd());
|
|
16660
16777
|
}
|
|
16661
16778
|
|
|
16662
16779
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
16663
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
16664
|
-
import { join as
|
|
16665
|
-
var DEVLOG_DIR =
|
|
16780
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync33 } from "fs";
|
|
16781
|
+
import { join as join39 } from "path";
|
|
16782
|
+
var DEVLOG_DIR = join39(BLOG_REPO_ROOT, "src/content/devlog");
|
|
16666
16783
|
function extractFrontmatter(content) {
|
|
16667
16784
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
16668
16785
|
return fm?.[1] ?? null;
|
|
@@ -16690,7 +16807,7 @@ function readDevlogFiles(callback) {
|
|
|
16690
16807
|
try {
|
|
16691
16808
|
const files = readdirSync4(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
16692
16809
|
for (const file of files) {
|
|
16693
|
-
const content =
|
|
16810
|
+
const content = readFileSync33(join39(DEVLOG_DIR, file), "utf8");
|
|
16694
16811
|
const parsed = parseFrontmatter(content, file);
|
|
16695
16812
|
if (parsed) callback(parsed);
|
|
16696
16813
|
}
|
|
@@ -16726,7 +16843,7 @@ function loadAllDevlogLatestDates() {
|
|
|
16726
16843
|
// src/commands/devlog/shared.ts
|
|
16727
16844
|
function getCommitFiles(hash) {
|
|
16728
16845
|
try {
|
|
16729
|
-
const output =
|
|
16846
|
+
const output = execSync36(`git show --name-only --format="" ${hash}`, {
|
|
16730
16847
|
encoding: "utf8"
|
|
16731
16848
|
});
|
|
16732
16849
|
return output.trim().split("\n").filter(Boolean);
|
|
@@ -16760,14 +16877,14 @@ function parseGitLogCommits(output, ignore3, afterDate) {
|
|
|
16760
16877
|
const commitsByDate = /* @__PURE__ */ new Map();
|
|
16761
16878
|
for (const line of lines) {
|
|
16762
16879
|
const [date, hash, ...messageParts] = line.split("|");
|
|
16763
|
-
const
|
|
16880
|
+
const message3 = messageParts.join("|");
|
|
16764
16881
|
if (afterDate && date <= afterDate) {
|
|
16765
16882
|
continue;
|
|
16766
16883
|
}
|
|
16767
16884
|
const files = getCommitFiles(hash);
|
|
16768
16885
|
if (!shouldIgnoreCommit(files, ignore3)) {
|
|
16769
16886
|
const existing = commitsByDate.get(date) || [];
|
|
16770
|
-
existing.push({ date, hash, message:
|
|
16887
|
+
existing.push({ date, hash, message: message3, files });
|
|
16771
16888
|
commitsByDate.set(date, existing);
|
|
16772
16889
|
}
|
|
16773
16890
|
}
|
|
@@ -16792,7 +16909,7 @@ function list3(options2) {
|
|
|
16792
16909
|
const config = loadConfig();
|
|
16793
16910
|
const days = options2.days ?? 30;
|
|
16794
16911
|
const ignore3 = options2.ignore ?? config.devlog?.ignore ?? [];
|
|
16795
|
-
const repoName =
|
|
16912
|
+
const repoName = basename11(process.cwd());
|
|
16796
16913
|
const skipDays = loadBlogSkipDays(repoName);
|
|
16797
16914
|
const devlogEntries = loadDevlogEntries(repoName);
|
|
16798
16915
|
const args = ["log"];
|
|
@@ -16822,11 +16939,11 @@ function list3(options2) {
|
|
|
16822
16939
|
}
|
|
16823
16940
|
|
|
16824
16941
|
// src/commands/devlog/getLastVersionInfo.ts
|
|
16825
|
-
import { execFileSync as execFileSync4, execSync as
|
|
16942
|
+
import { execFileSync as execFileSync4, execSync as execSync37 } from "child_process";
|
|
16826
16943
|
import semver from "semver";
|
|
16827
16944
|
function getVersionAtCommit(hash) {
|
|
16828
16945
|
try {
|
|
16829
|
-
const content =
|
|
16946
|
+
const content = execSync37(`git show ${hash}:package.json`, {
|
|
16830
16947
|
encoding: "utf8"
|
|
16831
16948
|
});
|
|
16832
16949
|
const pkg = JSON.parse(content);
|
|
@@ -16999,7 +17116,7 @@ function next2(options2) {
|
|
|
16999
17116
|
}
|
|
17000
17117
|
|
|
17001
17118
|
// src/commands/devlog/repos/index.ts
|
|
17002
|
-
import { execSync as
|
|
17119
|
+
import { execSync as execSync38 } from "child_process";
|
|
17003
17120
|
|
|
17004
17121
|
// src/commands/devlog/repos/printReposTable.ts
|
|
17005
17122
|
import chalk141 from "chalk";
|
|
@@ -17034,7 +17151,7 @@ function getStatus(lastPush, lastDevlog) {
|
|
|
17034
17151
|
return lastDevlog < lastPush ? "outdated" : "ok";
|
|
17035
17152
|
}
|
|
17036
17153
|
function fetchRepos(days, all) {
|
|
17037
|
-
const json =
|
|
17154
|
+
const json = execSync38(
|
|
17038
17155
|
"gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
|
|
17039
17156
|
{ encoding: "utf8" }
|
|
17040
17157
|
);
|
|
@@ -17078,11 +17195,11 @@ function repos(options2) {
|
|
|
17078
17195
|
|
|
17079
17196
|
// src/commands/devlog/skip.ts
|
|
17080
17197
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
17081
|
-
import { join as
|
|
17198
|
+
import { join as join40 } from "path";
|
|
17082
17199
|
import chalk142 from "chalk";
|
|
17083
17200
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
17084
17201
|
function getBlogConfigPath() {
|
|
17085
|
-
return
|
|
17202
|
+
return join40(BLOG_REPO_ROOT, "assist.yml");
|
|
17086
17203
|
}
|
|
17087
17204
|
function skip(date) {
|
|
17088
17205
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -17163,16 +17280,16 @@ function registerDevlog(program2) {
|
|
|
17163
17280
|
|
|
17164
17281
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
17165
17282
|
import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync5 } from "fs";
|
|
17166
|
-
import { join as
|
|
17283
|
+
import { join as join41 } from "path";
|
|
17167
17284
|
import chalk144 from "chalk";
|
|
17168
17285
|
|
|
17169
17286
|
// src/shared/findRepoRoot.ts
|
|
17170
|
-
import { existsSync as
|
|
17287
|
+
import { existsSync as existsSync38 } from "fs";
|
|
17171
17288
|
import path30 from "path";
|
|
17172
17289
|
function findRepoRoot(dir) {
|
|
17173
17290
|
let current = dir;
|
|
17174
17291
|
while (current !== path30.dirname(current)) {
|
|
17175
|
-
if (
|
|
17292
|
+
if (existsSync38(path30.join(current, ".git"))) {
|
|
17176
17293
|
return current;
|
|
17177
17294
|
}
|
|
17178
17295
|
current = path30.dirname(current);
|
|
@@ -17191,7 +17308,7 @@ function isLockedDll(debugDir) {
|
|
|
17191
17308
|
}
|
|
17192
17309
|
for (const file of files) {
|
|
17193
17310
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
17194
|
-
const dllPath =
|
|
17311
|
+
const dllPath = join41(debugDir, file);
|
|
17195
17312
|
try {
|
|
17196
17313
|
const fd = openSync3(dllPath, "r+");
|
|
17197
17314
|
closeSync3(fd);
|
|
@@ -17209,13 +17326,13 @@ function findFirstLockedDll(dir) {
|
|
|
17209
17326
|
return null;
|
|
17210
17327
|
}
|
|
17211
17328
|
if (entries.includes("bin")) {
|
|
17212
|
-
const locked = isLockedDll(
|
|
17329
|
+
const locked = isLockedDll(join41(dir, "bin", "Debug"));
|
|
17213
17330
|
if (locked) return locked;
|
|
17214
17331
|
}
|
|
17215
17332
|
for (const entry of entries) {
|
|
17216
17333
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
17217
17334
|
continue;
|
|
17218
|
-
const found = findFirstLockedDll(
|
|
17335
|
+
const found = findFirstLockedDll(join41(dir, entry));
|
|
17219
17336
|
if (found) return found;
|
|
17220
17337
|
}
|
|
17221
17338
|
return null;
|
|
@@ -17238,11 +17355,11 @@ async function checkBuildLocksCommand() {
|
|
|
17238
17355
|
}
|
|
17239
17356
|
|
|
17240
17357
|
// src/commands/dotnet/buildTree.ts
|
|
17241
|
-
import { readFileSync as
|
|
17358
|
+
import { readFileSync as readFileSync34 } from "fs";
|
|
17242
17359
|
import path31 from "path";
|
|
17243
17360
|
var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
17244
17361
|
function getProjectRefs(csprojPath) {
|
|
17245
|
-
const content =
|
|
17362
|
+
const content = readFileSync34(csprojPath, "utf8");
|
|
17246
17363
|
const refs = [];
|
|
17247
17364
|
for (const match of content.matchAll(PROJECT_REF_RE)) {
|
|
17248
17365
|
refs.push(match[1].replace(/\\/g, "/"));
|
|
@@ -17259,7 +17376,7 @@ function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
|
|
|
17259
17376
|
for (const ref of getProjectRefs(abs)) {
|
|
17260
17377
|
const childAbs = path31.resolve(dir, ref);
|
|
17261
17378
|
try {
|
|
17262
|
-
|
|
17379
|
+
readFileSync34(childAbs);
|
|
17263
17380
|
node.children.push(buildTree(childAbs, repoRoot, visited));
|
|
17264
17381
|
} catch {
|
|
17265
17382
|
node.children.push({
|
|
@@ -17284,7 +17401,7 @@ function collectAllDeps(node) {
|
|
|
17284
17401
|
}
|
|
17285
17402
|
|
|
17286
17403
|
// src/commands/dotnet/findContainingSolutions.ts
|
|
17287
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
17404
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync35, statSync as statSync6 } from "fs";
|
|
17288
17405
|
import path32 from "path";
|
|
17289
17406
|
function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
17290
17407
|
if (depth > maxDepth) return [];
|
|
@@ -17300,7 +17417,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
|
|
|
17300
17417
|
continue;
|
|
17301
17418
|
const full = path32.join(dir, entry);
|
|
17302
17419
|
try {
|
|
17303
|
-
const stat3 =
|
|
17420
|
+
const stat3 = statSync6(full);
|
|
17304
17421
|
if (stat3.isFile() && entry.endsWith(".sln")) {
|
|
17305
17422
|
results.push(full);
|
|
17306
17423
|
} else if (stat3.isDirectory()) {
|
|
@@ -17319,7 +17436,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
|
|
|
17319
17436
|
const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
|
|
17320
17437
|
for (const sln of slnFiles) {
|
|
17321
17438
|
try {
|
|
17322
|
-
const content =
|
|
17439
|
+
const content = readFileSync35(sln, "utf8");
|
|
17323
17440
|
if (pattern2.test(content)) {
|
|
17324
17441
|
matches.push(path32.relative(repoRoot, sln));
|
|
17325
17442
|
}
|
|
@@ -17383,12 +17500,12 @@ function printJson(tree, totalCount, solutions) {
|
|
|
17383
17500
|
}
|
|
17384
17501
|
|
|
17385
17502
|
// src/commands/dotnet/resolveCsproj.ts
|
|
17386
|
-
import { existsSync as
|
|
17503
|
+
import { existsSync as existsSync39 } from "fs";
|
|
17387
17504
|
import path33 from "path";
|
|
17388
17505
|
import chalk146 from "chalk";
|
|
17389
17506
|
function resolveCsproj(csprojPath) {
|
|
17390
17507
|
const resolved = path33.resolve(csprojPath);
|
|
17391
|
-
if (!
|
|
17508
|
+
if (!existsSync39(resolved)) {
|
|
17392
17509
|
console.error(chalk146.red(`File not found: ${resolved}`));
|
|
17393
17510
|
process.exit(1);
|
|
17394
17511
|
}
|
|
@@ -17414,7 +17531,7 @@ async function deps(csprojPath, options2) {
|
|
|
17414
17531
|
}
|
|
17415
17532
|
|
|
17416
17533
|
// src/commands/dotnet/getChangedCsFiles.ts
|
|
17417
|
-
import { execSync as
|
|
17534
|
+
import { execSync as execSync39 } from "child_process";
|
|
17418
17535
|
var SCOPE_ALL = "all";
|
|
17419
17536
|
var SCOPE_BASE = "base:";
|
|
17420
17537
|
var SCOPE_COMMIT = "commit:";
|
|
@@ -17438,7 +17555,7 @@ function getChangedCsFiles(scope) {
|
|
|
17438
17555
|
} else {
|
|
17439
17556
|
cmd = "git diff --name-only HEAD";
|
|
17440
17557
|
}
|
|
17441
|
-
const output =
|
|
17558
|
+
const output = execSync39(cmd, { encoding: "utf8" }).trim();
|
|
17442
17559
|
if (output === "") return [];
|
|
17443
17560
|
return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
|
|
17444
17561
|
}
|
|
@@ -17556,17 +17673,17 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
17556
17673
|
}
|
|
17557
17674
|
|
|
17558
17675
|
// src/commands/dotnet/resolveSolution.ts
|
|
17559
|
-
import { existsSync as
|
|
17676
|
+
import { existsSync as existsSync40 } from "fs";
|
|
17560
17677
|
import path34 from "path";
|
|
17561
17678
|
import chalk150 from "chalk";
|
|
17562
17679
|
|
|
17563
17680
|
// src/commands/dotnet/findSolution.ts
|
|
17564
17681
|
import { readdirSync as readdirSync7 } from "fs";
|
|
17565
|
-
import { dirname as
|
|
17682
|
+
import { dirname as dirname23, join as join42 } from "path";
|
|
17566
17683
|
import chalk149 from "chalk";
|
|
17567
17684
|
function findSlnInDir(dir) {
|
|
17568
17685
|
try {
|
|
17569
|
-
return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
17686
|
+
return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) => join42(dir, f));
|
|
17570
17687
|
} catch {
|
|
17571
17688
|
return [];
|
|
17572
17689
|
}
|
|
@@ -17587,7 +17704,7 @@ function findSolution() {
|
|
|
17587
17704
|
process.exit(1);
|
|
17588
17705
|
}
|
|
17589
17706
|
if (current === ceiling) break;
|
|
17590
|
-
current =
|
|
17707
|
+
current = dirname23(current);
|
|
17591
17708
|
}
|
|
17592
17709
|
console.error(chalk149.red("No .sln file found between cwd and repo root"));
|
|
17593
17710
|
process.exit(1);
|
|
@@ -17597,7 +17714,7 @@ function findSolution() {
|
|
|
17597
17714
|
function resolveSolution(sln) {
|
|
17598
17715
|
if (sln) {
|
|
17599
17716
|
const resolved = path34.resolve(sln);
|
|
17600
|
-
if (!
|
|
17717
|
+
if (!existsSync40(resolved)) {
|
|
17601
17718
|
console.error(chalk150.red(`Solution file not found: ${resolved}`));
|
|
17602
17719
|
process.exit(1);
|
|
17603
17720
|
}
|
|
@@ -17636,14 +17753,14 @@ function parseInspectReport(json) {
|
|
|
17636
17753
|
}
|
|
17637
17754
|
|
|
17638
17755
|
// src/commands/dotnet/runInspectCode.ts
|
|
17639
|
-
import { execSync as
|
|
17640
|
-
import { existsSync as
|
|
17756
|
+
import { execSync as execSync40 } from "child_process";
|
|
17757
|
+
import { existsSync as existsSync41, readFileSync as readFileSync36, unlinkSync as unlinkSync10 } from "fs";
|
|
17641
17758
|
import { tmpdir as tmpdir4 } from "os";
|
|
17642
17759
|
import path35 from "path";
|
|
17643
17760
|
import chalk151 from "chalk";
|
|
17644
17761
|
function assertJbInstalled() {
|
|
17645
17762
|
try {
|
|
17646
|
-
|
|
17763
|
+
execSync40("jb inspectcode --version", { stdio: "pipe" });
|
|
17647
17764
|
} catch {
|
|
17648
17765
|
console.error(chalk151.red("jb is not installed. Install with:"));
|
|
17649
17766
|
console.error(
|
|
@@ -17657,7 +17774,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
17657
17774
|
const includeFlag = include ? ` --include="${include}"` : "";
|
|
17658
17775
|
const sweaFlag = swea ? " --swea" : "";
|
|
17659
17776
|
try {
|
|
17660
|
-
|
|
17777
|
+
execSync40(
|
|
17661
17778
|
`jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
|
|
17662
17779
|
{ stdio: "pipe" }
|
|
17663
17780
|
);
|
|
@@ -17668,17 +17785,17 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
17668
17785
|
console.error(chalk151.red("jb inspectcode failed"));
|
|
17669
17786
|
process.exit(1);
|
|
17670
17787
|
}
|
|
17671
|
-
if (!
|
|
17788
|
+
if (!existsSync41(reportPath)) {
|
|
17672
17789
|
console.error(chalk151.red("Report file not generated"));
|
|
17673
17790
|
process.exit(1);
|
|
17674
17791
|
}
|
|
17675
|
-
const xml =
|
|
17792
|
+
const xml = readFileSync36(reportPath, "utf8");
|
|
17676
17793
|
unlinkSync10(reportPath);
|
|
17677
17794
|
return xml;
|
|
17678
17795
|
}
|
|
17679
17796
|
|
|
17680
17797
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
17681
|
-
import { execSync as
|
|
17798
|
+
import { execSync as execSync41 } from "child_process";
|
|
17682
17799
|
import chalk152 from "chalk";
|
|
17683
17800
|
function resolveMsbuildPath() {
|
|
17684
17801
|
const { run: run4 } = loadConfig();
|
|
@@ -17689,7 +17806,7 @@ function resolveMsbuildPath() {
|
|
|
17689
17806
|
function assertMsbuildInstalled() {
|
|
17690
17807
|
const msbuild = resolveMsbuildPath();
|
|
17691
17808
|
try {
|
|
17692
|
-
|
|
17809
|
+
execSync41(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
17693
17810
|
} catch {
|
|
17694
17811
|
console.error(chalk152.red(`msbuild not found at: ${msbuild}`));
|
|
17695
17812
|
console.error(
|
|
@@ -17715,7 +17832,7 @@ function runRoslynInspect(slnPath) {
|
|
|
17715
17832
|
const msbuild = resolveMsbuildPath();
|
|
17716
17833
|
let output;
|
|
17717
17834
|
try {
|
|
17718
|
-
output =
|
|
17835
|
+
output = execSync41(
|
|
17719
17836
|
`"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
|
|
17720
17837
|
{ encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
|
|
17721
17838
|
);
|
|
@@ -17931,11 +18048,11 @@ function decideCommentGuard(input, existingContent) {
|
|
|
17931
18048
|
}
|
|
17932
18049
|
|
|
17933
18050
|
// src/commands/dbMigration/consumeMigrationApproval.ts
|
|
17934
|
-
import { existsSync as
|
|
18051
|
+
import { existsSync as existsSync42, unlinkSync as unlinkSync11 } from "fs";
|
|
17935
18052
|
function consumeMigrationApproval(migrationId) {
|
|
17936
18053
|
sweepRestrictedDir();
|
|
17937
18054
|
const path71 = getMigrationApprovalPath(migrationId);
|
|
17938
|
-
if (!
|
|
18055
|
+
if (!existsSync42(path71)) return false;
|
|
17939
18056
|
try {
|
|
17940
18057
|
unlinkSync11(path71);
|
|
17941
18058
|
return true;
|
|
@@ -18055,7 +18172,7 @@ function aggregateCommitters(authorLists) {
|
|
|
18055
18172
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
18056
18173
|
import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
18057
18174
|
import { tmpdir as tmpdir5 } from "os";
|
|
18058
|
-
import { join as
|
|
18175
|
+
import { join as join43 } from "path";
|
|
18059
18176
|
function buildArgs2(queryFile, vars) {
|
|
18060
18177
|
const args = ["api", "graphql", "-F", `query=@${queryFile}`];
|
|
18061
18178
|
for (const [key, value] of Object.entries(vars)) {
|
|
@@ -18080,7 +18197,7 @@ function throwOnGraphqlErrors(stdout) {
|
|
|
18080
18197
|
throw new Error(messages || "GraphQL request returned errors");
|
|
18081
18198
|
}
|
|
18082
18199
|
function runGhGraphql(mutation, vars) {
|
|
18083
|
-
const queryFile =
|
|
18200
|
+
const queryFile = join43(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
18084
18201
|
writeFileSync30(queryFile, mutation);
|
|
18085
18202
|
try {
|
|
18086
18203
|
const result = spawnSync4("gh", buildArgs2(queryFile, vars), {
|
|
@@ -18267,24 +18384,24 @@ async function countPendingHandovers(orm, origin) {
|
|
|
18267
18384
|
|
|
18268
18385
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
18269
18386
|
import {
|
|
18270
|
-
existsSync as
|
|
18387
|
+
existsSync as existsSync43,
|
|
18271
18388
|
readdirSync as readdirSync8,
|
|
18272
|
-
readFileSync as
|
|
18389
|
+
readFileSync as readFileSync37,
|
|
18273
18390
|
rmSync as rmSync3,
|
|
18274
|
-
statSync as
|
|
18391
|
+
statSync as statSync7
|
|
18275
18392
|
} from "fs";
|
|
18276
|
-
import { basename as
|
|
18393
|
+
import { basename as basename12, join as join46 } from "path";
|
|
18277
18394
|
|
|
18278
18395
|
// src/commands/handover/getHandoverPath.ts
|
|
18279
|
-
import { join as
|
|
18396
|
+
import { join as join44 } from "path";
|
|
18280
18397
|
function getHandoverPath(cwd = process.cwd()) {
|
|
18281
|
-
return
|
|
18398
|
+
return join44(cwd, ".assist", "HANDOVER.md");
|
|
18282
18399
|
}
|
|
18283
18400
|
|
|
18284
18401
|
// src/commands/handover/getHandoversDir.ts
|
|
18285
|
-
import { join as
|
|
18402
|
+
import { join as join45 } from "path";
|
|
18286
18403
|
function getHandoversDir(cwd = process.cwd()) {
|
|
18287
|
-
return
|
|
18404
|
+
return join45(cwd, ".assist", "handovers");
|
|
18288
18405
|
}
|
|
18289
18406
|
|
|
18290
18407
|
// src/commands/handover/parseArchiveTimestamp.ts
|
|
@@ -18322,17 +18439,17 @@ function summariseHandoverContent(content) {
|
|
|
18322
18439
|
|
|
18323
18440
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
18324
18441
|
function collectMarkdown(dir) {
|
|
18325
|
-
if (!
|
|
18442
|
+
if (!existsSync43(dir)) return [];
|
|
18326
18443
|
const out = [];
|
|
18327
18444
|
for (const entry of readdirSync8(dir, { withFileTypes: true })) {
|
|
18328
|
-
const full =
|
|
18445
|
+
const full = join46(dir, entry.name);
|
|
18329
18446
|
if (entry.isDirectory()) out.push(...collectMarkdown(full));
|
|
18330
18447
|
else if (entry.isFile() && entry.name.endsWith(".md")) out.push(full);
|
|
18331
18448
|
}
|
|
18332
18449
|
return out;
|
|
18333
18450
|
}
|
|
18334
18451
|
async function migrateFile(orm, origin, file, createdAt) {
|
|
18335
|
-
const content =
|
|
18452
|
+
const content = readFileSync37(file, "utf8");
|
|
18336
18453
|
await saveHandover(orm, {
|
|
18337
18454
|
origin,
|
|
18338
18455
|
summary: summariseHandoverContent(content),
|
|
@@ -18344,13 +18461,13 @@ async function migrateFile(orm, origin, file, createdAt) {
|
|
|
18344
18461
|
async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
|
|
18345
18462
|
let migrated = 0;
|
|
18346
18463
|
for (const file of collectMarkdown(getHandoversDir(cwd))) {
|
|
18347
|
-
const createdAt = parseArchiveTimestamp(
|
|
18464
|
+
const createdAt = parseArchiveTimestamp(basename12(file)) ?? statSync7(file).mtime;
|
|
18348
18465
|
await migrateFile(orm, origin, file, createdAt);
|
|
18349
18466
|
migrated++;
|
|
18350
18467
|
}
|
|
18351
18468
|
const handoverPath = getHandoverPath(cwd);
|
|
18352
|
-
if (
|
|
18353
|
-
await migrateFile(orm, origin, handoverPath,
|
|
18469
|
+
if (existsSync43(handoverPath)) {
|
|
18470
|
+
await migrateFile(orm, origin, handoverPath, statSync7(handoverPath).mtime);
|
|
18354
18471
|
migrated++;
|
|
18355
18472
|
}
|
|
18356
18473
|
return migrated;
|
|
@@ -18380,10 +18497,10 @@ function advisory(count8) {
|
|
|
18380
18497
|
const noun = count8 === 1 ? "handover" : "handovers";
|
|
18381
18498
|
return `${count8} unrecalled ${noun} for this repo. Run /recall to load.`;
|
|
18382
18499
|
}
|
|
18383
|
-
function emit2(
|
|
18500
|
+
function emit2(message3) {
|
|
18384
18501
|
const json = JSON.stringify({
|
|
18385
18502
|
hookSpecificOutput: { hookEventName: "SessionStart" },
|
|
18386
|
-
systemMessage:
|
|
18503
|
+
systemMessage: message3
|
|
18387
18504
|
});
|
|
18388
18505
|
console.log(json);
|
|
18389
18506
|
return json;
|
|
@@ -18562,16 +18679,16 @@ function acceptanceCriteria(issueKey) {
|
|
|
18562
18679
|
}
|
|
18563
18680
|
|
|
18564
18681
|
// src/commands/jira/jiraAuth.ts
|
|
18565
|
-
import { execSync as
|
|
18682
|
+
import { execSync as execSync42 } from "child_process";
|
|
18566
18683
|
|
|
18567
18684
|
// src/shared/promptInput.ts
|
|
18568
18685
|
import Enquirer from "enquirer";
|
|
18569
18686
|
var prompts = Enquirer;
|
|
18570
|
-
async function promptInput(name,
|
|
18571
|
-
return exitOnCancel(new prompts.Input({ name, message:
|
|
18687
|
+
async function promptInput(name, message3, initial) {
|
|
18688
|
+
return exitOnCancel(new prompts.Input({ name, message: message3, initial }).run());
|
|
18572
18689
|
}
|
|
18573
|
-
async function promptPassword(name,
|
|
18574
|
-
return exitOnCancel(new prompts.Password({ name, message:
|
|
18690
|
+
async function promptPassword(name, message3) {
|
|
18691
|
+
return exitOnCancel(new prompts.Password({ name, message: message3 }).run());
|
|
18575
18692
|
}
|
|
18576
18693
|
|
|
18577
18694
|
// src/commands/jira/jiraAuth.ts
|
|
@@ -18597,7 +18714,7 @@ async function jiraAuth() {
|
|
|
18597
18714
|
console.error("All fields are required.");
|
|
18598
18715
|
process.exit(1);
|
|
18599
18716
|
}
|
|
18600
|
-
|
|
18717
|
+
execSync42(`acli jira auth login --site ${site} --email "${email}" --token`, {
|
|
18601
18718
|
encoding: "utf8",
|
|
18602
18719
|
input: token,
|
|
18603
18720
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -18698,8 +18815,8 @@ import chalk158 from "chalk";
|
|
|
18698
18815
|
var RING_CAPACITY = 1e3;
|
|
18699
18816
|
var ring = [];
|
|
18700
18817
|
var sink;
|
|
18701
|
-
function daemonLog(
|
|
18702
|
-
emit3(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${
|
|
18818
|
+
function daemonLog(message3) {
|
|
18819
|
+
emit3(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message3}`);
|
|
18703
18820
|
}
|
|
18704
18821
|
function relayDaemonLog(line) {
|
|
18705
18822
|
emit3(`[windows] ${line}`);
|
|
@@ -18718,18 +18835,18 @@ function recentDaemonLogLines() {
|
|
|
18718
18835
|
}
|
|
18719
18836
|
|
|
18720
18837
|
// src/commands/sessions/daemon/worktree/createWorktree.ts
|
|
18721
|
-
import { existsSync as
|
|
18722
|
-
import { basename as
|
|
18838
|
+
import { existsSync as existsSync44 } from "fs";
|
|
18839
|
+
import { basename as basename14, dirname as dirname24 } from "path";
|
|
18723
18840
|
|
|
18724
18841
|
// src/commands/sessions/daemon/worktree/planAllocation.ts
|
|
18725
|
-
import { basename as
|
|
18842
|
+
import { basename as basename13, join as join47 } from "path";
|
|
18726
18843
|
function planAllocation(clone, boundTreeRoots2) {
|
|
18727
18844
|
return boundTreeRoots2.has(clone) ? "spill" : "primary";
|
|
18728
18845
|
}
|
|
18729
18846
|
function nextWorktreePath(clone, base, isTaken) {
|
|
18730
|
-
const name =
|
|
18847
|
+
const name = basename13(clone);
|
|
18731
18848
|
for (let n = 2; n < 1e3; n++) {
|
|
18732
|
-
const candidate =
|
|
18849
|
+
const candidate = join47(base, `${name}-${n}`);
|
|
18733
18850
|
if (!isTaken(candidate)) return candidate;
|
|
18734
18851
|
}
|
|
18735
18852
|
throw new Error(`no free worktree suffix for ${clone}`);
|
|
@@ -18762,13 +18879,13 @@ function cloneHead(clone) {
|
|
|
18762
18879
|
|
|
18763
18880
|
// src/commands/sessions/daemon/worktree/createWorktree.ts
|
|
18764
18881
|
function createWorktree(clone, strategy, boundTreeRoots2) {
|
|
18765
|
-
const base = strategy.root ? expandTilde2(strategy.root) :
|
|
18882
|
+
const base = strategy.root ? expandTilde2(strategy.root) : dirname24(clone);
|
|
18766
18883
|
const registered = new Set(listWorktreePaths(clone));
|
|
18767
18884
|
const branches = new Set(listLocalBranches(clone));
|
|
18768
18885
|
const path71 = nextWorktreePath(
|
|
18769
18886
|
clone,
|
|
18770
18887
|
base,
|
|
18771
|
-
(candidate) => registered.has(candidate) ||
|
|
18888
|
+
(candidate) => registered.has(candidate) || existsSync44(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename14(candidate))
|
|
18772
18889
|
);
|
|
18773
18890
|
const start3 = worktreeStartPoint(clone, strategy.trunk);
|
|
18774
18891
|
gitSync(clone, [
|
|
@@ -18776,19 +18893,19 @@ function createWorktree(clone, strategy, boundTreeRoots2) {
|
|
|
18776
18893
|
"add",
|
|
18777
18894
|
start3.track ? "--track" : "--no-track",
|
|
18778
18895
|
"-b",
|
|
18779
|
-
|
|
18896
|
+
basename14(path71),
|
|
18780
18897
|
path71,
|
|
18781
18898
|
start3.ref
|
|
18782
18899
|
]);
|
|
18783
18900
|
recordWorktree(path71, clone, getCurrentOrigin(clone));
|
|
18784
18901
|
daemonLog(
|
|
18785
|
-
start3.track ? `worktree allocated ${path71} (branch ${
|
|
18902
|
+
start3.track ? `worktree allocated ${path71} (branch ${basename14(path71)} tracking ${start3.ref}) for clone ${clone}` : `worktree allocated ${path71} (branch ${basename14(path71)} off ${start3.ref}, no mainline tracking) for clone ${clone}`
|
|
18786
18903
|
);
|
|
18787
18904
|
return path71;
|
|
18788
18905
|
}
|
|
18789
18906
|
|
|
18790
18907
|
// src/commands/sessions/daemon/worktree/treeDurability.ts
|
|
18791
|
-
import { existsSync as
|
|
18908
|
+
import { existsSync as existsSync45 } from "fs";
|
|
18792
18909
|
function treeDurability(state) {
|
|
18793
18910
|
if (state.dirty) return { durable: false, reason: "uncommitted changes" };
|
|
18794
18911
|
if (state.localOnlyCommits)
|
|
@@ -18818,14 +18935,14 @@ function* durabilityProbes() {
|
|
|
18818
18935
|
});
|
|
18819
18936
|
}
|
|
18820
18937
|
async function checkDurability(cwd) {
|
|
18821
|
-
if (!
|
|
18938
|
+
if (!existsSync45(cwd)) return { durable: true };
|
|
18822
18939
|
const probes = durabilityProbes();
|
|
18823
18940
|
let step2 = probes.next();
|
|
18824
18941
|
while (!step2.done) step2 = probes.next(await gitResult(cwd, step2.value));
|
|
18825
18942
|
return step2.value;
|
|
18826
18943
|
}
|
|
18827
18944
|
function checkDurabilitySync(cwd) {
|
|
18828
|
-
if (!
|
|
18945
|
+
if (!existsSync45(cwd)) return { durable: true };
|
|
18829
18946
|
const probes = durabilityProbes();
|
|
18830
18947
|
let step2 = probes.next();
|
|
18831
18948
|
while (!step2.done) step2 = probes.next(gitSyncResult(cwd, step2.value));
|
|
@@ -18987,20 +19104,20 @@ function persistedTreeRoots() {
|
|
|
18987
19104
|
}
|
|
18988
19105
|
|
|
18989
19106
|
// src/commands/sessions/daemon/worktree/seedWorktree.ts
|
|
18990
|
-
import { copyFileSync, existsSync as
|
|
18991
|
-
import { dirname as
|
|
19107
|
+
import { copyFileSync, existsSync as existsSync47, mkdirSync as mkdirSync16 } from "fs";
|
|
19108
|
+
import { dirname as dirname25, join as join49 } from "path";
|
|
18992
19109
|
|
|
18993
19110
|
// src/commands/sessions/daemon/worktree/runInstall.ts
|
|
18994
19111
|
import { spawn as spawn5 } from "child_process";
|
|
18995
19112
|
|
|
18996
19113
|
// src/commands/sessions/daemon/worktree/resolveInstallCommand.ts
|
|
18997
|
-
import { existsSync as
|
|
18998
|
-
import { join as
|
|
19114
|
+
import { existsSync as existsSync46 } from "fs";
|
|
19115
|
+
import { join as join48 } from "path";
|
|
18999
19116
|
function detectInstallCommand(repoRoot) {
|
|
19000
|
-
if (!
|
|
19001
|
-
if (
|
|
19002
|
-
if (
|
|
19003
|
-
if (
|
|
19117
|
+
if (!existsSync46(join48(repoRoot, "package.json"))) return null;
|
|
19118
|
+
if (existsSync46(join48(repoRoot, "pnpm-lock.yaml"))) return "pnpm install";
|
|
19119
|
+
if (existsSync46(join48(repoRoot, "yarn.lock"))) return "yarn install";
|
|
19120
|
+
if (existsSync46(join48(repoRoot, "bun.lockb"))) return "bun install";
|
|
19004
19121
|
return "npm install";
|
|
19005
19122
|
}
|
|
19006
19123
|
function resolveInstallCommand(repoRoot, install) {
|
|
@@ -19102,21 +19219,21 @@ function seedWorktree(worktreePath, clone, onSeeded = () => {
|
|
|
19102
19219
|
}
|
|
19103
19220
|
function copyConfigFiles(worktreePath, clone, copy) {
|
|
19104
19221
|
for (const rel of copy) {
|
|
19105
|
-
const src =
|
|
19106
|
-
if (!
|
|
19107
|
-
const dest =
|
|
19222
|
+
const src = join49(clone, rel);
|
|
19223
|
+
if (!existsSync47(src)) continue;
|
|
19224
|
+
const dest = join49(worktreePath, rel);
|
|
19108
19225
|
try {
|
|
19109
|
-
mkdirSync16(
|
|
19226
|
+
mkdirSync16(dirname25(dest), { recursive: true });
|
|
19110
19227
|
copyFileSync(src, dest);
|
|
19111
19228
|
daemonLog(`worktree ${worktreePath} seeded ${rel}`);
|
|
19112
19229
|
} catch (error) {
|
|
19113
19230
|
daemonLog(
|
|
19114
|
-
`worktree ${worktreePath} failed to seed ${rel}: ${
|
|
19231
|
+
`worktree ${worktreePath} failed to seed ${rel}: ${message2(error)}`
|
|
19115
19232
|
);
|
|
19116
19233
|
}
|
|
19117
19234
|
}
|
|
19118
19235
|
}
|
|
19119
|
-
function
|
|
19236
|
+
function message2(error) {
|
|
19120
19237
|
return error instanceof Error ? error.message : String(error);
|
|
19121
19238
|
}
|
|
19122
19239
|
|
|
@@ -19127,7 +19244,7 @@ function placedByDaemon() {
|
|
|
19127
19244
|
function seed(worktreePath, clone) {
|
|
19128
19245
|
console.log(`Preparing ${worktreePath}\u2026`);
|
|
19129
19246
|
return new Promise(
|
|
19130
|
-
(
|
|
19247
|
+
(resolve21) => seedWorktree(worktreePath, clone, resolve21)
|
|
19131
19248
|
);
|
|
19132
19249
|
}
|
|
19133
19250
|
async function moveToPrCheckoutTree() {
|
|
@@ -19175,11 +19292,11 @@ function worktreeHoldingBranch(cwd, branch2) {
|
|
|
19175
19292
|
}
|
|
19176
19293
|
|
|
19177
19294
|
// src/commands/review/checkoutPr.ts
|
|
19178
|
-
function
|
|
19295
|
+
function currentBranch3() {
|
|
19179
19296
|
return gitSyncOrNull(process.cwd(), ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
19180
19297
|
}
|
|
19181
19298
|
function moveToExistingCheckout(number, headRef) {
|
|
19182
|
-
if (
|
|
19299
|
+
if (currentBranch3() === headRef) {
|
|
19183
19300
|
console.log(`Already on ${headRef} for PR #${number}; reviewing here.`);
|
|
19184
19301
|
return true;
|
|
19185
19302
|
}
|
|
@@ -19273,12 +19390,12 @@ function registerList(program2) {
|
|
|
19273
19390
|
|
|
19274
19391
|
// src/commands/mermaid/index.ts
|
|
19275
19392
|
import { mkdirSync as mkdirSync17, readdirSync as readdirSync9 } from "fs";
|
|
19276
|
-
import { resolve as
|
|
19393
|
+
import { resolve as resolve14 } from "path";
|
|
19277
19394
|
import chalk161 from "chalk";
|
|
19278
19395
|
|
|
19279
19396
|
// src/commands/mermaid/exportFile.ts
|
|
19280
|
-
import { readFileSync as
|
|
19281
|
-
import { basename as
|
|
19397
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync31 } from "fs";
|
|
19398
|
+
import { basename as basename15, extname as extname2, resolve as resolve13 } from "path";
|
|
19282
19399
|
import chalk160 from "chalk";
|
|
19283
19400
|
|
|
19284
19401
|
// src/commands/mermaid/renderBlock.ts
|
|
@@ -19303,9 +19420,9 @@ async function renderBlock(krokiUrl, source) {
|
|
|
19303
19420
|
|
|
19304
19421
|
// src/commands/mermaid/exportFile.ts
|
|
19305
19422
|
async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
19306
|
-
const content =
|
|
19423
|
+
const content = readFileSync38(file, "utf8");
|
|
19307
19424
|
const blocks = extractMermaidBlocks(content);
|
|
19308
|
-
const stem =
|
|
19425
|
+
const stem = basename15(file, extname2(file));
|
|
19309
19426
|
if (onlyIndex !== void 0) {
|
|
19310
19427
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
19311
19428
|
console.error(
|
|
@@ -19326,7 +19443,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
19326
19443
|
for (const [i, source] of blocks.entries()) {
|
|
19327
19444
|
const idx = i + 1;
|
|
19328
19445
|
if (onlyIndex !== void 0 && idx !== onlyIndex) continue;
|
|
19329
|
-
const outPath =
|
|
19446
|
+
const outPath = resolve13(outDir, `${stem}-${idx}.svg`);
|
|
19330
19447
|
const svg = await renderBlock(krokiUrl, source);
|
|
19331
19448
|
writeFileSync31(outPath, svg, "utf8");
|
|
19332
19449
|
console.log(chalk160.green(` \u2192 ${outPath}`));
|
|
@@ -19340,7 +19457,7 @@ function extractMermaidBlocks(markdown) {
|
|
|
19340
19457
|
// src/commands/mermaid/index.ts
|
|
19341
19458
|
async function mermaidExport(file, options2 = {}) {
|
|
19342
19459
|
const { mermaid } = loadConfig();
|
|
19343
|
-
const outDir =
|
|
19460
|
+
const outDir = resolve14(process.cwd(), options2.out ?? ".");
|
|
19344
19461
|
mkdirSync17(outDir, { recursive: true });
|
|
19345
19462
|
if (options2.index !== void 0) {
|
|
19346
19463
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
@@ -19388,7 +19505,7 @@ function registerMermaid(program2) {
|
|
|
19388
19505
|
// src/commands/netcap/netcap.ts
|
|
19389
19506
|
import { mkdir as mkdir4 } from "fs/promises";
|
|
19390
19507
|
import { createServer as createServer2 } from "http";
|
|
19391
|
-
import { dirname as
|
|
19508
|
+
import { dirname as dirname27 } from "path";
|
|
19392
19509
|
import chalk163 from "chalk";
|
|
19393
19510
|
|
|
19394
19511
|
// src/commands/netcap/corsHeaders.ts
|
|
@@ -19467,15 +19584,15 @@ function createNetcapHandler(options2) {
|
|
|
19467
19584
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
19468
19585
|
import { cp, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
19469
19586
|
import { networkInterfaces } from "os";
|
|
19470
|
-
import { join as
|
|
19587
|
+
import { join as join51 } from "path";
|
|
19471
19588
|
import chalk162 from "chalk";
|
|
19472
19589
|
|
|
19473
19590
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
19474
|
-
import { dirname as
|
|
19591
|
+
import { dirname as dirname26, join as join50 } from "path";
|
|
19475
19592
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
19476
|
-
var moduleDir =
|
|
19593
|
+
var moduleDir = dirname26(fileURLToPath6(import.meta.url));
|
|
19477
19594
|
function netcapExtensionDir() {
|
|
19478
|
-
return
|
|
19595
|
+
return join50(moduleDir, "commands", "netcap", "netcap-extension");
|
|
19479
19596
|
}
|
|
19480
19597
|
|
|
19481
19598
|
// src/commands/netcap/prepareExtensionForLoad.ts
|
|
@@ -19490,7 +19607,7 @@ function lanIPv4() {
|
|
|
19490
19607
|
return void 0;
|
|
19491
19608
|
}
|
|
19492
19609
|
async function configureBackground(dir, host, port, filter) {
|
|
19493
|
-
const file =
|
|
19610
|
+
const file = join51(dir, "background.js");
|
|
19494
19611
|
const source = await readFile3(file, "utf8");
|
|
19495
19612
|
await writeFile3(
|
|
19496
19613
|
file,
|
|
@@ -19530,20 +19647,20 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
19530
19647
|
}
|
|
19531
19648
|
|
|
19532
19649
|
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
19533
|
-
import { isAbsolute as
|
|
19650
|
+
import { isAbsolute as isAbsolute3, join as join53, resolve as resolve15 } from "path";
|
|
19534
19651
|
|
|
19535
19652
|
// src/commands/netcap/defaultCapturePath.ts
|
|
19536
19653
|
import { homedir as homedir19 } from "os";
|
|
19537
|
-
import { join as
|
|
19654
|
+
import { join as join52 } from "path";
|
|
19538
19655
|
function defaultCapturePath() {
|
|
19539
|
-
return
|
|
19656
|
+
return join52(homedir19(), ".assist", "netcap", "capture.jsonl");
|
|
19540
19657
|
}
|
|
19541
19658
|
|
|
19542
19659
|
// src/commands/netcap/resolveNetcapOutPath.ts
|
|
19543
19660
|
function resolveNetcapOutPath(out) {
|
|
19544
19661
|
if (!out) return defaultCapturePath();
|
|
19545
|
-
const dir =
|
|
19546
|
-
return
|
|
19662
|
+
const dir = isAbsolute3(out) ? out : resolve15(process.cwd(), out);
|
|
19663
|
+
return join53(dir, "capture.jsonl");
|
|
19547
19664
|
}
|
|
19548
19665
|
|
|
19549
19666
|
// src/commands/netcap/netcap.ts
|
|
@@ -19551,7 +19668,7 @@ async function netcap(options2) {
|
|
|
19551
19668
|
const port = Number(options2.port);
|
|
19552
19669
|
const outPath = resolveNetcapOutPath(options2.out);
|
|
19553
19670
|
const filter = options2.filter ?? "";
|
|
19554
|
-
await mkdir4(
|
|
19671
|
+
await mkdir4(dirname27(outPath), { recursive: true });
|
|
19555
19672
|
const extensionPath = await prepareExtensionForLoad(port, filter);
|
|
19556
19673
|
let count8 = 0;
|
|
19557
19674
|
const handler = createNetcapHandler({
|
|
@@ -19590,11 +19707,11 @@ netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} t
|
|
|
19590
19707
|
|
|
19591
19708
|
// src/commands/netcap/netcapExtract.ts
|
|
19592
19709
|
import { writeFileSync as writeFileSync32 } from "fs";
|
|
19593
|
-
import { join as
|
|
19710
|
+
import { join as join54 } from "path";
|
|
19594
19711
|
import chalk164 from "chalk";
|
|
19595
19712
|
|
|
19596
19713
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
19597
|
-
import { readFileSync as
|
|
19714
|
+
import { readFileSync as readFileSync39 } from "fs";
|
|
19598
19715
|
|
|
19599
19716
|
// src/commands/netcap/parseRscRows.ts
|
|
19600
19717
|
var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
|
|
@@ -19633,25 +19750,25 @@ function isVisibleText(t) {
|
|
|
19633
19750
|
return /[a-zA-Z]{3,}/.test(t);
|
|
19634
19751
|
}
|
|
19635
19752
|
var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
|
|
19636
|
-
function collectRscText(v,
|
|
19753
|
+
function collectRscText(v, resolve21, sink2, seen) {
|
|
19637
19754
|
if (v == null) return;
|
|
19638
19755
|
if (typeof v === "string") {
|
|
19639
19756
|
if (isRscRef(v)) {
|
|
19640
19757
|
if (!seen.has(v)) {
|
|
19641
19758
|
seen.add(v);
|
|
19642
|
-
collectRscText(
|
|
19759
|
+
collectRscText(resolve21(v), resolve21, sink2, seen);
|
|
19643
19760
|
}
|
|
19644
19761
|
} else if (isHashtag(v)) sink2.hashtags.push(v);
|
|
19645
19762
|
else if (isVisibleText(v)) sink2.text.push(v);
|
|
19646
19763
|
return;
|
|
19647
19764
|
}
|
|
19648
19765
|
if (Array.isArray(v)) {
|
|
19649
|
-
for (const x of v) collectRscText(x,
|
|
19766
|
+
for (const x of v) collectRscText(x, resolve21, sink2, seen);
|
|
19650
19767
|
return;
|
|
19651
19768
|
}
|
|
19652
19769
|
if (typeof v === "object") {
|
|
19653
19770
|
for (const val of Object.values(v)) {
|
|
19654
|
-
collectRscText(val,
|
|
19771
|
+
collectRscText(val, resolve21, sink2, seen);
|
|
19655
19772
|
}
|
|
19656
19773
|
}
|
|
19657
19774
|
}
|
|
@@ -19683,7 +19800,7 @@ function visitObjects(root, fn) {
|
|
|
19683
19800
|
}
|
|
19684
19801
|
}
|
|
19685
19802
|
}
|
|
19686
|
-
function buildMentionMap(rows,
|
|
19803
|
+
function buildMentionMap(rows, resolve21) {
|
|
19687
19804
|
const map = /* @__PURE__ */ new Map();
|
|
19688
19805
|
visitObjects(rows, (o) => {
|
|
19689
19806
|
const url = profileActionUrl(o);
|
|
@@ -19691,7 +19808,7 @@ function buildMentionMap(rows, resolve20) {
|
|
|
19691
19808
|
const slug = slugFromProfileUrl(url);
|
|
19692
19809
|
if (!slug || map.has(slug)) return;
|
|
19693
19810
|
const sink2 = { text: [], hashtags: [] };
|
|
19694
|
-
collectRscText(o.children,
|
|
19811
|
+
collectRscText(o.children, resolve21, sink2, /* @__PURE__ */ new Set());
|
|
19695
19812
|
const name = sink2.text.join(" ").replace(/\s+/g, " ").trim();
|
|
19696
19813
|
map.set(slug, name ? { slug, name, url } : { slug, url });
|
|
19697
19814
|
});
|
|
@@ -19777,10 +19894,10 @@ function buildPost(raw, mentionMap, author) {
|
|
|
19777
19894
|
|
|
19778
19895
|
// src/commands/netcap/walkPostRow.ts
|
|
19779
19896
|
var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
|
|
19780
|
-
function walkPostRow(v,
|
|
19897
|
+
function walkPostRow(v, resolve21, raw) {
|
|
19781
19898
|
if (v == null || typeof v !== "object") return;
|
|
19782
19899
|
if (Array.isArray(v)) {
|
|
19783
|
-
for (const x of v) walkPostRow(x,
|
|
19900
|
+
for (const x of v) walkPostRow(x, resolve21, raw);
|
|
19784
19901
|
return;
|
|
19785
19902
|
}
|
|
19786
19903
|
const o = v;
|
|
@@ -19794,9 +19911,9 @@ function walkPostRow(v, resolve20, raw) {
|
|
|
19794
19911
|
}
|
|
19795
19912
|
if (isCommentary(o)) {
|
|
19796
19913
|
const sink2 = { text: raw.text, hashtags: raw.hashtags };
|
|
19797
|
-
collectRscText(o.children,
|
|
19914
|
+
collectRscText(o.children, resolve21, sink2, /* @__PURE__ */ new Set());
|
|
19798
19915
|
}
|
|
19799
|
-
for (const val of Object.values(o)) walkPostRow(val,
|
|
19916
|
+
for (const val of Object.values(o)) walkPostRow(val, resolve21, raw);
|
|
19800
19917
|
}
|
|
19801
19918
|
|
|
19802
19919
|
// src/commands/netcap/extractLinkedInPosts.ts
|
|
@@ -19810,8 +19927,8 @@ function findCommentaryRows(rows) {
|
|
|
19810
19927
|
}
|
|
19811
19928
|
function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
19812
19929
|
const rows = parseRscRows(flight);
|
|
19813
|
-
const
|
|
19814
|
-
const mentionMap = buildMentionMap(rows,
|
|
19930
|
+
const resolve21 = makeRscResolver(rows);
|
|
19931
|
+
const mentionMap = buildMentionMap(rows, resolve21);
|
|
19815
19932
|
const posts = [];
|
|
19816
19933
|
for (const id of findCommentaryRows(rows)) {
|
|
19817
19934
|
const raw = {
|
|
@@ -19821,7 +19938,7 @@ function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
|
19821
19938
|
links: [],
|
|
19822
19939
|
related: []
|
|
19823
19940
|
};
|
|
19824
|
-
walkPostRow(rows[id],
|
|
19941
|
+
walkPostRow(rows[id], resolve21, raw);
|
|
19825
19942
|
const post = buildPost(raw, mentionMap, author);
|
|
19826
19943
|
if (post) posts.push(post);
|
|
19827
19944
|
}
|
|
@@ -19990,7 +20107,7 @@ function extractVoyagerPosts(body) {
|
|
|
19990
20107
|
|
|
19991
20108
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
19992
20109
|
function captureEntries(captureFile) {
|
|
19993
|
-
const lines =
|
|
20110
|
+
const lines = readFileSync39(captureFile, "utf8").split("\n").filter(Boolean);
|
|
19994
20111
|
const entries = [];
|
|
19995
20112
|
for (const line of lines) {
|
|
19996
20113
|
let entry;
|
|
@@ -20035,7 +20152,7 @@ function extractPostsFromCapture(captureFile) {
|
|
|
20035
20152
|
function netcapExtract(file) {
|
|
20036
20153
|
const captureFile = file ?? defaultCapturePath();
|
|
20037
20154
|
const posts = extractPostsFromCapture(captureFile);
|
|
20038
|
-
const outFile =
|
|
20155
|
+
const outFile = join54(captureFile, "..", "posts.json");
|
|
20039
20156
|
writeFileSync32(outFile, `${JSON.stringify(posts, null, 2)}
|
|
20040
20157
|
`);
|
|
20041
20158
|
console.log(
|
|
@@ -20187,7 +20304,7 @@ function registerPrompts(program2) {
|
|
|
20187
20304
|
}
|
|
20188
20305
|
|
|
20189
20306
|
// src/commands/prs/shared.ts
|
|
20190
|
-
import { execSync as
|
|
20307
|
+
import { execSync as execSync43 } from "child_process";
|
|
20191
20308
|
function isGhNotInstalled(error) {
|
|
20192
20309
|
if (error instanceof Error) {
|
|
20193
20310
|
const msg = error.message.toLowerCase();
|
|
@@ -20205,12 +20322,12 @@ function getRepoInfo() {
|
|
|
20205
20322
|
const preferred = getPreferredRemoteRepo();
|
|
20206
20323
|
if (preferred) return preferred;
|
|
20207
20324
|
const repoInfo = JSON.parse(
|
|
20208
|
-
|
|
20325
|
+
execSync43("gh repo view --json owner,name", { encoding: "utf8" })
|
|
20209
20326
|
);
|
|
20210
20327
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
20211
20328
|
}
|
|
20212
20329
|
function getCurrentBranch2() {
|
|
20213
|
-
return
|
|
20330
|
+
return execSync43("git rev-parse --abbrev-ref HEAD", {
|
|
20214
20331
|
encoding: "utf8"
|
|
20215
20332
|
}).trim();
|
|
20216
20333
|
}
|
|
@@ -20218,7 +20335,7 @@ function viewCurrentPr(fields) {
|
|
|
20218
20335
|
const { org, repo } = getRepoInfo();
|
|
20219
20336
|
const branch2 = getCurrentBranch2();
|
|
20220
20337
|
return JSON.parse(
|
|
20221
|
-
|
|
20338
|
+
execSync43(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
|
|
20222
20339
|
encoding: "utf8"
|
|
20223
20340
|
})
|
|
20224
20341
|
);
|
|
@@ -20520,42 +20637,54 @@ function edit(options2) {
|
|
|
20520
20637
|
}
|
|
20521
20638
|
|
|
20522
20639
|
// src/commands/prs/fixed.ts
|
|
20523
|
-
import { execSync as
|
|
20640
|
+
import { execSync as execSync46 } from "child_process";
|
|
20524
20641
|
|
|
20525
20642
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
20526
|
-
import { execSync as
|
|
20643
|
+
import { execSync as execSync45 } from "child_process";
|
|
20527
20644
|
import { unlinkSync as unlinkSync14, writeFileSync as writeFileSync33 } from "fs";
|
|
20528
20645
|
import { tmpdir as tmpdir6 } from "os";
|
|
20529
|
-
import { join as
|
|
20646
|
+
import { join as join56 } from "path";
|
|
20530
20647
|
|
|
20531
20648
|
// src/commands/prs/loadCommentsCache.ts
|
|
20532
|
-
import { existsSync as
|
|
20533
|
-
import { join as join54 } from "path";
|
|
20649
|
+
import { existsSync as existsSync48, readFileSync as readFileSync40, unlinkSync as unlinkSync13 } from "fs";
|
|
20534
20650
|
import { parse as parse2 } from "yaml";
|
|
20535
|
-
|
|
20536
|
-
|
|
20651
|
+
|
|
20652
|
+
// src/commands/prs/commentsCachePath.ts
|
|
20653
|
+
import { homedir as homedir20 } from "os";
|
|
20654
|
+
import { join as join55 } from "path";
|
|
20655
|
+
function commentsCachePath(org, repo, prNumber) {
|
|
20656
|
+
return join55(
|
|
20657
|
+
homedir20(),
|
|
20658
|
+
".assist",
|
|
20659
|
+
"pr-comments",
|
|
20660
|
+
org,
|
|
20661
|
+
repo,
|
|
20662
|
+
`pr-${prNumber}-comments.yaml`
|
|
20663
|
+
);
|
|
20537
20664
|
}
|
|
20538
|
-
|
|
20539
|
-
|
|
20540
|
-
|
|
20665
|
+
|
|
20666
|
+
// src/commands/prs/loadCommentsCache.ts
|
|
20667
|
+
function loadCommentsCache(org, repo, prNumber) {
|
|
20668
|
+
const cachePath = commentsCachePath(org, repo, prNumber);
|
|
20669
|
+
if (!existsSync48(cachePath)) {
|
|
20541
20670
|
return null;
|
|
20542
20671
|
}
|
|
20543
|
-
const content =
|
|
20672
|
+
const content = readFileSync40(cachePath, "utf8");
|
|
20544
20673
|
return parse2(content);
|
|
20545
20674
|
}
|
|
20546
|
-
function deleteCommentsCache(prNumber) {
|
|
20547
|
-
const cachePath =
|
|
20548
|
-
if (
|
|
20675
|
+
function deleteCommentsCache(org, repo, prNumber) {
|
|
20676
|
+
const cachePath = commentsCachePath(org, repo, prNumber);
|
|
20677
|
+
if (existsSync48(cachePath)) {
|
|
20549
20678
|
unlinkSync13(cachePath);
|
|
20550
20679
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
20551
20680
|
}
|
|
20552
20681
|
}
|
|
20553
20682
|
|
|
20554
20683
|
// src/commands/prs/replyToComment.ts
|
|
20555
|
-
import { execSync as
|
|
20556
|
-
function replyToComment(org, repo, prNumber, commentId,
|
|
20557
|
-
|
|
20558
|
-
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${
|
|
20684
|
+
import { execSync as execSync44 } from "child_process";
|
|
20685
|
+
function replyToComment(org, repo, prNumber, commentId, message3) {
|
|
20686
|
+
execSync44(
|
|
20687
|
+
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message3.replace(/"/g, String.raw`\"`)}" -F in_reply_to=${commentId}`,
|
|
20559
20688
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
20560
20689
|
);
|
|
20561
20690
|
}
|
|
@@ -20563,10 +20692,10 @@ function replyToComment(org, repo, prNumber, commentId, message2) {
|
|
|
20563
20692
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
20564
20693
|
function resolveThread(threadId) {
|
|
20565
20694
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
20566
|
-
const queryFile =
|
|
20695
|
+
const queryFile = join56(tmpdir6(), `gh-mutation-${Date.now()}.graphql`);
|
|
20567
20696
|
writeFileSync33(queryFile, mutation);
|
|
20568
20697
|
try {
|
|
20569
|
-
|
|
20698
|
+
execSync45(
|
|
20570
20699
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
20571
20700
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
20572
20701
|
);
|
|
@@ -20574,8 +20703,8 @@ function resolveThread(threadId) {
|
|
|
20574
20703
|
unlinkSync14(queryFile);
|
|
20575
20704
|
}
|
|
20576
20705
|
}
|
|
20577
|
-
function requireCache(prNumber) {
|
|
20578
|
-
const cache4 = loadCommentsCache(prNumber);
|
|
20706
|
+
function requireCache(org, repo, prNumber) {
|
|
20707
|
+
const cache4 = loadCommentsCache(org, repo, prNumber);
|
|
20579
20708
|
if (!cache4) {
|
|
20580
20709
|
console.error(
|
|
20581
20710
|
`Error: No cached comments found for PR #${prNumber}. Run "assist prs list-comments" first.`
|
|
@@ -20597,28 +20726,28 @@ function requireLineComment(cache4, commentId) {
|
|
|
20597
20726
|
}
|
|
20598
20727
|
return comment3;
|
|
20599
20728
|
}
|
|
20600
|
-
function cleanupCacheIfDone(cache4, prNumber, commentId) {
|
|
20729
|
+
function cleanupCacheIfDone(cache4, org, repo, prNumber, commentId) {
|
|
20601
20730
|
const hasRemaining = cache4.comments.some(
|
|
20602
20731
|
(c) => c.type === "line" && c.id !== commentId
|
|
20603
20732
|
);
|
|
20604
|
-
if (!hasRemaining) deleteCommentsCache(prNumber);
|
|
20733
|
+
if (!hasRemaining) deleteCommentsCache(org, repo, prNumber);
|
|
20605
20734
|
}
|
|
20606
|
-
function resolveCommentWithReply(commentId,
|
|
20735
|
+
function resolveCommentWithReply(commentId, message3) {
|
|
20607
20736
|
const prNumber = getCurrentPrNumber();
|
|
20608
20737
|
const { org, repo } = getRepoInfo();
|
|
20609
|
-
const cache4 = requireCache(prNumber);
|
|
20738
|
+
const cache4 = requireCache(org, repo, prNumber);
|
|
20610
20739
|
const comment3 = requireLineComment(cache4, commentId);
|
|
20611
|
-
replyToComment(org, repo, prNumber, commentId,
|
|
20740
|
+
replyToComment(org, repo, prNumber, commentId, message3);
|
|
20612
20741
|
console.log("Reply posted successfully.");
|
|
20613
20742
|
resolveThread(comment3.threadId);
|
|
20614
20743
|
console.log("Thread resolved successfully.");
|
|
20615
|
-
cleanupCacheIfDone(cache4, prNumber, commentId);
|
|
20744
|
+
cleanupCacheIfDone(cache4, org, repo, prNumber, commentId);
|
|
20616
20745
|
}
|
|
20617
20746
|
|
|
20618
20747
|
// src/commands/prs/fixed.ts
|
|
20619
20748
|
function verifySha(sha) {
|
|
20620
20749
|
try {
|
|
20621
|
-
return
|
|
20750
|
+
return execSync46(`git rev-parse --verify ${sha}`, {
|
|
20622
20751
|
encoding: "utf8"
|
|
20623
20752
|
}).trim();
|
|
20624
20753
|
} catch {
|
|
@@ -20631,9 +20760,9 @@ function fixed(commentId, sha) {
|
|
|
20631
20760
|
const fullSha = verifySha(sha);
|
|
20632
20761
|
const { org, repo } = getRepoInfo();
|
|
20633
20762
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
20634
|
-
const
|
|
20763
|
+
const message3 = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
20635
20764
|
pushCommit(loadConfig().worktree?.trunk === true);
|
|
20636
|
-
resolveCommentWithReply(commentId,
|
|
20765
|
+
resolveCommentWithReply(commentId, message3);
|
|
20637
20766
|
} catch (error) {
|
|
20638
20767
|
if (isGhNotInstalled(error)) {
|
|
20639
20768
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -20644,22 +20773,17 @@ function fixed(commentId, sha) {
|
|
|
20644
20773
|
}
|
|
20645
20774
|
}
|
|
20646
20775
|
|
|
20647
|
-
// src/commands/prs/listComments/index.ts
|
|
20648
|
-
import { existsSync as existsSync48, mkdirSync as mkdirSync18, writeFileSync as writeFileSync35 } from "fs";
|
|
20649
|
-
import { join as join57 } from "path";
|
|
20650
|
-
import { stringify } from "yaml";
|
|
20651
|
-
|
|
20652
20776
|
// src/commands/prs/fetchThreadIds.ts
|
|
20653
|
-
import { execSync as
|
|
20777
|
+
import { execSync as execSync47 } from "child_process";
|
|
20654
20778
|
import { unlinkSync as unlinkSync15, writeFileSync as writeFileSync34 } from "fs";
|
|
20655
20779
|
import { tmpdir as tmpdir7 } from "os";
|
|
20656
|
-
import { join as
|
|
20780
|
+
import { join as join57 } from "path";
|
|
20657
20781
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
20658
20782
|
function fetchThreadIds(org, repo, prNumber) {
|
|
20659
|
-
const queryFile =
|
|
20783
|
+
const queryFile = join57(tmpdir7(), `gh-query-${Date.now()}.graphql`);
|
|
20660
20784
|
writeFileSync34(queryFile, THREAD_QUERY);
|
|
20661
20785
|
try {
|
|
20662
|
-
const result =
|
|
20786
|
+
const result = execSync47(
|
|
20663
20787
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
20664
20788
|
{ encoding: "utf8" }
|
|
20665
20789
|
);
|
|
@@ -20681,9 +20805,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
20681
20805
|
}
|
|
20682
20806
|
|
|
20683
20807
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
20684
|
-
import { execSync as
|
|
20808
|
+
import { execSync as execSync48 } from "child_process";
|
|
20685
20809
|
function fetchJson(endpoint) {
|
|
20686
|
-
const result =
|
|
20810
|
+
const result = execSync48(`gh api --paginate ${endpoint}`, {
|
|
20687
20811
|
encoding: "utf8"
|
|
20688
20812
|
});
|
|
20689
20813
|
if (!result.trim()) return [];
|
|
@@ -20724,6 +20848,28 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
20724
20848
|
);
|
|
20725
20849
|
}
|
|
20726
20850
|
|
|
20851
|
+
// src/commands/prs/listComments/updateCommentsCache.ts
|
|
20852
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync35 } from "fs";
|
|
20853
|
+
import { dirname as dirname28 } from "path";
|
|
20854
|
+
import { stringify } from "yaml";
|
|
20855
|
+
function writeCommentsCache(org, repo, prNumber, comments3) {
|
|
20856
|
+
const cachePath = commentsCachePath(org, repo, prNumber);
|
|
20857
|
+
mkdirSync18(dirname28(cachePath), { recursive: true });
|
|
20858
|
+
const cacheData = {
|
|
20859
|
+
prNumber,
|
|
20860
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20861
|
+
comments: comments3
|
|
20862
|
+
};
|
|
20863
|
+
writeFileSync35(cachePath, stringify(cacheData));
|
|
20864
|
+
}
|
|
20865
|
+
function updateCommentsCache(org, repo, prNumber, comments3) {
|
|
20866
|
+
if (comments3.some((c) => c.type === "line")) {
|
|
20867
|
+
writeCommentsCache(org, repo, prNumber, comments3);
|
|
20868
|
+
} else {
|
|
20869
|
+
deleteCommentsCache(org, repo, prNumber);
|
|
20870
|
+
}
|
|
20871
|
+
}
|
|
20872
|
+
|
|
20727
20873
|
// src/commands/prs/listComments/printComments.ts
|
|
20728
20874
|
import chalk167 from "chalk";
|
|
20729
20875
|
function formatForHuman(comment3) {
|
|
@@ -20769,19 +20915,6 @@ function printComments2(result) {
|
|
|
20769
20915
|
}
|
|
20770
20916
|
|
|
20771
20917
|
// src/commands/prs/listComments/index.ts
|
|
20772
|
-
function writeCommentsCache(prNumber, comments3) {
|
|
20773
|
-
const assistDir = join57(process.cwd(), ".assist");
|
|
20774
|
-
if (!existsSync48(assistDir)) {
|
|
20775
|
-
mkdirSync18(assistDir, { recursive: true });
|
|
20776
|
-
}
|
|
20777
|
-
const cacheData = {
|
|
20778
|
-
prNumber,
|
|
20779
|
-
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20780
|
-
comments: comments3
|
|
20781
|
-
};
|
|
20782
|
-
const cachePath = join57(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
20783
|
-
writeFileSync35(cachePath, stringify(cacheData));
|
|
20784
|
-
}
|
|
20785
20918
|
function handleKnownErrors(error) {
|
|
20786
20919
|
if (isGhNotInstalled(error)) {
|
|
20787
20920
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -20794,13 +20927,6 @@ function handleKnownErrors(error) {
|
|
|
20794
20927
|
}
|
|
20795
20928
|
return null;
|
|
20796
20929
|
}
|
|
20797
|
-
function updateCache(prNumber, comments3) {
|
|
20798
|
-
if (comments3.some((c) => c.type === "line")) {
|
|
20799
|
-
writeCommentsCache(prNumber, comments3);
|
|
20800
|
-
} else {
|
|
20801
|
-
deleteCommentsCache(prNumber);
|
|
20802
|
-
}
|
|
20803
|
-
}
|
|
20804
20930
|
async function listComments() {
|
|
20805
20931
|
try {
|
|
20806
20932
|
const prNumber = getCurrentPrNumber();
|
|
@@ -20810,9 +20936,9 @@ async function listComments() {
|
|
|
20810
20936
|
...fetchReviewComments(org, repo, prNumber),
|
|
20811
20937
|
...fetchLineComments(org, repo, prNumber, threadInfo)
|
|
20812
20938
|
];
|
|
20813
|
-
|
|
20939
|
+
updateCommentsCache(org, repo, prNumber, allComments);
|
|
20814
20940
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
20815
|
-
const cachePath = hasLineComments ?
|
|
20941
|
+
const cachePath = hasLineComments ? commentsCachePath(org, repo, prNumber) : null;
|
|
20816
20942
|
return { comments: allComments, cachePath };
|
|
20817
20943
|
} catch (error) {
|
|
20818
20944
|
const handled = handleKnownErrors(error);
|
|
@@ -20822,7 +20948,7 @@ async function listComments() {
|
|
|
20822
20948
|
}
|
|
20823
20949
|
|
|
20824
20950
|
// src/commands/prs/prs/index.ts
|
|
20825
|
-
import { execSync as
|
|
20951
|
+
import { execSync as execSync49 } from "child_process";
|
|
20826
20952
|
|
|
20827
20953
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
20828
20954
|
import enquirer9 from "enquirer";
|
|
@@ -20929,7 +21055,7 @@ async function prs(options2) {
|
|
|
20929
21055
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
20930
21056
|
try {
|
|
20931
21057
|
const { org, repo } = getRepoInfo();
|
|
20932
|
-
const result =
|
|
21058
|
+
const result = execSync49(
|
|
20933
21059
|
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
|
|
20934
21060
|
{ encoding: "utf8" }
|
|
20935
21061
|
);
|
|
@@ -21000,16 +21126,16 @@ function buildCreateArgs(title, body, options2) {
|
|
|
21000
21126
|
}
|
|
21001
21127
|
|
|
21002
21128
|
// src/commands/prs/readSessionPrRef.ts
|
|
21003
|
-
import { execSync as
|
|
21129
|
+
import { execSync as execSync50 } from "child_process";
|
|
21004
21130
|
function readSessionPrRef() {
|
|
21005
21131
|
try {
|
|
21006
|
-
const branch2 =
|
|
21132
|
+
const branch2 = execSync50("git rev-parse --abbrev-ref HEAD", {
|
|
21007
21133
|
encoding: "utf8",
|
|
21008
21134
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21009
21135
|
}).trim();
|
|
21010
21136
|
if (!branch2 || branch2 === "HEAD") return null;
|
|
21011
21137
|
const pr = JSON.parse(
|
|
21012
|
-
|
|
21138
|
+
execSync50(`gh pr view ${branch2} --json number,title,url,state`, {
|
|
21013
21139
|
encoding: "utf8",
|
|
21014
21140
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21015
21141
|
})
|
|
@@ -21137,7 +21263,7 @@ function reply(commentId, body) {
|
|
|
21137
21263
|
}
|
|
21138
21264
|
|
|
21139
21265
|
// src/commands/prs/wontfix.ts
|
|
21140
|
-
import { execSync as
|
|
21266
|
+
import { execSync as execSync51 } from "child_process";
|
|
21141
21267
|
function validateReason(reason4) {
|
|
21142
21268
|
const lowerReason = reason4.toLowerCase();
|
|
21143
21269
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -21154,7 +21280,7 @@ function validateShaReferences(reason4) {
|
|
|
21154
21280
|
const invalidShas = [];
|
|
21155
21281
|
for (const sha of shas) {
|
|
21156
21282
|
try {
|
|
21157
|
-
|
|
21283
|
+
execSync51(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
21158
21284
|
} catch {
|
|
21159
21285
|
invalidShas.push(sha);
|
|
21160
21286
|
}
|
|
@@ -21431,10 +21557,10 @@ import chalk171 from "chalk";
|
|
|
21431
21557
|
import Enquirer2 from "enquirer";
|
|
21432
21558
|
|
|
21433
21559
|
// src/commands/ravendb/searchItems.ts
|
|
21434
|
-
import { execSync as
|
|
21560
|
+
import { execSync as execSync52 } from "child_process";
|
|
21435
21561
|
import chalk170 from "chalk";
|
|
21436
21562
|
function opExec(args) {
|
|
21437
|
-
return
|
|
21563
|
+
return execSync52(`op ${args}`, {
|
|
21438
21564
|
encoding: "utf8",
|
|
21439
21565
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21440
21566
|
}).trim();
|
|
@@ -21466,9 +21592,9 @@ function getItemFields(itemId2) {
|
|
|
21466
21592
|
|
|
21467
21593
|
// src/commands/ravendb/selectOpSecret.ts
|
|
21468
21594
|
var { Input, Select } = Enquirer2;
|
|
21469
|
-
async function selectOne(
|
|
21595
|
+
async function selectOne(message3, choices) {
|
|
21470
21596
|
if (choices.length === 1) return choices[0].value;
|
|
21471
|
-
const selected = await new Select({ name: "choice", message:
|
|
21597
|
+
const selected = await new Select({ name: "choice", message: message3, choices }).run();
|
|
21472
21598
|
return choices.find((c) => c.name === selected)?.value ?? selected;
|
|
21473
21599
|
}
|
|
21474
21600
|
async function selectOpSecret(searchTerm) {
|
|
@@ -21586,7 +21712,7 @@ ${errorText}`
|
|
|
21586
21712
|
}
|
|
21587
21713
|
|
|
21588
21714
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
21589
|
-
import { execSync as
|
|
21715
|
+
import { execSync as execSync53 } from "child_process";
|
|
21590
21716
|
import chalk175 from "chalk";
|
|
21591
21717
|
function resolveOpSecret(reference) {
|
|
21592
21718
|
if (!reference.startsWith("op://")) {
|
|
@@ -21594,7 +21720,7 @@ function resolveOpSecret(reference) {
|
|
|
21594
21720
|
process.exit(1);
|
|
21595
21721
|
}
|
|
21596
21722
|
try {
|
|
21597
|
-
return
|
|
21723
|
+
return execSync53(`op read "${reference}"`, {
|
|
21598
21724
|
encoding: "utf8",
|
|
21599
21725
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21600
21726
|
}).trim();
|
|
@@ -21858,7 +21984,7 @@ Refactor check failed:
|
|
|
21858
21984
|
}
|
|
21859
21985
|
|
|
21860
21986
|
// src/commands/refactor/check/getViolations/index.ts
|
|
21861
|
-
import { execSync as
|
|
21987
|
+
import { execSync as execSync54 } from "child_process";
|
|
21862
21988
|
import fs25 from "fs";
|
|
21863
21989
|
import { minimatch as minimatch6 } from "minimatch";
|
|
21864
21990
|
|
|
@@ -21908,7 +22034,7 @@ function getGitFiles(options2) {
|
|
|
21908
22034
|
}
|
|
21909
22035
|
const files = /* @__PURE__ */ new Set();
|
|
21910
22036
|
if (options2.staged || options2.modified) {
|
|
21911
|
-
const staged =
|
|
22037
|
+
const staged = execSync54("git diff --cached --name-only", {
|
|
21912
22038
|
encoding: "utf8"
|
|
21913
22039
|
});
|
|
21914
22040
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -21916,7 +22042,7 @@ function getGitFiles(options2) {
|
|
|
21916
22042
|
}
|
|
21917
22043
|
}
|
|
21918
22044
|
if (options2.unstaged || options2.modified) {
|
|
21919
|
-
const unstaged =
|
|
22045
|
+
const unstaged = execSync54("git diff --name-only", { encoding: "utf8" });
|
|
21920
22046
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
21921
22047
|
files.add(file);
|
|
21922
22048
|
}
|
|
@@ -21946,7 +22072,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
21946
22072
|
|
|
21947
22073
|
// src/commands/refactor/check/index.ts
|
|
21948
22074
|
function runScript(script, cwd) {
|
|
21949
|
-
return new Promise((
|
|
22075
|
+
return new Promise((resolve21) => {
|
|
21950
22076
|
const child = spawn6("npm", ["run", script], {
|
|
21951
22077
|
stdio: "pipe",
|
|
21952
22078
|
shell: true,
|
|
@@ -21960,7 +22086,7 @@ function runScript(script, cwd) {
|
|
|
21960
22086
|
output += data.toString();
|
|
21961
22087
|
});
|
|
21962
22088
|
child.on("close", (code) => {
|
|
21963
|
-
|
|
22089
|
+
resolve21({ script, code: code ?? 1, output });
|
|
21964
22090
|
});
|
|
21965
22091
|
});
|
|
21966
22092
|
}
|
|
@@ -22532,9 +22658,9 @@ function rewriteImportPaths(imports, sourcePath, destPath) {
|
|
|
22532
22658
|
const destDir = path39.dirname(destPath);
|
|
22533
22659
|
return imports.map((imp) => {
|
|
22534
22660
|
if (!imp.moduleSpecifier.startsWith(".")) return imp;
|
|
22535
|
-
const
|
|
22536
|
-
let rel = path39.relative(destDir,
|
|
22537
|
-
if (rel === "") rel = `../${path39.basename(
|
|
22661
|
+
const absolute2 = path39.resolve(sourceDir, imp.moduleSpecifier);
|
|
22662
|
+
let rel = path39.relative(destDir, absolute2).replace(/\\/g, "/");
|
|
22663
|
+
if (rel === "") rel = `../${path39.basename(absolute2)}`;
|
|
22538
22664
|
else if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
22539
22665
|
return { ...imp, moduleSpecifier: rel };
|
|
22540
22666
|
});
|
|
@@ -23183,8 +23309,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
23183
23309
|
function clusterFiles(graph) {
|
|
23184
23310
|
const clusters = /* @__PURE__ */ new Map();
|
|
23185
23311
|
for (const file of graph.files) {
|
|
23186
|
-
const
|
|
23187
|
-
if (
|
|
23312
|
+
const basename21 = path52.basename(file, path52.extname(file));
|
|
23313
|
+
if (basename21 === "index") continue;
|
|
23188
23314
|
const importers = graph.importedBy.get(file);
|
|
23189
23315
|
if (!importers || importers.size !== 1) continue;
|
|
23190
23316
|
const parent = [...importers][0];
|
|
@@ -23603,14 +23729,14 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
|
|
|
23603
23729
|
}
|
|
23604
23730
|
|
|
23605
23731
|
// src/commands/review/buildReviewPaths.ts
|
|
23606
|
-
import { homedir as
|
|
23607
|
-
import { basename as
|
|
23732
|
+
import { homedir as homedir21 } from "os";
|
|
23733
|
+
import { basename as basename16, join as join58 } from "path";
|
|
23608
23734
|
function buildReviewPaths(repoRoot, key) {
|
|
23609
23735
|
const reviewDir = join58(
|
|
23610
|
-
|
|
23736
|
+
homedir21(),
|
|
23611
23737
|
".assist",
|
|
23612
23738
|
"reviews",
|
|
23613
|
-
|
|
23739
|
+
basename16(repoRoot),
|
|
23614
23740
|
key
|
|
23615
23741
|
);
|
|
23616
23742
|
return {
|
|
@@ -23623,9 +23749,9 @@ function buildReviewPaths(repoRoot, key) {
|
|
|
23623
23749
|
}
|
|
23624
23750
|
|
|
23625
23751
|
// src/commands/review/fetchExistingComments.ts
|
|
23626
|
-
import { execSync as
|
|
23752
|
+
import { execSync as execSync55 } from "child_process";
|
|
23627
23753
|
function fetchRawComments(org, repo, prNumber) {
|
|
23628
|
-
const out =
|
|
23754
|
+
const out = execSync55(
|
|
23629
23755
|
`gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
23630
23756
|
{ encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
|
|
23631
23757
|
);
|
|
@@ -23656,14 +23782,14 @@ function fetchExistingComments() {
|
|
|
23656
23782
|
}
|
|
23657
23783
|
|
|
23658
23784
|
// src/commands/review/gatherContext.ts
|
|
23659
|
-
import { execSync as
|
|
23785
|
+
import { execSync as execSync58 } from "child_process";
|
|
23660
23786
|
|
|
23661
23787
|
// src/commands/review/fetchPrDiff.ts
|
|
23662
|
-
import { execSync as
|
|
23788
|
+
import { execSync as execSync56 } from "child_process";
|
|
23663
23789
|
function fetchPrDiff(prNumber, baseSha, headSha) {
|
|
23664
23790
|
const { org, repo } = getRepoInfo();
|
|
23665
23791
|
try {
|
|
23666
|
-
return
|
|
23792
|
+
return execSync56(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
|
|
23667
23793
|
encoding: "utf8",
|
|
23668
23794
|
maxBuffer: 256 * 1024 * 1024,
|
|
23669
23795
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -23678,19 +23804,19 @@ function isDiffTooLarge(error) {
|
|
|
23678
23804
|
}
|
|
23679
23805
|
function fetchDiffViaGit(baseSha, headSha) {
|
|
23680
23806
|
try {
|
|
23681
|
-
|
|
23807
|
+
execSync56(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
|
|
23682
23808
|
} catch {
|
|
23683
23809
|
}
|
|
23684
|
-
return
|
|
23810
|
+
return execSync56(`git diff ${baseSha}...${headSha}`, {
|
|
23685
23811
|
encoding: "utf8",
|
|
23686
23812
|
maxBuffer: 256 * 1024 * 1024
|
|
23687
23813
|
});
|
|
23688
23814
|
}
|
|
23689
23815
|
|
|
23690
23816
|
// src/commands/review/fetchPrDiffInfo.ts
|
|
23691
|
-
import { execSync as
|
|
23817
|
+
import { execSync as execSync57 } from "child_process";
|
|
23692
23818
|
function getCurrentBranch3() {
|
|
23693
|
-
return
|
|
23819
|
+
return execSync57("git rev-parse --abbrev-ref HEAD", {
|
|
23694
23820
|
encoding: "utf8"
|
|
23695
23821
|
}).trim();
|
|
23696
23822
|
}
|
|
@@ -23698,7 +23824,7 @@ function fetchPrDiffInfo() {
|
|
|
23698
23824
|
const { org, repo } = getRepoInfo();
|
|
23699
23825
|
const branch2 = getCurrentBranch3();
|
|
23700
23826
|
const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
|
|
23701
|
-
const raw =
|
|
23827
|
+
const raw = execSync57(
|
|
23702
23828
|
`gh pr list --state open --head ${branch2} --json ${fields} -R ${org}/${repo}`,
|
|
23703
23829
|
{
|
|
23704
23830
|
encoding: "utf8",
|
|
@@ -23723,7 +23849,7 @@ function fetchPrDiffInfo() {
|
|
|
23723
23849
|
}
|
|
23724
23850
|
function fetchPrChangedFiles(prNumber) {
|
|
23725
23851
|
const { org, repo } = getRepoInfo();
|
|
23726
|
-
const out =
|
|
23852
|
+
const out = execSync57(
|
|
23727
23853
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
|
|
23728
23854
|
{
|
|
23729
23855
|
encoding: "utf8",
|
|
@@ -23735,11 +23861,11 @@ function fetchPrChangedFiles(prNumber) {
|
|
|
23735
23861
|
|
|
23736
23862
|
// src/commands/review/gatherContext.ts
|
|
23737
23863
|
function gatherContext() {
|
|
23738
|
-
const branch2 =
|
|
23864
|
+
const branch2 = execSync58("git rev-parse --abbrev-ref HEAD", {
|
|
23739
23865
|
encoding: "utf8"
|
|
23740
23866
|
}).trim();
|
|
23741
|
-
const sha =
|
|
23742
|
-
const shortSha =
|
|
23867
|
+
const sha = execSync58("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
23868
|
+
const shortSha = execSync58("git rev-parse --short=7 HEAD", {
|
|
23743
23869
|
encoding: "utf8"
|
|
23744
23870
|
}).trim();
|
|
23745
23871
|
const prInfo = fetchPrDiffInfo();
|
|
@@ -23760,7 +23886,7 @@ function gatherContext() {
|
|
|
23760
23886
|
}
|
|
23761
23887
|
|
|
23762
23888
|
// src/commands/review/postReviewToPr.ts
|
|
23763
|
-
import { readFileSync as
|
|
23889
|
+
import { readFileSync as readFileSync41 } from "fs";
|
|
23764
23890
|
|
|
23765
23891
|
// src/commands/review/parseFindings.ts
|
|
23766
23892
|
var SEVERITIES = ["blocker", "major", "minor", "nit"];
|
|
@@ -23915,9 +24041,9 @@ function postFindings(findings) {
|
|
|
23915
24041
|
posted++;
|
|
23916
24042
|
} catch (error) {
|
|
23917
24043
|
failed2++;
|
|
23918
|
-
const
|
|
24044
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
23919
24045
|
console.error(
|
|
23920
|
-
`Failed to post comment on ${finding.file}:${finding.line}: ${
|
|
24046
|
+
`Failed to post comment on ${finding.file}:${finding.line}: ${message3}`
|
|
23921
24047
|
);
|
|
23922
24048
|
}
|
|
23923
24049
|
}
|
|
@@ -23936,8 +24062,8 @@ function submitPendingReview(body) {
|
|
|
23936
24062
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
23937
24063
|
return;
|
|
23938
24064
|
}
|
|
23939
|
-
const
|
|
23940
|
-
console.error(`Failed to submit review: ${
|
|
24065
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
24066
|
+
console.error(`Failed to submit review: ${message3}`);
|
|
23941
24067
|
}
|
|
23942
24068
|
}
|
|
23943
24069
|
|
|
@@ -24075,7 +24201,7 @@ async function confirmPost(prNumber, count8, options2) {
|
|
|
24075
24201
|
async function postReviewToPr(synthesisPath, options2) {
|
|
24076
24202
|
const prInfo = fetchPrDiffInfo();
|
|
24077
24203
|
const prNumber = prInfo.prNumber;
|
|
24078
|
-
const markdown =
|
|
24204
|
+
const markdown = readFileSync41(synthesisPath, "utf8");
|
|
24079
24205
|
const findings = parseFindings(markdown);
|
|
24080
24206
|
if (findings.length === 0) {
|
|
24081
24207
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -24228,11 +24354,11 @@ async function runBacklogSession(synthesisPath) {
|
|
|
24228
24354
|
}
|
|
24229
24355
|
|
|
24230
24356
|
// src/commands/review/cachedReviewerResult.ts
|
|
24231
|
-
import { statSync as
|
|
24357
|
+
import { statSync as statSync8 } from "fs";
|
|
24232
24358
|
function cachedReviewerResult(name, outputPath) {
|
|
24233
24359
|
let size;
|
|
24234
24360
|
try {
|
|
24235
|
-
size =
|
|
24361
|
+
size = statSync8(outputPath).size;
|
|
24236
24362
|
} catch {
|
|
24237
24363
|
return null;
|
|
24238
24364
|
}
|
|
@@ -24728,10 +24854,10 @@ function messageFor(err, command) {
|
|
|
24728
24854
|
return err.message || String(err);
|
|
24729
24855
|
}
|
|
24730
24856
|
function handleSpawnError(ctx, err) {
|
|
24731
|
-
const
|
|
24857
|
+
const message3 = messageFor(err, ctx.command);
|
|
24732
24858
|
const stderr = ctx.stderr ? `${ctx.stderr}
|
|
24733
|
-
${
|
|
24734
|
-
if (!ctx.quiet) console.error(`[${ctx.name}] failed: ${
|
|
24859
|
+
${message3}` : message3;
|
|
24860
|
+
if (!ctx.quiet) console.error(`[${ctx.name}] failed: ${message3}`);
|
|
24735
24861
|
return {
|
|
24736
24862
|
exitCode: 127,
|
|
24737
24863
|
stderr,
|
|
@@ -24769,12 +24895,12 @@ function onCloseResult(ctx, code) {
|
|
|
24769
24895
|
return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
|
|
24770
24896
|
}
|
|
24771
24897
|
function waitForChildExit(ctx) {
|
|
24772
|
-
return new Promise((
|
|
24898
|
+
return new Promise((resolve21) => {
|
|
24773
24899
|
let settled = false;
|
|
24774
24900
|
const settle = (result) => {
|
|
24775
24901
|
if (settled) return;
|
|
24776
24902
|
settled = true;
|
|
24777
|
-
|
|
24903
|
+
resolve21(result);
|
|
24778
24904
|
};
|
|
24779
24905
|
ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
|
|
24780
24906
|
ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
|
|
@@ -24959,7 +25085,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
24959
25085
|
}
|
|
24960
25086
|
|
|
24961
25087
|
// src/commands/review/synthesise.ts
|
|
24962
|
-
import { readFileSync as
|
|
25088
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
24963
25089
|
|
|
24964
25090
|
// src/commands/review/buildSynthesisStdin.ts
|
|
24965
25091
|
var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
|
|
@@ -25015,7 +25141,7 @@ Files:
|
|
|
25015
25141
|
|
|
25016
25142
|
// src/commands/review/synthesise.ts
|
|
25017
25143
|
function printSummary2(synthesisPath) {
|
|
25018
|
-
const markdown =
|
|
25144
|
+
const markdown = readFileSync42(synthesisPath, "utf8");
|
|
25019
25145
|
console.log("");
|
|
25020
25146
|
console.log(buildReviewSummary(markdown));
|
|
25021
25147
|
console.log("");
|
|
@@ -25874,9 +26000,9 @@ function createReadlineInterface() {
|
|
|
25874
26000
|
});
|
|
25875
26001
|
}
|
|
25876
26002
|
function askQuestion(rl, question) {
|
|
25877
|
-
return new Promise((
|
|
26003
|
+
return new Promise((resolve21) => {
|
|
25878
26004
|
rl.question(question, (answer) => {
|
|
25879
|
-
|
|
26005
|
+
resolve21(answer.trim());
|
|
25880
26006
|
});
|
|
25881
26007
|
});
|
|
25882
26008
|
}
|
|
@@ -25936,14 +26062,14 @@ async function configure() {
|
|
|
25936
26062
|
}
|
|
25937
26063
|
|
|
25938
26064
|
// src/commands/transcript/list.ts
|
|
25939
|
-
import { existsSync as existsSync52, readdirSync as readdirSync10, statSync as
|
|
26065
|
+
import { existsSync as existsSync52, readdirSync as readdirSync10, statSync as statSync9 } from "fs";
|
|
25940
26066
|
import { join as join59 } from "path";
|
|
25941
26067
|
function list4() {
|
|
25942
26068
|
const { vttDir } = getTranscriptConfig();
|
|
25943
26069
|
if (!existsSync52(vttDir)) return;
|
|
25944
26070
|
for (const entry of readdirSync10(vttDir)) {
|
|
25945
26071
|
if (!entry.endsWith(".vtt")) continue;
|
|
25946
|
-
if (
|
|
26072
|
+
if (statSync9(join59(vttDir, entry)).isDirectory()) continue;
|
|
25947
26073
|
console.log(entry);
|
|
25948
26074
|
}
|
|
25949
26075
|
}
|
|
@@ -25952,11 +26078,11 @@ function list4() {
|
|
|
25952
26078
|
import {
|
|
25953
26079
|
existsSync as existsSync53,
|
|
25954
26080
|
mkdirSync as mkdirSync20,
|
|
25955
|
-
readFileSync as
|
|
26081
|
+
readFileSync as readFileSync43,
|
|
25956
26082
|
renameSync as renameSync2,
|
|
25957
26083
|
writeFileSync as writeFileSync38
|
|
25958
26084
|
} from "fs";
|
|
25959
|
-
import { basename as
|
|
26085
|
+
import { basename as basename17, join as join60 } from "path";
|
|
25960
26086
|
|
|
25961
26087
|
// src/commands/transcript/cleanText.ts
|
|
25962
26088
|
function cleanText(text17) {
|
|
@@ -26164,7 +26290,7 @@ function formatChatLog(messages) {
|
|
|
26164
26290
|
// src/commands/transcript/move.ts
|
|
26165
26291
|
var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
26166
26292
|
function convertVttToMarkdown(inputPath) {
|
|
26167
|
-
const cues = parseVtt(
|
|
26293
|
+
const cues = parseVtt(readFileSync43(inputPath, "utf8"));
|
|
26168
26294
|
const messages = cuesToChatMessages(deduplicateCues(cues));
|
|
26169
26295
|
return formatChatLog(messages);
|
|
26170
26296
|
}
|
|
@@ -26180,13 +26306,13 @@ function move(file, options2) {
|
|
|
26180
26306
|
process.exit(1);
|
|
26181
26307
|
}
|
|
26182
26308
|
const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
26183
|
-
const filename =
|
|
26309
|
+
const filename = basename17(file);
|
|
26184
26310
|
const sourcePath = join60(vttDir, filename);
|
|
26185
26311
|
if (!existsSync53(sourcePath)) {
|
|
26186
26312
|
console.error(`Error: VTT file not found: ${sourcePath}`);
|
|
26187
26313
|
process.exit(1);
|
|
26188
26314
|
}
|
|
26189
|
-
const base =
|
|
26315
|
+
const base = basename17(filename, ".vtt").replace(/ Transcription$/, "");
|
|
26190
26316
|
const outputName = `${date} ${base}.md`;
|
|
26191
26317
|
const formattedDir = join60(transcriptsDir, client);
|
|
26192
26318
|
mkdirSync20(formattedDir, { recursive: true });
|
|
@@ -26316,11 +26442,11 @@ import { spawnSync as spawnSync6 } from "child_process";
|
|
|
26316
26442
|
import { join as join62 } from "path";
|
|
26317
26443
|
|
|
26318
26444
|
// src/commands/voice/shared.ts
|
|
26319
|
-
import { homedir as
|
|
26320
|
-
import { dirname as
|
|
26445
|
+
import { homedir as homedir22 } from "os";
|
|
26446
|
+
import { dirname as dirname30, join as join61 } from "path";
|
|
26321
26447
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
26322
|
-
var __dirname5 =
|
|
26323
|
-
var VOICE_DIR = join61(
|
|
26448
|
+
var __dirname5 = dirname30(fileURLToPath7(import.meta.url));
|
|
26449
|
+
var VOICE_DIR = join61(homedir22(), ".assist", "voice");
|
|
26324
26450
|
var voicePaths = {
|
|
26325
26451
|
dir: VOICE_DIR,
|
|
26326
26452
|
pid: join61(VOICE_DIR, "voice.pid"),
|
|
@@ -26349,14 +26475,14 @@ function devices() {
|
|
|
26349
26475
|
}
|
|
26350
26476
|
|
|
26351
26477
|
// src/commands/voice/logs.ts
|
|
26352
|
-
import { existsSync as existsSync54, readFileSync as
|
|
26478
|
+
import { existsSync as existsSync54, readFileSync as readFileSync44 } from "fs";
|
|
26353
26479
|
function logs(options2) {
|
|
26354
26480
|
if (!existsSync54(voicePaths.log)) {
|
|
26355
26481
|
console.log("No voice log file found");
|
|
26356
26482
|
return;
|
|
26357
26483
|
}
|
|
26358
26484
|
const count8 = Number.parseInt(options2.lines ?? "150", 10);
|
|
26359
|
-
const content =
|
|
26485
|
+
const content = readFileSync44(voicePaths.log, "utf8").trim();
|
|
26360
26486
|
if (!content) {
|
|
26361
26487
|
console.log("Voice log is empty");
|
|
26362
26488
|
return;
|
|
@@ -26382,8 +26508,8 @@ import { mkdirSync as mkdirSync22 } from "fs";
|
|
|
26382
26508
|
import { join as join64 } from "path";
|
|
26383
26509
|
|
|
26384
26510
|
// src/commands/voice/checkLockFile.ts
|
|
26385
|
-
import { execSync as
|
|
26386
|
-
import { existsSync as existsSync55, mkdirSync as mkdirSync21, readFileSync as
|
|
26511
|
+
import { execSync as execSync59 } from "child_process";
|
|
26512
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync21, readFileSync as readFileSync45, writeFileSync as writeFileSync39 } from "fs";
|
|
26387
26513
|
import { join as join63 } from "path";
|
|
26388
26514
|
function isProcessAlive2(pid) {
|
|
26389
26515
|
try {
|
|
@@ -26397,7 +26523,7 @@ function checkLockFile() {
|
|
|
26397
26523
|
const lockFile = getLockFile();
|
|
26398
26524
|
if (!existsSync55(lockFile)) return;
|
|
26399
26525
|
try {
|
|
26400
|
-
const lock2 = JSON.parse(
|
|
26526
|
+
const lock2 = JSON.parse(readFileSync45(lockFile, "utf8"));
|
|
26401
26527
|
if (lock2.pid && isProcessAlive2(lock2.pid)) {
|
|
26402
26528
|
console.error(
|
|
26403
26529
|
`Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
|
|
@@ -26411,7 +26537,7 @@ function bootstrapVenv() {
|
|
|
26411
26537
|
if (existsSync55(getVenvPython())) return;
|
|
26412
26538
|
console.log("Setting up Python environment...");
|
|
26413
26539
|
const pythonDir = getPythonDir();
|
|
26414
|
-
|
|
26540
|
+
execSync59(
|
|
26415
26541
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
26416
26542
|
{
|
|
26417
26543
|
stdio: "inherit",
|
|
@@ -26499,7 +26625,7 @@ function start2(options2) {
|
|
|
26499
26625
|
}
|
|
26500
26626
|
|
|
26501
26627
|
// src/commands/voice/status.ts
|
|
26502
|
-
import { existsSync as existsSync56, readFileSync as
|
|
26628
|
+
import { existsSync as existsSync56, readFileSync as readFileSync46 } from "fs";
|
|
26503
26629
|
function isProcessAlive3(pid) {
|
|
26504
26630
|
try {
|
|
26505
26631
|
process.kill(pid, 0);
|
|
@@ -26510,7 +26636,7 @@ function isProcessAlive3(pid) {
|
|
|
26510
26636
|
}
|
|
26511
26637
|
function readRecentLogs(count8) {
|
|
26512
26638
|
if (!existsSync56(voicePaths.log)) return [];
|
|
26513
|
-
const lines =
|
|
26639
|
+
const lines = readFileSync46(voicePaths.log, "utf8").trim().split("\n");
|
|
26514
26640
|
return lines.slice(-count8);
|
|
26515
26641
|
}
|
|
26516
26642
|
function status2() {
|
|
@@ -26518,7 +26644,7 @@ function status2() {
|
|
|
26518
26644
|
console.log("Voice daemon: not running (no PID file)");
|
|
26519
26645
|
return;
|
|
26520
26646
|
}
|
|
26521
|
-
const pid = Number.parseInt(
|
|
26647
|
+
const pid = Number.parseInt(readFileSync46(voicePaths.pid, "utf8").trim(), 10);
|
|
26522
26648
|
const alive = isProcessAlive3(pid);
|
|
26523
26649
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
26524
26650
|
const recent = readRecentLogs(5);
|
|
@@ -26537,13 +26663,13 @@ function status2() {
|
|
|
26537
26663
|
}
|
|
26538
26664
|
|
|
26539
26665
|
// src/commands/voice/stop.ts
|
|
26540
|
-
import { existsSync as existsSync57, readFileSync as
|
|
26666
|
+
import { existsSync as existsSync57, readFileSync as readFileSync47, unlinkSync as unlinkSync19 } from "fs";
|
|
26541
26667
|
function stop2() {
|
|
26542
26668
|
if (!existsSync57(voicePaths.pid)) {
|
|
26543
26669
|
console.log("Voice daemon is not running (no PID file)");
|
|
26544
26670
|
return;
|
|
26545
26671
|
}
|
|
26546
|
-
const pid = Number.parseInt(
|
|
26672
|
+
const pid = Number.parseInt(readFileSync47(voicePaths.pid, "utf8").trim(), 10);
|
|
26547
26673
|
try {
|
|
26548
26674
|
process.kill(pid, "SIGTERM");
|
|
26549
26675
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -26677,8 +26803,8 @@ function gitFailureReason(error) {
|
|
|
26677
26803
|
const text17 = stream == null ? "" : String(stream).trim();
|
|
26678
26804
|
if (text17) return text17;
|
|
26679
26805
|
}
|
|
26680
|
-
const
|
|
26681
|
-
return
|
|
26806
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
26807
|
+
return message3.trim() || "git failed without reporting a reason";
|
|
26682
26808
|
}
|
|
26683
26809
|
|
|
26684
26810
|
// src/commands/watch/resolveUpstream.ts
|
|
@@ -26782,7 +26908,7 @@ function waitForUpstream(options2) {
|
|
|
26782
26908
|
return Promise.resolve({ kind: "moved", upstream, ...moved });
|
|
26783
26909
|
}
|
|
26784
26910
|
const fetchTimeoutMs = Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS);
|
|
26785
|
-
return new Promise((
|
|
26911
|
+
return new Promise((resolve21) => {
|
|
26786
26912
|
let settled = false;
|
|
26787
26913
|
const finish = (outcome) => {
|
|
26788
26914
|
if (settled) return;
|
|
@@ -26790,7 +26916,7 @@ function waitForUpstream(options2) {
|
|
|
26790
26916
|
clearInterval(ticker);
|
|
26791
26917
|
clearTimeout(deadline);
|
|
26792
26918
|
process.off("SIGINT", onInterrupt);
|
|
26793
|
-
|
|
26919
|
+
resolve21(outcome);
|
|
26794
26920
|
};
|
|
26795
26921
|
const onInterrupt = () => finish({ kind: "interrupted" });
|
|
26796
26922
|
const ticker = setInterval(() => {
|
|
@@ -26815,9 +26941,9 @@ function parseOrExit(value) {
|
|
|
26815
26941
|
return process.exit(1);
|
|
26816
26942
|
}
|
|
26817
26943
|
}
|
|
26818
|
-
function report({ exitCode, message:
|
|
26819
|
-
if (exitCode === 0) console.log(
|
|
26820
|
-
else console.error(
|
|
26944
|
+
function report({ exitCode, message: message3 }) {
|
|
26945
|
+
if (exitCode === 0) console.log(message3);
|
|
26946
|
+
else console.error(message3);
|
|
26821
26947
|
}
|
|
26822
26948
|
async function watchWait(options2) {
|
|
26823
26949
|
const intervalMs = parseOrExit(options2.interval);
|
|
@@ -26878,7 +27004,7 @@ function extractCode(url, expectedState) {
|
|
|
26878
27004
|
return code;
|
|
26879
27005
|
}
|
|
26880
27006
|
function waitForCallback(port, expectedState) {
|
|
26881
|
-
return new Promise((
|
|
27007
|
+
return new Promise((resolve21, reject) => {
|
|
26882
27008
|
const timeout = setTimeout(() => {
|
|
26883
27009
|
server.close();
|
|
26884
27010
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -26895,7 +27021,7 @@ function waitForCallback(port, expectedState) {
|
|
|
26895
27021
|
const code = extractCode(url, expectedState);
|
|
26896
27022
|
respondHtml(res, 200, "Authorization successful!");
|
|
26897
27023
|
server.close();
|
|
26898
|
-
|
|
27024
|
+
resolve21(code);
|
|
26899
27025
|
} catch (error) {
|
|
26900
27026
|
respondHtml(res, 400, error.message);
|
|
26901
27027
|
server.close();
|
|
@@ -27016,7 +27142,7 @@ async function auth() {
|
|
|
27016
27142
|
|
|
27017
27143
|
// src/commands/roam/postRoamActivity.ts
|
|
27018
27144
|
import { execFileSync as execFileSync12 } from "child_process";
|
|
27019
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
27145
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync48, statSync as statSync10 } from "fs";
|
|
27020
27146
|
import { join as join66 } from "path";
|
|
27021
27147
|
function findPortFile(roamDir) {
|
|
27022
27148
|
let entries;
|
|
@@ -27028,7 +27154,7 @@ function findPortFile(roamDir) {
|
|
|
27028
27154
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
27029
27155
|
const path71 = join66(roamDir, name);
|
|
27030
27156
|
try {
|
|
27031
|
-
return { path: path71, mtimeMs:
|
|
27157
|
+
return { path: path71, mtimeMs: statSync10(path71).mtimeMs };
|
|
27032
27158
|
} catch {
|
|
27033
27159
|
return void 0;
|
|
27034
27160
|
}
|
|
@@ -27042,7 +27168,7 @@ function postRoamActivity(app, event) {
|
|
|
27042
27168
|
if (!portFile) return;
|
|
27043
27169
|
let port;
|
|
27044
27170
|
try {
|
|
27045
|
-
port =
|
|
27171
|
+
port = readFileSync48(portFile, "utf8").trim();
|
|
27046
27172
|
} catch {
|
|
27047
27173
|
return;
|
|
27048
27174
|
}
|
|
@@ -27172,7 +27298,7 @@ var rootConfigHelp = {
|
|
|
27172
27298
|
};
|
|
27173
27299
|
|
|
27174
27300
|
// src/commands/run/index.ts
|
|
27175
|
-
import { resolve as
|
|
27301
|
+
import { resolve as resolve17 } from "path";
|
|
27176
27302
|
|
|
27177
27303
|
// src/commands/run/findRunConfig.ts
|
|
27178
27304
|
function exitNoRunConfigs() {
|
|
@@ -27256,11 +27382,11 @@ function resolveParams(params, cliArgs) {
|
|
|
27256
27382
|
}
|
|
27257
27383
|
|
|
27258
27384
|
// src/commands/run/runPreCommands.ts
|
|
27259
|
-
import { execSync as
|
|
27385
|
+
import { execSync as execSync60 } from "child_process";
|
|
27260
27386
|
function runPreCommands(pre, cwd) {
|
|
27261
27387
|
for (const cmd of pre) {
|
|
27262
27388
|
try {
|
|
27263
|
-
|
|
27389
|
+
execSync60(cmd, { stdio: "inherit", cwd });
|
|
27264
27390
|
} catch (error) {
|
|
27265
27391
|
const code = error && typeof error === "object" && "status" in error ? error.status : 1;
|
|
27266
27392
|
process.exit(code);
|
|
@@ -27271,12 +27397,12 @@ function runPreCommands(pre, cwd) {
|
|
|
27271
27397
|
// src/commands/run/spawnRunCommand.ts
|
|
27272
27398
|
import { execFileSync as execFileSync13, spawn as spawn9 } from "child_process";
|
|
27273
27399
|
import { existsSync as existsSync58 } from "fs";
|
|
27274
|
-
import { dirname as
|
|
27400
|
+
import { dirname as dirname31, join as join67, resolve as resolve16 } from "path";
|
|
27275
27401
|
function resolveCommand2(command) {
|
|
27276
27402
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
27277
27403
|
try {
|
|
27278
27404
|
const gitPath = execFileSync13("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
27279
|
-
const gitRoot =
|
|
27405
|
+
const gitRoot = resolve16(dirname31(gitPath), "..");
|
|
27280
27406
|
const gitBash = join67(gitRoot, "bin", "bash.exe");
|
|
27281
27407
|
if (existsSync58(gitBash)) return gitBash;
|
|
27282
27408
|
} catch {
|
|
@@ -27324,7 +27450,7 @@ function listRunConfigs(verbose) {
|
|
|
27324
27450
|
}
|
|
27325
27451
|
}
|
|
27326
27452
|
function execRunConfig(config, args) {
|
|
27327
|
-
const cwd = config.cwd ?
|
|
27453
|
+
const cwd = config.cwd ? resolve17(getConfigDir(), config.cwd) : void 0;
|
|
27328
27454
|
if (config.pre) runPreCommands(config.pre, cwd);
|
|
27329
27455
|
const resolved = resolveParams(config.params, args);
|
|
27330
27456
|
spawnRunCommand(
|
|
@@ -27561,10 +27687,10 @@ function registerRun(program2) {
|
|
|
27561
27687
|
}
|
|
27562
27688
|
|
|
27563
27689
|
// src/commands/screenshot/index.ts
|
|
27564
|
-
import { execSync as
|
|
27690
|
+
import { execSync as execSync61 } from "child_process";
|
|
27565
27691
|
import { existsSync as existsSync60, mkdirSync as mkdirSync25, unlinkSync as unlinkSync21, writeFileSync as writeFileSync42 } from "fs";
|
|
27566
27692
|
import { tmpdir as tmpdir8 } from "os";
|
|
27567
|
-
import { join as join70, resolve as
|
|
27693
|
+
import { join as join70, resolve as resolve18 } from "path";
|
|
27568
27694
|
import chalk209 from "chalk";
|
|
27569
27695
|
|
|
27570
27696
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -27698,13 +27824,13 @@ function buildOutputPath(outputDir, processName) {
|
|
|
27698
27824
|
mkdirSync25(outputDir, { recursive: true });
|
|
27699
27825
|
}
|
|
27700
27826
|
const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27701
|
-
return
|
|
27827
|
+
return resolve18(outputDir, `${processName}-${timestamp6}.png`);
|
|
27702
27828
|
}
|
|
27703
27829
|
function runPowerShellScript(processName, outputPath) {
|
|
27704
27830
|
const scriptPath = join70(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
|
|
27705
27831
|
writeFileSync42(scriptPath, captureWindowPs1, "utf8");
|
|
27706
27832
|
try {
|
|
27707
|
-
|
|
27833
|
+
execSync61(
|
|
27708
27834
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
27709
27835
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
|
|
27710
27836
|
);
|
|
@@ -27714,7 +27840,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
27714
27840
|
}
|
|
27715
27841
|
function screenshot(processName) {
|
|
27716
27842
|
const config = loadConfig();
|
|
27717
|
-
const outputDir =
|
|
27843
|
+
const outputDir = resolve18(config.screenshot.outputDir);
|
|
27718
27844
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
27719
27845
|
console.log(chalk209.gray(`Capturing window for process "${processName}" ...`));
|
|
27720
27846
|
try {
|
|
@@ -27747,10 +27873,10 @@ var STATUS_TIMEOUT_MS = 5e3;
|
|
|
27747
27873
|
function queryDaemon(socket) {
|
|
27748
27874
|
socket.write(`${JSON.stringify({ type: "ping" })}
|
|
27749
27875
|
`);
|
|
27750
|
-
return new Promise((
|
|
27876
|
+
return new Promise((resolve21) => {
|
|
27751
27877
|
const result = { sessions: [] };
|
|
27752
27878
|
const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
|
|
27753
|
-
const timer = setTimeout(() =>
|
|
27879
|
+
const timer = setTimeout(() => resolve21(result), STATUS_TIMEOUT_MS);
|
|
27754
27880
|
const lines = createInterface5({ input: socket });
|
|
27755
27881
|
lines.on("error", () => {
|
|
27756
27882
|
});
|
|
@@ -27758,7 +27884,7 @@ function queryDaemon(socket) {
|
|
|
27758
27884
|
applyLine(result, pending, line);
|
|
27759
27885
|
if (pending.size === 0) {
|
|
27760
27886
|
clearTimeout(timer);
|
|
27761
|
-
|
|
27887
|
+
resolve21(result);
|
|
27762
27888
|
}
|
|
27763
27889
|
});
|
|
27764
27890
|
});
|
|
@@ -27778,7 +27904,7 @@ function applyLine(result, pending, line) {
|
|
|
27778
27904
|
}
|
|
27779
27905
|
|
|
27780
27906
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
27781
|
-
import { readFileSync as
|
|
27907
|
+
import { readFileSync as readFileSync49 } from "fs";
|
|
27782
27908
|
function reportStolenSocket(socketPid) {
|
|
27783
27909
|
if (!socketPid) return;
|
|
27784
27910
|
const filePid = readPidFile();
|
|
@@ -27790,7 +27916,7 @@ function reportStolenSocket(socketPid) {
|
|
|
27790
27916
|
function readPidFile() {
|
|
27791
27917
|
try {
|
|
27792
27918
|
const pid = Number.parseInt(
|
|
27793
|
-
|
|
27919
|
+
readFileSync49(daemonPaths.pid, "utf8").trim(),
|
|
27794
27920
|
10
|
|
27795
27921
|
);
|
|
27796
27922
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -27844,11 +27970,11 @@ function clearPersistedSessionsOnDrain() {
|
|
|
27844
27970
|
|
|
27845
27971
|
// src/commands/sessions/daemon/readDaemonMessage.ts
|
|
27846
27972
|
function readDaemonMessage(lines, timeoutMs, fallback, match) {
|
|
27847
|
-
return new Promise((
|
|
27973
|
+
return new Promise((resolve21) => {
|
|
27848
27974
|
const finish = (value) => {
|
|
27849
27975
|
clearTimeout(timer);
|
|
27850
27976
|
lines.off("line", onLine);
|
|
27851
|
-
|
|
27977
|
+
resolve21(value);
|
|
27852
27978
|
};
|
|
27853
27979
|
const timer = setTimeout(() => finish(fallback), timeoutMs);
|
|
27854
27980
|
const onLine = (line) => {
|
|
@@ -28186,7 +28312,7 @@ function readDesignSystemPrompt() {
|
|
|
28186
28312
|
import * as pty from "node-pty";
|
|
28187
28313
|
|
|
28188
28314
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
28189
|
-
import { chmodSync, existsSync as existsSync61, statSync as
|
|
28315
|
+
import { chmodSync, existsSync as existsSync61, statSync as statSync11 } from "fs";
|
|
28190
28316
|
import { createRequire as createRequire3 } from "module";
|
|
28191
28317
|
import path59 from "path";
|
|
28192
28318
|
var require4 = createRequire3(import.meta.url);
|
|
@@ -28202,7 +28328,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
28202
28328
|
"spawn-helper"
|
|
28203
28329
|
);
|
|
28204
28330
|
if (!existsSync61(helper)) return;
|
|
28205
|
-
const mode =
|
|
28331
|
+
const mode = statSync11(helper).mode;
|
|
28206
28332
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
28207
28333
|
}
|
|
28208
28334
|
|
|
@@ -28362,14 +28488,14 @@ function otherTreeHolders(sessions, session) {
|
|
|
28362
28488
|
|
|
28363
28489
|
// src/commands/sessions/daemon/worktree/reapWorktree.ts
|
|
28364
28490
|
import { existsSync as existsSync63 } from "fs";
|
|
28365
|
-
import { basename as
|
|
28491
|
+
import { basename as basename18 } from "path";
|
|
28366
28492
|
|
|
28367
28493
|
// src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
|
|
28368
28494
|
import { existsSync as existsSync62 } from "fs";
|
|
28369
28495
|
import { join as join73 } from "path";
|
|
28370
28496
|
|
|
28371
28497
|
// src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
|
|
28372
|
-
import { statSync as
|
|
28498
|
+
import { statSync as statSync12 } from "fs";
|
|
28373
28499
|
import { rm as rm2 } from "fs/promises";
|
|
28374
28500
|
import { join as join72 } from "path";
|
|
28375
28501
|
async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
@@ -28398,7 +28524,7 @@ async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
|
28398
28524
|
return true;
|
|
28399
28525
|
}
|
|
28400
28526
|
function holdsAGitDirectoryRatherThanALink(worktreePath) {
|
|
28401
|
-
return
|
|
28527
|
+
return statSync12(join72(worktreePath, ".git"), {
|
|
28402
28528
|
throwIfNoEntry: false
|
|
28403
28529
|
})?.isDirectory() === true;
|
|
28404
28530
|
}
|
|
@@ -28500,7 +28626,7 @@ async function reapWorktree(worktreePath, force = false) {
|
|
|
28500
28626
|
stopInstall(worktreePath);
|
|
28501
28627
|
const clone = owningClone(worktreePath);
|
|
28502
28628
|
if (!await removeTree(clone, worktreePath, force)) return false;
|
|
28503
|
-
await deleteWorktreeBranch(clone,
|
|
28629
|
+
await deleteWorktreeBranch(clone, basename18(worktreePath));
|
|
28504
28630
|
forgetWorktree(worktreePath);
|
|
28505
28631
|
daemonLog(`worktree ${worktreePath} reaped${force ? " (forced)" : ""}`);
|
|
28506
28632
|
return true;
|
|
@@ -29025,7 +29151,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
|
|
|
29025
29151
|
|
|
29026
29152
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
29027
29153
|
import { existsSync as existsSync66, mkdirSync as mkdirSync26, watch as watch2 } from "fs";
|
|
29028
|
-
import { dirname as
|
|
29154
|
+
import { dirname as dirname33 } from "path";
|
|
29029
29155
|
|
|
29030
29156
|
// src/commands/sessions/daemon/applyReviewPause.ts
|
|
29031
29157
|
function applyReviewPause(session, activity2) {
|
|
@@ -29079,7 +29205,7 @@ var DEBOUNCE_MS2 = 50;
|
|
|
29079
29205
|
function watchActivity(session, notify2, onClaudeSessionId) {
|
|
29080
29206
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
29081
29207
|
const path71 = activityPath(session.id);
|
|
29082
|
-
const dir =
|
|
29208
|
+
const dir = dirname33(path71);
|
|
29083
29209
|
try {
|
|
29084
29210
|
mkdirSync26(dir, { recursive: true });
|
|
29085
29211
|
} catch {
|
|
@@ -29295,9 +29421,9 @@ function normalizeEntry(entry) {
|
|
|
29295
29421
|
return null;
|
|
29296
29422
|
}
|
|
29297
29423
|
function normalizeAssistant(entry) {
|
|
29298
|
-
const
|
|
29299
|
-
const stopReason = typeof
|
|
29300
|
-
const content =
|
|
29424
|
+
const message3 = asRecord2(entry.message);
|
|
29425
|
+
const stopReason = typeof message3?.stop_reason === "string" ? message3.stop_reason : null;
|
|
29426
|
+
const content = message3?.content;
|
|
29301
29427
|
const toolUses = [];
|
|
29302
29428
|
if (Array.isArray(content))
|
|
29303
29429
|
for (const block of content) {
|
|
@@ -30195,7 +30321,7 @@ function rearmStoppedSessions(sessions, notify2) {
|
|
|
30195
30321
|
|
|
30196
30322
|
// src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
|
|
30197
30323
|
import { existsSync as existsSync69 } from "fs";
|
|
30198
|
-
import { basename as
|
|
30324
|
+
import { basename as basename20 } from "path";
|
|
30199
30325
|
|
|
30200
30326
|
// src/commands/sessions/daemon/worktree/accountedTrees.ts
|
|
30201
30327
|
function accountedTrees(sessions) {
|
|
@@ -30264,9 +30390,9 @@ async function changedFiles(path71) {
|
|
|
30264
30390
|
};
|
|
30265
30391
|
}
|
|
30266
30392
|
async function unpushedCommits(path71, reason4) {
|
|
30267
|
-
const
|
|
30268
|
-
if (!
|
|
30269
|
-
const lines = nonEmptyLines(
|
|
30393
|
+
const log2 = await gitResult(path71, ["log", "--oneline", "@{upstream}..HEAD"]);
|
|
30394
|
+
if (!log2.ok) return { summary: reason4, items: [] };
|
|
30395
|
+
const lines = nonEmptyLines(log2.out);
|
|
30270
30396
|
return {
|
|
30271
30397
|
summary: `${lines.length} unpushed ${lines.length === 1 ? "commit" : "commits"}`,
|
|
30272
30398
|
items: capped(lines)
|
|
@@ -30322,7 +30448,7 @@ async function reclaimBranch(clone, branch2) {
|
|
|
30322
30448
|
}
|
|
30323
30449
|
|
|
30324
30450
|
// src/commands/sessions/daemon/worktree/resurfaceOrphanedWorktree.ts
|
|
30325
|
-
import { basename as
|
|
30451
|
+
import { basename as basename19 } from "path";
|
|
30326
30452
|
function resurfaceOrphanedWorktree(sessions, spawnWith, recovered, notify2) {
|
|
30327
30453
|
const { orphan, reason: reason4, held } = recovered;
|
|
30328
30454
|
let id;
|
|
@@ -30345,7 +30471,7 @@ function orphanedSession(id, recovered) {
|
|
|
30345
30471
|
const { orphan, reason: reason4, held } = recovered;
|
|
30346
30472
|
return {
|
|
30347
30473
|
...sessionBase(id, "stopped"),
|
|
30348
|
-
name: `recovered ${
|
|
30474
|
+
name: `recovered ${basename19(orphan.path)}`,
|
|
30349
30475
|
subtitle: `${held.summary} in ${orphan.path}`,
|
|
30350
30476
|
commandType: "claude",
|
|
30351
30477
|
pty: null,
|
|
@@ -30382,7 +30508,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
|
|
|
30382
30508
|
if (!existsSync69(path71)) {
|
|
30383
30509
|
vanished.set(clone, [
|
|
30384
30510
|
...vanished.get(clone) ?? [],
|
|
30385
|
-
{ path: path71, branch:
|
|
30511
|
+
{ path: path71, branch: basename20(path71) }
|
|
30386
30512
|
]);
|
|
30387
30513
|
continue;
|
|
30388
30514
|
}
|
|
@@ -30649,7 +30775,7 @@ function windowsDaemonHost() {
|
|
|
30649
30775
|
var CONNECT_TIMEOUT_MS = 2e3;
|
|
30650
30776
|
var KEEPALIVE_PROBE_MS = 1e4;
|
|
30651
30777
|
function connectToWindowsDaemon() {
|
|
30652
|
-
return new Promise((
|
|
30778
|
+
return new Promise((resolve21, reject) => {
|
|
30653
30779
|
const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
|
|
30654
30780
|
socket.setTimeout(CONNECT_TIMEOUT_MS);
|
|
30655
30781
|
socket.once("timeout", () => {
|
|
@@ -30659,7 +30785,7 @@ function connectToWindowsDaemon() {
|
|
|
30659
30785
|
socket.once("connect", () => {
|
|
30660
30786
|
socket.setTimeout(0);
|
|
30661
30787
|
socket.setKeepAlive(true, KEEPALIVE_PROBE_MS);
|
|
30662
|
-
|
|
30788
|
+
resolve21(socket);
|
|
30663
30789
|
});
|
|
30664
30790
|
socket.once("error", reject);
|
|
30665
30791
|
});
|
|
@@ -30737,7 +30863,7 @@ async function waitForWindowsDaemon() {
|
|
|
30737
30863
|
);
|
|
30738
30864
|
}
|
|
30739
30865
|
function delay2(ms) {
|
|
30740
|
-
return new Promise((
|
|
30866
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
30741
30867
|
}
|
|
30742
30868
|
|
|
30743
30869
|
// src/commands/sessions/daemon/defaultConnect.ts
|
|
@@ -30747,19 +30873,19 @@ async function defaultConnect() {
|
|
|
30747
30873
|
}
|
|
30748
30874
|
|
|
30749
30875
|
// src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
|
|
30750
|
-
import { existsSync as existsSync70, readFileSync as
|
|
30876
|
+
import { existsSync as existsSync70, readFileSync as readFileSync51 } from "fs";
|
|
30751
30877
|
import { posix } from "path";
|
|
30752
30878
|
function hasPersistedWindowsSessions() {
|
|
30753
30879
|
const sessionsFile = windowsSessionsFileFromWsl();
|
|
30754
30880
|
if (!sessionsFile) return false;
|
|
30755
30881
|
try {
|
|
30756
30882
|
if (!existsSync70(sessionsFile)) return false;
|
|
30757
|
-
const data = JSON.parse(
|
|
30883
|
+
const data = JSON.parse(readFileSync51(sessionsFile, "utf8"));
|
|
30758
30884
|
return Array.isArray(data) && data.length > 0;
|
|
30759
30885
|
} catch (error) {
|
|
30760
|
-
const
|
|
30886
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
30761
30887
|
daemonLog(
|
|
30762
|
-
`windows proxy: could not read windows sessions.json: ${
|
|
30888
|
+
`windows proxy: could not read windows sessions.json: ${message3}`
|
|
30763
30889
|
);
|
|
30764
30890
|
return false;
|
|
30765
30891
|
}
|
|
@@ -30786,8 +30912,8 @@ async function discoverWindowsSessions(conn) {
|
|
|
30786
30912
|
try {
|
|
30787
30913
|
await conn.ensure();
|
|
30788
30914
|
} catch (error) {
|
|
30789
|
-
const
|
|
30790
|
-
daemonLog(`windows proxy: discovery failed: ${
|
|
30915
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
30916
|
+
daemonLog(`windows proxy: discovery failed: ${message3}`);
|
|
30791
30917
|
}
|
|
30792
30918
|
}
|
|
30793
30919
|
|
|
@@ -30825,11 +30951,11 @@ async function forwardWindowsCreate(conn, state, client, data) {
|
|
|
30825
30951
|
state.pendingCreators.push({ client, timer });
|
|
30826
30952
|
conn.write(stripOutboundSessionId(data));
|
|
30827
30953
|
} catch (error) {
|
|
30828
|
-
const
|
|
30829
|
-
daemonLog(`windows proxy: forwardCreate failed: ${
|
|
30954
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
30955
|
+
daemonLog(`windows proxy: forwardCreate failed: ${message3}`);
|
|
30830
30956
|
sendTo(client, {
|
|
30831
30957
|
type: "error",
|
|
30832
|
-
message: `Windows session unavailable: ${
|
|
30958
|
+
message: `Windows session unavailable: ${message3}`
|
|
30833
30959
|
});
|
|
30834
30960
|
}
|
|
30835
30961
|
}
|
|
@@ -30867,10 +30993,10 @@ function takePendingCreator(state) {
|
|
|
30867
30993
|
clearTimeout(pending.timer);
|
|
30868
30994
|
return pending.client;
|
|
30869
30995
|
}
|
|
30870
|
-
function failPendingCreators(state,
|
|
30996
|
+
function failPendingCreators(state, message3) {
|
|
30871
30997
|
for (const { client, timer } of state.pendingCreators) {
|
|
30872
30998
|
clearTimeout(timer);
|
|
30873
|
-
sendTo(client, { type: "error", message:
|
|
30999
|
+
sendTo(client, { type: "error", message: message3 });
|
|
30874
31000
|
}
|
|
30875
31001
|
state.pendingCreators = [];
|
|
30876
31002
|
}
|
|
@@ -31010,9 +31136,9 @@ async function healWindowsDaemon() {
|
|
|
31010
31136
|
try {
|
|
31011
31137
|
await runOnWindowsHost("assist update", UPDATE_TIMEOUT_MS);
|
|
31012
31138
|
} catch (error) {
|
|
31013
|
-
const
|
|
31139
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
31014
31140
|
daemonLog(
|
|
31015
|
-
`windows daemon: auto-heal: \`assist update\` failed: ${
|
|
31141
|
+
`windows daemon: auto-heal: \`assist update\` failed: ${message3}`
|
|
31016
31142
|
);
|
|
31017
31143
|
throw error;
|
|
31018
31144
|
}
|
|
@@ -31021,7 +31147,7 @@ async function healWindowsDaemon() {
|
|
|
31021
31147
|
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
31022
31148
|
}
|
|
31023
31149
|
function runOnWindowsHost(command, timeoutMs) {
|
|
31024
|
-
return new Promise((
|
|
31150
|
+
return new Promise((resolve21, reject) => {
|
|
31025
31151
|
const child = spawn12("pwsh.exe", ["-Command", command], {
|
|
31026
31152
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31027
31153
|
});
|
|
@@ -31041,7 +31167,7 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
31041
31167
|
});
|
|
31042
31168
|
child.on("exit", (code) => {
|
|
31043
31169
|
clearTimeout(timer);
|
|
31044
|
-
if (code === 0)
|
|
31170
|
+
if (code === 0) resolve21();
|
|
31045
31171
|
else
|
|
31046
31172
|
reject(
|
|
31047
31173
|
new Error(
|
|
@@ -31179,11 +31305,11 @@ async function autoHealWindowsDaemon(conn, state, heal, version2) {
|
|
|
31179
31305
|
daemonLog("windows proxy: heal complete, reconnecting to windows daemon");
|
|
31180
31306
|
await conn.ensure();
|
|
31181
31307
|
} catch (error) {
|
|
31182
|
-
const
|
|
31183
|
-
daemonLog(`windows proxy: auto-heal failed: ${
|
|
31308
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
31309
|
+
daemonLog(`windows proxy: auto-heal failed: ${message3}`);
|
|
31184
31310
|
state.broadcast({
|
|
31185
31311
|
type: "error",
|
|
31186
|
-
message: `Windows host auto-update failed: ${
|
|
31312
|
+
message: `Windows host auto-update failed: ${message3}`
|
|
31187
31313
|
});
|
|
31188
31314
|
}
|
|
31189
31315
|
}
|
|
@@ -31972,7 +32098,7 @@ function handleConnection(socket, manager) {
|
|
|
31972
32098
|
import { unlinkSync as unlinkSync22, writeFileSync as writeFileSync43 } from "fs";
|
|
31973
32099
|
|
|
31974
32100
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
31975
|
-
import { readFileSync as
|
|
32101
|
+
import { readFileSync as readFileSync52 } from "fs";
|
|
31976
32102
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
31977
32103
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
31978
32104
|
const timer = setInterval(() => {
|
|
@@ -31983,7 +32109,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
31983
32109
|
}
|
|
31984
32110
|
function ownsPidFile() {
|
|
31985
32111
|
try {
|
|
31986
|
-
return
|
|
32112
|
+
return readFileSync52(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
31987
32113
|
} catch {
|
|
31988
32114
|
return false;
|
|
31989
32115
|
}
|
|
@@ -32400,13 +32526,13 @@ function buildLimitsSegment(rateLimits) {
|
|
|
32400
32526
|
}
|
|
32401
32527
|
|
|
32402
32528
|
// src/commands/readGitBranch.ts
|
|
32403
|
-
import { readFileSync as
|
|
32404
|
-
import { isAbsolute as
|
|
32529
|
+
import { readFileSync as readFileSync54, statSync as statSync14 } from "fs";
|
|
32530
|
+
import { isAbsolute as isAbsolute4, join as join75, resolve as resolve19 } from "path";
|
|
32405
32531
|
function resolveGitDir(cwd) {
|
|
32406
32532
|
const dotGit = join75(cwd, ".git");
|
|
32407
32533
|
let stat3;
|
|
32408
32534
|
try {
|
|
32409
|
-
stat3 =
|
|
32535
|
+
stat3 = statSync14(dotGit);
|
|
32410
32536
|
} catch {
|
|
32411
32537
|
return null;
|
|
32412
32538
|
}
|
|
@@ -32415,7 +32541,7 @@ function resolveGitDir(cwd) {
|
|
|
32415
32541
|
}
|
|
32416
32542
|
let contents;
|
|
32417
32543
|
try {
|
|
32418
|
-
contents =
|
|
32544
|
+
contents = readFileSync54(dotGit, "utf8");
|
|
32419
32545
|
} catch {
|
|
32420
32546
|
return null;
|
|
32421
32547
|
}
|
|
@@ -32424,7 +32550,7 @@ function resolveGitDir(cwd) {
|
|
|
32424
32550
|
return null;
|
|
32425
32551
|
}
|
|
32426
32552
|
const gitDir = match[1].trim();
|
|
32427
|
-
return
|
|
32553
|
+
return isAbsolute4(gitDir) ? gitDir : resolve19(cwd, gitDir);
|
|
32428
32554
|
}
|
|
32429
32555
|
function readGitBranch(cwd) {
|
|
32430
32556
|
const gitDir = resolveGitDir(cwd);
|
|
@@ -32433,7 +32559,7 @@ function readGitBranch(cwd) {
|
|
|
32433
32559
|
}
|
|
32434
32560
|
let head;
|
|
32435
32561
|
try {
|
|
32436
|
-
head =
|
|
32562
|
+
head = readFileSync54(join75(gitDir, "HEAD"), "utf8");
|
|
32437
32563
|
} catch {
|
|
32438
32564
|
return null;
|
|
32439
32565
|
}
|
|
@@ -32789,7 +32915,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
32789
32915
|
}
|
|
32790
32916
|
|
|
32791
32917
|
// src/commands/update.ts
|
|
32792
|
-
import { execSync as
|
|
32918
|
+
import { execSync as execSync62 } from "child_process";
|
|
32793
32919
|
import * as path70 from "path";
|
|
32794
32920
|
|
|
32795
32921
|
// src/commands/restartDaemonAfterUpdate.ts
|
|
@@ -32813,7 +32939,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
32813
32939
|
if (resolved.split(path70.sep).includes("node_modules")) {
|
|
32814
32940
|
return true;
|
|
32815
32941
|
}
|
|
32816
|
-
const globalPrefix =
|
|
32942
|
+
const globalPrefix = execSync62("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
32817
32943
|
return resolved.toLowerCase().startsWith(path70.resolve(globalPrefix).toLowerCase());
|
|
32818
32944
|
} catch {
|
|
32819
32945
|
return false;
|
|
@@ -32824,18 +32950,18 @@ async function update2() {
|
|
|
32824
32950
|
console.log(`Assist is installed at: ${installDir}`);
|
|
32825
32951
|
if (isGitRepo(installDir)) {
|
|
32826
32952
|
console.log("Detected git repo installation, pulling latest...");
|
|
32827
|
-
|
|
32953
|
+
execSync62("git pull", { cwd: installDir, stdio: "inherit" });
|
|
32828
32954
|
console.log("Installing dependencies...");
|
|
32829
|
-
|
|
32955
|
+
execSync62("npm i", { cwd: installDir, stdio: "inherit" });
|
|
32830
32956
|
console.log("Building...");
|
|
32831
|
-
|
|
32957
|
+
execSync62("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
32832
32958
|
console.log("Syncing commands...");
|
|
32833
|
-
|
|
32959
|
+
execSync62("assist sync", { stdio: "inherit" });
|
|
32834
32960
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
32835
32961
|
console.log("Detected global npm installation, updating...");
|
|
32836
|
-
|
|
32962
|
+
execSync62("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
32837
32963
|
console.log("Syncing commands...");
|
|
32838
|
-
|
|
32964
|
+
execSync62("assist sync", { stdio: "inherit" });
|
|
32839
32965
|
} else {
|
|
32840
32966
|
console.error(
|
|
32841
32967
|
"Could not determine installation method. Expected a git repo or global npm install."
|