@staff0rd/assist 0.533.2 → 0.534.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/allowed.cli-writes +1 -0
- package/dist/allowed.cli-writes +1 -0
- package/dist/commands/sessions/web/bundle.js +391 -391
- package/dist/index.js +894 -755
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.534.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -149,8 +149,8 @@ import { dirname as dirname2, join as join2 } from "path";
|
|
|
149
149
|
|
|
150
150
|
// src/commands/backlog/getCurrentOrigin.ts
|
|
151
151
|
import { execFileSync } from "child_process";
|
|
152
|
-
function stripLeadingSlashes(
|
|
153
|
-
return
|
|
152
|
+
function stripLeadingSlashes(path73) {
|
|
153
|
+
return path73.replace(/^\/+/, "");
|
|
154
154
|
}
|
|
155
155
|
function normalizeOrigin(raw) {
|
|
156
156
|
const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
@@ -225,9 +225,9 @@ function findGitLink(dir) {
|
|
|
225
225
|
}
|
|
226
226
|
return null;
|
|
227
227
|
}
|
|
228
|
-
function isFile(
|
|
228
|
+
function isFile(path73) {
|
|
229
229
|
try {
|
|
230
|
-
return statSync(
|
|
230
|
+
return statSync(path73).isFile();
|
|
231
231
|
} catch {
|
|
232
232
|
return false;
|
|
233
233
|
}
|
|
@@ -246,9 +246,9 @@ function linkedGitDirParent(gitDir) {
|
|
|
246
246
|
const match = /^(.*)[/\\]worktrees[/\\][^/\\]+[/\\]?$/.exec(gitDir);
|
|
247
247
|
return match ? match[1] : null;
|
|
248
248
|
}
|
|
249
|
-
function readTrimmed(
|
|
249
|
+
function readTrimmed(path73) {
|
|
250
250
|
try {
|
|
251
|
-
const content = readFileSync(
|
|
251
|
+
const content = readFileSync(path73, "utf8").trim();
|
|
252
252
|
return content === "" ? null : content;
|
|
253
253
|
} catch {
|
|
254
254
|
return null;
|
|
@@ -261,10 +261,10 @@ function absolute(target, from) {
|
|
|
261
261
|
// src/shared/loadRawYaml.ts
|
|
262
262
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
263
263
|
import { parse as parseYaml } from "yaml";
|
|
264
|
-
function loadRawYaml(
|
|
265
|
-
if (!existsSync2(
|
|
264
|
+
function loadRawYaml(path73) {
|
|
265
|
+
if (!existsSync2(path73)) return {};
|
|
266
266
|
try {
|
|
267
|
-
const content = readFileSync2(
|
|
267
|
+
const content = readFileSync2(path73, "utf8");
|
|
268
268
|
return parseYaml(content) || {};
|
|
269
269
|
} catch {
|
|
270
270
|
return {};
|
|
@@ -336,8 +336,8 @@ function mergeRawConfigs(globalRaw, projectRaw) {
|
|
|
336
336
|
// src/commands/backlog/originDisplayName.ts
|
|
337
337
|
function originDisplayName(origin) {
|
|
338
338
|
if (origin.startsWith("local:")) {
|
|
339
|
-
const
|
|
340
|
-
const segments =
|
|
339
|
+
const path73 = origin.slice("local:".length).replace(/\/+$/, "");
|
|
340
|
+
const segments = path73.split("/").filter(Boolean);
|
|
341
341
|
return segments[segments.length - 1] ?? origin;
|
|
342
342
|
}
|
|
343
343
|
const firstSlash = origin.indexOf("/");
|
|
@@ -1746,8 +1746,8 @@ function findUnmergedPaths() {
|
|
|
1746
1746
|
}
|
|
1747
1747
|
const found = /* @__PURE__ */ new Set();
|
|
1748
1748
|
for (const line of output.split("\n")) {
|
|
1749
|
-
const
|
|
1750
|
-
if (
|
|
1749
|
+
const path73 = line.split(" ")[1];
|
|
1750
|
+
if (path73) found.add(path73.trim());
|
|
1751
1751
|
}
|
|
1752
1752
|
return [...found];
|
|
1753
1753
|
}
|
|
@@ -1857,8 +1857,8 @@ function getPreferredRemoteRepo(cwd) {
|
|
|
1857
1857
|
function gitRefUrl(kind, ref, cwd) {
|
|
1858
1858
|
const repo = getPreferredRemoteRepo(cwd);
|
|
1859
1859
|
if (!repo) return void 0;
|
|
1860
|
-
const
|
|
1861
|
-
return `https://github.com/${repo.org}/${repo.repo}/${
|
|
1860
|
+
const path73 = kind === "branch" ? "tree" : "commit";
|
|
1861
|
+
return `https://github.com/${repo.org}/${repo.repo}/${path73}/${ref}`;
|
|
1862
1862
|
}
|
|
1863
1863
|
|
|
1864
1864
|
// src/commands/commit/collectCommitRefs.ts
|
|
@@ -3833,11 +3833,11 @@ function enumValues(node) {
|
|
|
3833
3833
|
function opaqueConfigNode(inner, base) {
|
|
3834
3834
|
return { ...base, kind: "other", type: leafTypeOf(inner) };
|
|
3835
3835
|
}
|
|
3836
|
-
function build(node,
|
|
3836
|
+
function build(node, path73) {
|
|
3837
3837
|
const { inner, defaultValue, optional } = unwrapSchemaNode(node);
|
|
3838
3838
|
const secret = isSecretSchemaNode(node) || isSecretSchemaNode(inner);
|
|
3839
3839
|
const base = {
|
|
3840
|
-
path:
|
|
3840
|
+
path: path73,
|
|
3841
3841
|
...optional ? { optional: true } : {},
|
|
3842
3842
|
...defaultValue === void 0 ? {} : { defaultValue },
|
|
3843
3843
|
...secret ? { secret: true } : {}
|
|
@@ -3856,9 +3856,9 @@ function segmentText(segment) {
|
|
|
3856
3856
|
if (segment.kind === "index") return `[${segment.index}]`;
|
|
3857
3857
|
return "[]";
|
|
3858
3858
|
}
|
|
3859
|
-
function formatConfigPath(
|
|
3859
|
+
function formatConfigPath(path73) {
|
|
3860
3860
|
let text17 = "";
|
|
3861
|
-
for (const segment of
|
|
3861
|
+
for (const segment of path73) {
|
|
3862
3862
|
const dotted = segment.kind === "key" || segment.kind === "entry";
|
|
3863
3863
|
const rendered = segmentText(segment);
|
|
3864
3864
|
text17 += dotted && text17 ? `.${rendered}` : rendered;
|
|
@@ -4471,9 +4471,9 @@ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
|
|
|
4471
4471
|
|
|
4472
4472
|
// src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
|
|
4473
4473
|
import { minimatch as minimatch2 } from "minimatch";
|
|
4474
|
-
function resolveStringsAtPath(data,
|
|
4474
|
+
function resolveStringsAtPath(data, path73) {
|
|
4475
4475
|
let current = data;
|
|
4476
|
-
for (const segment of
|
|
4476
|
+
for (const segment of path73.split(".")) {
|
|
4477
4477
|
if (current === null || typeof current !== "object") return [];
|
|
4478
4478
|
current = current[segment];
|
|
4479
4479
|
}
|
|
@@ -4486,10 +4486,10 @@ function resolveStringsAtPath(data, path71) {
|
|
|
4486
4486
|
}
|
|
4487
4487
|
function findRuleViolations(data, rule) {
|
|
4488
4488
|
const violations = [];
|
|
4489
|
-
for (const
|
|
4490
|
-
for (const value of resolveStringsAtPath(data,
|
|
4489
|
+
for (const path73 of rule.paths) {
|
|
4490
|
+
for (const value of resolveStringsAtPath(data, path73)) {
|
|
4491
4491
|
if (minimatch2(value, rule.disallowed))
|
|
4492
|
-
violations.push({ file: rule.file, path:
|
|
4492
|
+
violations.push({ file: rule.file, path: path73, value });
|
|
4493
4493
|
}
|
|
4494
4494
|
}
|
|
4495
4495
|
return violations;
|
|
@@ -4528,8 +4528,8 @@ function forbiddenStrings() {
|
|
|
4528
4528
|
process.exit(0);
|
|
4529
4529
|
}
|
|
4530
4530
|
console.log("Forbidden strings found:\n");
|
|
4531
|
-
for (const { file, path:
|
|
4532
|
-
console.log(` ${file} ${
|
|
4531
|
+
for (const { file, path: path73, value } of violations) {
|
|
4532
|
+
console.log(` ${file} ${path73}: ${value}`);
|
|
4533
4533
|
}
|
|
4534
4534
|
console.log(`
|
|
4535
4535
|
Total: ${violations.length} forbidden string(s).`);
|
|
@@ -4844,15 +4844,15 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
4844
4844
|
} catch {
|
|
4845
4845
|
return baseline;
|
|
4846
4846
|
}
|
|
4847
|
-
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((
|
|
4848
|
-
for (const
|
|
4847
|
+
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path73) => MIGRATION_FILE3.test(basename2(path73)));
|
|
4848
|
+
for (const path73 of paths) {
|
|
4849
4849
|
try {
|
|
4850
|
-
const content = execSync14(`git show "${ref}:${
|
|
4850
|
+
const content = execSync14(`git show "${ref}:${path73}"`, {
|
|
4851
4851
|
encoding: "utf8",
|
|
4852
4852
|
maxBuffer: 16 * 1024 * 1024,
|
|
4853
4853
|
stdio: ["pipe", "pipe", "pipe"]
|
|
4854
4854
|
});
|
|
4855
|
-
baseline.set(basename2(
|
|
4855
|
+
baseline.set(basename2(path73), content);
|
|
4856
4856
|
} catch {
|
|
4857
4857
|
}
|
|
4858
4858
|
}
|
|
@@ -6286,10 +6286,10 @@ var hooksSettings = {
|
|
|
6286
6286
|
}
|
|
6287
6287
|
};
|
|
6288
6288
|
function ensureHooksSettings() {
|
|
6289
|
-
const
|
|
6290
|
-
mkdirSync5(dirname13(
|
|
6291
|
-
writeFileSync15(
|
|
6292
|
-
return
|
|
6289
|
+
const path73 = daemonPaths.hooksSettings;
|
|
6290
|
+
mkdirSync5(dirname13(path73), { recursive: true });
|
|
6291
|
+
writeFileSync15(path73, JSON.stringify(hooksSettings, null, 2));
|
|
6292
|
+
return path73;
|
|
6293
6293
|
}
|
|
6294
6294
|
|
|
6295
6295
|
// src/shared/spawnInherit.ts
|
|
@@ -6587,9 +6587,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
|
|
|
6587
6587
|
function backupLocalBacklogFiles(dir) {
|
|
6588
6588
|
const moved = [];
|
|
6589
6589
|
for (const name of LOCAL_FILES) {
|
|
6590
|
-
const
|
|
6591
|
-
if (existsSync19(
|
|
6592
|
-
renameSync(
|
|
6590
|
+
const path73 = join15(dir, ".assist", name);
|
|
6591
|
+
if (existsSync19(path73)) {
|
|
6592
|
+
renameSync(path73, `${path73}.bak`);
|
|
6593
6593
|
moved.push(`${name} \u2192 ${name}.bak`);
|
|
6594
6594
|
}
|
|
6595
6595
|
}
|
|
@@ -7068,8 +7068,8 @@ var backlogItemSchema = z4.strictObject({
|
|
|
7068
7068
|
var backlogFileSchema = z4.array(backlogItemSchema);
|
|
7069
7069
|
|
|
7070
7070
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
7071
|
-
function parseBacklogJsonl(
|
|
7072
|
-
const content = readFileSync15(
|
|
7071
|
+
function parseBacklogJsonl(path73) {
|
|
7072
|
+
const content = readFileSync15(path73, "utf8").trim();
|
|
7073
7073
|
if (content.length === 0) return [];
|
|
7074
7074
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
7075
7075
|
}
|
|
@@ -7856,24 +7856,24 @@ function getOwnerPath(itemId2) {
|
|
|
7856
7856
|
function recordSignalOwner(itemId2) {
|
|
7857
7857
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
7858
7858
|
if (!sessionId) return;
|
|
7859
|
-
const
|
|
7860
|
-
mkdirSync7(dirname15(
|
|
7861
|
-
writeFileSync17(
|
|
7859
|
+
const path73 = getOwnerPath(itemId2);
|
|
7860
|
+
mkdirSync7(dirname15(path73), { recursive: true });
|
|
7861
|
+
writeFileSync17(path73, JSON.stringify({ sessionId }));
|
|
7862
7862
|
}
|
|
7863
7863
|
function readSignalOwner(itemId2) {
|
|
7864
|
-
const
|
|
7865
|
-
if (!existsSync23(
|
|
7864
|
+
const path73 = getOwnerPath(itemId2);
|
|
7865
|
+
if (!existsSync23(path73)) return void 0;
|
|
7866
7866
|
try {
|
|
7867
|
-
const parsed = JSON.parse(readFileSync16(
|
|
7867
|
+
const parsed = JSON.parse(readFileSync16(path73, "utf8"));
|
|
7868
7868
|
return parsed.sessionId;
|
|
7869
7869
|
} catch {
|
|
7870
7870
|
return void 0;
|
|
7871
7871
|
}
|
|
7872
7872
|
}
|
|
7873
7873
|
function clearSignalOwner(itemId2) {
|
|
7874
|
-
const
|
|
7874
|
+
const path73 = getOwnerPath(itemId2);
|
|
7875
7875
|
try {
|
|
7876
|
-
rmSync(
|
|
7876
|
+
rmSync(path73);
|
|
7877
7877
|
} catch {
|
|
7878
7878
|
}
|
|
7879
7879
|
}
|
|
@@ -7910,19 +7910,19 @@ function resolveSignalTarget(event, data) {
|
|
|
7910
7910
|
function writeSignal(event, data) {
|
|
7911
7911
|
const target = resolveSignalTarget(event, data);
|
|
7912
7912
|
if (!target) return;
|
|
7913
|
-
const
|
|
7914
|
-
if (!
|
|
7913
|
+
const path73 = getSignalPath(target);
|
|
7914
|
+
if (!path73) return;
|
|
7915
7915
|
const signal = { event, sessionId: target, ...data };
|
|
7916
|
-
mkdirSync8(dirname16(
|
|
7917
|
-
writeFileSync18(
|
|
7916
|
+
mkdirSync8(dirname16(path73), { recursive: true });
|
|
7917
|
+
writeFileSync18(path73, JSON.stringify(signal));
|
|
7918
7918
|
}
|
|
7919
7919
|
|
|
7920
7920
|
// src/commands/backlog/readSignal.ts
|
|
7921
7921
|
function readSignal() {
|
|
7922
|
-
const
|
|
7923
|
-
if (!
|
|
7922
|
+
const path73 = getSignalPath();
|
|
7923
|
+
if (!path73 || !existsSync24(path73)) return void 0;
|
|
7924
7924
|
try {
|
|
7925
|
-
return JSON.parse(readFileSync17(
|
|
7925
|
+
return JSON.parse(readFileSync17(path73, "utf8"));
|
|
7926
7926
|
} catch {
|
|
7927
7927
|
return void 0;
|
|
7928
7928
|
}
|
|
@@ -8119,13 +8119,13 @@ function activityPath(sessionId) {
|
|
|
8119
8119
|
function emitActivity(activity2) {
|
|
8120
8120
|
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
8121
8121
|
if (!sessionId) return;
|
|
8122
|
-
const
|
|
8123
|
-
mkdirSync9(dirname17(
|
|
8124
|
-
writeFileSync19(
|
|
8122
|
+
const path73 = activityPath(sessionId);
|
|
8123
|
+
mkdirSync9(dirname17(path73), { recursive: true });
|
|
8124
|
+
writeFileSync19(path73, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
8125
8125
|
}
|
|
8126
|
-
function readActivity(
|
|
8126
|
+
function readActivity(path73) {
|
|
8127
8127
|
try {
|
|
8128
|
-
return JSON.parse(readFileSync18(
|
|
8128
|
+
return JSON.parse(readFileSync18(path73, "utf8"));
|
|
8129
8129
|
} catch {
|
|
8130
8130
|
return void 0;
|
|
8131
8131
|
}
|
|
@@ -8135,9 +8135,9 @@ function reconcileActivity(sessionId, activity2) {
|
|
|
8135
8135
|
removeActivity(sessionId);
|
|
8136
8136
|
return;
|
|
8137
8137
|
}
|
|
8138
|
-
const
|
|
8139
|
-
mkdirSync9(dirname17(
|
|
8140
|
-
writeFileSync19(
|
|
8138
|
+
const path73 = activityPath(sessionId);
|
|
8139
|
+
mkdirSync9(dirname17(path73), { recursive: true });
|
|
8140
|
+
writeFileSync19(path73, JSON.stringify(activity2));
|
|
8141
8141
|
}
|
|
8142
8142
|
function removeActivity(sessionId) {
|
|
8143
8143
|
try {
|
|
@@ -9380,10 +9380,10 @@ function getStorePath(filename) {
|
|
|
9380
9380
|
return join24(getStoreDir(), filename);
|
|
9381
9381
|
}
|
|
9382
9382
|
function loadJson(filename) {
|
|
9383
|
-
const
|
|
9384
|
-
if (existsSync27(
|
|
9383
|
+
const path73 = getStorePath(filename);
|
|
9384
|
+
if (existsSync27(path73)) {
|
|
9385
9385
|
try {
|
|
9386
|
-
return JSON.parse(readFileSync19(
|
|
9386
|
+
return JSON.parse(readFileSync19(path73, "utf8"));
|
|
9387
9387
|
} catch {
|
|
9388
9388
|
return {};
|
|
9389
9389
|
}
|
|
@@ -9402,22 +9402,22 @@ function saveJson(filename, data) {
|
|
|
9402
9402
|
var REGISTRY_FILE = "worktrees.json";
|
|
9403
9403
|
function readWorktreeRegistry() {
|
|
9404
9404
|
const data = loadJson(REGISTRY_FILE);
|
|
9405
|
-
return Object.entries(data).filter(([, record]) => !record.reaped).map(([
|
|
9405
|
+
return Object.entries(data).filter(([, record]) => !record.reaped).map(([path73, record]) => ({ path: path73, ...record }));
|
|
9406
9406
|
}
|
|
9407
|
-
function worktreeAttributionIncludingReaped(
|
|
9408
|
-
const record = loadJson(REGISTRY_FILE)[
|
|
9407
|
+
function worktreeAttributionIncludingReaped(path73) {
|
|
9408
|
+
const record = loadJson(REGISTRY_FILE)[path73];
|
|
9409
9409
|
return record ? { clone: record.clone, origin: record.origin } : void 0;
|
|
9410
9410
|
}
|
|
9411
|
-
function recordWorktree(
|
|
9411
|
+
function recordWorktree(path73, clone, origin) {
|
|
9412
9412
|
const data = loadJson(REGISTRY_FILE);
|
|
9413
|
-
data[
|
|
9413
|
+
data[path73] = { clone, origin };
|
|
9414
9414
|
saveJson(REGISTRY_FILE, data);
|
|
9415
9415
|
}
|
|
9416
|
-
function forgetWorktree(
|
|
9416
|
+
function forgetWorktree(path73) {
|
|
9417
9417
|
const data = loadJson(REGISTRY_FILE);
|
|
9418
|
-
const record = data[
|
|
9418
|
+
const record = data[path73];
|
|
9419
9419
|
if (!record || record.reaped) return;
|
|
9420
|
-
data[
|
|
9420
|
+
data[path73] = { ...record, reaped: true };
|
|
9421
9421
|
saveJson(REGISTRY_FILE, data);
|
|
9422
9422
|
}
|
|
9423
9423
|
|
|
@@ -10173,8 +10173,8 @@ async function loadCommittedPaths(cwd, sessionId) {
|
|
|
10173
10173
|
for (const commit2 of commits2) {
|
|
10174
10174
|
const resolved = await resolveCommit(cwd, commit2.sha);
|
|
10175
10175
|
if (!resolved) continue;
|
|
10176
|
-
for (const
|
|
10177
|
-
if (!bases.has(
|
|
10176
|
+
for (const path73 of resolved.paths) {
|
|
10177
|
+
if (!bases.has(path73)) bases.set(path73, resolved.base);
|
|
10178
10178
|
}
|
|
10179
10179
|
}
|
|
10180
10180
|
return { commits: commits2, bases };
|
|
@@ -10192,16 +10192,16 @@ async function itemChangeSet(cwd, sessionId) {
|
|
|
10192
10192
|
}
|
|
10193
10193
|
function groupByBase(bases) {
|
|
10194
10194
|
const groups = /* @__PURE__ */ new Map();
|
|
10195
|
-
for (const [
|
|
10195
|
+
for (const [path73, base] of bases) {
|
|
10196
10196
|
const paths = groups.get(base);
|
|
10197
|
-
if (paths) paths.push(
|
|
10198
|
-
else groups.set(base, [
|
|
10197
|
+
if (paths) paths.push(path73);
|
|
10198
|
+
else groups.set(base, [path73]);
|
|
10199
10199
|
}
|
|
10200
10200
|
return [...groups].map(([base, paths]) => ({ base, paths: paths.sort() }));
|
|
10201
10201
|
}
|
|
10202
10202
|
async function dirtyPaths(cwd, bases) {
|
|
10203
10203
|
const output = await execGit(cwd, ["diff", "--name-only", "HEAD"]);
|
|
10204
|
-
return output.split("\n").filter((
|
|
10204
|
+
return output.split("\n").filter((path73) => path73 && !bases.has(path73)).sort();
|
|
10205
10205
|
}
|
|
10206
10206
|
|
|
10207
10207
|
// src/commands/sessions/web/scopedDiff.ts
|
|
@@ -10210,8 +10210,8 @@ async function scopedDiff(cwd, session, scope) {
|
|
|
10210
10210
|
if (scope.kind === "commit") return commitDiff(cwd, scope.sha);
|
|
10211
10211
|
return await trackedScopeDiff(cwd, session, scope) + await untrackedDiff(cwd);
|
|
10212
10212
|
}
|
|
10213
|
-
async function untrackedFileDiff(cwd,
|
|
10214
|
-
return execGit(cwd, ["diff", "--no-index", "--", "/dev/null",
|
|
10213
|
+
async function untrackedFileDiff(cwd, path73) {
|
|
10214
|
+
return execGit(cwd, ["diff", "--no-index", "--", "/dev/null", path73], {
|
|
10215
10215
|
maxBuffer: MAX_DIFF_BYTES,
|
|
10216
10216
|
allowFailure: true
|
|
10217
10217
|
});
|
|
@@ -10224,7 +10224,7 @@ async function untrackedDiff(cwd) {
|
|
|
10224
10224
|
]);
|
|
10225
10225
|
const paths = list5.split("\n").filter(Boolean);
|
|
10226
10226
|
const diffs = await Promise.all(
|
|
10227
|
-
paths.map((
|
|
10227
|
+
paths.map((path73) => untrackedFileDiff(cwd, path73))
|
|
10228
10228
|
);
|
|
10229
10229
|
return diffs.join("");
|
|
10230
10230
|
}
|
|
@@ -10317,9 +10317,9 @@ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10
|
|
|
10317
10317
|
function repoRoot(cwd) {
|
|
10318
10318
|
return resolve10(toGitCwd(cwd));
|
|
10319
10319
|
}
|
|
10320
|
-
function resolveWithinCwd(cwd,
|
|
10320
|
+
function resolveWithinCwd(cwd, path73) {
|
|
10321
10321
|
const root = repoRoot(cwd);
|
|
10322
|
-
const target = resolve10(root,
|
|
10322
|
+
const target = resolve10(root, path73);
|
|
10323
10323
|
const rel = relative2(root, target);
|
|
10324
10324
|
if (rel === "" || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
10325
10325
|
return target;
|
|
@@ -10329,14 +10329,14 @@ function resolveWithinCwd(cwd, path71) {
|
|
|
10329
10329
|
function getFileTarget(req, res) {
|
|
10330
10330
|
const cwd = getCwdParam(req, res);
|
|
10331
10331
|
if (!cwd) return null;
|
|
10332
|
-
const
|
|
10332
|
+
const path73 = new URL(req.url ?? "/", "http://localhost").searchParams.get(
|
|
10333
10333
|
"path"
|
|
10334
10334
|
);
|
|
10335
|
-
if (!
|
|
10335
|
+
if (!path73) {
|
|
10336
10336
|
respondJson(res, 400, { error: "Missing path" });
|
|
10337
10337
|
return null;
|
|
10338
10338
|
}
|
|
10339
|
-
const target = resolveWithinCwd(cwd,
|
|
10339
|
+
const target = resolveWithinCwd(cwd, path73);
|
|
10340
10340
|
if (!target) {
|
|
10341
10341
|
respondJson(res, 400, { error: "Path outside cwd" });
|
|
10342
10342
|
return null;
|
|
@@ -10405,35 +10405,35 @@ function isPlainRecord(value) {
|
|
|
10405
10405
|
}
|
|
10406
10406
|
|
|
10407
10407
|
// src/shared/mapConfigSecrets.ts
|
|
10408
|
-
function mapChildren(value,
|
|
10408
|
+
function mapChildren(value, path73, childNode, map) {
|
|
10409
10409
|
if (!isPlainRecord(value)) return value;
|
|
10410
10410
|
return Object.fromEntries(
|
|
10411
10411
|
Object.entries(value).map(([name, child]) => [
|
|
10412
10412
|
name,
|
|
10413
|
-
walk(child, [...
|
|
10413
|
+
walk(child, [...path73, name], childNode(name), map)
|
|
10414
10414
|
])
|
|
10415
10415
|
);
|
|
10416
10416
|
}
|
|
10417
|
-
function mapItems(value,
|
|
10417
|
+
function mapItems(value, path73, item, map) {
|
|
10418
10418
|
if (!Array.isArray(value)) return value;
|
|
10419
|
-
return value.map((entry, index3) => walk(entry, [...
|
|
10419
|
+
return value.map((entry, index3) => walk(entry, [...path73, index3], item, map));
|
|
10420
10420
|
}
|
|
10421
|
-
function walk(value,
|
|
10421
|
+
function walk(value, path73, node, map) {
|
|
10422
10422
|
if (!node || value === void 0 || value === null) return value;
|
|
10423
|
-
if (node.secret) return map(value,
|
|
10423
|
+
if (node.secret) return map(value, path73);
|
|
10424
10424
|
switch (node.kind) {
|
|
10425
10425
|
case "object":
|
|
10426
10426
|
case "unionOfObjects":
|
|
10427
10427
|
return mapChildren(
|
|
10428
10428
|
value,
|
|
10429
|
-
|
|
10429
|
+
path73,
|
|
10430
10430
|
(name) => configNodeField(node, name),
|
|
10431
10431
|
map
|
|
10432
10432
|
);
|
|
10433
10433
|
case "objectList":
|
|
10434
|
-
return mapItems(value,
|
|
10434
|
+
return mapItems(value, path73, node.item, map);
|
|
10435
10435
|
case "record":
|
|
10436
|
-
return mapChildren(value,
|
|
10436
|
+
return mapChildren(value, path73, () => node.value, map);
|
|
10437
10437
|
default:
|
|
10438
10438
|
return value;
|
|
10439
10439
|
}
|
|
@@ -10465,9 +10465,9 @@ function isTraversable(value) {
|
|
|
10465
10465
|
function stepInto(current, key) {
|
|
10466
10466
|
return isTraversable(current) ? current[key] : void 0;
|
|
10467
10467
|
}
|
|
10468
|
-
function getNestedValue(obj,
|
|
10468
|
+
function getNestedValue(obj, path73) {
|
|
10469
10469
|
let current = obj;
|
|
10470
|
-
for (const key of
|
|
10470
|
+
for (const key of path73.split(".")) current = stepInto(current, key);
|
|
10471
10471
|
return current;
|
|
10472
10472
|
}
|
|
10473
10473
|
|
|
@@ -10552,9 +10552,9 @@ function step(node, segment) {
|
|
|
10552
10552
|
return void 0;
|
|
10553
10553
|
}
|
|
10554
10554
|
}
|
|
10555
|
-
function findConfigNode(root,
|
|
10555
|
+
function findConfigNode(root, path73) {
|
|
10556
10556
|
let current = root;
|
|
10557
|
-
for (const segment of
|
|
10557
|
+
for (const segment of path73) {
|
|
10558
10558
|
if (!current) return void 0;
|
|
10559
10559
|
current = step(current, segment);
|
|
10560
10560
|
}
|
|
@@ -10571,34 +10571,34 @@ function nameSegment(name) {
|
|
|
10571
10571
|
return name === RECORD_ENTRY_TOKEN ? { kind: "entry" } : { kind: "key", name };
|
|
10572
10572
|
}
|
|
10573
10573
|
function parseConfigPath(text17) {
|
|
10574
|
-
const
|
|
10574
|
+
const path73 = [];
|
|
10575
10575
|
let at2 = 0;
|
|
10576
10576
|
while (at2 < text17.length) {
|
|
10577
10577
|
if (text17[at2] === "[") {
|
|
10578
10578
|
const close = text17.indexOf("]", at2);
|
|
10579
10579
|
const segment = close === -1 ? void 0 : bracketSegment(text17.slice(at2 + 1, close));
|
|
10580
10580
|
if (!segment) return void 0;
|
|
10581
|
-
|
|
10581
|
+
path73.push(segment);
|
|
10582
10582
|
at2 = close + 1;
|
|
10583
10583
|
continue;
|
|
10584
10584
|
}
|
|
10585
10585
|
if (text17[at2] === ".") {
|
|
10586
|
-
if (
|
|
10586
|
+
if (path73.length === 0) return void 0;
|
|
10587
10587
|
at2 += 1;
|
|
10588
10588
|
}
|
|
10589
10589
|
const start3 = at2;
|
|
10590
10590
|
while (at2 < text17.length && text17[at2] !== "." && text17[at2] !== "[") at2 += 1;
|
|
10591
10591
|
const name = text17.slice(start3, at2);
|
|
10592
10592
|
if (!name) return void 0;
|
|
10593
|
-
|
|
10593
|
+
path73.push(nameSegment(name));
|
|
10594
10594
|
}
|
|
10595
|
-
return
|
|
10595
|
+
return path73;
|
|
10596
10596
|
}
|
|
10597
10597
|
|
|
10598
10598
|
// src/commands/config/configEntryNode.ts
|
|
10599
10599
|
function configEntryNode(root, key) {
|
|
10600
|
-
const
|
|
10601
|
-
return
|
|
10600
|
+
const path73 = parseConfigPath(key);
|
|
10601
|
+
return path73 ? findConfigNode(root, path73) : void 0;
|
|
10602
10602
|
}
|
|
10603
10603
|
|
|
10604
10604
|
// src/commands/config/readConfigEntries.ts
|
|
@@ -10703,7 +10703,7 @@ function findSynthesisForBranch(repoReviewsDir, branch2) {
|
|
|
10703
10703
|
const parent = dirname21(branchKeyPath);
|
|
10704
10704
|
const branchPrefix = basename7(branchKeyPath);
|
|
10705
10705
|
if (!existsSync29(parent)) return null;
|
|
10706
|
-
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join27(parent, name, "synthesis.md")).filter((
|
|
10706
|
+
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join27(parent, name, "synthesis.md")).filter((path73) => existsSync29(path73)).map((path73) => ({ path: path73, mtime: statSync4(path73).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
10707
10707
|
return synthesisFiles[0]?.path ?? null;
|
|
10708
10708
|
}
|
|
10709
10709
|
|
|
@@ -10733,12 +10733,12 @@ async function getReviewSynthesis(req, res) {
|
|
|
10733
10733
|
const cwd = getCwdParam(req, res);
|
|
10734
10734
|
if (!cwd) return;
|
|
10735
10735
|
try {
|
|
10736
|
-
const
|
|
10737
|
-
if (!
|
|
10736
|
+
const path73 = await resolveSynthesisPath(cwd);
|
|
10737
|
+
if (!path73) {
|
|
10738
10738
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
10739
10739
|
return;
|
|
10740
10740
|
}
|
|
10741
|
-
respondJson(res, 200, { synthesis: readFileSync21(
|
|
10741
|
+
respondJson(res, 200, { synthesis: readFileSync21(path73, "utf8") });
|
|
10742
10742
|
} catch {
|
|
10743
10743
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
10744
10744
|
}
|
|
@@ -10821,8 +10821,8 @@ function parseDiffNameStatus(output) {
|
|
|
10821
10821
|
if (!status3 || fields.length < 2) continue;
|
|
10822
10822
|
const category = categorize(status3[0]);
|
|
10823
10823
|
if (!category) continue;
|
|
10824
|
-
const
|
|
10825
|
-
if (
|
|
10824
|
+
const path73 = fields[fields.length - 1];
|
|
10825
|
+
if (path73) result[category].push(path73);
|
|
10826
10826
|
}
|
|
10827
10827
|
return result;
|
|
10828
10828
|
}
|
|
@@ -10958,21 +10958,21 @@ function subsequenceScore(text17, query) {
|
|
|
10958
10958
|
}
|
|
10959
10959
|
return score - Math.min(text17.length, MAX_LENGTH_PENALTY);
|
|
10960
10960
|
}
|
|
10961
|
-
function scoreFilePath(
|
|
10961
|
+
function scoreFilePath(path73, query) {
|
|
10962
10962
|
const needle = query.trim().toLowerCase();
|
|
10963
10963
|
if (!needle) return 0;
|
|
10964
|
-
const
|
|
10965
|
-
const inBasename = subsequenceScore(
|
|
10964
|
+
const basename23 = path73.slice(path73.lastIndexOf("/") + 1);
|
|
10965
|
+
const inBasename = subsequenceScore(basename23, needle);
|
|
10966
10966
|
if (inBasename !== null) return BASENAME_WEIGHT + inBasename;
|
|
10967
|
-
return subsequenceScore(
|
|
10967
|
+
return subsequenceScore(path73, needle);
|
|
10968
10968
|
}
|
|
10969
10969
|
|
|
10970
10970
|
// src/commands/sessions/web/rankFilePaths.ts
|
|
10971
10971
|
function rankFilePaths(paths, query, limit) {
|
|
10972
10972
|
const scored = [];
|
|
10973
|
-
for (const
|
|
10974
|
-
const score = scoreFilePath(
|
|
10975
|
-
if (score !== null) scored.push({ path:
|
|
10973
|
+
for (const path73 of paths) {
|
|
10974
|
+
const score = scoreFilePath(path73, query);
|
|
10975
|
+
if (score !== null) scored.push({ path: path73, score });
|
|
10976
10976
|
}
|
|
10977
10977
|
scored.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
|
|
10978
10978
|
return scored.slice(0, limit).map((entry) => entry.path);
|
|
@@ -11437,38 +11437,38 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
11437
11437
|
import { relative as relative3 } from "path";
|
|
11438
11438
|
|
|
11439
11439
|
// src/commands/sessions/web/revertPathChanges.ts
|
|
11440
|
-
async function isTracked(cwd,
|
|
11440
|
+
async function isTracked(cwd, path73) {
|
|
11441
11441
|
try {
|
|
11442
|
-
await execGit(cwd, ["ls-files", "--error-unmatch", "--",
|
|
11442
|
+
await execGit(cwd, ["ls-files", "--error-unmatch", "--", path73]);
|
|
11443
11443
|
return true;
|
|
11444
11444
|
} catch {
|
|
11445
11445
|
return false;
|
|
11446
11446
|
}
|
|
11447
11447
|
}
|
|
11448
|
-
async function isInHead(cwd,
|
|
11449
|
-
const listing = await execGit(cwd, ["ls-tree", "HEAD", "--",
|
|
11448
|
+
async function isInHead(cwd, path73) {
|
|
11449
|
+
const listing = await execGit(cwd, ["ls-tree", "HEAD", "--", path73]);
|
|
11450
11450
|
return listing.trim().length > 0;
|
|
11451
11451
|
}
|
|
11452
|
-
async function revertPathChanges(cwd,
|
|
11453
|
-
if (!await isTracked(cwd,
|
|
11454
|
-
await execGit(cwd, ["clean", "-f", "--",
|
|
11452
|
+
async function revertPathChanges(cwd, path73) {
|
|
11453
|
+
if (!await isTracked(cwd, path73)) {
|
|
11454
|
+
await execGit(cwd, ["clean", "-f", "--", path73]);
|
|
11455
11455
|
return;
|
|
11456
11456
|
}
|
|
11457
|
-
if (await isInHead(cwd,
|
|
11458
|
-
await execGit(cwd, ["checkout", "HEAD", "--",
|
|
11457
|
+
if (await isInHead(cwd, path73)) {
|
|
11458
|
+
await execGit(cwd, ["checkout", "HEAD", "--", path73]);
|
|
11459
11459
|
return;
|
|
11460
11460
|
}
|
|
11461
|
-
await execGit(cwd, ["rm", "-f", "--",
|
|
11461
|
+
await execGit(cwd, ["rm", "-f", "--", path73]);
|
|
11462
11462
|
}
|
|
11463
11463
|
|
|
11464
11464
|
// src/commands/sessions/web/revertDiffFile.ts
|
|
11465
11465
|
async function revertDiffFile(req, res) {
|
|
11466
11466
|
const resolved = getFileTarget(req, res);
|
|
11467
11467
|
if (!resolved) return;
|
|
11468
|
-
const
|
|
11468
|
+
const path73 = relative3(repoRoot(resolved.cwd), resolved.target);
|
|
11469
11469
|
try {
|
|
11470
|
-
await revertPathChanges(resolved.cwd,
|
|
11471
|
-
respondJson(res, 200, { reverted:
|
|
11470
|
+
await revertPathChanges(resolved.cwd, path73);
|
|
11471
|
+
respondJson(res, 200, { reverted: path73 });
|
|
11472
11472
|
} catch (error) {
|
|
11473
11473
|
respondJson(res, 500, {
|
|
11474
11474
|
error: error instanceof Error ? error.message : "Failed to revert file"
|
|
@@ -11549,11 +11549,11 @@ function coerceStructuredConfigValue(key, raw) {
|
|
|
11549
11549
|
};
|
|
11550
11550
|
}
|
|
11551
11551
|
function formatIssue(key, issue) {
|
|
11552
|
-
const
|
|
11552
|
+
const path73 = formatConfigPath([
|
|
11553
11553
|
{ kind: "key", name: key },
|
|
11554
11554
|
...issue.path.map(toSegment)
|
|
11555
11555
|
]);
|
|
11556
|
-
return `${
|
|
11556
|
+
return `${path73}: ${issue.message}`;
|
|
11557
11557
|
}
|
|
11558
11558
|
function toSegment(part) {
|
|
11559
11559
|
return typeof part === "number" ? { kind: "index", index: part } : { kind: "key", name: String(part) };
|
|
@@ -11648,9 +11648,9 @@ function coerceUnion(key, raw, types) {
|
|
|
11648
11648
|
}
|
|
11649
11649
|
|
|
11650
11650
|
// src/shared/valueAtConfigPath.ts
|
|
11651
|
-
function valueAtConfigPath(value,
|
|
11651
|
+
function valueAtConfigPath(value, path73) {
|
|
11652
11652
|
let current = value;
|
|
11653
|
-
for (const key of
|
|
11653
|
+
for (const key of path73) {
|
|
11654
11654
|
if (typeof key === "number") {
|
|
11655
11655
|
if (!Array.isArray(current)) return void 0;
|
|
11656
11656
|
current = current[key];
|
|
@@ -11667,7 +11667,7 @@ function restoreConfigSecrets(value, stored, node) {
|
|
|
11667
11667
|
return mapConfigSecrets(
|
|
11668
11668
|
value,
|
|
11669
11669
|
node,
|
|
11670
|
-
(secret,
|
|
11670
|
+
(secret, path73) => isRedactedSecret(secret) ? valueAtConfigPath(stored, path73) : secret
|
|
11671
11671
|
);
|
|
11672
11672
|
}
|
|
11673
11673
|
|
|
@@ -11716,8 +11716,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
11716
11716
|
}
|
|
11717
11717
|
return ensureObject(container, resolved);
|
|
11718
11718
|
}
|
|
11719
|
-
function setNestedValue(obj,
|
|
11720
|
-
const keys =
|
|
11719
|
+
function setNestedValue(obj, path73, value) {
|
|
11720
|
+
const keys = path73.split(".");
|
|
11721
11721
|
const result = { ...obj };
|
|
11722
11722
|
let current = result;
|
|
11723
11723
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -11738,8 +11738,8 @@ function validateConfig(updated, key, schema2 = assistConfigSchema) {
|
|
|
11738
11738
|
};
|
|
11739
11739
|
}
|
|
11740
11740
|
function formatIssue2(issue, key) {
|
|
11741
|
-
const
|
|
11742
|
-
return `${
|
|
11741
|
+
const path73 = issue.path.length > 0 ? issue.path.join(".") : key;
|
|
11742
|
+
return `${path73}: ${issue.message}`;
|
|
11743
11743
|
}
|
|
11744
11744
|
|
|
11745
11745
|
// src/commands/config/applyConfigSet.ts
|
|
@@ -11970,8 +11970,8 @@ function removeAt(container, keys) {
|
|
|
11970
11970
|
}
|
|
11971
11971
|
return removeFromChild(container, key, rest);
|
|
11972
11972
|
}
|
|
11973
|
-
function unsetNestedValue(obj,
|
|
11974
|
-
const { container, removed } = removeAt(obj,
|
|
11973
|
+
function unsetNestedValue(obj, path73) {
|
|
11974
|
+
const { container, removed } = removeAt(obj, path73.split("."));
|
|
11975
11975
|
return { config: container, removed };
|
|
11976
11976
|
}
|
|
11977
11977
|
|
|
@@ -12963,9 +12963,9 @@ function originToSshUrl(origin) {
|
|
|
12963
12963
|
const firstSlash = origin.indexOf("/");
|
|
12964
12964
|
if (firstSlash <= 0) return null;
|
|
12965
12965
|
const host = origin.slice(0, firstSlash);
|
|
12966
|
-
const
|
|
12967
|
-
if (!
|
|
12968
|
-
return `git@${host}:${
|
|
12966
|
+
const path73 = origin.slice(firstSlash + 1);
|
|
12967
|
+
if (!path73) return null;
|
|
12968
|
+
return `git@${host}:${path73}.git`;
|
|
12969
12969
|
}
|
|
12970
12970
|
|
|
12971
12971
|
// src/commands/backlog/cloneRepo.ts
|
|
@@ -15937,9 +15937,9 @@ var __dirname4 = dirname23(__filename3);
|
|
|
15937
15937
|
function packageRoot() {
|
|
15938
15938
|
return __dirname4;
|
|
15939
15939
|
}
|
|
15940
|
-
function readLines(
|
|
15941
|
-
if (!existsSync32(
|
|
15942
|
-
return readFileSync25(
|
|
15940
|
+
function readLines(path73) {
|
|
15941
|
+
if (!existsSync32(path73)) return [];
|
|
15942
|
+
return readFileSync25(path73, "utf8").split("\n").filter((line) => line.trim() !== "");
|
|
15943
15943
|
}
|
|
15944
15944
|
var cachedReads;
|
|
15945
15945
|
var cachedWrites;
|
|
@@ -16433,14 +16433,14 @@ function showProgress(p, label2) {
|
|
|
16433
16433
|
const pct = Math.round(p.done / p.total * 100);
|
|
16434
16434
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
16435
16435
|
}
|
|
16436
|
-
async function resolveCommand(cli,
|
|
16437
|
-
showProgress(p,
|
|
16438
|
-
const subHelp = await runHelp([cli, ...
|
|
16436
|
+
async function resolveCommand(cli, path73, description, depth, p) {
|
|
16437
|
+
showProgress(p, path73.join(" "));
|
|
16438
|
+
const subHelp = await runHelp([cli, ...path73]);
|
|
16439
16439
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
16440
|
-
return [{ path:
|
|
16440
|
+
return [{ path: path73, description }];
|
|
16441
16441
|
}
|
|
16442
|
-
const children = await discoverAt(cli,
|
|
16443
|
-
return children.length > 0 ? children : [{ path:
|
|
16442
|
+
const children = await discoverAt(cli, path73, depth + 1, p);
|
|
16443
|
+
return children.length > 0 ? children : [{ path: path73, description }];
|
|
16444
16444
|
}
|
|
16445
16445
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
16446
16446
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -16588,9 +16588,9 @@ function logPath(cli) {
|
|
|
16588
16588
|
return join34(homedir16(), ".assist", `cli-discover-${safeName}.log`);
|
|
16589
16589
|
}
|
|
16590
16590
|
function readCache(cli) {
|
|
16591
|
-
const
|
|
16592
|
-
if (!existsSync34(
|
|
16593
|
-
return readFileSync27(
|
|
16591
|
+
const path73 = logPath(cli);
|
|
16592
|
+
if (!existsSync34(path73)) return void 0;
|
|
16593
|
+
return readFileSync27(path73, "utf8");
|
|
16594
16594
|
}
|
|
16595
16595
|
function writeCache(cli, output) {
|
|
16596
16596
|
const dir = join34(homedir16(), ".assist");
|
|
@@ -16750,9 +16750,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
16750
16750
|
}
|
|
16751
16751
|
const cutoff = Date.now() - STALE_AFTER_MS;
|
|
16752
16752
|
for (const entry of entries) {
|
|
16753
|
-
const
|
|
16753
|
+
const path73 = join36(dir, entry);
|
|
16754
16754
|
try {
|
|
16755
|
-
if (statSync5(
|
|
16755
|
+
if (statSync5(path73).mtimeMs < cutoff) unlinkSync7(path73);
|
|
16756
16756
|
} catch {
|
|
16757
16757
|
continue;
|
|
16758
16758
|
}
|
|
@@ -16762,10 +16762,10 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
16762
16762
|
// src/commands/codeComment/readPinState.ts
|
|
16763
16763
|
import { existsSync as existsSync35, readFileSync as readFileSync28 } from "fs";
|
|
16764
16764
|
function readPinState(pin) {
|
|
16765
|
-
const
|
|
16766
|
-
if (!existsSync35(
|
|
16765
|
+
const path73 = getPinStatePath(pin);
|
|
16766
|
+
if (!existsSync35(path73)) return void 0;
|
|
16767
16767
|
try {
|
|
16768
|
-
const state = JSON.parse(readFileSync28(
|
|
16768
|
+
const state = JSON.parse(readFileSync28(path73, "utf8"));
|
|
16769
16769
|
if (state.pin !== pin) return void 0;
|
|
16770
16770
|
return state;
|
|
16771
16771
|
} catch {
|
|
@@ -17850,10 +17850,10 @@ function getMigrationApprovalPath(migrationId) {
|
|
|
17850
17850
|
// src/commands/dbMigration/readMigrationPinState.ts
|
|
17851
17851
|
import { existsSync as existsSync37, readFileSync as readFileSync30 } from "fs";
|
|
17852
17852
|
function readMigrationPinState(pin) {
|
|
17853
|
-
const
|
|
17854
|
-
if (!existsSync37(
|
|
17853
|
+
const path73 = getMigrationPinPath(pin);
|
|
17854
|
+
if (!existsSync37(path73)) return void 0;
|
|
17855
17855
|
try {
|
|
17856
|
-
const state = JSON.parse(readFileSync30(
|
|
17856
|
+
const state = JSON.parse(readFileSync30(path73, "utf8"));
|
|
17857
17857
|
if (state.pin !== pin) return void 0;
|
|
17858
17858
|
if (!Number.isInteger(state.migrationId)) return void 0;
|
|
17859
17859
|
return state;
|
|
@@ -19251,10 +19251,10 @@ function decideCommentGuard(input, existingContent) {
|
|
|
19251
19251
|
import { existsSync as existsSync43, unlinkSync as unlinkSync11 } from "fs";
|
|
19252
19252
|
function consumeMigrationApproval(migrationId) {
|
|
19253
19253
|
sweepRestrictedDir();
|
|
19254
|
-
const
|
|
19255
|
-
if (!existsSync43(
|
|
19254
|
+
const path73 = getMigrationApprovalPath(migrationId);
|
|
19255
|
+
if (!existsSync43(path73)) return false;
|
|
19256
19256
|
try {
|
|
19257
|
-
unlinkSync11(
|
|
19257
|
+
unlinkSync11(path73);
|
|
19258
19258
|
return true;
|
|
19259
19259
|
} catch {
|
|
19260
19260
|
return false;
|
|
@@ -20061,22 +20061,22 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
|
|
|
20061
20061
|
const registered = new Set(listWorktreePaths(clone));
|
|
20062
20062
|
const branches = new Set(listLocalBranches(clone));
|
|
20063
20063
|
const isTaken = (candidate) => registered.has(candidate) || existsSync45(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename14(candidate));
|
|
20064
|
-
const
|
|
20064
|
+
const path73 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
|
|
20065
20065
|
const start3 = worktreeStartPoint(clone, strategy.trunk);
|
|
20066
20066
|
gitSync(clone, [
|
|
20067
20067
|
"worktree",
|
|
20068
20068
|
"add",
|
|
20069
20069
|
start3.track ? "--track" : "--no-track",
|
|
20070
20070
|
"-b",
|
|
20071
|
-
basename14(
|
|
20072
|
-
|
|
20071
|
+
basename14(path73),
|
|
20072
|
+
path73,
|
|
20073
20073
|
start3.ref
|
|
20074
20074
|
]);
|
|
20075
|
-
recordWorktree(
|
|
20075
|
+
recordWorktree(path73, clone, getCurrentOrigin(clone));
|
|
20076
20076
|
daemonLog(
|
|
20077
|
-
start3.track ? `worktree allocated ${
|
|
20077
|
+
start3.track ? `worktree allocated ${path73} (branch ${basename14(path73)} tracking ${start3.ref}) for clone ${clone}` : `worktree allocated ${path73} (branch ${basename14(path73)} off ${start3.ref}, no mainline tracking) for clone ${clone}`
|
|
20078
20078
|
);
|
|
20079
|
-
return
|
|
20079
|
+
return path73;
|
|
20080
20080
|
}
|
|
20081
20081
|
|
|
20082
20082
|
// src/commands/sessions/daemon/worktree/treeDurability.ts
|
|
@@ -20188,13 +20188,13 @@ function allocateTree(requestedCwd, boundTreeRoots2, options2 = {}) {
|
|
|
20188
20188
|
if (forcedSpill) daemonLog(forcedSpill);
|
|
20189
20189
|
else if (reusesClone(clone, boundTreeRoots2, reuse))
|
|
20190
20190
|
return { cwd: clone, kind: "primary", created: false, clone };
|
|
20191
|
-
const
|
|
20191
|
+
const path73 = createWorktree(
|
|
20192
20192
|
clone,
|
|
20193
20193
|
{ root: cfg.root, trunk: cfg.trunk },
|
|
20194
20194
|
boundTreeRoots2,
|
|
20195
20195
|
options2.replacesTree
|
|
20196
20196
|
);
|
|
20197
|
-
return { cwd:
|
|
20197
|
+
return { cwd: path73, kind: "worktree", created: true, clone };
|
|
20198
20198
|
}
|
|
20199
20199
|
function keptInPlace(cwd) {
|
|
20200
20200
|
daemonLog(
|
|
@@ -20525,13 +20525,13 @@ function worktreeHoldingBranch(cwd, branch2) {
|
|
|
20525
20525
|
const listing = gitSyncOrNull(cwd, ["worktree", "list", "--porcelain"]);
|
|
20526
20526
|
if (!listing) return null;
|
|
20527
20527
|
const here = gitSyncOrNull(cwd, ["rev-parse", "--show-toplevel"]);
|
|
20528
|
-
let
|
|
20528
|
+
let path73 = null;
|
|
20529
20529
|
for (const line of listing.split("\n")) {
|
|
20530
20530
|
const trimmed = line.trim();
|
|
20531
20531
|
if (trimmed.startsWith("worktree "))
|
|
20532
|
-
|
|
20532
|
+
path73 = trimmed.slice("worktree ".length).trim();
|
|
20533
20533
|
else if (trimmed === `branch refs/heads/${branch2}`)
|
|
20534
|
-
return
|
|
20534
|
+
return path73 && path73 !== here ? path73 : null;
|
|
20535
20535
|
}
|
|
20536
20536
|
return null;
|
|
20537
20537
|
}
|
|
@@ -20988,9 +20988,9 @@ function parseRscRows(flight) {
|
|
|
20988
20988
|
}
|
|
20989
20989
|
function makeRscResolver(rows) {
|
|
20990
20990
|
return (ref) => {
|
|
20991
|
-
const [id, ...
|
|
20991
|
+
const [id, ...path73] = ref.slice(1).replace(/^[L@]/, "").split(":");
|
|
20992
20992
|
let v = rows[id];
|
|
20993
|
-
for (const key of
|
|
20993
|
+
for (const key of path73) {
|
|
20994
20994
|
if (v == null || typeof v !== "object") return void 0;
|
|
20995
20995
|
v = v[key];
|
|
20996
20996
|
}
|
|
@@ -21676,15 +21676,15 @@ function postComment(vars) {
|
|
|
21676
21676
|
const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
|
|
21677
21677
|
assertThreadCreated(stdout);
|
|
21678
21678
|
}
|
|
21679
|
-
function comment2(
|
|
21679
|
+
function comment2(path73, line, body, startLine) {
|
|
21680
21680
|
validateBody(body);
|
|
21681
21681
|
validateLine(line);
|
|
21682
21682
|
if (startLine !== void 0) validateLine(startLine);
|
|
21683
21683
|
try {
|
|
21684
21684
|
const prId = getCurrentPrNodeId();
|
|
21685
|
-
postComment({ prId, body, path:
|
|
21685
|
+
postComment({ prId, body, path: path73, line, startLine });
|
|
21686
21686
|
const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
|
|
21687
|
-
console.log(`Added review comment on ${
|
|
21687
|
+
console.log(`Added review comment on ${path73}:${range}`);
|
|
21688
21688
|
} catch (error) {
|
|
21689
21689
|
if (isGhNotInstalled(error)) {
|
|
21690
21690
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -22939,8 +22939,8 @@ function registerPrs(program2) {
|
|
|
22939
22939
|
prsCommand.command("reply <comment-id> <body>").description("Reply to a comment thread without resolving it").action((commentId, body) => {
|
|
22940
22940
|
reply(Number.parseInt(commentId, 10), body);
|
|
22941
22941
|
});
|
|
22942
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
22943
|
-
comment2(
|
|
22942
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path73, line, body) => {
|
|
22943
|
+
comment2(path73, Number.parseInt(line, 10), body);
|
|
22944
22944
|
});
|
|
22945
22945
|
configHelp(prsCommand, prsConfigHelp);
|
|
22946
22946
|
}
|
|
@@ -23193,10 +23193,10 @@ function resolveOpSecret(reference) {
|
|
|
23193
23193
|
}
|
|
23194
23194
|
|
|
23195
23195
|
// src/commands/ravendb/ravenFetch.ts
|
|
23196
|
-
async function ravenFetch(connection,
|
|
23196
|
+
async function ravenFetch(connection, path73) {
|
|
23197
23197
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
23198
23198
|
let accessToken = await getAccessToken(apiKey);
|
|
23199
|
-
const url = `${connection.url}${
|
|
23199
|
+
const url = `${connection.url}${path73}`;
|
|
23200
23200
|
const headers = {
|
|
23201
23201
|
Authorization: `Bearer ${accessToken}`,
|
|
23202
23202
|
"Content-Type": "application/json"
|
|
@@ -23286,16 +23286,16 @@ import chalk182 from "chalk";
|
|
|
23286
23286
|
// src/commands/ravendb/buildQueryPath.ts
|
|
23287
23287
|
function buildQueryPath(opts) {
|
|
23288
23288
|
const db = encodeURIComponent(opts.db);
|
|
23289
|
-
let
|
|
23289
|
+
let path73;
|
|
23290
23290
|
if (opts.collection) {
|
|
23291
|
-
|
|
23291
|
+
path73 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
23292
23292
|
} else {
|
|
23293
|
-
|
|
23293
|
+
path73 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
23294
23294
|
}
|
|
23295
23295
|
if (opts.query) {
|
|
23296
|
-
|
|
23296
|
+
path73 += `&query=${encodeURIComponent(opts.query)}`;
|
|
23297
23297
|
}
|
|
23298
|
-
return
|
|
23298
|
+
return path73;
|
|
23299
23299
|
}
|
|
23300
23300
|
|
|
23301
23301
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -23304,7 +23304,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
23304
23304
|
let start3 = 0;
|
|
23305
23305
|
while (true) {
|
|
23306
23306
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
23307
|
-
const
|
|
23307
|
+
const path73 = buildQueryPath({
|
|
23308
23308
|
db: connection.database,
|
|
23309
23309
|
collection: opts.collection,
|
|
23310
23310
|
start: start3,
|
|
@@ -23312,7 +23312,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
23312
23312
|
sort: opts.sort,
|
|
23313
23313
|
query: opts.query
|
|
23314
23314
|
});
|
|
23315
|
-
const data = await ravenFetch(connection,
|
|
23315
|
+
const data = await ravenFetch(connection, path73);
|
|
23316
23316
|
const results = data.Results ?? [];
|
|
23317
23317
|
const totalResults = data.TotalResults ?? 0;
|
|
23318
23318
|
if (results.length === 0) break;
|
|
@@ -24753,8 +24753,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
24753
24753
|
function clusterFiles(graph) {
|
|
24754
24754
|
const clusters = /* @__PURE__ */ new Map();
|
|
24755
24755
|
for (const file of graph.files) {
|
|
24756
|
-
const
|
|
24757
|
-
if (
|
|
24756
|
+
const basename23 = path52.basename(file, path52.extname(file));
|
|
24757
|
+
if (basename23 === "index") continue;
|
|
24758
24758
|
const importers = graph.importedBy.get(file);
|
|
24759
24759
|
if (!importers || importers.size !== 1) continue;
|
|
24760
24760
|
const parent = [...importers][0];
|
|
@@ -25907,8 +25907,8 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
|
|
|
25907
25907
|
// src/commands/review/prepareReviewDir.ts
|
|
25908
25908
|
import { existsSync as existsSync50, mkdirSync as mkdirSync19, unlinkSync as unlinkSync17, writeFileSync as writeFileSync36 } from "fs";
|
|
25909
25909
|
function clearReviewFiles(paths) {
|
|
25910
|
-
for (const
|
|
25911
|
-
if (existsSync50(
|
|
25910
|
+
for (const path73 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
25911
|
+
if (existsSync50(path73)) unlinkSync17(path73);
|
|
25912
25912
|
}
|
|
25913
25913
|
}
|
|
25914
25914
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -26998,8 +26998,8 @@ import chalk203 from "chalk";
|
|
|
26998
26998
|
|
|
26999
26999
|
// src/commands/seq/fetchSeq.ts
|
|
27000
27000
|
import chalk200 from "chalk";
|
|
27001
|
-
async function fetchSeq(conn,
|
|
27002
|
-
const url = `${conn.url}${
|
|
27001
|
+
async function fetchSeq(conn, path73, params) {
|
|
27002
|
+
const url = `${conn.url}${path73}?${params}`;
|
|
27003
27003
|
const response = await fetch(url, {
|
|
27004
27004
|
headers: {
|
|
27005
27005
|
Accept: "application/json",
|
|
@@ -27548,6 +27548,438 @@ function registerSql(program2) {
|
|
|
27548
27548
|
configHelp(cmd, sqlConfigHelp);
|
|
27549
27549
|
}
|
|
27550
27550
|
|
|
27551
|
+
// src/commands/sync.ts
|
|
27552
|
+
import * as fs43 from "fs";
|
|
27553
|
+
import * as os4 from "os";
|
|
27554
|
+
import * as path68 from "path";
|
|
27555
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
27556
|
+
|
|
27557
|
+
// src/commands/sync/pruneCommands.ts
|
|
27558
|
+
import * as path59 from "path";
|
|
27559
|
+
|
|
27560
|
+
// src/commands/sync/pruneTarget.ts
|
|
27561
|
+
import * as fs35 from "fs";
|
|
27562
|
+
import * as path58 from "path";
|
|
27563
|
+
function pruneTarget(targetDir, keepNames, shape, options2) {
|
|
27564
|
+
const result = {
|
|
27565
|
+
orphans: [],
|
|
27566
|
+
removed: [],
|
|
27567
|
+
skipped: [],
|
|
27568
|
+
unmanaged: []
|
|
27569
|
+
};
|
|
27570
|
+
if (!fs35.existsSync(targetDir)) return result;
|
|
27571
|
+
const keep = new Set(keepNames);
|
|
27572
|
+
for (const entry of fs35.readdirSync(targetDir, { withFileTypes: true })) {
|
|
27573
|
+
const name = shape.nameOf(entry);
|
|
27574
|
+
if (name === void 0) {
|
|
27575
|
+
result.unmanaged.push(entry.name);
|
|
27576
|
+
continue;
|
|
27577
|
+
}
|
|
27578
|
+
if (keep.has(name)) continue;
|
|
27579
|
+
result.orphans.push(entry.name);
|
|
27580
|
+
const entryPath = path58.join(targetDir, entry.name);
|
|
27581
|
+
const reason4 = shape.blockedBy?.(entryPath);
|
|
27582
|
+
if (reason4) {
|
|
27583
|
+
result.skipped.push({ name: entry.name, reason: reason4 });
|
|
27584
|
+
continue;
|
|
27585
|
+
}
|
|
27586
|
+
if (options2.force) {
|
|
27587
|
+
fs35.rmSync(entryPath, { recursive: true });
|
|
27588
|
+
result.removed.push(entry.name);
|
|
27589
|
+
}
|
|
27590
|
+
}
|
|
27591
|
+
return result;
|
|
27592
|
+
}
|
|
27593
|
+
|
|
27594
|
+
// src/commands/sync/pruneCommands.ts
|
|
27595
|
+
function pruneCommands(targetDir, commandNames, options2) {
|
|
27596
|
+
return pruneTarget(
|
|
27597
|
+
targetDir,
|
|
27598
|
+
commandNames,
|
|
27599
|
+
{
|
|
27600
|
+
nameOf: (entry) => entry.isFile() && entry.name.endsWith(".md") ? path59.basename(entry.name, ".md") : void 0
|
|
27601
|
+
},
|
|
27602
|
+
options2
|
|
27603
|
+
);
|
|
27604
|
+
}
|
|
27605
|
+
|
|
27606
|
+
// src/commands/sync/reportPrune.ts
|
|
27607
|
+
function reportPrune(label2, result, force) {
|
|
27608
|
+
if (result.orphans.length === 0) {
|
|
27609
|
+
console.log(`No orphaned commands in ${label2}`);
|
|
27610
|
+
} else if (force) {
|
|
27611
|
+
for (const name of result.removed) {
|
|
27612
|
+
console.log(`Removed ${name} from ${label2}`);
|
|
27613
|
+
}
|
|
27614
|
+
} else {
|
|
27615
|
+
console.log(`Orphaned commands in ${label2} (run with --force to remove):`);
|
|
27616
|
+
for (const name of result.orphans) {
|
|
27617
|
+
console.log(` ${name}`);
|
|
27618
|
+
}
|
|
27619
|
+
}
|
|
27620
|
+
if (result.skipped.length > 0) {
|
|
27621
|
+
console.log(`Left in place in ${label2} (not written by sync):`);
|
|
27622
|
+
for (const { name, reason: reason4 } of result.skipped) {
|
|
27623
|
+
console.log(` ${name} - ${reason4}`);
|
|
27624
|
+
}
|
|
27625
|
+
}
|
|
27626
|
+
if (result.unmanaged.length === 0) return;
|
|
27627
|
+
console.log(`Not managed by sync in ${label2} (never removed):`);
|
|
27628
|
+
for (const name of result.unmanaged) {
|
|
27629
|
+
console.log(` ${name}`);
|
|
27630
|
+
}
|
|
27631
|
+
}
|
|
27632
|
+
|
|
27633
|
+
// src/commands/sync/syncClaudeMd.ts
|
|
27634
|
+
import * as fs36 from "fs";
|
|
27635
|
+
import * as path60 from "path";
|
|
27636
|
+
import chalk210 from "chalk";
|
|
27637
|
+
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
27638
|
+
const source = path60.join(claudeDir, "CLAUDE.md");
|
|
27639
|
+
const target = path60.join(targetBase, "CLAUDE.md");
|
|
27640
|
+
const sourceContent = fs36.readFileSync(source, "utf8");
|
|
27641
|
+
if (fs36.existsSync(target)) {
|
|
27642
|
+
const targetContent = fs36.readFileSync(target, "utf8");
|
|
27643
|
+
if (sourceContent !== targetContent) {
|
|
27644
|
+
console.log(
|
|
27645
|
+
chalk210.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
27646
|
+
);
|
|
27647
|
+
console.log();
|
|
27648
|
+
printDiff(targetContent, sourceContent);
|
|
27649
|
+
if (!options2?.yes) {
|
|
27650
|
+
printAutoConfirmHint();
|
|
27651
|
+
const confirm = await promptConfirm(
|
|
27652
|
+
chalk210.red("Overwrite existing CLAUDE.md?"),
|
|
27653
|
+
false
|
|
27654
|
+
);
|
|
27655
|
+
if (!confirm) {
|
|
27656
|
+
console.log("Skipped CLAUDE.md");
|
|
27657
|
+
return;
|
|
27658
|
+
}
|
|
27659
|
+
}
|
|
27660
|
+
}
|
|
27661
|
+
}
|
|
27662
|
+
fs36.copyFileSync(source, target);
|
|
27663
|
+
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
27664
|
+
}
|
|
27665
|
+
|
|
27666
|
+
// src/commands/sync/syncCodex.ts
|
|
27667
|
+
import * as path63 from "path";
|
|
27668
|
+
|
|
27669
|
+
// src/commands/sync/installHarnessCommands.ts
|
|
27670
|
+
import * as fs37 from "fs";
|
|
27671
|
+
import * as path61 from "path";
|
|
27672
|
+
function installHarnessCommands(claudeDir, harness, transform) {
|
|
27673
|
+
const commandsSource = path61.join(claudeDir, "commands");
|
|
27674
|
+
const files = fs37.readdirSync(commandsSource);
|
|
27675
|
+
const names = [];
|
|
27676
|
+
let synced = 0;
|
|
27677
|
+
for (const file of files) {
|
|
27678
|
+
if (!file.endsWith(".md")) continue;
|
|
27679
|
+
const name = file.replace(/\.md$/, "");
|
|
27680
|
+
names.push(name);
|
|
27681
|
+
const content = fs37.readFileSync(path61.join(commandsSource, file), "utf8");
|
|
27682
|
+
const target = path61.join(harness.homeDir, harness.sync.commandDest(name));
|
|
27683
|
+
fs37.mkdirSync(path61.dirname(target), { recursive: true });
|
|
27684
|
+
fs37.writeFileSync(target, transform(name, content));
|
|
27685
|
+
synced++;
|
|
27686
|
+
}
|
|
27687
|
+
const agentsTarget = path61.join(harness.homeDir, harness.sync.agentsFile);
|
|
27688
|
+
fs37.mkdirSync(path61.dirname(agentsTarget), { recursive: true });
|
|
27689
|
+
fs37.copyFileSync(path61.join(claudeDir, "CLAUDE.md"), agentsTarget);
|
|
27690
|
+
return { total: files.length, synced, names };
|
|
27691
|
+
}
|
|
27692
|
+
|
|
27693
|
+
// src/commands/sync/pruneSkills.ts
|
|
27694
|
+
import * as fs38 from "fs";
|
|
27695
|
+
function pruneSkills(targetDir, skillNames, options2) {
|
|
27696
|
+
return pruneTarget(
|
|
27697
|
+
targetDir,
|
|
27698
|
+
skillNames,
|
|
27699
|
+
{
|
|
27700
|
+
nameOf: (entry) => entry.isDirectory() ? entry.name : void 0,
|
|
27701
|
+
blockedBy: unexpectedContent
|
|
27702
|
+
},
|
|
27703
|
+
options2
|
|
27704
|
+
);
|
|
27705
|
+
}
|
|
27706
|
+
function unexpectedContent(skillDir) {
|
|
27707
|
+
const entries = fs38.readdirSync(skillDir);
|
|
27708
|
+
const others = entries.filter((entry) => entry !== "SKILL.md");
|
|
27709
|
+
if (others.length > 0) return `contains ${others.sort().join(", ")}`;
|
|
27710
|
+
return entries.length === 0 ? "no SKILL.md" : void 0;
|
|
27711
|
+
}
|
|
27712
|
+
|
|
27713
|
+
// src/commands/sync/syncCodexHooks.ts
|
|
27714
|
+
import * as fs39 from "fs";
|
|
27715
|
+
import * as path62 from "path";
|
|
27716
|
+
var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
|
|
27717
|
+
var END = "# <<< assist codex hooks (managed) <<<";
|
|
27718
|
+
function upsertManagedBlock(existing, body) {
|
|
27719
|
+
const block = `${BEGIN}
|
|
27720
|
+
${body.trim()}
|
|
27721
|
+
${END}`;
|
|
27722
|
+
const begin = existing.indexOf(BEGIN);
|
|
27723
|
+
if (begin === -1) {
|
|
27724
|
+
const base = existing.replace(/\s*$/, "");
|
|
27725
|
+
return base ? `${base}
|
|
27726
|
+
|
|
27727
|
+
${block}
|
|
27728
|
+
` : `${block}
|
|
27729
|
+
`;
|
|
27730
|
+
}
|
|
27731
|
+
const endMarker = existing.indexOf(END, begin);
|
|
27732
|
+
const after = endMarker === -1 ? existing.length : endMarker + END.length;
|
|
27733
|
+
const before = existing.slice(0, begin).replace(/\s*$/, "");
|
|
27734
|
+
const rest = existing.slice(after).replace(/^\s*/, "");
|
|
27735
|
+
const head = before ? `${before}
|
|
27736
|
+
|
|
27737
|
+
${block}` : block;
|
|
27738
|
+
return rest ? `${head}
|
|
27739
|
+
|
|
27740
|
+
${rest}
|
|
27741
|
+
` : `${head}
|
|
27742
|
+
`;
|
|
27743
|
+
}
|
|
27744
|
+
function syncCodexHooks(sourcePath) {
|
|
27745
|
+
const body = fs39.readFileSync(sourcePath, "utf8");
|
|
27746
|
+
const configPath = path62.join(harnesses.codex.homeDir, "config.toml");
|
|
27747
|
+
const existing = fs39.existsSync(configPath) ? fs39.readFileSync(configPath, "utf8") : "";
|
|
27748
|
+
fs39.mkdirSync(path62.dirname(configPath), { recursive: true });
|
|
27749
|
+
fs39.writeFileSync(configPath, upsertManagedBlock(existing, body));
|
|
27750
|
+
console.log(
|
|
27751
|
+
"Registered assist codex-hook in ~/.codex/config.toml (PreToolUse, PermissionRequest)"
|
|
27752
|
+
);
|
|
27753
|
+
}
|
|
27754
|
+
|
|
27755
|
+
// src/commands/sync/syncCodex.ts
|
|
27756
|
+
function quoteYaml(value) {
|
|
27757
|
+
return `"${value.replace(/\\/g, String.raw`\\`).replace(/"/g, String.raw`\"`)}"`;
|
|
27758
|
+
}
|
|
27759
|
+
function commandToSkill(name, content) {
|
|
27760
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
27761
|
+
const frontmatter = match ? match[1] : "";
|
|
27762
|
+
const body = match ? content.slice(match[0].length) : content;
|
|
27763
|
+
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
27764
|
+
const description = descriptionMatch ? descriptionMatch[1].trim().replace(/^["']|["']$/g, "") : name;
|
|
27765
|
+
const header = `---
|
|
27766
|
+
name: ${name}
|
|
27767
|
+
description: ${quoteYaml(description)}
|
|
27768
|
+
---
|
|
27769
|
+
|
|
27770
|
+
`;
|
|
27771
|
+
return header + body.replace(/^\r?\n+/, "");
|
|
27772
|
+
}
|
|
27773
|
+
function syncCodex(claudeDir, options2) {
|
|
27774
|
+
if (!isHarnessAvailable("codex")) return;
|
|
27775
|
+
const { total, names } = installHarnessCommands(
|
|
27776
|
+
claudeDir,
|
|
27777
|
+
harnesses.codex,
|
|
27778
|
+
commandToSkill
|
|
27779
|
+
);
|
|
27780
|
+
syncCodexHooks(path63.join(claudeDir, "..", "codex", "config.toml"));
|
|
27781
|
+
console.log(
|
|
27782
|
+
`Synced ${total} skill(s) to ~/.codex/skills and CLAUDE.md to ~/.codex/AGENTS.md`
|
|
27783
|
+
);
|
|
27784
|
+
if (!options2?.prune) return;
|
|
27785
|
+
const force = options2.force ?? false;
|
|
27786
|
+
reportPrune(
|
|
27787
|
+
"~/.codex/skills",
|
|
27788
|
+
pruneSkills(path63.join(harnesses.codex.homeDir, "skills"), names, { force }),
|
|
27789
|
+
force
|
|
27790
|
+
);
|
|
27791
|
+
}
|
|
27792
|
+
|
|
27793
|
+
// src/commands/sync/syncDesign.ts
|
|
27794
|
+
import * as fs40 from "fs";
|
|
27795
|
+
import * as path64 from "path";
|
|
27796
|
+
function syncDesign(claudeDir, targetBase) {
|
|
27797
|
+
const systemPromptSource = path64.join(claudeDir, "design-system-prompt.md");
|
|
27798
|
+
const systemPromptTarget = path64.join(targetBase, "design-system-prompt.md");
|
|
27799
|
+
fs40.copyFileSync(systemPromptSource, systemPromptTarget);
|
|
27800
|
+
console.log(
|
|
27801
|
+
"Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
|
|
27802
|
+
);
|
|
27803
|
+
const skillsSource = path64.join(claudeDir, "skills");
|
|
27804
|
+
const skillsTarget = path64.join(targetBase, "skills");
|
|
27805
|
+
fs40.mkdirSync(skillsTarget, { recursive: true });
|
|
27806
|
+
const files = fs40.readdirSync(skillsSource);
|
|
27807
|
+
for (const file of files) {
|
|
27808
|
+
fs40.copyFileSync(
|
|
27809
|
+
path64.join(skillsSource, file),
|
|
27810
|
+
path64.join(skillsTarget, file)
|
|
27811
|
+
);
|
|
27812
|
+
}
|
|
27813
|
+
console.log(`Synced ${files.length} design skill(s) to ~/.claude/skills`);
|
|
27814
|
+
}
|
|
27815
|
+
|
|
27816
|
+
// src/commands/sync/syncPi.ts
|
|
27817
|
+
import * as path66 from "path";
|
|
27818
|
+
|
|
27819
|
+
// src/commands/sync/syncPiHooks.ts
|
|
27820
|
+
import * as fs41 from "fs";
|
|
27821
|
+
import * as path65 from "path";
|
|
27822
|
+
function piExtensionsDir() {
|
|
27823
|
+
return path65.join(harnesses.pi.homeDir, "extensions");
|
|
27824
|
+
}
|
|
27825
|
+
function syncPiHooks(sourceDir) {
|
|
27826
|
+
const target = piExtensionsDir();
|
|
27827
|
+
fs41.mkdirSync(target, { recursive: true });
|
|
27828
|
+
const files = fs41.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
|
|
27829
|
+
for (const file of files) {
|
|
27830
|
+
fs41.copyFileSync(
|
|
27831
|
+
path65.join(sourceDir, file),
|
|
27832
|
+
path65.join(target, `assist-${file}`)
|
|
27833
|
+
);
|
|
27834
|
+
}
|
|
27835
|
+
console.log(
|
|
27836
|
+
`Registered ${files.length} assist extension(s) in ~/.pi/agent/extensions`
|
|
27837
|
+
);
|
|
27838
|
+
}
|
|
27839
|
+
|
|
27840
|
+
// src/commands/sync/syncPi.ts
|
|
27841
|
+
function unquote(value) {
|
|
27842
|
+
return value.trim().replace(/^["']|["']$/g, "");
|
|
27843
|
+
}
|
|
27844
|
+
function commandToPrompt(name, content) {
|
|
27845
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
27846
|
+
const frontmatter = match ? match[1] : "";
|
|
27847
|
+
const body = match ? content.slice(match[0].length) : content;
|
|
27848
|
+
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
27849
|
+
const description = descriptionMatch ? unquote(descriptionMatch[1]) : name;
|
|
27850
|
+
const argsMatch = frontmatter.match(/^allowed_args:\s*(.*)$/m);
|
|
27851
|
+
const argumentHint = argsMatch ? unquote(argsMatch[1]) : void 0;
|
|
27852
|
+
const header = [
|
|
27853
|
+
"---",
|
|
27854
|
+
`description: ${description}`,
|
|
27855
|
+
...argumentHint ? [`argument-hint: ${argumentHint}`] : [],
|
|
27856
|
+
"---",
|
|
27857
|
+
"",
|
|
27858
|
+
""
|
|
27859
|
+
].join("\n");
|
|
27860
|
+
return header + body.replace(/^\r?\n+/, "");
|
|
27861
|
+
}
|
|
27862
|
+
function syncPi(claudeDir, options2) {
|
|
27863
|
+
if (!isHarnessAvailable("pi")) return;
|
|
27864
|
+
const { synced, names } = installHarnessCommands(
|
|
27865
|
+
claudeDir,
|
|
27866
|
+
harnesses.pi,
|
|
27867
|
+
commandToPrompt
|
|
27868
|
+
);
|
|
27869
|
+
syncPiHooks(path66.join(claudeDir, "..", "pi"));
|
|
27870
|
+
console.log(
|
|
27871
|
+
`Synced ${synced} prompt(s) to ~/.pi/agent/prompts and CLAUDE.md to ~/.pi/agent/AGENTS.md`
|
|
27872
|
+
);
|
|
27873
|
+
if (!options2?.prune) return;
|
|
27874
|
+
const force = options2.force ?? false;
|
|
27875
|
+
reportPrune(
|
|
27876
|
+
"~/.pi/agent/prompts",
|
|
27877
|
+
pruneCommands(path66.join(harnesses.pi.homeDir, "prompts"), names, { force }),
|
|
27878
|
+
force
|
|
27879
|
+
);
|
|
27880
|
+
}
|
|
27881
|
+
|
|
27882
|
+
// src/commands/sync/syncSettings.ts
|
|
27883
|
+
import * as fs42 from "fs";
|
|
27884
|
+
import * as path67 from "path";
|
|
27885
|
+
import chalk211 from "chalk";
|
|
27886
|
+
async function syncSettings(claudeDir, targetBase, options2) {
|
|
27887
|
+
const source = path67.join(claudeDir, "settings.json");
|
|
27888
|
+
const target = path67.join(targetBase, "settings.json");
|
|
27889
|
+
const sourceContent = fs42.readFileSync(source, "utf8");
|
|
27890
|
+
const sourceSettings = JSON.parse(sourceContent);
|
|
27891
|
+
const targetExists = fs42.existsSync(target);
|
|
27892
|
+
const targetContent = targetExists ? fs42.readFileSync(target, "utf8") : "";
|
|
27893
|
+
const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
|
|
27894
|
+
const mergedContent = JSON.stringify(
|
|
27895
|
+
{ ...preservedUserSettings, ...sourceSettings },
|
|
27896
|
+
null,
|
|
27897
|
+
" "
|
|
27898
|
+
);
|
|
27899
|
+
if (targetExists) {
|
|
27900
|
+
const normalizedTarget = JSON.stringify(preservedUserSettings, null, " ");
|
|
27901
|
+
if (mergedContent !== normalizedTarget) {
|
|
27902
|
+
if (!options2?.yes) {
|
|
27903
|
+
console.log(
|
|
27904
|
+
chalk211.yellow(
|
|
27905
|
+
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
27906
|
+
)
|
|
27907
|
+
);
|
|
27908
|
+
console.log();
|
|
27909
|
+
printDiff(targetContent, mergedContent);
|
|
27910
|
+
printAutoConfirmHint();
|
|
27911
|
+
const confirm = await promptConfirm(
|
|
27912
|
+
chalk211.red("Overwrite existing settings.json?"),
|
|
27913
|
+
false
|
|
27914
|
+
);
|
|
27915
|
+
if (!confirm) {
|
|
27916
|
+
console.log("Skipped settings.json");
|
|
27917
|
+
return;
|
|
27918
|
+
}
|
|
27919
|
+
}
|
|
27920
|
+
}
|
|
27921
|
+
}
|
|
27922
|
+
fs42.writeFileSync(target, mergedContent);
|
|
27923
|
+
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
27924
|
+
}
|
|
27925
|
+
|
|
27926
|
+
// src/commands/sync.ts
|
|
27927
|
+
var __filename4 = fileURLToPath7(import.meta.url);
|
|
27928
|
+
var __dirname5 = path68.dirname(__filename4);
|
|
27929
|
+
async function sync(options2) {
|
|
27930
|
+
const config = loadConfig();
|
|
27931
|
+
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
27932
|
+
const prune = { prune: options2?.prune, force: options2?.force };
|
|
27933
|
+
const claudeDir = path68.join(__dirname5, "..", "claude");
|
|
27934
|
+
const targetBase = path68.join(os4.homedir(), ".claude");
|
|
27935
|
+
const commandFiles = syncCommands(claudeDir, targetBase);
|
|
27936
|
+
syncDesign(claudeDir, targetBase);
|
|
27937
|
+
await syncSettings(claudeDir, targetBase, { yes });
|
|
27938
|
+
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
27939
|
+
syncCodex(claudeDir, prune);
|
|
27940
|
+
syncPi(claudeDir, prune);
|
|
27941
|
+
if (!options2?.prune) return;
|
|
27942
|
+
const commandNames = commandFiles.filter((file) => file.endsWith(".md")).map((file) => path68.basename(file, ".md"));
|
|
27943
|
+
const force = options2.force ?? false;
|
|
27944
|
+
reportPrune(
|
|
27945
|
+
"~/.claude/commands",
|
|
27946
|
+
pruneCommands(path68.join(targetBase, "commands"), commandNames, { force }),
|
|
27947
|
+
force
|
|
27948
|
+
);
|
|
27949
|
+
}
|
|
27950
|
+
function syncCommands(claudeDir, targetBase) {
|
|
27951
|
+
const sourceDir = path68.join(claudeDir, "commands");
|
|
27952
|
+
const targetDir = path68.join(targetBase, "commands");
|
|
27953
|
+
fs43.mkdirSync(targetDir, { recursive: true });
|
|
27954
|
+
const files = fs43.readdirSync(sourceDir);
|
|
27955
|
+
for (const file of files) {
|
|
27956
|
+
fs43.copyFileSync(path68.join(sourceDir, file), path68.join(targetDir, file));
|
|
27957
|
+
console.log(`Copied ${file} to ${targetDir}`);
|
|
27958
|
+
}
|
|
27959
|
+
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
27960
|
+
return files;
|
|
27961
|
+
}
|
|
27962
|
+
|
|
27963
|
+
// src/commands/registerSync.ts
|
|
27964
|
+
function registerSync(program2) {
|
|
27965
|
+
const syncCommand = program2.command("sync").description(
|
|
27966
|
+
"Copy command files to ~/.claude/commands; when codex is detected, also install commands as ~/.codex/skills/<name>/SKILL.md, CLAUDE.md as ~/.codex/AGENTS.md, and register the assist codex-hook auto-approval hook in ~/.codex/config.toml; when pi is detected, also install commands as ~/.pi/agent/prompts/<name>.md, CLAUDE.md as ~/.pi/agent/AGENTS.md, and register the assist pi-hook permission-gate extension in ~/.pi/agent/extensions. With --prune, also report commands in those target dirs that sync did not write, and with --prune --force remove them"
|
|
27967
|
+
).option("-y, --yes", "Overwrite settings.json without prompting").option(
|
|
27968
|
+
"--prune",
|
|
27969
|
+
"After syncing, list commands in the target dirs whose name is not in the repo's claude/commands/*.md set; subdirectories and non-.md files are listed separately and never removed"
|
|
27970
|
+
).option(
|
|
27971
|
+
"--force",
|
|
27972
|
+
"With --prune, remove the listed orphaned commands; a codex skill directory is removed only when SKILL.md is its sole content. Errors without --prune"
|
|
27973
|
+
).action((options2) => {
|
|
27974
|
+
if (options2.force && !options2.prune) {
|
|
27975
|
+
console.error("--force requires --prune.");
|
|
27976
|
+
process.exit(1);
|
|
27977
|
+
}
|
|
27978
|
+
return sync(options2);
|
|
27979
|
+
});
|
|
27980
|
+
configHelp(syncCommand, rootConfigHelp.sync);
|
|
27981
|
+
}
|
|
27982
|
+
|
|
27551
27983
|
// src/commands/transcript/shared.ts
|
|
27552
27984
|
import * as readline2 from "readline";
|
|
27553
27985
|
function createReadlineInterface() {
|
|
@@ -27619,27 +28051,27 @@ async function configure() {
|
|
|
27619
28051
|
}
|
|
27620
28052
|
|
|
27621
28053
|
// src/commands/transcript/list.ts
|
|
27622
|
-
import { existsSync as
|
|
27623
|
-
import { join as
|
|
28054
|
+
import { existsSync as existsSync57, readdirSync as readdirSync17, statSync as statSync9 } from "fs";
|
|
28055
|
+
import { join as join71 } from "path";
|
|
27624
28056
|
function list4() {
|
|
27625
28057
|
const { vttDir } = getTranscriptConfig();
|
|
27626
|
-
if (!
|
|
27627
|
-
for (const entry of
|
|
28058
|
+
if (!existsSync57(vttDir)) return;
|
|
28059
|
+
for (const entry of readdirSync17(vttDir)) {
|
|
27628
28060
|
if (!entry.endsWith(".vtt")) continue;
|
|
27629
|
-
if (statSync9(
|
|
28061
|
+
if (statSync9(join71(vttDir, entry)).isDirectory()) continue;
|
|
27630
28062
|
console.log(entry);
|
|
27631
28063
|
}
|
|
27632
28064
|
}
|
|
27633
28065
|
|
|
27634
28066
|
// src/commands/transcript/move.ts
|
|
27635
28067
|
import {
|
|
27636
|
-
existsSync as
|
|
27637
|
-
mkdirSync as
|
|
27638
|
-
readFileSync as
|
|
28068
|
+
existsSync as existsSync58,
|
|
28069
|
+
mkdirSync as mkdirSync25,
|
|
28070
|
+
readFileSync as readFileSync47,
|
|
27639
28071
|
renameSync as renameSync2,
|
|
27640
|
-
writeFileSync as
|
|
28072
|
+
writeFileSync as writeFileSync41
|
|
27641
28073
|
} from "fs";
|
|
27642
|
-
import { basename as
|
|
28074
|
+
import { basename as basename19, join as join72 } from "path";
|
|
27643
28075
|
|
|
27644
28076
|
// src/commands/transcript/cleanText.ts
|
|
27645
28077
|
function cleanText(text17) {
|
|
@@ -27847,14 +28279,14 @@ function formatChatLog(messages) {
|
|
|
27847
28279
|
// src/commands/transcript/move.ts
|
|
27848
28280
|
var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
27849
28281
|
function convertVttToMarkdown(inputPath) {
|
|
27850
|
-
const cues = parseVtt(
|
|
28282
|
+
const cues = parseVtt(readFileSync47(inputPath, "utf8"));
|
|
27851
28283
|
const messages = cuesToChatMessages(deduplicateCues(cues));
|
|
27852
28284
|
return formatChatLog(messages);
|
|
27853
28285
|
}
|
|
27854
28286
|
function archiveRawVtt(vttDir, sourcePath, filename) {
|
|
27855
|
-
const processedDir =
|
|
27856
|
-
|
|
27857
|
-
renameSync2(sourcePath,
|
|
28287
|
+
const processedDir = join72(vttDir, "processed");
|
|
28288
|
+
mkdirSync25(processedDir, { recursive: true });
|
|
28289
|
+
renameSync2(sourcePath, join72(processedDir, filename));
|
|
27858
28290
|
}
|
|
27859
28291
|
function move(file, options2) {
|
|
27860
28292
|
const { date, client } = options2;
|
|
@@ -27863,20 +28295,20 @@ function move(file, options2) {
|
|
|
27863
28295
|
process.exit(1);
|
|
27864
28296
|
}
|
|
27865
28297
|
const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
27866
|
-
const filename =
|
|
27867
|
-
const sourcePath =
|
|
27868
|
-
if (!
|
|
28298
|
+
const filename = basename19(file);
|
|
28299
|
+
const sourcePath = join72(vttDir, filename);
|
|
28300
|
+
if (!existsSync58(sourcePath)) {
|
|
27869
28301
|
console.error(`Error: VTT file not found: ${sourcePath}`);
|
|
27870
28302
|
process.exit(1);
|
|
27871
28303
|
}
|
|
27872
|
-
const base =
|
|
28304
|
+
const base = basename19(filename, ".vtt").replace(/ Transcription$/, "");
|
|
27873
28305
|
const outputName = `${date} ${base}.md`;
|
|
27874
|
-
const formattedDir =
|
|
27875
|
-
|
|
27876
|
-
const formattedPath =
|
|
27877
|
-
|
|
28306
|
+
const formattedDir = join72(transcriptsDir, client);
|
|
28307
|
+
mkdirSync25(formattedDir, { recursive: true });
|
|
28308
|
+
const formattedPath = join72(formattedDir, outputName);
|
|
28309
|
+
writeFileSync41(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
|
|
27878
28310
|
archiveRawVtt(vttDir, sourcePath, filename);
|
|
27879
|
-
const summaryPath =
|
|
28311
|
+
const summaryPath = join72(summaryDir, client, outputName);
|
|
27880
28312
|
console.log(`Formatted transcript: ${formattedPath}`);
|
|
27881
28313
|
console.log(`Summary target: ${summaryPath}`);
|
|
27882
28314
|
}
|
|
@@ -27958,50 +28390,50 @@ function registerVerify(program2) {
|
|
|
27958
28390
|
|
|
27959
28391
|
// src/commands/voice/devices.ts
|
|
27960
28392
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
27961
|
-
import { join as
|
|
28393
|
+
import { join as join74 } from "path";
|
|
27962
28394
|
|
|
27963
28395
|
// src/commands/voice/shared.ts
|
|
27964
|
-
import { homedir as
|
|
27965
|
-
import { dirname as
|
|
27966
|
-
import { fileURLToPath as
|
|
27967
|
-
var
|
|
27968
|
-
var VOICE_DIR =
|
|
28396
|
+
import { homedir as homedir23 } from "os";
|
|
28397
|
+
import { dirname as dirname34, join as join73 } from "path";
|
|
28398
|
+
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
28399
|
+
var __dirname6 = dirname34(fileURLToPath8(import.meta.url));
|
|
28400
|
+
var VOICE_DIR = join73(homedir23(), ".assist", "voice");
|
|
27969
28401
|
var voicePaths = {
|
|
27970
28402
|
dir: VOICE_DIR,
|
|
27971
|
-
pid:
|
|
27972
|
-
log:
|
|
27973
|
-
venv:
|
|
27974
|
-
lock:
|
|
28403
|
+
pid: join73(VOICE_DIR, "voice.pid"),
|
|
28404
|
+
log: join73(VOICE_DIR, "voice.log"),
|
|
28405
|
+
venv: join73(VOICE_DIR, ".venv"),
|
|
28406
|
+
lock: join73(VOICE_DIR, "voice.lock")
|
|
27975
28407
|
};
|
|
27976
28408
|
function getPythonDir() {
|
|
27977
|
-
return
|
|
28409
|
+
return join73(__dirname6, "commands", "voice", "python");
|
|
27978
28410
|
}
|
|
27979
28411
|
function getVenvPython() {
|
|
27980
|
-
return process.platform === "win32" ?
|
|
28412
|
+
return process.platform === "win32" ? join73(voicePaths.venv, "Scripts", "python.exe") : join73(voicePaths.venv, "bin", "python");
|
|
27981
28413
|
}
|
|
27982
28414
|
function getLockDir() {
|
|
27983
28415
|
const config = loadConfig();
|
|
27984
28416
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
27985
28417
|
}
|
|
27986
28418
|
function getLockFile() {
|
|
27987
|
-
return
|
|
28419
|
+
return join73(getLockDir(), "voice.lock");
|
|
27988
28420
|
}
|
|
27989
28421
|
|
|
27990
28422
|
// src/commands/voice/devices.ts
|
|
27991
28423
|
function devices() {
|
|
27992
|
-
const script =
|
|
28424
|
+
const script = join74(getPythonDir(), "list_devices.py");
|
|
27993
28425
|
spawnSync6(getVenvPython(), [script], { stdio: "inherit" });
|
|
27994
28426
|
}
|
|
27995
28427
|
|
|
27996
28428
|
// src/commands/voice/logs.ts
|
|
27997
|
-
import { existsSync as
|
|
28429
|
+
import { existsSync as existsSync59, readFileSync as readFileSync48 } from "fs";
|
|
27998
28430
|
function logs(options2) {
|
|
27999
|
-
if (!
|
|
28431
|
+
if (!existsSync59(voicePaths.log)) {
|
|
28000
28432
|
console.log("No voice log file found");
|
|
28001
28433
|
return;
|
|
28002
28434
|
}
|
|
28003
28435
|
const count8 = Number.parseInt(options2.lines ?? "150", 10);
|
|
28004
|
-
const content =
|
|
28436
|
+
const content = readFileSync48(voicePaths.log, "utf8").trim();
|
|
28005
28437
|
if (!content) {
|
|
28006
28438
|
console.log("Voice log is empty");
|
|
28007
28439
|
return;
|
|
@@ -28023,13 +28455,13 @@ function logs(options2) {
|
|
|
28023
28455
|
|
|
28024
28456
|
// src/commands/voice/setup.ts
|
|
28025
28457
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
28026
|
-
import { mkdirSync as
|
|
28027
|
-
import { join as
|
|
28458
|
+
import { mkdirSync as mkdirSync27 } from "fs";
|
|
28459
|
+
import { join as join76 } from "path";
|
|
28028
28460
|
|
|
28029
28461
|
// src/commands/voice/checkLockFile.ts
|
|
28030
28462
|
import { execSync as execSync59 } from "child_process";
|
|
28031
|
-
import { existsSync as
|
|
28032
|
-
import { join as
|
|
28463
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync26, readFileSync as readFileSync49, writeFileSync as writeFileSync42 } from "fs";
|
|
28464
|
+
import { join as join75 } from "path";
|
|
28033
28465
|
function isProcessAlive2(pid) {
|
|
28034
28466
|
try {
|
|
28035
28467
|
process.kill(pid, 0);
|
|
@@ -28040,9 +28472,9 @@ function isProcessAlive2(pid) {
|
|
|
28040
28472
|
}
|
|
28041
28473
|
function checkLockFile() {
|
|
28042
28474
|
const lockFile = getLockFile();
|
|
28043
|
-
if (!
|
|
28475
|
+
if (!existsSync60(lockFile)) return;
|
|
28044
28476
|
try {
|
|
28045
|
-
const lock2 = JSON.parse(
|
|
28477
|
+
const lock2 = JSON.parse(readFileSync49(lockFile, "utf8"));
|
|
28046
28478
|
if (lock2.pid && isProcessAlive2(lock2.pid)) {
|
|
28047
28479
|
console.error(
|
|
28048
28480
|
`Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
|
|
@@ -28053,7 +28485,7 @@ function checkLockFile() {
|
|
|
28053
28485
|
}
|
|
28054
28486
|
}
|
|
28055
28487
|
function bootstrapVenv() {
|
|
28056
|
-
if (
|
|
28488
|
+
if (existsSync60(getVenvPython())) return;
|
|
28057
28489
|
console.log("Setting up Python environment...");
|
|
28058
28490
|
const pythonDir = getPythonDir();
|
|
28059
28491
|
execSync59(
|
|
@@ -28066,8 +28498,8 @@ function bootstrapVenv() {
|
|
|
28066
28498
|
}
|
|
28067
28499
|
function writeLockFile(pid) {
|
|
28068
28500
|
const lockFile = getLockFile();
|
|
28069
|
-
|
|
28070
|
-
|
|
28501
|
+
mkdirSync26(join75(lockFile, ".."), { recursive: true });
|
|
28502
|
+
writeFileSync42(
|
|
28071
28503
|
lockFile,
|
|
28072
28504
|
JSON.stringify({
|
|
28073
28505
|
pid,
|
|
@@ -28079,10 +28511,10 @@ function writeLockFile(pid) {
|
|
|
28079
28511
|
|
|
28080
28512
|
// src/commands/voice/setup.ts
|
|
28081
28513
|
function setup() {
|
|
28082
|
-
|
|
28514
|
+
mkdirSync27(voicePaths.dir, { recursive: true });
|
|
28083
28515
|
bootstrapVenv();
|
|
28084
28516
|
console.log("\nDownloading models...\n");
|
|
28085
|
-
const script =
|
|
28517
|
+
const script = join76(getPythonDir(), "setup_models.py");
|
|
28086
28518
|
const result = spawnSync7(getVenvPython(), [script], {
|
|
28087
28519
|
stdio: "inherit",
|
|
28088
28520
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -28095,8 +28527,8 @@ function setup() {
|
|
|
28095
28527
|
|
|
28096
28528
|
// src/commands/voice/start.ts
|
|
28097
28529
|
import { spawn as spawn8 } from "child_process";
|
|
28098
|
-
import { mkdirSync as
|
|
28099
|
-
import { join as
|
|
28530
|
+
import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync43 } from "fs";
|
|
28531
|
+
import { join as join77 } from "path";
|
|
28100
28532
|
|
|
28101
28533
|
// src/commands/voice/buildDaemonEnv.ts
|
|
28102
28534
|
function buildDaemonEnv(options2) {
|
|
@@ -28124,17 +28556,17 @@ function spawnBackground(python, script, env) {
|
|
|
28124
28556
|
console.error("Failed to start voice daemon");
|
|
28125
28557
|
process.exit(1);
|
|
28126
28558
|
}
|
|
28127
|
-
|
|
28559
|
+
writeFileSync43(voicePaths.pid, String(pid));
|
|
28128
28560
|
writeLockFile(pid);
|
|
28129
28561
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
28130
28562
|
}
|
|
28131
28563
|
function start2(options2) {
|
|
28132
|
-
|
|
28564
|
+
mkdirSync28(voicePaths.dir, { recursive: true });
|
|
28133
28565
|
checkLockFile();
|
|
28134
28566
|
bootstrapVenv();
|
|
28135
28567
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
28136
28568
|
const env = buildDaemonEnv({ debug });
|
|
28137
|
-
const script =
|
|
28569
|
+
const script = join77(getPythonDir(), "voice_daemon.py");
|
|
28138
28570
|
const python = getVenvPython();
|
|
28139
28571
|
if (options2.foreground) {
|
|
28140
28572
|
spawnForeground(python, script, env);
|
|
@@ -28144,7 +28576,7 @@ function start2(options2) {
|
|
|
28144
28576
|
}
|
|
28145
28577
|
|
|
28146
28578
|
// src/commands/voice/status.ts
|
|
28147
|
-
import { existsSync as
|
|
28579
|
+
import { existsSync as existsSync61, readFileSync as readFileSync50 } from "fs";
|
|
28148
28580
|
function isProcessAlive3(pid) {
|
|
28149
28581
|
try {
|
|
28150
28582
|
process.kill(pid, 0);
|
|
@@ -28154,16 +28586,16 @@ function isProcessAlive3(pid) {
|
|
|
28154
28586
|
}
|
|
28155
28587
|
}
|
|
28156
28588
|
function readRecentLogs(count8) {
|
|
28157
|
-
if (!
|
|
28158
|
-
const lines2 =
|
|
28589
|
+
if (!existsSync61(voicePaths.log)) return [];
|
|
28590
|
+
const lines2 = readFileSync50(voicePaths.log, "utf8").trim().split("\n");
|
|
28159
28591
|
return lines2.slice(-count8);
|
|
28160
28592
|
}
|
|
28161
28593
|
function status2() {
|
|
28162
|
-
if (!
|
|
28594
|
+
if (!existsSync61(voicePaths.pid)) {
|
|
28163
28595
|
console.log("Voice daemon: not running (no PID file)");
|
|
28164
28596
|
return;
|
|
28165
28597
|
}
|
|
28166
|
-
const pid = Number.parseInt(
|
|
28598
|
+
const pid = Number.parseInt(readFileSync50(voicePaths.pid, "utf8").trim(), 10);
|
|
28167
28599
|
const alive = isProcessAlive3(pid);
|
|
28168
28600
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
28169
28601
|
const recent = readRecentLogs(5);
|
|
@@ -28182,13 +28614,13 @@ function status2() {
|
|
|
28182
28614
|
}
|
|
28183
28615
|
|
|
28184
28616
|
// src/commands/voice/stop.ts
|
|
28185
|
-
import { existsSync as
|
|
28617
|
+
import { existsSync as existsSync62, readFileSync as readFileSync51, unlinkSync as unlinkSync20 } from "fs";
|
|
28186
28618
|
function stop2() {
|
|
28187
|
-
if (!
|
|
28619
|
+
if (!existsSync62(voicePaths.pid)) {
|
|
28188
28620
|
console.log("Voice daemon is not running (no PID file)");
|
|
28189
28621
|
return;
|
|
28190
28622
|
}
|
|
28191
|
-
const pid = Number.parseInt(
|
|
28623
|
+
const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
|
|
28192
28624
|
try {
|
|
28193
28625
|
process.kill(pid, "SIGTERM");
|
|
28194
28626
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -28201,7 +28633,7 @@ function stop2() {
|
|
|
28201
28633
|
}
|
|
28202
28634
|
try {
|
|
28203
28635
|
const lockFile = getLockFile();
|
|
28204
|
-
if (
|
|
28636
|
+
if (existsSync62(lockFile)) unlinkSync20(lockFile);
|
|
28205
28637
|
} catch {
|
|
28206
28638
|
}
|
|
28207
28639
|
console.log("Voice daemon stopped");
|
|
@@ -28220,7 +28652,7 @@ function registerVoice(program2) {
|
|
|
28220
28652
|
}
|
|
28221
28653
|
|
|
28222
28654
|
// src/commands/watch/readBuiltVersion.ts
|
|
28223
|
-
import { join as
|
|
28655
|
+
import { join as join78 } from "path";
|
|
28224
28656
|
|
|
28225
28657
|
// src/commands/watch/resolveUpstream.ts
|
|
28226
28658
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
@@ -28266,7 +28698,7 @@ function resolveUpstream(cwd) {
|
|
|
28266
28698
|
function readBuiltVersion(cwd) {
|
|
28267
28699
|
try {
|
|
28268
28700
|
const root = runGit2(["rev-parse", "--show-toplevel"], cwd);
|
|
28269
|
-
return readPackageJson(
|
|
28701
|
+
return readPackageJson(join78(root, "package.json")).version ?? "unknown";
|
|
28270
28702
|
} catch {
|
|
28271
28703
|
return "unknown";
|
|
28272
28704
|
}
|
|
@@ -28318,11 +28750,11 @@ var webUiPrefix = "src/commands/sessions/web/ui/";
|
|
|
28318
28750
|
var sessionsPrefix = "src/commands/sessions/";
|
|
28319
28751
|
var rules = [
|
|
28320
28752
|
{
|
|
28321
|
-
matches: (
|
|
28753
|
+
matches: (path73) => path73.startsWith(webUiPrefix),
|
|
28322
28754
|
advice: "restart the web server, then hard-reload the browser tab"
|
|
28323
28755
|
},
|
|
28324
28756
|
{
|
|
28325
|
-
matches: (
|
|
28757
|
+
matches: (path73) => path73.startsWith(sessionsPrefix) && !path73.startsWith(webUiPrefix),
|
|
28326
28758
|
advice: "restart the daemon"
|
|
28327
28759
|
}
|
|
28328
28760
|
];
|
|
@@ -28564,7 +28996,7 @@ function resolveParams(params, cliArgs) {
|
|
|
28564
28996
|
}
|
|
28565
28997
|
|
|
28566
28998
|
// src/commands/run/resolveRunCwd.ts
|
|
28567
|
-
import { existsSync as
|
|
28999
|
+
import { existsSync as existsSync63 } from "fs";
|
|
28568
29000
|
import { resolve as resolve17 } from "path";
|
|
28569
29001
|
var MissingRunCwdError = class extends Error {
|
|
28570
29002
|
constructor(runName, cwd) {
|
|
@@ -28577,25 +29009,25 @@ var MissingRunCwdError = class extends Error {
|
|
|
28577
29009
|
function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
|
|
28578
29010
|
if (!config.cwd) return void 0;
|
|
28579
29011
|
const cwd = resolve17(baseDir, config.cwd);
|
|
28580
|
-
if (!
|
|
29012
|
+
if (!existsSync63(cwd)) throw new MissingRunCwdError(config.name, cwd);
|
|
28581
29013
|
return cwd;
|
|
28582
29014
|
}
|
|
28583
29015
|
|
|
28584
29016
|
// src/commands/run/runCommandToCompletion.ts
|
|
28585
29017
|
import { spawn as spawn9 } from "child_process";
|
|
28586
|
-
import { existsSync as
|
|
29018
|
+
import { existsSync as existsSync65 } from "fs";
|
|
28587
29019
|
|
|
28588
29020
|
// src/commands/run/resolveCommand.ts
|
|
28589
29021
|
import { execFileSync as execFileSync11 } from "child_process";
|
|
28590
|
-
import { existsSync as
|
|
28591
|
-
import { dirname as
|
|
29022
|
+
import { existsSync as existsSync64 } from "fs";
|
|
29023
|
+
import { dirname as dirname35, join as join79, resolve as resolve18 } from "path";
|
|
28592
29024
|
function resolveCommand2(command) {
|
|
28593
29025
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
28594
29026
|
try {
|
|
28595
29027
|
const gitPath = execFileSync11("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
28596
|
-
const gitRoot = resolve18(
|
|
28597
|
-
const gitBash =
|
|
28598
|
-
if (
|
|
29028
|
+
const gitRoot = resolve18(dirname35(gitPath), "..");
|
|
29029
|
+
const gitBash = join79(gitRoot, "bin", "bash.exe");
|
|
29030
|
+
if (existsSync64(gitBash)) return gitBash;
|
|
28599
29031
|
} catch {
|
|
28600
29032
|
return command;
|
|
28601
29033
|
}
|
|
@@ -28605,7 +29037,7 @@ function resolveCommand2(command) {
|
|
|
28605
29037
|
// src/commands/run/runCommandToCompletion.ts
|
|
28606
29038
|
function runCommandToCompletion(command, args, env, cwd, quiet) {
|
|
28607
29039
|
return new Promise((resolveResult) => {
|
|
28608
|
-
if (cwd && !
|
|
29040
|
+
if (cwd && !existsSync65(cwd)) {
|
|
28609
29041
|
resolveResult({
|
|
28610
29042
|
kind: "failed",
|
|
28611
29043
|
message: `Failed to execute command: cwd ${cwd} does not exist`
|
|
@@ -28835,7 +29267,7 @@ function registerWatch(program2) {
|
|
|
28835
29267
|
|
|
28836
29268
|
// src/commands/roam/auth.ts
|
|
28837
29269
|
import { randomBytes } from "crypto";
|
|
28838
|
-
import
|
|
29270
|
+
import chalk212 from "chalk";
|
|
28839
29271
|
|
|
28840
29272
|
// src/commands/roam/waitForCallback.ts
|
|
28841
29273
|
import { createServer as createServer3 } from "http";
|
|
@@ -28966,13 +29398,13 @@ async function auth() {
|
|
|
28966
29398
|
saveGlobalConfig(config);
|
|
28967
29399
|
const state = randomBytes(16).toString("hex");
|
|
28968
29400
|
console.log(
|
|
28969
|
-
|
|
29401
|
+
chalk212.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
28970
29402
|
);
|
|
28971
|
-
console.log(
|
|
28972
|
-
console.log(
|
|
28973
|
-
console.log(
|
|
29403
|
+
console.log(chalk212.white("http://localhost:14523/callback\n"));
|
|
29404
|
+
console.log(chalk212.blue("Opening browser for authorization..."));
|
|
29405
|
+
console.log(chalk212.dim("Waiting for authorization callback..."));
|
|
28974
29406
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
28975
|
-
console.log(
|
|
29407
|
+
console.log(chalk212.dim("Exchanging code for tokens..."));
|
|
28976
29408
|
const tokens = await exchangeToken({
|
|
28977
29409
|
code,
|
|
28978
29410
|
clientId,
|
|
@@ -28988,25 +29420,25 @@ async function auth() {
|
|
|
28988
29420
|
};
|
|
28989
29421
|
saveGlobalConfig(config);
|
|
28990
29422
|
console.log(
|
|
28991
|
-
|
|
29423
|
+
chalk212.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
28992
29424
|
);
|
|
28993
29425
|
}
|
|
28994
29426
|
|
|
28995
29427
|
// src/commands/roam/postRoamActivity.ts
|
|
28996
29428
|
import { execFileSync as execFileSync13 } from "child_process";
|
|
28997
|
-
import { readdirSync as
|
|
28998
|
-
import { join as
|
|
29429
|
+
import { readdirSync as readdirSync18, readFileSync as readFileSync52, statSync as statSync10 } from "fs";
|
|
29430
|
+
import { join as join80 } from "path";
|
|
28999
29431
|
function findPortFile(roamDir) {
|
|
29000
29432
|
let entries;
|
|
29001
29433
|
try {
|
|
29002
|
-
entries =
|
|
29434
|
+
entries = readdirSync18(roamDir);
|
|
29003
29435
|
} catch {
|
|
29004
29436
|
return void 0;
|
|
29005
29437
|
}
|
|
29006
29438
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
29007
|
-
const
|
|
29439
|
+
const path73 = join80(roamDir, name);
|
|
29008
29440
|
try {
|
|
29009
|
-
return { path:
|
|
29441
|
+
return { path: path73, mtimeMs: statSync10(path73).mtimeMs };
|
|
29010
29442
|
} catch {
|
|
29011
29443
|
return void 0;
|
|
29012
29444
|
}
|
|
@@ -29016,11 +29448,11 @@ function findPortFile(roamDir) {
|
|
|
29016
29448
|
function postRoamActivity(app, event) {
|
|
29017
29449
|
const appData = process.env.APPDATA;
|
|
29018
29450
|
if (!appData) return;
|
|
29019
|
-
const portFile = findPortFile(
|
|
29451
|
+
const portFile = findPortFile(join80(appData, "Roam"));
|
|
29020
29452
|
if (!portFile) return;
|
|
29021
29453
|
let port;
|
|
29022
29454
|
try {
|
|
29023
|
-
port =
|
|
29455
|
+
port = readFileSync52(portFile, "utf8").trim();
|
|
29024
29456
|
} catch {
|
|
29025
29457
|
return;
|
|
29026
29458
|
}
|
|
@@ -29148,8 +29580,8 @@ async function run3(name, args) {
|
|
|
29148
29580
|
}
|
|
29149
29581
|
|
|
29150
29582
|
// src/commands/run/add.ts
|
|
29151
|
-
import { mkdirSync as
|
|
29152
|
-
import { join as
|
|
29583
|
+
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync44 } from "fs";
|
|
29584
|
+
import { join as join81 } from "path";
|
|
29153
29585
|
|
|
29154
29586
|
// src/commands/run/extractOption.ts
|
|
29155
29587
|
function extractOption(args, flag) {
|
|
@@ -29210,16 +29642,16 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
29210
29642
|
saveConfig(config);
|
|
29211
29643
|
}
|
|
29212
29644
|
function createCommandFile(name) {
|
|
29213
|
-
const dir =
|
|
29214
|
-
|
|
29645
|
+
const dir = join81(".claude", "commands");
|
|
29646
|
+
mkdirSync29(dir, { recursive: true });
|
|
29215
29647
|
const content = `---
|
|
29216
29648
|
description: Run ${name}
|
|
29217
29649
|
---
|
|
29218
29650
|
|
|
29219
29651
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
29220
29652
|
`;
|
|
29221
|
-
const filePath =
|
|
29222
|
-
|
|
29653
|
+
const filePath = join81(dir, `${name}.md`);
|
|
29654
|
+
writeFileSync44(filePath, content);
|
|
29223
29655
|
console.log(`Created command file: ${filePath}`);
|
|
29224
29656
|
}
|
|
29225
29657
|
function add3() {
|
|
@@ -29242,11 +29674,11 @@ function findLinkIndex() {
|
|
|
29242
29674
|
function parseLinkArgs() {
|
|
29243
29675
|
const idx = findLinkIndex();
|
|
29244
29676
|
if (idx === -1) return null;
|
|
29245
|
-
const
|
|
29677
|
+
const path73 = process.argv[idx + 1];
|
|
29246
29678
|
const rest = process.argv.slice(idx + 2);
|
|
29247
29679
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
29248
29680
|
if (!prefix2) return null;
|
|
29249
|
-
return { path:
|
|
29681
|
+
return { path: path73, prefix: prefix2 };
|
|
29250
29682
|
}
|
|
29251
29683
|
function hasDuplicateLink(runList, linkPath) {
|
|
29252
29684
|
return runList.some(
|
|
@@ -29274,8 +29706,8 @@ function link2() {
|
|
|
29274
29706
|
}
|
|
29275
29707
|
|
|
29276
29708
|
// src/commands/run/remove.ts
|
|
29277
|
-
import { existsSync as
|
|
29278
|
-
import { join as
|
|
29709
|
+
import { existsSync as existsSync66, unlinkSync as unlinkSync21 } from "fs";
|
|
29710
|
+
import { join as join82 } from "path";
|
|
29279
29711
|
function findRemoveIndex() {
|
|
29280
29712
|
const idx = process.argv.indexOf("remove");
|
|
29281
29713
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -29290,8 +29722,8 @@ function parseRemoveName() {
|
|
|
29290
29722
|
return process.argv[idx + 1];
|
|
29291
29723
|
}
|
|
29292
29724
|
function deleteCommandFile(name) {
|
|
29293
|
-
const filePath =
|
|
29294
|
-
if (
|
|
29725
|
+
const filePath = join82(".claude", "commands", `${name}.md`);
|
|
29726
|
+
if (existsSync66(filePath)) {
|
|
29295
29727
|
unlinkSync21(filePath);
|
|
29296
29728
|
console.log(`Deleted command file: ${filePath}`);
|
|
29297
29729
|
}
|
|
@@ -29336,10 +29768,10 @@ function registerRun(program2) {
|
|
|
29336
29768
|
|
|
29337
29769
|
// src/commands/screenshot/index.ts
|
|
29338
29770
|
import { execSync as execSync61 } from "child_process";
|
|
29339
|
-
import { existsSync as
|
|
29771
|
+
import { existsSync as existsSync67, mkdirSync as mkdirSync30, unlinkSync as unlinkSync22, writeFileSync as writeFileSync45 } from "fs";
|
|
29340
29772
|
import { tmpdir as tmpdir8 } from "os";
|
|
29341
|
-
import { join as
|
|
29342
|
-
import
|
|
29773
|
+
import { join as join83, resolve as resolve19 } from "path";
|
|
29774
|
+
import chalk213 from "chalk";
|
|
29343
29775
|
|
|
29344
29776
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
29345
29777
|
var captureWindowPs1 = `
|
|
@@ -29468,15 +29900,15 @@ Write-Output $OutputPath
|
|
|
29468
29900
|
|
|
29469
29901
|
// src/commands/screenshot/index.ts
|
|
29470
29902
|
function buildOutputPath(outputDir, processName) {
|
|
29471
|
-
if (!
|
|
29472
|
-
|
|
29903
|
+
if (!existsSync67(outputDir)) {
|
|
29904
|
+
mkdirSync30(outputDir, { recursive: true });
|
|
29473
29905
|
}
|
|
29474
29906
|
const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
29475
29907
|
return resolve19(outputDir, `${processName}-${timestamp6}.png`);
|
|
29476
29908
|
}
|
|
29477
29909
|
function runPowerShellScript(processName, outputPath) {
|
|
29478
|
-
const scriptPath =
|
|
29479
|
-
|
|
29910
|
+
const scriptPath = join83(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
|
|
29911
|
+
writeFileSync45(scriptPath, captureWindowPs1, "utf8");
|
|
29480
29912
|
try {
|
|
29481
29913
|
execSync61(
|
|
29482
29914
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
@@ -29490,13 +29922,13 @@ function screenshot(processName) {
|
|
|
29490
29922
|
const config = loadConfig();
|
|
29491
29923
|
const outputDir = resolve19(config.screenshot.outputDir);
|
|
29492
29924
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
29493
|
-
console.log(
|
|
29925
|
+
console.log(chalk213.gray(`Capturing window for process "${processName}" ...`));
|
|
29494
29926
|
try {
|
|
29495
29927
|
runPowerShellScript(processName, outputPath);
|
|
29496
|
-
console.log(
|
|
29928
|
+
console.log(chalk213.green(`Screenshot saved: ${outputPath}`));
|
|
29497
29929
|
} catch (error) {
|
|
29498
29930
|
const msg = error instanceof Error ? error.message : String(error);
|
|
29499
|
-
console.error(
|
|
29931
|
+
console.error(chalk213.red(`Failed to capture screenshot: ${msg}`));
|
|
29500
29932
|
process.exit(1);
|
|
29501
29933
|
}
|
|
29502
29934
|
}
|
|
@@ -29552,7 +29984,7 @@ function applyLine(result, pending, line) {
|
|
|
29552
29984
|
}
|
|
29553
29985
|
|
|
29554
29986
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
29555
|
-
import { readFileSync as
|
|
29987
|
+
import { readFileSync as readFileSync53 } from "fs";
|
|
29556
29988
|
function reportStolenSocket(socketPid) {
|
|
29557
29989
|
if (!socketPid) return;
|
|
29558
29990
|
const filePid = readPidFile();
|
|
@@ -29564,7 +29996,7 @@ function reportStolenSocket(socketPid) {
|
|
|
29564
29996
|
function readPidFile() {
|
|
29565
29997
|
try {
|
|
29566
29998
|
const pid = Number.parseInt(
|
|
29567
|
-
|
|
29999
|
+
readFileSync53(daemonPaths.pid, "utf8").trim(),
|
|
29568
30000
|
10
|
|
29569
30001
|
);
|
|
29570
30002
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -29699,7 +30131,7 @@ function requestDrain(socket, lines2) {
|
|
|
29699
30131
|
}
|
|
29700
30132
|
|
|
29701
30133
|
// src/commands/sessions/daemon/runDaemon.ts
|
|
29702
|
-
import { mkdirSync as
|
|
30134
|
+
import { mkdirSync as mkdirSync34 } from "fs";
|
|
29703
30135
|
|
|
29704
30136
|
// src/commands/sessions/daemon/createAutoExit.ts
|
|
29705
30137
|
var DEFAULT_GRACE_MS = 6e4;
|
|
@@ -29962,42 +30394,42 @@ function serverRunMeta(runName, cwd) {
|
|
|
29962
30394
|
}
|
|
29963
30395
|
|
|
29964
30396
|
// src/commands/sessions/daemon/readDesignSystemPrompt.ts
|
|
29965
|
-
import * as
|
|
29966
|
-
import * as
|
|
29967
|
-
import { fileURLToPath as
|
|
29968
|
-
var
|
|
29969
|
-
var
|
|
30397
|
+
import * as fs44 from "fs";
|
|
30398
|
+
import * as path69 from "path";
|
|
30399
|
+
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
30400
|
+
var __filename5 = fileURLToPath9(import.meta.url);
|
|
30401
|
+
var __dirname7 = path69.dirname(__filename5);
|
|
29970
30402
|
function readDesignSystemPrompt() {
|
|
29971
|
-
const promptPath =
|
|
29972
|
-
|
|
30403
|
+
const promptPath = path69.join(
|
|
30404
|
+
__dirname7,
|
|
29973
30405
|
"..",
|
|
29974
30406
|
"claude",
|
|
29975
30407
|
"design-system-prompt.md"
|
|
29976
30408
|
);
|
|
29977
|
-
return
|
|
30409
|
+
return fs44.readFileSync(promptPath, "utf8");
|
|
29978
30410
|
}
|
|
29979
30411
|
|
|
29980
30412
|
// src/commands/sessions/daemon/spawnPty.ts
|
|
29981
|
-
import { existsSync as
|
|
30413
|
+
import { existsSync as existsSync69 } from "fs";
|
|
29982
30414
|
import * as pty from "node-pty";
|
|
29983
30415
|
|
|
29984
30416
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
29985
|
-
import { chmodSync, existsSync as
|
|
30417
|
+
import { chmodSync, existsSync as existsSync68, statSync as statSync11 } from "fs";
|
|
29986
30418
|
import { createRequire as createRequire3 } from "module";
|
|
29987
|
-
import
|
|
30419
|
+
import path70 from "path";
|
|
29988
30420
|
var require4 = createRequire3(import.meta.url);
|
|
29989
30421
|
var ensured = false;
|
|
29990
30422
|
function ensureSpawnHelperExecutable() {
|
|
29991
30423
|
if (ensured || process.platform !== "darwin") return;
|
|
29992
30424
|
ensured = true;
|
|
29993
|
-
const ptyRoot =
|
|
29994
|
-
const helper =
|
|
30425
|
+
const ptyRoot = path70.join(path70.dirname(require4.resolve("node-pty")), "..");
|
|
30426
|
+
const helper = path70.join(
|
|
29995
30427
|
ptyRoot,
|
|
29996
30428
|
"prebuilds",
|
|
29997
30429
|
`${process.platform}-${process.arch}`,
|
|
29998
30430
|
"spawn-helper"
|
|
29999
30431
|
);
|
|
30000
|
-
if (!
|
|
30432
|
+
if (!existsSync68(helper)) return;
|
|
30001
30433
|
const mode = statSync11(helper).mode;
|
|
30002
30434
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
30003
30435
|
}
|
|
@@ -30033,7 +30465,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
|
|
|
30033
30465
|
});
|
|
30034
30466
|
}
|
|
30035
30467
|
function refuseMissingCwd(cwd, sessionId) {
|
|
30036
|
-
if (!cwd ||
|
|
30468
|
+
if (!cwd || existsSync69(cwd)) return;
|
|
30037
30469
|
daemonLog(
|
|
30038
30470
|
`${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
|
|
30039
30471
|
);
|
|
@@ -30164,17 +30596,17 @@ function setStatus2(session, newStatus) {
|
|
|
30164
30596
|
}
|
|
30165
30597
|
|
|
30166
30598
|
// src/commands/sessions/daemon/worktree/reapWorktree.ts
|
|
30167
|
-
import { existsSync as
|
|
30168
|
-
import { basename as
|
|
30599
|
+
import { existsSync as existsSync71 } from "fs";
|
|
30600
|
+
import { basename as basename20 } from "path";
|
|
30169
30601
|
|
|
30170
30602
|
// src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
|
|
30171
|
-
import { existsSync as
|
|
30172
|
-
import { join as
|
|
30603
|
+
import { existsSync as existsSync70 } from "fs";
|
|
30604
|
+
import { join as join86 } from "path";
|
|
30173
30605
|
|
|
30174
30606
|
// src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
|
|
30175
30607
|
import { statSync as statSync12 } from "fs";
|
|
30176
30608
|
import { rm as rm2 } from "fs/promises";
|
|
30177
|
-
import { join as
|
|
30609
|
+
import { join as join85 } from "path";
|
|
30178
30610
|
async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
30179
30611
|
if (holdsAGitDirectoryRatherThanALink(worktreePath)) {
|
|
30180
30612
|
const refusal = "it is a clone of its own, not a linked worktree";
|
|
@@ -30202,7 +30634,7 @@ async function deleteTreeDirectly(clone, worktreePath, why) {
|
|
|
30202
30634
|
return { removed: true };
|
|
30203
30635
|
}
|
|
30204
30636
|
function holdsAGitDirectoryRatherThanALink(worktreePath) {
|
|
30205
|
-
return statSync12(
|
|
30637
|
+
return statSync12(join85(worktreePath, ".git"), {
|
|
30206
30638
|
throwIfNoEntry: false
|
|
30207
30639
|
})?.isDirectory() === true;
|
|
30208
30640
|
}
|
|
@@ -30238,7 +30670,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
|
|
|
30238
30670
|
);
|
|
30239
30671
|
}
|
|
30240
30672
|
function strandedReason(worktreePath, cause) {
|
|
30241
|
-
if (!
|
|
30673
|
+
if (!existsSync70(join86(worktreePath, ".git")))
|
|
30242
30674
|
return "its .git link is already gone";
|
|
30243
30675
|
if (/not a working tree|not a git repository/i.test(reason2(cause)))
|
|
30244
30676
|
return "git no longer recognises it as a working tree";
|
|
@@ -30290,7 +30722,7 @@ function reason3(error) {
|
|
|
30290
30722
|
|
|
30291
30723
|
// src/commands/sessions/daemon/worktree/reapWorktree.ts
|
|
30292
30724
|
async function reapWorktree(worktreePath, force = false) {
|
|
30293
|
-
if (!
|
|
30725
|
+
if (!existsSync71(worktreePath)) {
|
|
30294
30726
|
forgetWorktree(worktreePath);
|
|
30295
30727
|
daemonLog(
|
|
30296
30728
|
`worktree ${worktreePath} already gone; its record was forgotten`
|
|
@@ -30308,14 +30740,14 @@ async function reapWorktree(worktreePath, force = false) {
|
|
|
30308
30740
|
const clone = owningClone(worktreePath);
|
|
30309
30741
|
const removal = await removeTree(clone, worktreePath, force);
|
|
30310
30742
|
if (!removal.removed) return removal;
|
|
30311
|
-
await deleteWorktreeBranch(clone,
|
|
30743
|
+
await deleteWorktreeBranch(clone, basename20(worktreePath));
|
|
30312
30744
|
forgetWorktree(worktreePath);
|
|
30313
30745
|
daemonLog(`worktree ${worktreePath} reaped${force ? " (forced)" : ""}`);
|
|
30314
30746
|
return removal;
|
|
30315
30747
|
}
|
|
30316
30748
|
function owningClone(worktreePath) {
|
|
30317
30749
|
const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
|
|
30318
|
-
if (recorded &&
|
|
30750
|
+
if (recorded && existsSync71(recorded)) return recorded;
|
|
30319
30751
|
const detected = mainWorktree(worktreePath);
|
|
30320
30752
|
if (detected) return detected;
|
|
30321
30753
|
daemonLog(
|
|
@@ -30443,12 +30875,12 @@ function closeGateApplies(sessions, session) {
|
|
|
30443
30875
|
}
|
|
30444
30876
|
|
|
30445
30877
|
// src/commands/sessions/daemon/worktree/watchGitState.ts
|
|
30446
|
-
import { existsSync as
|
|
30878
|
+
import { existsSync as existsSync72, watch } from "fs";
|
|
30447
30879
|
var DEBOUNCE_MS = 500;
|
|
30448
30880
|
var POLL_MS = 3e4;
|
|
30449
30881
|
function watchGitState(cwd, onChange) {
|
|
30450
30882
|
const common = gitCommonDir(cwd);
|
|
30451
|
-
if (!common || !
|
|
30883
|
+
if (!common || !existsSync72(common)) return void 0;
|
|
30452
30884
|
const watchers = [
|
|
30453
30885
|
watchGitDir(common, onChange),
|
|
30454
30886
|
pollGitState(cwd, onChange)
|
|
@@ -30893,10 +31325,10 @@ function emitSessionOutput(session, clients, data) {
|
|
|
30893
31325
|
}
|
|
30894
31326
|
|
|
30895
31327
|
// src/commands/sessions/daemon/exitReason.ts
|
|
30896
|
-
import { existsSync as
|
|
31328
|
+
import { existsSync as existsSync73 } from "fs";
|
|
30897
31329
|
import { resolve as resolve20 } from "path";
|
|
30898
31330
|
function exitDetail(session) {
|
|
30899
|
-
if (session.cwd && !
|
|
31331
|
+
if (session.cwd && !existsSync73(session.cwd))
|
|
30900
31332
|
return `working directory ${session.cwd} no longer exists`;
|
|
30901
31333
|
return missingRunConfigCwd(session);
|
|
30902
31334
|
}
|
|
@@ -30910,7 +31342,7 @@ function missingRunConfigCwd(session) {
|
|
|
30910
31342
|
const config = resolveRunConfig(session.runName, dir);
|
|
30911
31343
|
if (!config?.cwd) return void 0;
|
|
30912
31344
|
const configured = resolve20(runConfigBaseDirFrom(dir), config.cwd);
|
|
30913
|
-
if (
|
|
31345
|
+
if (existsSync73(configured)) return void 0;
|
|
30914
31346
|
return `run config "${config.name}": cwd ${configured} does not exist`;
|
|
30915
31347
|
}
|
|
30916
31348
|
|
|
@@ -30927,8 +31359,8 @@ function handleFailedResume(session, exitCode, onStatusChange) {
|
|
|
30927
31359
|
}
|
|
30928
31360
|
|
|
30929
31361
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
30930
|
-
import { existsSync as
|
|
30931
|
-
import { dirname as
|
|
31362
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync31, watch as watch2 } from "fs";
|
|
31363
|
+
import { dirname as dirname37 } from "path";
|
|
30932
31364
|
|
|
30933
31365
|
// src/commands/sessions/daemon/applyReviewPause.ts
|
|
30934
31366
|
function applyReviewPause(session, activity2) {
|
|
@@ -30981,10 +31413,10 @@ async function seedRunningMsFromUsage(session, notify2) {
|
|
|
30981
31413
|
var DEBOUNCE_MS2 = 50;
|
|
30982
31414
|
function watchActivity(session, notify2, onClaudeSessionId) {
|
|
30983
31415
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
30984
|
-
const
|
|
30985
|
-
const dir =
|
|
31416
|
+
const path73 = activityPath(session.id);
|
|
31417
|
+
const dir = dirname37(path73);
|
|
30986
31418
|
try {
|
|
30987
|
-
|
|
31419
|
+
mkdirSync31(dir, { recursive: true });
|
|
30988
31420
|
} catch {
|
|
30989
31421
|
return;
|
|
30990
31422
|
}
|
|
@@ -30992,7 +31424,7 @@ function watchActivity(session, notify2, onClaudeSessionId) {
|
|
|
30992
31424
|
let timer = null;
|
|
30993
31425
|
const read = () => {
|
|
30994
31426
|
timer = null;
|
|
30995
|
-
const activity2 = readActivity(
|
|
31427
|
+
const activity2 = readActivity(path73);
|
|
30996
31428
|
if (!activity2) return;
|
|
30997
31429
|
session.activity = activity2;
|
|
30998
31430
|
if (activity2.claudeSessionId) {
|
|
@@ -31004,11 +31436,11 @@ function watchActivity(session, notify2, onClaudeSessionId) {
|
|
|
31004
31436
|
notify2();
|
|
31005
31437
|
};
|
|
31006
31438
|
session.activityWatcher = watch2(dir, (_event, filename) => {
|
|
31007
|
-
if (filename && !
|
|
31439
|
+
if (filename && !path73.endsWith(filename)) return;
|
|
31008
31440
|
if (timer) clearTimeout(timer);
|
|
31009
31441
|
timer = setTimeout(read, DEBOUNCE_MS2);
|
|
31010
31442
|
});
|
|
31011
|
-
if (
|
|
31443
|
+
if (existsSync74(path73)) read();
|
|
31012
31444
|
}
|
|
31013
31445
|
function refreshActivity(session) {
|
|
31014
31446
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -31097,56 +31529,56 @@ function reportSilentFailure(session, clients) {
|
|
|
31097
31529
|
import { watch as watch3 } from "fs";
|
|
31098
31530
|
|
|
31099
31531
|
// src/commands/sessions/shared/findTranscriptPathSync.ts
|
|
31100
|
-
import * as
|
|
31101
|
-
import * as
|
|
31102
|
-
import * as
|
|
31532
|
+
import * as fs45 from "fs";
|
|
31533
|
+
import * as os5 from "os";
|
|
31534
|
+
import * as path71 from "path";
|
|
31103
31535
|
function projectDirForCwd(cwd) {
|
|
31104
|
-
return
|
|
31105
|
-
|
|
31536
|
+
return path71.join(
|
|
31537
|
+
os5.homedir(),
|
|
31106
31538
|
".claude",
|
|
31107
31539
|
"projects",
|
|
31108
31540
|
cwd.replace(/[^a-zA-Z0-9]/g, "-")
|
|
31109
31541
|
);
|
|
31110
31542
|
}
|
|
31111
31543
|
function transcriptPathFor(cwd, claudeSessionId) {
|
|
31112
|
-
return
|
|
31544
|
+
return path71.join(projectDirForCwd(cwd), `${claudeSessionId}.jsonl`);
|
|
31113
31545
|
}
|
|
31114
31546
|
function findTranscriptPathSync(cwd, claudeSessionId) {
|
|
31115
31547
|
const direct = transcriptPathFor(cwd, claudeSessionId);
|
|
31116
|
-
if (
|
|
31548
|
+
if (fs45.existsSync(direct)) return direct;
|
|
31117
31549
|
const dir = projectDirForCwd(cwd);
|
|
31118
31550
|
let files;
|
|
31119
31551
|
try {
|
|
31120
|
-
files =
|
|
31552
|
+
files = fs45.readdirSync(dir);
|
|
31121
31553
|
} catch {
|
|
31122
31554
|
return null;
|
|
31123
31555
|
}
|
|
31124
31556
|
for (const file of files) {
|
|
31125
31557
|
if (!file.endsWith(".jsonl")) continue;
|
|
31126
|
-
if (headContainsSessionId(
|
|
31127
|
-
return
|
|
31558
|
+
if (headContainsSessionId(path71.join(dir, file), claudeSessionId))
|
|
31559
|
+
return path71.join(dir, file);
|
|
31128
31560
|
}
|
|
31129
31561
|
return null;
|
|
31130
31562
|
}
|
|
31131
31563
|
function headContainsSessionId(filePath, claudeSessionId) {
|
|
31132
31564
|
let fd;
|
|
31133
31565
|
try {
|
|
31134
|
-
fd =
|
|
31566
|
+
fd = fs45.openSync(filePath, "r");
|
|
31135
31567
|
const buf = Buffer.alloc(16384);
|
|
31136
|
-
const bytesRead =
|
|
31568
|
+
const bytesRead = fs45.readSync(fd, buf, 0, buf.length, 0);
|
|
31137
31569
|
return buf.toString("utf8", 0, bytesRead).includes(claudeSessionId);
|
|
31138
31570
|
} catch {
|
|
31139
31571
|
return false;
|
|
31140
31572
|
} finally {
|
|
31141
|
-
if (fd !== void 0)
|
|
31573
|
+
if (fd !== void 0) fs45.closeSync(fd);
|
|
31142
31574
|
}
|
|
31143
31575
|
}
|
|
31144
31576
|
|
|
31145
31577
|
// src/commands/sessions/daemon/ensureProjectDirExists.ts
|
|
31146
|
-
import { mkdirSync as
|
|
31578
|
+
import { mkdirSync as mkdirSync32 } from "fs";
|
|
31147
31579
|
function ensureProjectDirExists(dir, sessionId) {
|
|
31148
31580
|
try {
|
|
31149
|
-
|
|
31581
|
+
mkdirSync32(dir, { recursive: true });
|
|
31150
31582
|
return true;
|
|
31151
31583
|
} catch (error) {
|
|
31152
31584
|
daemonLog(
|
|
@@ -31253,7 +31685,7 @@ function resolvedToolUseIds(events, afterIdx) {
|
|
|
31253
31685
|
}
|
|
31254
31686
|
|
|
31255
31687
|
// src/commands/sessions/shared/readTranscriptTail.ts
|
|
31256
|
-
import * as
|
|
31688
|
+
import * as fs46 from "fs";
|
|
31257
31689
|
var DEFAULT_MAX_BYTES = 256 * 1024;
|
|
31258
31690
|
function parseTailEntries(raw) {
|
|
31259
31691
|
const entries = [];
|
|
@@ -31277,7 +31709,7 @@ function dropPartialFirstLine(raw, sliced) {
|
|
|
31277
31709
|
async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
31278
31710
|
let handle;
|
|
31279
31711
|
try {
|
|
31280
|
-
handle = await
|
|
31712
|
+
handle = await fs46.promises.open(filePath, "r");
|
|
31281
31713
|
const { size } = await handle.stat();
|
|
31282
31714
|
const start3 = Math.max(0, size - maxBytes);
|
|
31283
31715
|
const length = size - start3;
|
|
@@ -31296,20 +31728,20 @@ async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
|
31296
31728
|
function readTranscriptTailSync(filePath, maxBytes = DEFAULT_MAX_BYTES) {
|
|
31297
31729
|
let fd;
|
|
31298
31730
|
try {
|
|
31299
|
-
fd =
|
|
31300
|
-
const { size } =
|
|
31731
|
+
fd = fs46.openSync(filePath, "r");
|
|
31732
|
+
const { size } = fs46.fstatSync(fd);
|
|
31301
31733
|
const start3 = Math.max(0, size - maxBytes);
|
|
31302
31734
|
const length = size - start3;
|
|
31303
31735
|
if (length === 0) return [];
|
|
31304
31736
|
const buf = Buffer.alloc(length);
|
|
31305
|
-
|
|
31737
|
+
fs46.readSync(fd, buf, 0, length, start3);
|
|
31306
31738
|
return parseTailEntries(
|
|
31307
31739
|
dropPartialFirstLine(buf.toString("utf8"), start3 > 0)
|
|
31308
31740
|
);
|
|
31309
31741
|
} catch {
|
|
31310
31742
|
return [];
|
|
31311
31743
|
} finally {
|
|
31312
|
-
if (fd !== void 0)
|
|
31744
|
+
if (fd !== void 0) fs46.closeSync(fd);
|
|
31313
31745
|
}
|
|
31314
31746
|
}
|
|
31315
31747
|
|
|
@@ -31674,7 +32106,7 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
|
31674
32106
|
}
|
|
31675
32107
|
|
|
31676
32108
|
// src/commands/sessions/shared/transcriptUsage.ts
|
|
31677
|
-
import * as
|
|
32109
|
+
import * as fs47 from "fs";
|
|
31678
32110
|
function transcriptUsage(lines2) {
|
|
31679
32111
|
const byId = /* @__PURE__ */ new Map();
|
|
31680
32112
|
for (const line of lines2) {
|
|
@@ -31698,7 +32130,7 @@ function transcriptUsage(lines2) {
|
|
|
31698
32130
|
return [...byId.values()];
|
|
31699
32131
|
}
|
|
31700
32132
|
async function readTranscriptUsage(transcriptPath2) {
|
|
31701
|
-
const content = await
|
|
32133
|
+
const content = await fs47.promises.readFile(transcriptPath2, "utf8");
|
|
31702
32134
|
return transcriptUsage(content.split("\n"));
|
|
31703
32135
|
}
|
|
31704
32136
|
|
|
@@ -32365,8 +32797,8 @@ function rearmStoppedSessions(sessions, notify2) {
|
|
|
32365
32797
|
}
|
|
32366
32798
|
|
|
32367
32799
|
// src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
|
|
32368
|
-
import { existsSync as
|
|
32369
|
-
import { basename as
|
|
32800
|
+
import { existsSync as existsSync77 } from "fs";
|
|
32801
|
+
import { basename as basename22 } from "path";
|
|
32370
32802
|
|
|
32371
32803
|
// src/commands/sessions/daemon/worktree/accountedTrees.ts
|
|
32372
32804
|
function accountedTrees(sessions) {
|
|
@@ -32421,21 +32853,21 @@ function bindResumedWorktree(session, cwd, notify2) {
|
|
|
32421
32853
|
|
|
32422
32854
|
// src/commands/sessions/daemon/worktree/describeHeldWork.ts
|
|
32423
32855
|
var MAX_ITEMS = 20;
|
|
32424
|
-
async function describeHeldWork(
|
|
32425
|
-
if (reason4.startsWith("uncommitted")) return await changedFiles(
|
|
32426
|
-
if (reason4.startsWith("unpushed")) return await unpushedCommits(
|
|
32856
|
+
async function describeHeldWork(path73, reason4) {
|
|
32857
|
+
if (reason4.startsWith("uncommitted")) return await changedFiles(path73);
|
|
32858
|
+
if (reason4.startsWith("unpushed")) return await unpushedCommits(path73, reason4);
|
|
32427
32859
|
return { summary: reason4, items: [] };
|
|
32428
32860
|
}
|
|
32429
|
-
async function changedFiles(
|
|
32430
|
-
const status3 = await gitResult(
|
|
32861
|
+
async function changedFiles(path73) {
|
|
32862
|
+
const status3 = await gitResult(path73, ["status", "--porcelain"]);
|
|
32431
32863
|
const lines2 = status3.ok ? nonEmptyLines(status3.out) : [];
|
|
32432
32864
|
return {
|
|
32433
32865
|
summary: `${lines2.length} uncommitted ${lines2.length === 1 ? "file" : "files"}`,
|
|
32434
32866
|
items: capped(lines2)
|
|
32435
32867
|
};
|
|
32436
32868
|
}
|
|
32437
|
-
async function unpushedCommits(
|
|
32438
|
-
const log2 = await gitResult(
|
|
32869
|
+
async function unpushedCommits(path73, reason4) {
|
|
32870
|
+
const log2 = await gitResult(path73, ["log", "--oneline", "@{upstream}..HEAD"]);
|
|
32439
32871
|
if (!log2.ok) return { summary: reason4, items: [] };
|
|
32440
32872
|
const lines2 = nonEmptyLines(log2.out);
|
|
32441
32873
|
return {
|
|
@@ -32455,18 +32887,18 @@ function capped(lines2) {
|
|
|
32455
32887
|
}
|
|
32456
32888
|
|
|
32457
32889
|
// src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
|
|
32458
|
-
import { existsSync as
|
|
32890
|
+
import { existsSync as existsSync76 } from "fs";
|
|
32459
32891
|
async function reclaimVanishedWorktrees(clone, paths) {
|
|
32460
|
-
if (!
|
|
32461
|
-
for (const { path:
|
|
32892
|
+
if (!existsSync76(clone)) {
|
|
32893
|
+
for (const { path: path73 } of paths) forgetWorktree(path73);
|
|
32462
32894
|
daemonLog(
|
|
32463
32895
|
`clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
|
|
32464
32896
|
);
|
|
32465
32897
|
return;
|
|
32466
32898
|
}
|
|
32467
32899
|
await pruneBookkeeping2(clone);
|
|
32468
|
-
for (const { path:
|
|
32469
|
-
if (await reclaimBranch(clone, branch2)) forgetWorktree(
|
|
32900
|
+
for (const { path: path73, branch: branch2 } of paths)
|
|
32901
|
+
if (await reclaimBranch(clone, branch2)) forgetWorktree(path73);
|
|
32470
32902
|
}
|
|
32471
32903
|
async function pruneBookkeeping2(clone) {
|
|
32472
32904
|
try {
|
|
@@ -32493,7 +32925,7 @@ async function reclaimBranch(clone, branch2) {
|
|
|
32493
32925
|
}
|
|
32494
32926
|
|
|
32495
32927
|
// src/commands/sessions/daemon/worktree/resurfaceOrphanedWorktree.ts
|
|
32496
|
-
import { basename as
|
|
32928
|
+
import { basename as basename21 } from "path";
|
|
32497
32929
|
function resurfaceOrphanedWorktree(sessions, spawnWith, recovered, notify2) {
|
|
32498
32930
|
const { orphan, reason: reason4, held } = recovered;
|
|
32499
32931
|
let id;
|
|
@@ -32516,7 +32948,7 @@ function orphanedSession(id, recovered) {
|
|
|
32516
32948
|
const { orphan, reason: reason4, held } = recovered;
|
|
32517
32949
|
return {
|
|
32518
32950
|
...sessionBase(id, "stopped"),
|
|
32519
|
-
name: `recovered ${
|
|
32951
|
+
name: `recovered ${basename21(orphan.path)}`,
|
|
32520
32952
|
subtitle: `${held.summary} in ${orphan.path}`,
|
|
32521
32953
|
commandType: "claude",
|
|
32522
32954
|
pty: null,
|
|
@@ -32541,17 +32973,17 @@ function recoveryNotice({ orphan, held }) {
|
|
|
32541
32973
|
}
|
|
32542
32974
|
|
|
32543
32975
|
// src/commands/sessions/daemon/worktree/logVanishedTree.ts
|
|
32544
|
-
function logVanishedTree(sessions,
|
|
32976
|
+
function logVanishedTree(sessions, path73) {
|
|
32545
32977
|
const claimants = [...sessions.values()].filter(
|
|
32546
|
-
(s) => s.cwd ===
|
|
32978
|
+
(s) => s.cwd === path73 || s.worktree?.path === path73
|
|
32547
32979
|
);
|
|
32548
32980
|
if (claimants.length === 0) {
|
|
32549
|
-
daemonLog(`worktree ${
|
|
32981
|
+
daemonLog(`worktree ${path73} gone from disk and unclaimed; reclaiming it`);
|
|
32550
32982
|
return;
|
|
32551
32983
|
}
|
|
32552
32984
|
for (const s of claimants)
|
|
32553
32985
|
daemonLog(
|
|
32554
|
-
`session ${s.id} ("${s.name}") claims worktree ${
|
|
32986
|
+
`session ${s.id} ("${s.name}") claims worktree ${path73}, which is gone from disk; reclaiming it`
|
|
32555
32987
|
);
|
|
32556
32988
|
}
|
|
32557
32989
|
|
|
@@ -32563,17 +32995,17 @@ function reconcileWorktreesOnRestore(sessions, spawnWith, notify2) {
|
|
|
32563
32995
|
async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
|
|
32564
32996
|
const accounted = accountedTrees(sessions);
|
|
32565
32997
|
const vanished = /* @__PURE__ */ new Map();
|
|
32566
|
-
for (const { path:
|
|
32567
|
-
if (!
|
|
32568
|
-
logVanishedTree(sessions,
|
|
32998
|
+
for (const { path: path73, clone } of readWorktreeRegistry()) {
|
|
32999
|
+
if (!existsSync77(path73)) {
|
|
33000
|
+
logVanishedTree(sessions, path73);
|
|
32569
33001
|
vanished.set(clone, [
|
|
32570
33002
|
...vanished.get(clone) ?? [],
|
|
32571
|
-
{ path:
|
|
33003
|
+
{ path: path73, branch: basename22(path73) }
|
|
32572
33004
|
]);
|
|
32573
33005
|
continue;
|
|
32574
33006
|
}
|
|
32575
|
-
if (accounted.has(
|
|
32576
|
-
await recoverOrphan(sessions, spawnWith, { path:
|
|
33007
|
+
if (accounted.has(path73)) continue;
|
|
33008
|
+
await recoverOrphan(sessions, spawnWith, { path: path73, clone }, notify2);
|
|
32577
33009
|
}
|
|
32578
33010
|
for (const [clone, paths] of vanished)
|
|
32579
33011
|
await reclaimVanishedWorktrees(clone, paths);
|
|
@@ -33152,14 +33584,14 @@ async function defaultConnect() {
|
|
|
33152
33584
|
}
|
|
33153
33585
|
|
|
33154
33586
|
// src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
|
|
33155
|
-
import { existsSync as
|
|
33587
|
+
import { existsSync as existsSync78, readFileSync as readFileSync55 } from "fs";
|
|
33156
33588
|
import { posix } from "path";
|
|
33157
33589
|
function hasPersistedWindowsSessions() {
|
|
33158
33590
|
const sessionsFile = windowsSessionsFileFromWsl();
|
|
33159
33591
|
if (!sessionsFile) return false;
|
|
33160
33592
|
try {
|
|
33161
|
-
if (!
|
|
33162
|
-
const data = JSON.parse(
|
|
33593
|
+
if (!existsSync78(sessionsFile)) return false;
|
|
33594
|
+
const data = JSON.parse(readFileSync55(sessionsFile, "utf8"));
|
|
33163
33595
|
return Array.isArray(data) && data.length > 0;
|
|
33164
33596
|
} catch (error) {
|
|
33165
33597
|
const message3 = error instanceof Error ? error.message : String(error);
|
|
@@ -33737,7 +34169,7 @@ function addAgentToStream(ctx, targetId, prompt, harness) {
|
|
|
33737
34169
|
}
|
|
33738
34170
|
|
|
33739
34171
|
// src/commands/sessions/daemon/worktree/spawnInTree.ts
|
|
33740
|
-
import { existsSync as
|
|
34172
|
+
import { existsSync as existsSync81 } from "fs";
|
|
33741
34173
|
|
|
33742
34174
|
// src/commands/sessions/daemon/createAssistSession.ts
|
|
33743
34175
|
function createAssistSession(id, assistArgs, cwd, meta, holdPty) {
|
|
@@ -33790,11 +34222,11 @@ function resumeSession(id, sessionId, cwd, name, holdPty) {
|
|
|
33790
34222
|
}
|
|
33791
34223
|
|
|
33792
34224
|
// src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
|
|
33793
|
-
import { existsSync as
|
|
34225
|
+
import { existsSync as existsSync80 } from "fs";
|
|
33794
34226
|
|
|
33795
34227
|
// src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
|
|
33796
|
-
import { copyFileSync as
|
|
33797
|
-
import { join as
|
|
34228
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync79, mkdirSync as mkdirSync33 } from "fs";
|
|
34229
|
+
import { join as join88 } from "path";
|
|
33798
34230
|
function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
|
|
33799
34231
|
const dir = projectDirForCwd(toCwd);
|
|
33800
34232
|
if (dir === projectDirForCwd(fromCwd)) {
|
|
@@ -33803,8 +34235,8 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
|
|
|
33803
34235
|
);
|
|
33804
34236
|
return;
|
|
33805
34237
|
}
|
|
33806
|
-
const dest =
|
|
33807
|
-
if (
|
|
34238
|
+
const dest = join88(dir, `${claudeSessionId}.jsonl`);
|
|
34239
|
+
if (existsSync79(dest)) {
|
|
33808
34240
|
daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
|
|
33809
34241
|
return;
|
|
33810
34242
|
}
|
|
@@ -33816,8 +34248,8 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
|
|
|
33816
34248
|
return;
|
|
33817
34249
|
}
|
|
33818
34250
|
try {
|
|
33819
|
-
|
|
33820
|
-
|
|
34251
|
+
mkdirSync33(dir, { recursive: true });
|
|
34252
|
+
copyFileSync7(source, dest);
|
|
33821
34253
|
daemonLog(
|
|
33822
34254
|
`transcript ${source} copied to ${dest} so ${toCwd} can resume it`
|
|
33823
34255
|
);
|
|
@@ -33848,7 +34280,7 @@ function resumeInReplacementTree(ctx, claudeSessionId, missingCwd, name) {
|
|
|
33848
34280
|
}
|
|
33849
34281
|
function cloneForReapedTree(missingCwd) {
|
|
33850
34282
|
const clone = worktreeAttributionIncludingReaped(missingCwd)?.clone;
|
|
33851
|
-
if (!clone || !
|
|
34283
|
+
if (!clone || !existsSync80(clone))
|
|
33852
34284
|
throw new Error(
|
|
33853
34285
|
`working directory no longer exists and no clone is recorded to re-allocate from: ${missingCwd}`
|
|
33854
34286
|
);
|
|
@@ -33880,7 +34312,7 @@ function spawnAssistInTree(ctx, assistArgs, cwd, meta) {
|
|
|
33880
34312
|
return id;
|
|
33881
34313
|
}
|
|
33882
34314
|
function resumeInTree(ctx, sessionId, cwd, name) {
|
|
33883
|
-
if (!
|
|
34315
|
+
if (!existsSync81(cwd))
|
|
33884
34316
|
return resumeInReplacementTree(ctx, sessionId, cwd, name);
|
|
33885
34317
|
const id = ctx.spawnWith((sid) => resumeSession(sid, sessionId, cwd, name));
|
|
33886
34318
|
daemonLog(`session ${id} resuming ${sessionId} in ${cwd}`);
|
|
@@ -34172,12 +34604,12 @@ function handleSetStatus(client, m, d) {
|
|
|
34172
34604
|
}
|
|
34173
34605
|
|
|
34174
34606
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
34175
|
-
import * as
|
|
34607
|
+
import * as fs48 from "fs";
|
|
34176
34608
|
async function parseTranscript(sessionId) {
|
|
34177
34609
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
34178
34610
|
if (!filePath) return [];
|
|
34179
34611
|
try {
|
|
34180
|
-
const raw = await
|
|
34612
|
+
const raw = await fs48.promises.readFile(filePath, "utf8");
|
|
34181
34613
|
return parseTranscriptLines(raw.split("\n"));
|
|
34182
34614
|
} catch {
|
|
34183
34615
|
return [];
|
|
@@ -34201,9 +34633,9 @@ function safeParse2(line) {
|
|
|
34201
34633
|
}
|
|
34202
34634
|
|
|
34203
34635
|
// src/commands/sessions/daemon/repoDirExists.ts
|
|
34204
|
-
import { existsSync as
|
|
34636
|
+
import { existsSync as existsSync82 } from "fs";
|
|
34205
34637
|
function repoDirExists(cwd) {
|
|
34206
|
-
return
|
|
34638
|
+
return existsSync82(toGitCwd(cwd));
|
|
34207
34639
|
}
|
|
34208
34640
|
|
|
34209
34641
|
// src/commands/sessions/daemon/withRepoGroups.ts
|
|
@@ -34404,10 +34836,10 @@ function handleConnection(socket, manager) {
|
|
|
34404
34836
|
}
|
|
34405
34837
|
|
|
34406
34838
|
// src/commands/sessions/daemon/onListening.ts
|
|
34407
|
-
import { unlinkSync as unlinkSync23, writeFileSync as
|
|
34839
|
+
import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync46 } from "fs";
|
|
34408
34840
|
|
|
34409
34841
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
34410
|
-
import { readFileSync as
|
|
34842
|
+
import { readFileSync as readFileSync56 } from "fs";
|
|
34411
34843
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
34412
34844
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
34413
34845
|
const timer = setInterval(() => {
|
|
@@ -34418,7 +34850,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
34418
34850
|
}
|
|
34419
34851
|
function ownsPidFile() {
|
|
34420
34852
|
try {
|
|
34421
|
-
return
|
|
34853
|
+
return readFileSync56(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
34422
34854
|
} catch {
|
|
34423
34855
|
return false;
|
|
34424
34856
|
}
|
|
@@ -34426,7 +34858,7 @@ function ownsPidFile() {
|
|
|
34426
34858
|
|
|
34427
34859
|
// src/commands/sessions/daemon/onListening.ts
|
|
34428
34860
|
function onListening(manager, checkAutoExit) {
|
|
34429
|
-
|
|
34861
|
+
writeFileSync46(daemonPaths.pid, String(process.pid));
|
|
34430
34862
|
startPidFileWatchdog(() => {
|
|
34431
34863
|
daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
|
|
34432
34864
|
void manager.flushActiveMs().finally(() => {
|
|
@@ -34508,7 +34940,7 @@ async function recoverFromAddrInUse(server, manager, checkAutoExit) {
|
|
|
34508
34940
|
|
|
34509
34941
|
// src/commands/sessions/daemon/runDaemon.ts
|
|
34510
34942
|
async function runDaemon() {
|
|
34511
|
-
|
|
34943
|
+
mkdirSync34(daemonPaths.dir, { recursive: true });
|
|
34512
34944
|
daemonLog(
|
|
34513
34945
|
`starting (reason: ${process.env.ASSIST_DAEMON_SPAWN_REASON ?? "manual"})`
|
|
34514
34946
|
);
|
|
@@ -34562,17 +34994,17 @@ function registerSetStatusCommand(cmd) {
|
|
|
34562
34994
|
}
|
|
34563
34995
|
|
|
34564
34996
|
// src/commands/sessions/summarise/index.ts
|
|
34565
|
-
import * as
|
|
34566
|
-
import
|
|
34997
|
+
import * as fs50 from "fs";
|
|
34998
|
+
import chalk214 from "chalk";
|
|
34567
34999
|
|
|
34568
35000
|
// src/commands/sessions/summarise/shared.ts
|
|
34569
|
-
import * as
|
|
35001
|
+
import * as fs49 from "fs";
|
|
34570
35002
|
function writeSummary(jsonlPath2, summary) {
|
|
34571
|
-
|
|
35003
|
+
fs49.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
|
|
34572
35004
|
`, "utf8");
|
|
34573
35005
|
}
|
|
34574
35006
|
function hasSummary(jsonlPath2) {
|
|
34575
|
-
return
|
|
35007
|
+
return fs49.existsSync(summaryPathFor(jsonlPath2));
|
|
34576
35008
|
}
|
|
34577
35009
|
function summaryPathFor(jsonlPath2) {
|
|
34578
35010
|
return jsonlPath2.replace(/\.jsonl$/, ".summary");
|
|
@@ -34622,29 +35054,29 @@ ${firstMessage}`);
|
|
|
34622
35054
|
async function summarise2(options2) {
|
|
34623
35055
|
const files = await discoverSessionFiles();
|
|
34624
35056
|
if (files.length === 0) {
|
|
34625
|
-
console.log(
|
|
35057
|
+
console.log(chalk214.yellow("No sessions found."));
|
|
34626
35058
|
return;
|
|
34627
35059
|
}
|
|
34628
35060
|
const toProcess = selectCandidates(files, options2);
|
|
34629
35061
|
if (toProcess.length === 0) {
|
|
34630
|
-
console.log(
|
|
35062
|
+
console.log(chalk214.green("All sessions already summarised."));
|
|
34631
35063
|
return;
|
|
34632
35064
|
}
|
|
34633
35065
|
console.log(
|
|
34634
|
-
|
|
35066
|
+
chalk214.cyan(
|
|
34635
35067
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
34636
35068
|
)
|
|
34637
35069
|
);
|
|
34638
35070
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
34639
35071
|
console.log(
|
|
34640
|
-
|
|
35072
|
+
chalk214.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk214.yellow(`, ${failed2} skipped`) : "")
|
|
34641
35073
|
);
|
|
34642
35074
|
}
|
|
34643
35075
|
function selectCandidates(files, options2) {
|
|
34644
35076
|
const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
|
|
34645
35077
|
candidates.sort((a, b) => {
|
|
34646
35078
|
try {
|
|
34647
|
-
return
|
|
35079
|
+
return fs50.statSync(b).mtimeMs - fs50.statSync(a).mtimeMs;
|
|
34648
35080
|
} catch {
|
|
34649
35081
|
return 0;
|
|
34650
35082
|
}
|
|
@@ -34657,16 +35089,16 @@ function processSessions(files) {
|
|
|
34657
35089
|
let failed2 = 0;
|
|
34658
35090
|
for (let i = 0; i < files.length; i++) {
|
|
34659
35091
|
const file = files[i];
|
|
34660
|
-
process.stdout.write(
|
|
35092
|
+
process.stdout.write(chalk214.dim(` [${i + 1}/${files.length}] `));
|
|
34661
35093
|
const summary = summariseSession(file);
|
|
34662
35094
|
if (summary) {
|
|
34663
35095
|
writeSummary(file, summary);
|
|
34664
35096
|
succeeded++;
|
|
34665
|
-
process.stdout.write(`${
|
|
35097
|
+
process.stdout.write(`${chalk214.green("\u2713")} ${summary}
|
|
34666
35098
|
`);
|
|
34667
35099
|
} else {
|
|
34668
35100
|
failed2++;
|
|
34669
|
-
process.stdout.write(` ${
|
|
35101
|
+
process.stdout.write(` ${chalk214.yellow("skip")}
|
|
34670
35102
|
`);
|
|
34671
35103
|
}
|
|
34672
35104
|
}
|
|
@@ -34687,7 +35119,7 @@ function registerSessions(program2) {
|
|
|
34687
35119
|
}
|
|
34688
35120
|
|
|
34689
35121
|
// src/commands/statusLine.ts
|
|
34690
|
-
import
|
|
35122
|
+
import chalk216 from "chalk";
|
|
34691
35123
|
|
|
34692
35124
|
// src/shared/contextLevel.ts
|
|
34693
35125
|
function contextLevel(pct) {
|
|
@@ -34697,7 +35129,7 @@ function contextLevel(pct) {
|
|
|
34697
35129
|
}
|
|
34698
35130
|
|
|
34699
35131
|
// src/commands/buildLimitsSegment.ts
|
|
34700
|
-
import
|
|
35132
|
+
import chalk215 from "chalk";
|
|
34701
35133
|
|
|
34702
35134
|
// src/shared/rateLimitLevel.ts
|
|
34703
35135
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -34733,9 +35165,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
34733
35165
|
|
|
34734
35166
|
// src/commands/buildLimitsSegment.ts
|
|
34735
35167
|
var LEVEL_COLOR = {
|
|
34736
|
-
ok:
|
|
34737
|
-
warn:
|
|
34738
|
-
over:
|
|
35168
|
+
ok: chalk215.green,
|
|
35169
|
+
warn: chalk215.yellow,
|
|
35170
|
+
over: chalk215.red
|
|
34739
35171
|
};
|
|
34740
35172
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
34741
35173
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -34766,10 +35198,10 @@ function buildLimitsSegment(rateLimits) {
|
|
|
34766
35198
|
}
|
|
34767
35199
|
|
|
34768
35200
|
// src/commands/readGitBranch.ts
|
|
34769
|
-
import { readFileSync as
|
|
34770
|
-
import { isAbsolute as isAbsolute4, join as
|
|
35201
|
+
import { readFileSync as readFileSync58, statSync as statSync14 } from "fs";
|
|
35202
|
+
import { isAbsolute as isAbsolute4, join as join89, resolve as resolve21 } from "path";
|
|
34771
35203
|
function resolveGitDir(cwd) {
|
|
34772
|
-
const dotGit =
|
|
35204
|
+
const dotGit = join89(cwd, ".git");
|
|
34773
35205
|
let stat4;
|
|
34774
35206
|
try {
|
|
34775
35207
|
stat4 = statSync14(dotGit);
|
|
@@ -34781,7 +35213,7 @@ function resolveGitDir(cwd) {
|
|
|
34781
35213
|
}
|
|
34782
35214
|
let contents;
|
|
34783
35215
|
try {
|
|
34784
|
-
contents =
|
|
35216
|
+
contents = readFileSync58(dotGit, "utf8");
|
|
34785
35217
|
} catch {
|
|
34786
35218
|
return null;
|
|
34787
35219
|
}
|
|
@@ -34799,7 +35231,7 @@ function readGitBranch(cwd) {
|
|
|
34799
35231
|
}
|
|
34800
35232
|
let head;
|
|
34801
35233
|
try {
|
|
34802
|
-
head =
|
|
35234
|
+
head = readFileSync58(join89(gitDir, "HEAD"), "utf8");
|
|
34803
35235
|
} catch {
|
|
34804
35236
|
return null;
|
|
34805
35237
|
}
|
|
@@ -34831,7 +35263,7 @@ async function relayUsage(claudeSessionId, transcriptPath2, usedPct) {
|
|
|
34831
35263
|
}
|
|
34832
35264
|
|
|
34833
35265
|
// src/commands/statusLine.ts
|
|
34834
|
-
|
|
35266
|
+
chalk216.level = 3;
|
|
34835
35267
|
function formatNumber(num) {
|
|
34836
35268
|
return num.toLocaleString("en-US");
|
|
34837
35269
|
}
|
|
@@ -34839,9 +35271,9 @@ function colorizePercent(pct) {
|
|
|
34839
35271
|
const label2 = `${Math.round(pct)}%`;
|
|
34840
35272
|
switch (contextLevel(pct)) {
|
|
34841
35273
|
case "red":
|
|
34842
|
-
return
|
|
35274
|
+
return chalk216.red(label2);
|
|
34843
35275
|
case "yellow":
|
|
34844
|
-
return
|
|
35276
|
+
return chalk216.yellow(label2);
|
|
34845
35277
|
default:
|
|
34846
35278
|
return label2;
|
|
34847
35279
|
}
|
|
@@ -34854,7 +35286,7 @@ async function statusLine() {
|
|
|
34854
35286
|
const usedPct = data.context_window.used_percentage ?? 0;
|
|
34855
35287
|
const dir = data.workspace?.current_dir ?? data.cwd;
|
|
34856
35288
|
const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
|
|
34857
|
-
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${
|
|
35289
|
+
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk216.cyan(branch2)} | ` : "";
|
|
34858
35290
|
console.log(
|
|
34859
35291
|
`${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
|
|
34860
35292
|
);
|
|
@@ -34866,299 +35298,9 @@ async function statusLine() {
|
|
|
34866
35298
|
);
|
|
34867
35299
|
}
|
|
34868
35300
|
|
|
34869
|
-
// src/commands/sync.ts
|
|
34870
|
-
import * as fs48 from "fs";
|
|
34871
|
-
import * as os5 from "os";
|
|
34872
|
-
import * as path69 from "path";
|
|
34873
|
-
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
34874
|
-
|
|
34875
|
-
// src/commands/sync/syncClaudeMd.ts
|
|
34876
|
-
import * as fs42 from "fs";
|
|
34877
|
-
import * as path61 from "path";
|
|
34878
|
-
import chalk215 from "chalk";
|
|
34879
|
-
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
34880
|
-
const source = path61.join(claudeDir, "CLAUDE.md");
|
|
34881
|
-
const target = path61.join(targetBase, "CLAUDE.md");
|
|
34882
|
-
const sourceContent = fs42.readFileSync(source, "utf8");
|
|
34883
|
-
if (fs42.existsSync(target)) {
|
|
34884
|
-
const targetContent = fs42.readFileSync(target, "utf8");
|
|
34885
|
-
if (sourceContent !== targetContent) {
|
|
34886
|
-
console.log(
|
|
34887
|
-
chalk215.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
34888
|
-
);
|
|
34889
|
-
console.log();
|
|
34890
|
-
printDiff(targetContent, sourceContent);
|
|
34891
|
-
if (!options2?.yes) {
|
|
34892
|
-
printAutoConfirmHint();
|
|
34893
|
-
const confirm = await promptConfirm(
|
|
34894
|
-
chalk215.red("Overwrite existing CLAUDE.md?"),
|
|
34895
|
-
false
|
|
34896
|
-
);
|
|
34897
|
-
if (!confirm) {
|
|
34898
|
-
console.log("Skipped CLAUDE.md");
|
|
34899
|
-
return;
|
|
34900
|
-
}
|
|
34901
|
-
}
|
|
34902
|
-
}
|
|
34903
|
-
}
|
|
34904
|
-
fs42.copyFileSync(source, target);
|
|
34905
|
-
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
34906
|
-
}
|
|
34907
|
-
|
|
34908
|
-
// src/commands/sync/syncCodex.ts
|
|
34909
|
-
import * as path64 from "path";
|
|
34910
|
-
|
|
34911
|
-
// src/commands/sync/installHarnessCommands.ts
|
|
34912
|
-
import * as fs43 from "fs";
|
|
34913
|
-
import * as path62 from "path";
|
|
34914
|
-
function installHarnessCommands(claudeDir, harness, transform) {
|
|
34915
|
-
const commandsSource = path62.join(claudeDir, "commands");
|
|
34916
|
-
const files = fs43.readdirSync(commandsSource);
|
|
34917
|
-
let synced = 0;
|
|
34918
|
-
for (const file of files) {
|
|
34919
|
-
if (!file.endsWith(".md")) continue;
|
|
34920
|
-
const name = file.replace(/\.md$/, "");
|
|
34921
|
-
const content = fs43.readFileSync(path62.join(commandsSource, file), "utf8");
|
|
34922
|
-
const target = path62.join(harness.homeDir, harness.sync.commandDest(name));
|
|
34923
|
-
fs43.mkdirSync(path62.dirname(target), { recursive: true });
|
|
34924
|
-
fs43.writeFileSync(target, transform(name, content));
|
|
34925
|
-
synced++;
|
|
34926
|
-
}
|
|
34927
|
-
const agentsTarget = path62.join(harness.homeDir, harness.sync.agentsFile);
|
|
34928
|
-
fs43.mkdirSync(path62.dirname(agentsTarget), { recursive: true });
|
|
34929
|
-
fs43.copyFileSync(path62.join(claudeDir, "CLAUDE.md"), agentsTarget);
|
|
34930
|
-
return { total: files.length, synced };
|
|
34931
|
-
}
|
|
34932
|
-
|
|
34933
|
-
// src/commands/sync/syncCodexHooks.ts
|
|
34934
|
-
import * as fs44 from "fs";
|
|
34935
|
-
import * as path63 from "path";
|
|
34936
|
-
var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
|
|
34937
|
-
var END = "# <<< assist codex hooks (managed) <<<";
|
|
34938
|
-
function upsertManagedBlock(existing, body) {
|
|
34939
|
-
const block = `${BEGIN}
|
|
34940
|
-
${body.trim()}
|
|
34941
|
-
${END}`;
|
|
34942
|
-
const begin = existing.indexOf(BEGIN);
|
|
34943
|
-
if (begin === -1) {
|
|
34944
|
-
const base = existing.replace(/\s*$/, "");
|
|
34945
|
-
return base ? `${base}
|
|
34946
|
-
|
|
34947
|
-
${block}
|
|
34948
|
-
` : `${block}
|
|
34949
|
-
`;
|
|
34950
|
-
}
|
|
34951
|
-
const endMarker = existing.indexOf(END, begin);
|
|
34952
|
-
const after = endMarker === -1 ? existing.length : endMarker + END.length;
|
|
34953
|
-
const before = existing.slice(0, begin).replace(/\s*$/, "");
|
|
34954
|
-
const rest = existing.slice(after).replace(/^\s*/, "");
|
|
34955
|
-
const head = before ? `${before}
|
|
34956
|
-
|
|
34957
|
-
${block}` : block;
|
|
34958
|
-
return rest ? `${head}
|
|
34959
|
-
|
|
34960
|
-
${rest}
|
|
34961
|
-
` : `${head}
|
|
34962
|
-
`;
|
|
34963
|
-
}
|
|
34964
|
-
function syncCodexHooks(sourcePath) {
|
|
34965
|
-
const body = fs44.readFileSync(sourcePath, "utf8");
|
|
34966
|
-
const configPath = path63.join(harnesses.codex.homeDir, "config.toml");
|
|
34967
|
-
const existing = fs44.existsSync(configPath) ? fs44.readFileSync(configPath, "utf8") : "";
|
|
34968
|
-
fs44.mkdirSync(path63.dirname(configPath), { recursive: true });
|
|
34969
|
-
fs44.writeFileSync(configPath, upsertManagedBlock(existing, body));
|
|
34970
|
-
console.log(
|
|
34971
|
-
"Registered assist codex-hook in ~/.codex/config.toml (PreToolUse, PermissionRequest)"
|
|
34972
|
-
);
|
|
34973
|
-
}
|
|
34974
|
-
|
|
34975
|
-
// src/commands/sync/syncCodex.ts
|
|
34976
|
-
function quoteYaml(value) {
|
|
34977
|
-
return `"${value.replace(/\\/g, String.raw`\\`).replace(/"/g, String.raw`\"`)}"`;
|
|
34978
|
-
}
|
|
34979
|
-
function commandToSkill(name, content) {
|
|
34980
|
-
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
34981
|
-
const frontmatter = match ? match[1] : "";
|
|
34982
|
-
const body = match ? content.slice(match[0].length) : content;
|
|
34983
|
-
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
34984
|
-
const description = descriptionMatch ? descriptionMatch[1].trim().replace(/^["']|["']$/g, "") : name;
|
|
34985
|
-
const header = `---
|
|
34986
|
-
name: ${name}
|
|
34987
|
-
description: ${quoteYaml(description)}
|
|
34988
|
-
---
|
|
34989
|
-
|
|
34990
|
-
`;
|
|
34991
|
-
return header + body.replace(/^\r?\n+/, "");
|
|
34992
|
-
}
|
|
34993
|
-
function syncCodex(claudeDir) {
|
|
34994
|
-
if (!isHarnessAvailable("codex")) return;
|
|
34995
|
-
const { total } = installHarnessCommands(
|
|
34996
|
-
claudeDir,
|
|
34997
|
-
harnesses.codex,
|
|
34998
|
-
commandToSkill
|
|
34999
|
-
);
|
|
35000
|
-
syncCodexHooks(path64.join(claudeDir, "..", "codex", "config.toml"));
|
|
35001
|
-
console.log(
|
|
35002
|
-
`Synced ${total} skill(s) to ~/.codex/skills and CLAUDE.md to ~/.codex/AGENTS.md`
|
|
35003
|
-
);
|
|
35004
|
-
}
|
|
35005
|
-
|
|
35006
|
-
// src/commands/sync/syncDesign.ts
|
|
35007
|
-
import * as fs45 from "fs";
|
|
35008
|
-
import * as path65 from "path";
|
|
35009
|
-
function syncDesign(claudeDir, targetBase) {
|
|
35010
|
-
const systemPromptSource = path65.join(claudeDir, "design-system-prompt.md");
|
|
35011
|
-
const systemPromptTarget = path65.join(targetBase, "design-system-prompt.md");
|
|
35012
|
-
fs45.copyFileSync(systemPromptSource, systemPromptTarget);
|
|
35013
|
-
console.log(
|
|
35014
|
-
"Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
|
|
35015
|
-
);
|
|
35016
|
-
const skillsSource = path65.join(claudeDir, "skills");
|
|
35017
|
-
const skillsTarget = path65.join(targetBase, "skills");
|
|
35018
|
-
fs45.mkdirSync(skillsTarget, { recursive: true });
|
|
35019
|
-
const files = fs45.readdirSync(skillsSource);
|
|
35020
|
-
for (const file of files) {
|
|
35021
|
-
fs45.copyFileSync(
|
|
35022
|
-
path65.join(skillsSource, file),
|
|
35023
|
-
path65.join(skillsTarget, file)
|
|
35024
|
-
);
|
|
35025
|
-
}
|
|
35026
|
-
console.log(`Synced ${files.length} design skill(s) to ~/.claude/skills`);
|
|
35027
|
-
}
|
|
35028
|
-
|
|
35029
|
-
// src/commands/sync/syncPi.ts
|
|
35030
|
-
import * as path67 from "path";
|
|
35031
|
-
|
|
35032
|
-
// src/commands/sync/syncPiHooks.ts
|
|
35033
|
-
import * as fs46 from "fs";
|
|
35034
|
-
import * as path66 from "path";
|
|
35035
|
-
function piExtensionsDir() {
|
|
35036
|
-
return path66.join(harnesses.pi.homeDir, "extensions");
|
|
35037
|
-
}
|
|
35038
|
-
function syncPiHooks(sourceDir) {
|
|
35039
|
-
const target = piExtensionsDir();
|
|
35040
|
-
fs46.mkdirSync(target, { recursive: true });
|
|
35041
|
-
const files = fs46.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
|
|
35042
|
-
for (const file of files) {
|
|
35043
|
-
fs46.copyFileSync(
|
|
35044
|
-
path66.join(sourceDir, file),
|
|
35045
|
-
path66.join(target, `assist-${file}`)
|
|
35046
|
-
);
|
|
35047
|
-
}
|
|
35048
|
-
console.log(
|
|
35049
|
-
`Registered ${files.length} assist extension(s) in ~/.pi/agent/extensions`
|
|
35050
|
-
);
|
|
35051
|
-
}
|
|
35052
|
-
|
|
35053
|
-
// src/commands/sync/syncPi.ts
|
|
35054
|
-
function unquote(value) {
|
|
35055
|
-
return value.trim().replace(/^["']|["']$/g, "");
|
|
35056
|
-
}
|
|
35057
|
-
function commandToPrompt(name, content) {
|
|
35058
|
-
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
35059
|
-
const frontmatter = match ? match[1] : "";
|
|
35060
|
-
const body = match ? content.slice(match[0].length) : content;
|
|
35061
|
-
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
35062
|
-
const description = descriptionMatch ? unquote(descriptionMatch[1]) : name;
|
|
35063
|
-
const argsMatch = frontmatter.match(/^allowed_args:\s*(.*)$/m);
|
|
35064
|
-
const argumentHint = argsMatch ? unquote(argsMatch[1]) : void 0;
|
|
35065
|
-
const header = [
|
|
35066
|
-
"---",
|
|
35067
|
-
`description: ${description}`,
|
|
35068
|
-
...argumentHint ? [`argument-hint: ${argumentHint}`] : [],
|
|
35069
|
-
"---",
|
|
35070
|
-
"",
|
|
35071
|
-
""
|
|
35072
|
-
].join("\n");
|
|
35073
|
-
return header + body.replace(/^\r?\n+/, "");
|
|
35074
|
-
}
|
|
35075
|
-
function syncPi(claudeDir) {
|
|
35076
|
-
if (!isHarnessAvailable("pi")) return;
|
|
35077
|
-
const { synced } = installHarnessCommands(
|
|
35078
|
-
claudeDir,
|
|
35079
|
-
harnesses.pi,
|
|
35080
|
-
commandToPrompt
|
|
35081
|
-
);
|
|
35082
|
-
syncPiHooks(path67.join(claudeDir, "..", "pi"));
|
|
35083
|
-
console.log(
|
|
35084
|
-
`Synced ${synced} prompt(s) to ~/.pi/agent/prompts and CLAUDE.md to ~/.pi/agent/AGENTS.md`
|
|
35085
|
-
);
|
|
35086
|
-
}
|
|
35087
|
-
|
|
35088
|
-
// src/commands/sync/syncSettings.ts
|
|
35089
|
-
import * as fs47 from "fs";
|
|
35090
|
-
import * as path68 from "path";
|
|
35091
|
-
import chalk216 from "chalk";
|
|
35092
|
-
async function syncSettings(claudeDir, targetBase, options2) {
|
|
35093
|
-
const source = path68.join(claudeDir, "settings.json");
|
|
35094
|
-
const target = path68.join(targetBase, "settings.json");
|
|
35095
|
-
const sourceContent = fs47.readFileSync(source, "utf8");
|
|
35096
|
-
const sourceSettings = JSON.parse(sourceContent);
|
|
35097
|
-
const targetExists = fs47.existsSync(target);
|
|
35098
|
-
const targetContent = targetExists ? fs47.readFileSync(target, "utf8") : "";
|
|
35099
|
-
const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
|
|
35100
|
-
const mergedContent = JSON.stringify(
|
|
35101
|
-
{ ...preservedUserSettings, ...sourceSettings },
|
|
35102
|
-
null,
|
|
35103
|
-
" "
|
|
35104
|
-
);
|
|
35105
|
-
if (targetExists) {
|
|
35106
|
-
const normalizedTarget = JSON.stringify(preservedUserSettings, null, " ");
|
|
35107
|
-
if (mergedContent !== normalizedTarget) {
|
|
35108
|
-
if (!options2?.yes) {
|
|
35109
|
-
console.log(
|
|
35110
|
-
chalk216.yellow(
|
|
35111
|
-
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
35112
|
-
)
|
|
35113
|
-
);
|
|
35114
|
-
console.log();
|
|
35115
|
-
printDiff(targetContent, mergedContent);
|
|
35116
|
-
printAutoConfirmHint();
|
|
35117
|
-
const confirm = await promptConfirm(
|
|
35118
|
-
chalk216.red("Overwrite existing settings.json?"),
|
|
35119
|
-
false
|
|
35120
|
-
);
|
|
35121
|
-
if (!confirm) {
|
|
35122
|
-
console.log("Skipped settings.json");
|
|
35123
|
-
return;
|
|
35124
|
-
}
|
|
35125
|
-
}
|
|
35126
|
-
}
|
|
35127
|
-
}
|
|
35128
|
-
fs47.writeFileSync(target, mergedContent);
|
|
35129
|
-
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
35130
|
-
}
|
|
35131
|
-
|
|
35132
|
-
// src/commands/sync.ts
|
|
35133
|
-
var __filename5 = fileURLToPath9(import.meta.url);
|
|
35134
|
-
var __dirname7 = path69.dirname(__filename5);
|
|
35135
|
-
async function sync(options2) {
|
|
35136
|
-
const config = loadConfig();
|
|
35137
|
-
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
35138
|
-
const claudeDir = path69.join(__dirname7, "..", "claude");
|
|
35139
|
-
const targetBase = path69.join(os5.homedir(), ".claude");
|
|
35140
|
-
syncCommands(claudeDir, targetBase);
|
|
35141
|
-
syncDesign(claudeDir, targetBase);
|
|
35142
|
-
await syncSettings(claudeDir, targetBase, { yes });
|
|
35143
|
-
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
35144
|
-
syncCodex(claudeDir);
|
|
35145
|
-
syncPi(claudeDir);
|
|
35146
|
-
}
|
|
35147
|
-
function syncCommands(claudeDir, targetBase) {
|
|
35148
|
-
const sourceDir = path69.join(claudeDir, "commands");
|
|
35149
|
-
const targetDir = path69.join(targetBase, "commands");
|
|
35150
|
-
fs48.mkdirSync(targetDir, { recursive: true });
|
|
35151
|
-
const files = fs48.readdirSync(sourceDir);
|
|
35152
|
-
for (const file of files) {
|
|
35153
|
-
fs48.copyFileSync(path69.join(sourceDir, file), path69.join(targetDir, file));
|
|
35154
|
-
console.log(`Copied ${file} to ${targetDir}`);
|
|
35155
|
-
}
|
|
35156
|
-
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
35157
|
-
}
|
|
35158
|
-
|
|
35159
35301
|
// src/commands/update.ts
|
|
35160
35302
|
import { execSync as execSync62 } from "child_process";
|
|
35161
|
-
import * as
|
|
35303
|
+
import * as path72 from "path";
|
|
35162
35304
|
|
|
35163
35305
|
// src/commands/restartDaemonAfterUpdate.ts
|
|
35164
35306
|
async function restartDaemonAfterUpdate() {
|
|
@@ -35177,12 +35319,12 @@ async function restartDaemonAfterUpdate() {
|
|
|
35177
35319
|
// src/commands/update.ts
|
|
35178
35320
|
function isGlobalNpmInstall(dir) {
|
|
35179
35321
|
try {
|
|
35180
|
-
const resolved =
|
|
35181
|
-
if (resolved.split(
|
|
35322
|
+
const resolved = path72.resolve(dir);
|
|
35323
|
+
if (resolved.split(path72.sep).includes("node_modules")) {
|
|
35182
35324
|
return true;
|
|
35183
35325
|
}
|
|
35184
35326
|
const globalPrefix = execSync62("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
35185
|
-
return resolved.toLowerCase().startsWith(
|
|
35327
|
+
return resolved.toLowerCase().startsWith(path72.resolve(globalPrefix).toLowerCase());
|
|
35186
35328
|
} catch {
|
|
35187
35329
|
return false;
|
|
35188
35330
|
}
|
|
@@ -35227,10 +35369,7 @@ function reportCliError(error) {
|
|
|
35227
35369
|
// src/index.ts
|
|
35228
35370
|
var program = new Command();
|
|
35229
35371
|
program.name("assist").description("CLI application").version(package_default.version).option("--no-open", "Do not open a browser on startup").action((options2) => web({ port: "3100", open: options2.open }));
|
|
35230
|
-
|
|
35231
|
-
"Copy command files to ~/.claude/commands; when codex is detected, also install commands as ~/.codex/skills/<name>/SKILL.md, CLAUDE.md as ~/.codex/AGENTS.md, and register the assist codex-hook auto-approval hook in ~/.codex/config.toml; when pi is detected, also install commands as ~/.pi/agent/prompts/<name>.md, CLAUDE.md as ~/.pi/agent/AGENTS.md, and register the assist pi-hook permission-gate extension in ~/.pi/agent/extensions"
|
|
35232
|
-
).option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
|
|
35233
|
-
configHelp(syncCommand, rootConfigHelp.sync);
|
|
35372
|
+
registerSync(program);
|
|
35234
35373
|
program.command("init").description("Initialize VS Code and verify configurations").action(init5);
|
|
35235
35374
|
var commitCommand = program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);
|
|
35236
35375
|
configHelp(commitCommand, rootConfigHelp.commit);
|