@staff0rd/assist 0.393.0 → 0.395.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 +4 -3
- package/dist/commands/sessions/web/bundle.js +86 -86
- package/dist/index.js +380 -208
- package/package.json +2 -1
- package/pi/permission-gate.ts +46 -0
- package/pi/status-driver.ts +22 -0
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.395.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -18,6 +18,7 @@ var package_default = {
|
|
|
18
18
|
"dist",
|
|
19
19
|
"claude",
|
|
20
20
|
"codex",
|
|
21
|
+
"pi",
|
|
21
22
|
"allowed.cli-reads",
|
|
22
23
|
"allowed.cli-writes"
|
|
23
24
|
],
|
|
@@ -141,10 +142,10 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
141
142
|
// src/shared/loadRawYaml.ts
|
|
142
143
|
import { existsSync, readFileSync } from "fs";
|
|
143
144
|
import { parse as parseYaml } from "yaml";
|
|
144
|
-
function loadRawYaml(
|
|
145
|
-
if (!existsSync(
|
|
145
|
+
function loadRawYaml(path67) {
|
|
146
|
+
if (!existsSync(path67)) return {};
|
|
146
147
|
try {
|
|
147
|
-
const content = readFileSync(
|
|
148
|
+
const content = readFileSync(path67, "utf8");
|
|
148
149
|
return parseYaml(content) || {};
|
|
149
150
|
} catch {
|
|
150
151
|
return {};
|
|
@@ -344,8 +345,9 @@ var assistConfigSchema = z2.strictObject({
|
|
|
344
345
|
autoConfirm: z2.boolean().default(false)
|
|
345
346
|
}).default({ autoConfirm: false }),
|
|
346
347
|
harness: z2.strictObject({
|
|
347
|
-
engine: z2.enum(["claude", "codex"]).default("claude"),
|
|
348
|
-
exposeCodexActions: z2.boolean().optional()
|
|
348
|
+
engine: z2.enum(["claude", "codex", "pi"]).default("claude"),
|
|
349
|
+
exposeCodexActions: z2.boolean().optional(),
|
|
350
|
+
exposePiActions: z2.boolean().optional()
|
|
349
351
|
}).default({ engine: "claude" }),
|
|
350
352
|
voice: z2.strictObject({
|
|
351
353
|
wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
|
|
@@ -1361,8 +1363,8 @@ function findUnmergedPaths() {
|
|
|
1361
1363
|
}
|
|
1362
1364
|
const found = /* @__PURE__ */ new Set();
|
|
1363
1365
|
for (const line of output.split("\n")) {
|
|
1364
|
-
const
|
|
1365
|
-
if (
|
|
1366
|
+
const path67 = line.split(" ")[1];
|
|
1367
|
+
if (path67) found.add(path67.trim());
|
|
1366
1368
|
}
|
|
1367
1369
|
return [...found];
|
|
1368
1370
|
}
|
|
@@ -1461,8 +1463,8 @@ function getPreferredRemoteRepo(cwd) {
|
|
|
1461
1463
|
function gitRefUrl(kind, ref, cwd) {
|
|
1462
1464
|
const repo = getPreferredRemoteRepo(cwd);
|
|
1463
1465
|
if (!repo) return void 0;
|
|
1464
|
-
const
|
|
1465
|
-
return `https://github.com/${repo.org}/${repo.repo}/${
|
|
1466
|
+
const path67 = kind === "branch" ? "tree" : "commit";
|
|
1467
|
+
return `https://github.com/${repo.org}/${repo.repo}/${path67}/${ref}`;
|
|
1466
1468
|
}
|
|
1467
1469
|
|
|
1468
1470
|
// src/commands/commit/collectCommitRefs.ts
|
|
@@ -3233,9 +3235,9 @@ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
|
|
|
3233
3235
|
|
|
3234
3236
|
// src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
|
|
3235
3237
|
import { minimatch as minimatch2 } from "minimatch";
|
|
3236
|
-
function resolveStringsAtPath(data,
|
|
3238
|
+
function resolveStringsAtPath(data, path67) {
|
|
3237
3239
|
let current = data;
|
|
3238
|
-
for (const segment of
|
|
3240
|
+
for (const segment of path67.split(".")) {
|
|
3239
3241
|
if (current === null || typeof current !== "object") return [];
|
|
3240
3242
|
current = current[segment];
|
|
3241
3243
|
}
|
|
@@ -3248,10 +3250,10 @@ function resolveStringsAtPath(data, path64) {
|
|
|
3248
3250
|
}
|
|
3249
3251
|
function findRuleViolations(data, rule) {
|
|
3250
3252
|
const violations = [];
|
|
3251
|
-
for (const
|
|
3252
|
-
for (const value of resolveStringsAtPath(data,
|
|
3253
|
+
for (const path67 of rule.paths) {
|
|
3254
|
+
for (const value of resolveStringsAtPath(data, path67)) {
|
|
3253
3255
|
if (minimatch2(value, rule.disallowed))
|
|
3254
|
-
violations.push({ file: rule.file, path:
|
|
3256
|
+
violations.push({ file: rule.file, path: path67, value });
|
|
3255
3257
|
}
|
|
3256
3258
|
}
|
|
3257
3259
|
return violations;
|
|
@@ -3290,8 +3292,8 @@ function forbiddenStrings() {
|
|
|
3290
3292
|
process.exit(0);
|
|
3291
3293
|
}
|
|
3292
3294
|
console.log("Forbidden strings found:\n");
|
|
3293
|
-
for (const { file, path:
|
|
3294
|
-
console.log(` ${file} ${
|
|
3295
|
+
for (const { file, path: path67, value } of violations) {
|
|
3296
|
+
console.log(` ${file} ${path67}: ${value}`);
|
|
3295
3297
|
}
|
|
3296
3298
|
console.log(`
|
|
3297
3299
|
Total: ${violations.length} forbidden string(s).`);
|
|
@@ -3583,15 +3585,15 @@ function readBaselineMigrations(repoRelativeDir, ref) {
|
|
|
3583
3585
|
} catch {
|
|
3584
3586
|
return baseline;
|
|
3585
3587
|
}
|
|
3586
|
-
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((
|
|
3587
|
-
for (const
|
|
3588
|
+
const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path67) => MIGRATION_FILE3.test(basename(path67)));
|
|
3589
|
+
for (const path67 of paths) {
|
|
3588
3590
|
try {
|
|
3589
|
-
const content = execSync12(`git show "${ref}:${
|
|
3591
|
+
const content = execSync12(`git show "${ref}:${path67}"`, {
|
|
3590
3592
|
encoding: "utf8",
|
|
3591
3593
|
maxBuffer: 16 * 1024 * 1024,
|
|
3592
3594
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3593
3595
|
});
|
|
3594
|
-
baseline.set(basename(
|
|
3596
|
+
baseline.set(basename(path67), content);
|
|
3595
3597
|
} catch {
|
|
3596
3598
|
}
|
|
3597
3599
|
}
|
|
@@ -4956,15 +4958,15 @@ var hooksSettings = {
|
|
|
4956
4958
|
}
|
|
4957
4959
|
};
|
|
4958
4960
|
function ensureHooksSettings() {
|
|
4959
|
-
const
|
|
4960
|
-
mkdirSync5(dirname12(
|
|
4961
|
-
writeFileSync15(
|
|
4962
|
-
return
|
|
4961
|
+
const path67 = daemonPaths.hooksSettings;
|
|
4962
|
+
mkdirSync5(dirname12(path67), { recursive: true });
|
|
4963
|
+
writeFileSync15(path67, JSON.stringify(hooksSettings, null, 2));
|
|
4964
|
+
return path67;
|
|
4963
4965
|
}
|
|
4964
4966
|
|
|
4965
4967
|
// src/shared/spawnInherit.ts
|
|
4966
4968
|
import { spawn as spawn3 } from "child_process";
|
|
4967
|
-
function spawnInherit(command, args) {
|
|
4969
|
+
function spawnInherit(command, args, options2 = {}) {
|
|
4968
4970
|
const {
|
|
4969
4971
|
ASSIST_ACTIVITY_ID: _activityId,
|
|
4970
4972
|
CLAUDE_CODE_CHILD_SESSION: _childSession,
|
|
@@ -4972,7 +4974,8 @@ function spawnInherit(command, args) {
|
|
|
4972
4974
|
} = process.env;
|
|
4973
4975
|
const child = spawn3(command, args, {
|
|
4974
4976
|
stdio: "inherit",
|
|
4975
|
-
env
|
|
4977
|
+
env,
|
|
4978
|
+
cwd: options2.cwd
|
|
4976
4979
|
});
|
|
4977
4980
|
const done2 = new Promise((resolve18, reject) => {
|
|
4978
4981
|
child.on("close", (code) => resolve18(code ?? 0));
|
|
@@ -5223,9 +5226,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
|
|
|
5223
5226
|
function backupLocalBacklogFiles(dir) {
|
|
5224
5227
|
const moved = [];
|
|
5225
5228
|
for (const name of LOCAL_FILES) {
|
|
5226
|
-
const
|
|
5227
|
-
if (existsSync18(
|
|
5228
|
-
renameSync(
|
|
5229
|
+
const path67 = join15(dir, ".assist", name);
|
|
5230
|
+
if (existsSync18(path67)) {
|
|
5231
|
+
renameSync(path67, `${path67}.bak`);
|
|
5229
5232
|
moved.push(`${name} \u2192 ${name}.bak`);
|
|
5230
5233
|
}
|
|
5231
5234
|
}
|
|
@@ -5664,8 +5667,8 @@ var backlogItemSchema = z3.strictObject({
|
|
|
5664
5667
|
var backlogFileSchema = z3.array(backlogItemSchema);
|
|
5665
5668
|
|
|
5666
5669
|
// src/commands/backlog/parseBacklogJsonl.ts
|
|
5667
|
-
function parseBacklogJsonl(
|
|
5668
|
-
const content = readFileSync14(
|
|
5670
|
+
function parseBacklogJsonl(path67) {
|
|
5671
|
+
const content = readFileSync14(path67, "utf8").trim();
|
|
5669
5672
|
if (content.length === 0) return [];
|
|
5670
5673
|
return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
|
|
5671
5674
|
}
|
|
@@ -5747,8 +5750,8 @@ function findBacklogUp(startDir) {
|
|
|
5747
5750
|
|
|
5748
5751
|
// src/commands/backlog/getCurrentOrigin.ts
|
|
5749
5752
|
import { execFileSync } from "child_process";
|
|
5750
|
-
function stripLeadingSlashes(
|
|
5751
|
-
return
|
|
5753
|
+
function stripLeadingSlashes(path67) {
|
|
5754
|
+
return path67.replace(/^\/+/, "");
|
|
5752
5755
|
}
|
|
5753
5756
|
function normalizeOrigin(raw) {
|
|
5754
5757
|
const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
@@ -6288,24 +6291,24 @@ function getOwnerPath(itemId2) {
|
|
|
6288
6291
|
function recordSignalOwner(itemId2) {
|
|
6289
6292
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
6290
6293
|
if (!sessionId) return;
|
|
6291
|
-
const
|
|
6292
|
-
mkdirSync7(dirname14(
|
|
6293
|
-
writeFileSync17(
|
|
6294
|
+
const path67 = getOwnerPath(itemId2);
|
|
6295
|
+
mkdirSync7(dirname14(path67), { recursive: true });
|
|
6296
|
+
writeFileSync17(path67, JSON.stringify({ sessionId }));
|
|
6294
6297
|
}
|
|
6295
6298
|
function readSignalOwner(itemId2) {
|
|
6296
|
-
const
|
|
6297
|
-
if (!existsSync21(
|
|
6299
|
+
const path67 = getOwnerPath(itemId2);
|
|
6300
|
+
if (!existsSync21(path67)) return void 0;
|
|
6298
6301
|
try {
|
|
6299
|
-
const parsed = JSON.parse(readFileSync15(
|
|
6302
|
+
const parsed = JSON.parse(readFileSync15(path67, "utf8"));
|
|
6300
6303
|
return parsed.sessionId;
|
|
6301
6304
|
} catch {
|
|
6302
6305
|
return void 0;
|
|
6303
6306
|
}
|
|
6304
6307
|
}
|
|
6305
6308
|
function clearSignalOwner(itemId2) {
|
|
6306
|
-
const
|
|
6309
|
+
const path67 = getOwnerPath(itemId2);
|
|
6307
6310
|
try {
|
|
6308
|
-
rmSync(
|
|
6311
|
+
rmSync(path67);
|
|
6309
6312
|
} catch {
|
|
6310
6313
|
}
|
|
6311
6314
|
}
|
|
@@ -6342,19 +6345,19 @@ function resolveSignalTarget(event, data) {
|
|
|
6342
6345
|
function writeSignal(event, data) {
|
|
6343
6346
|
const target = resolveSignalTarget(event, data);
|
|
6344
6347
|
if (!target) return;
|
|
6345
|
-
const
|
|
6346
|
-
if (!
|
|
6348
|
+
const path67 = getSignalPath(target);
|
|
6349
|
+
if (!path67) return;
|
|
6347
6350
|
const signal = { event, sessionId: target, ...data };
|
|
6348
|
-
mkdirSync8(dirname15(
|
|
6349
|
-
writeFileSync18(
|
|
6351
|
+
mkdirSync8(dirname15(path67), { recursive: true });
|
|
6352
|
+
writeFileSync18(path67, JSON.stringify(signal));
|
|
6350
6353
|
}
|
|
6351
6354
|
|
|
6352
6355
|
// src/commands/backlog/readSignal.ts
|
|
6353
6356
|
function readSignal() {
|
|
6354
|
-
const
|
|
6355
|
-
if (!
|
|
6357
|
+
const path67 = getSignalPath();
|
|
6358
|
+
if (!path67 || !existsSync22(path67)) return void 0;
|
|
6356
6359
|
try {
|
|
6357
|
-
return JSON.parse(readFileSync16(
|
|
6360
|
+
return JSON.parse(readFileSync16(path67, "utf8"));
|
|
6358
6361
|
} catch {
|
|
6359
6362
|
return void 0;
|
|
6360
6363
|
}
|
|
@@ -6434,6 +6437,7 @@ import { dirname as dirname16, join as join20 } from "path";
|
|
|
6434
6437
|
import { z as z4 } from "zod";
|
|
6435
6438
|
var activitySchema = z4.object({
|
|
6436
6439
|
kind: z4.enum(["command", "backlog"]),
|
|
6440
|
+
harness: z4.enum(["claude", "codex", "pi"]).optional(),
|
|
6437
6441
|
name: z4.string().optional(),
|
|
6438
6442
|
itemId: z4.number().optional(),
|
|
6439
6443
|
itemName: z4.string().optional(),
|
|
@@ -6449,13 +6453,13 @@ function activityPath(sessionId) {
|
|
|
6449
6453
|
function emitActivity(activity2) {
|
|
6450
6454
|
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
6451
6455
|
if (!sessionId) return;
|
|
6452
|
-
const
|
|
6453
|
-
mkdirSync9(dirname16(
|
|
6454
|
-
writeFileSync19(
|
|
6456
|
+
const path67 = activityPath(sessionId);
|
|
6457
|
+
mkdirSync9(dirname16(path67), { recursive: true });
|
|
6458
|
+
writeFileSync19(path67, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
6455
6459
|
}
|
|
6456
|
-
function readActivity(
|
|
6460
|
+
function readActivity(path67) {
|
|
6457
6461
|
try {
|
|
6458
|
-
return JSON.parse(readFileSync17(
|
|
6462
|
+
return JSON.parse(readFileSync17(path67, "utf8"));
|
|
6459
6463
|
} catch {
|
|
6460
6464
|
return void 0;
|
|
6461
6465
|
}
|
|
@@ -6465,9 +6469,9 @@ function reconcileActivity(sessionId, activity2) {
|
|
|
6465
6469
|
removeActivity(sessionId);
|
|
6466
6470
|
return;
|
|
6467
6471
|
}
|
|
6468
|
-
const
|
|
6469
|
-
mkdirSync9(dirname16(
|
|
6470
|
-
writeFileSync19(
|
|
6472
|
+
const path67 = activityPath(sessionId);
|
|
6473
|
+
mkdirSync9(dirname16(path67), { recursive: true });
|
|
6474
|
+
writeFileSync19(path67, JSON.stringify(activity2));
|
|
6471
6475
|
}
|
|
6472
6476
|
function removeActivity(sessionId) {
|
|
6473
6477
|
try {
|
|
@@ -7698,8 +7702,8 @@ async function getBacklogExists(req, res) {
|
|
|
7698
7702
|
// src/commands/backlog/originDisplayName.ts
|
|
7699
7703
|
function originDisplayName(origin) {
|
|
7700
7704
|
if (origin.startsWith("local:")) {
|
|
7701
|
-
const
|
|
7702
|
-
const segments =
|
|
7705
|
+
const path67 = origin.slice("local:".length).replace(/\/+$/, "");
|
|
7706
|
+
const segments = path67.split("/").filter(Boolean);
|
|
7703
7707
|
return segments[segments.length - 1] ?? origin;
|
|
7704
7708
|
}
|
|
7705
7709
|
const firstSlash = origin.indexOf("/");
|
|
@@ -8102,7 +8106,7 @@ function findSynthesisForBranch(repoReviewsDir, branch2) {
|
|
|
8102
8106
|
const parent = dirname20(branchKeyPath);
|
|
8103
8107
|
const branchPrefix = basename5(branchKeyPath);
|
|
8104
8108
|
if (!existsSync25(parent)) return null;
|
|
8105
|
-
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join23(parent, name, "synthesis.md")).filter((
|
|
8109
|
+
const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join23(parent, name, "synthesis.md")).filter((path67) => existsSync25(path67)).map((path67) => ({ path: path67, mtime: statSync2(path67).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
8106
8110
|
return synthesisFiles[0]?.path ?? null;
|
|
8107
8111
|
}
|
|
8108
8112
|
|
|
@@ -8156,12 +8160,12 @@ async function getReviewSynthesis(req, res) {
|
|
|
8156
8160
|
const cwd = getCwdParam(req, res);
|
|
8157
8161
|
if (!cwd) return;
|
|
8158
8162
|
try {
|
|
8159
|
-
const
|
|
8160
|
-
if (!
|
|
8163
|
+
const path67 = await resolveSynthesisPath(cwd);
|
|
8164
|
+
if (!path67) {
|
|
8161
8165
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
8162
8166
|
return;
|
|
8163
8167
|
}
|
|
8164
|
-
respondJson(res, 200, { synthesis: readFileSync19(
|
|
8168
|
+
respondJson(res, 200, { synthesis: readFileSync19(path67, "utf8") });
|
|
8165
8169
|
} catch {
|
|
8166
8170
|
respondJson(res, 404, { error: "No synthesis found" });
|
|
8167
8171
|
}
|
|
@@ -8272,6 +8276,15 @@ var harnesses = {
|
|
|
8272
8276
|
agentsFile: "AGENTS.md",
|
|
8273
8277
|
commandDest: (name) => path25.join("skills", name, "SKILL.md")
|
|
8274
8278
|
}
|
|
8279
|
+
},
|
|
8280
|
+
pi: {
|
|
8281
|
+
kind: "pi",
|
|
8282
|
+
command: "pi",
|
|
8283
|
+
homeDir: path25.join(os2.homedir(), ".pi", "agent"),
|
|
8284
|
+
sync: {
|
|
8285
|
+
agentsFile: "AGENTS.md",
|
|
8286
|
+
commandDest: (name) => path25.join("prompts", `${name}.md`)
|
|
8287
|
+
}
|
|
8275
8288
|
}
|
|
8276
8289
|
};
|
|
8277
8290
|
function isHarnessAvailable(kind) {
|
|
@@ -8280,9 +8293,12 @@ function isHarnessAvailable(kind) {
|
|
|
8280
8293
|
|
|
8281
8294
|
// src/commands/sessions/web/harnessCapabilities.ts
|
|
8282
8295
|
function harnessCapabilities(_req, res) {
|
|
8283
|
-
const
|
|
8284
|
-
const
|
|
8285
|
-
|
|
8296
|
+
const config = loadConfig().harness;
|
|
8297
|
+
const codexForcedOff = config.exposeCodexActions === false;
|
|
8298
|
+
const exposeCodexActions = !codexForcedOff && isHarnessAvailable("codex");
|
|
8299
|
+
const piForcedOff = config.exposePiActions === false;
|
|
8300
|
+
const exposePiActions = !piForcedOff && isHarnessAvailable("pi");
|
|
8301
|
+
respondJson(res, 200, { exposeCodexActions, exposePiActions });
|
|
8286
8302
|
}
|
|
8287
8303
|
|
|
8288
8304
|
// src/shared/loadJson.ts
|
|
@@ -8296,10 +8312,10 @@ function getStorePath(filename) {
|
|
|
8296
8312
|
return join26(getStoreDir(), filename);
|
|
8297
8313
|
}
|
|
8298
8314
|
function loadJson(filename) {
|
|
8299
|
-
const
|
|
8300
|
-
if (existsSync26(
|
|
8315
|
+
const path67 = getStorePath(filename);
|
|
8316
|
+
if (existsSync26(path67)) {
|
|
8301
8317
|
try {
|
|
8302
|
-
return JSON.parse(readFileSync20(
|
|
8318
|
+
return JSON.parse(readFileSync20(path67, "utf8"));
|
|
8303
8319
|
} catch {
|
|
8304
8320
|
return {};
|
|
8305
8321
|
}
|
|
@@ -10092,11 +10108,20 @@ function spawnCodex(prompt, options2 = {}) {
|
|
|
10092
10108
|
return spawnInherit(harnesses.codex.command, ["-C", cwd, prompt]);
|
|
10093
10109
|
}
|
|
10094
10110
|
|
|
10111
|
+
// src/shared/spawnPi.ts
|
|
10112
|
+
function spawnPi(prompt, options2 = {}) {
|
|
10113
|
+
const cwd = options2.cwd ?? process.cwd();
|
|
10114
|
+
return spawnInherit(harnesses.pi.command, [prompt], { cwd });
|
|
10115
|
+
}
|
|
10116
|
+
|
|
10095
10117
|
// src/shared/spawnHarness.ts
|
|
10096
10118
|
function spawnHarness(harness, prompt, options2 = {}) {
|
|
10097
10119
|
if (harness === "codex") {
|
|
10098
10120
|
return spawnCodex(prompt, { cwd: options2.cwd });
|
|
10099
10121
|
}
|
|
10122
|
+
if (harness === "pi") {
|
|
10123
|
+
return spawnPi(prompt, { cwd: options2.cwd });
|
|
10124
|
+
}
|
|
10100
10125
|
return spawnClaude(prompt, {
|
|
10101
10126
|
allowEdits: true,
|
|
10102
10127
|
sessionId: options2.sessionId,
|
|
@@ -10261,7 +10286,7 @@ async function refine(id, options2) {
|
|
|
10261
10286
|
|
|
10262
10287
|
// src/commands/backlog/resolveHarness.ts
|
|
10263
10288
|
function resolveHarness(value) {
|
|
10264
|
-
if (value === "claude" || value === "codex") return value;
|
|
10289
|
+
if (value === "claude" || value === "codex" || value === "pi") return value;
|
|
10265
10290
|
return loadConfig().harness.engine;
|
|
10266
10291
|
}
|
|
10267
10292
|
|
|
@@ -10269,7 +10294,7 @@ function resolveHarness(value) {
|
|
|
10269
10294
|
function registerRefineCommand(cmd) {
|
|
10270
10295
|
cmd.command("refine").argument("[id]", "Backlog item ID").description("Alias for refine").option("--once", "Exit when the initial task completes").option(
|
|
10271
10296
|
"--harness <kind>",
|
|
10272
|
-
"Coding harness to launch (claude|codex); defaults to the configured harness.engine"
|
|
10297
|
+
"Coding harness to launch (claude|codex|pi); defaults to the configured harness.engine"
|
|
10273
10298
|
).action(
|
|
10274
10299
|
(id, opts) => refine(id, {
|
|
10275
10300
|
once: opts.once,
|
|
@@ -11543,9 +11568,9 @@ var __dirname4 = dirname21(__filename3);
|
|
|
11543
11568
|
function packageRoot() {
|
|
11544
11569
|
return __dirname4;
|
|
11545
11570
|
}
|
|
11546
|
-
function readLines(
|
|
11547
|
-
if (!existsSync27(
|
|
11548
|
-
return readFileSync23(
|
|
11571
|
+
function readLines(path67) {
|
|
11572
|
+
if (!existsSync27(path67)) return [];
|
|
11573
|
+
return readFileSync23(path67, "utf8").split("\n").filter((line) => line.trim() !== "");
|
|
11549
11574
|
}
|
|
11550
11575
|
var cachedReads;
|
|
11551
11576
|
var cachedWrites;
|
|
@@ -12037,14 +12062,14 @@ function showProgress(p, label2) {
|
|
|
12037
12062
|
const pct = Math.round(p.done / p.total * 100);
|
|
12038
12063
|
process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
|
|
12039
12064
|
}
|
|
12040
|
-
async function resolveCommand(cli,
|
|
12041
|
-
showProgress(p,
|
|
12042
|
-
const subHelp = await runHelp([cli, ...
|
|
12065
|
+
async function resolveCommand(cli, path67, description, depth, p) {
|
|
12066
|
+
showProgress(p, path67.join(" "));
|
|
12067
|
+
const subHelp = await runHelp([cli, ...path67]);
|
|
12043
12068
|
if (!subHelp || !hasSubcommands(subHelp)) {
|
|
12044
|
-
return [{ path:
|
|
12069
|
+
return [{ path: path67, description }];
|
|
12045
12070
|
}
|
|
12046
|
-
const children = await discoverAt(cli,
|
|
12047
|
-
return children.length > 0 ? children : [{ path:
|
|
12071
|
+
const children = await discoverAt(cli, path67, depth + 1, p);
|
|
12072
|
+
return children.length > 0 ? children : [{ path: path67, description }];
|
|
12048
12073
|
}
|
|
12049
12074
|
async function discoverAt(cli, parentPath, depth, p) {
|
|
12050
12075
|
if (depth > SAFETY_DEPTH) return [];
|
|
@@ -12192,9 +12217,9 @@ function logPath(cli) {
|
|
|
12192
12217
|
return join30(homedir16(), ".assist", `cli-discover-${safeName}.log`);
|
|
12193
12218
|
}
|
|
12194
12219
|
function readCache(cli) {
|
|
12195
|
-
const
|
|
12196
|
-
if (!existsSync29(
|
|
12197
|
-
return readFileSync25(
|
|
12220
|
+
const path67 = logPath(cli);
|
|
12221
|
+
if (!existsSync29(path67)) return void 0;
|
|
12222
|
+
return readFileSync25(path67, "utf8");
|
|
12198
12223
|
}
|
|
12199
12224
|
function writeCache(cli, output) {
|
|
12200
12225
|
const dir = join30(homedir16(), ".assist");
|
|
@@ -12366,9 +12391,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
12366
12391
|
}
|
|
12367
12392
|
const cutoff = Date.now() - STALE_AFTER_MS;
|
|
12368
12393
|
for (const entry of entries) {
|
|
12369
|
-
const
|
|
12394
|
+
const path67 = join32(dir, entry);
|
|
12370
12395
|
try {
|
|
12371
|
-
if (statSync3(
|
|
12396
|
+
if (statSync3(path67).mtimeMs < cutoff) unlinkSync7(path67);
|
|
12372
12397
|
} catch {
|
|
12373
12398
|
continue;
|
|
12374
12399
|
}
|
|
@@ -12378,10 +12403,10 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
|
|
|
12378
12403
|
// src/commands/codeComment/readPinState.ts
|
|
12379
12404
|
import { existsSync as existsSync30, readFileSync as readFileSync26 } from "fs";
|
|
12380
12405
|
function readPinState(pin) {
|
|
12381
|
-
const
|
|
12382
|
-
if (!existsSync30(
|
|
12406
|
+
const path67 = getPinStatePath(pin);
|
|
12407
|
+
if (!existsSync30(path67)) return void 0;
|
|
12383
12408
|
try {
|
|
12384
|
-
const state = JSON.parse(readFileSync26(
|
|
12409
|
+
const state = JSON.parse(readFileSync26(path67, "utf8"));
|
|
12385
12410
|
if (state.pin !== pin) return void 0;
|
|
12386
12411
|
return state;
|
|
12387
12412
|
} catch {
|
|
@@ -13206,8 +13231,8 @@ function stepIntoNested(container, key, nextKey) {
|
|
|
13206
13231
|
}
|
|
13207
13232
|
return ensureObject(container, resolved);
|
|
13208
13233
|
}
|
|
13209
|
-
function setNestedValue(obj,
|
|
13210
|
-
const keys =
|
|
13234
|
+
function setNestedValue(obj, path67, value) {
|
|
13235
|
+
const keys = path67.split(".");
|
|
13211
13236
|
const result = { ...obj };
|
|
13212
13237
|
let current = result;
|
|
13213
13238
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -13287,9 +13312,9 @@ function isTraversable(value) {
|
|
|
13287
13312
|
function stepInto(current, key) {
|
|
13288
13313
|
return isTraversable(current) ? current[key] : void 0;
|
|
13289
13314
|
}
|
|
13290
|
-
function getNestedValue(obj,
|
|
13315
|
+
function getNestedValue(obj, path67) {
|
|
13291
13316
|
let current = obj;
|
|
13292
|
-
for (const key of
|
|
13317
|
+
for (const key of path67.split(".")) current = stepInto(current, key);
|
|
13293
13318
|
return current;
|
|
13294
13319
|
}
|
|
13295
13320
|
|
|
@@ -15428,17 +15453,22 @@ function registerJira(program2) {
|
|
|
15428
15453
|
}
|
|
15429
15454
|
|
|
15430
15455
|
// src/commands/backlog/registerRefineLaunch.ts
|
|
15431
|
-
var HARNESS_FLAG = "Coding harness to launch (claude|codex); defaults to the configured harness.engine";
|
|
15456
|
+
var HARNESS_FLAG = "Coding harness to launch (claude|codex|pi); defaults to the configured harness.engine";
|
|
15432
15457
|
var HARNESS_CONFIG_HELP = [
|
|
15433
15458
|
{
|
|
15434
15459
|
key: "harness.engine",
|
|
15435
|
-
setter: "assist config set harness.engine <claude|codex>",
|
|
15460
|
+
setter: "assist config set harness.engine <claude|codex|pi>",
|
|
15436
15461
|
note: "default coding harness launched by refine and other flows"
|
|
15437
15462
|
},
|
|
15438
15463
|
{
|
|
15439
15464
|
key: "harness.exposeCodexActions",
|
|
15440
15465
|
setter: "assist config set harness.exposeCodexActions <true|false>",
|
|
15441
15466
|
note: "force the web UI 'with Codex' actions off even when codex is on PATH"
|
|
15467
|
+
},
|
|
15468
|
+
{
|
|
15469
|
+
key: "harness.exposePiActions",
|
|
15470
|
+
setter: "assist config set harness.exposePiActions <true|false>",
|
|
15471
|
+
note: "force the web UI 'with pi' actions off even when pi is on PATH"
|
|
15442
15472
|
}
|
|
15443
15473
|
];
|
|
15444
15474
|
function runRefine(id, opts) {
|
|
@@ -15875,9 +15905,9 @@ function parseRscRows(flight) {
|
|
|
15875
15905
|
}
|
|
15876
15906
|
function makeRscResolver(rows) {
|
|
15877
15907
|
return (ref) => {
|
|
15878
|
-
const [id, ...
|
|
15908
|
+
const [id, ...path67] = ref.slice(1).replace(/^[L@]/, "").split(":");
|
|
15879
15909
|
let v = rows[id];
|
|
15880
|
-
for (const key of
|
|
15910
|
+
for (const key of path67) {
|
|
15881
15911
|
if (v == null || typeof v !== "object") return void 0;
|
|
15882
15912
|
v = v[key];
|
|
15883
15913
|
}
|
|
@@ -16354,6 +16384,43 @@ function registerNews(program2) {
|
|
|
16354
16384
|
newsCommand.command("add").description("Add an RSS feed URL").argument("<url>", "RSS feed URL").action(add2);
|
|
16355
16385
|
}
|
|
16356
16386
|
|
|
16387
|
+
// src/commands/piHook/index.ts
|
|
16388
|
+
var TOOL_MAP = {
|
|
16389
|
+
bash: "Bash",
|
|
16390
|
+
powershell: "PowerShell"
|
|
16391
|
+
};
|
|
16392
|
+
function parseInput2(raw) {
|
|
16393
|
+
try {
|
|
16394
|
+
const data = JSON.parse(raw);
|
|
16395
|
+
const command = data.command;
|
|
16396
|
+
if (typeof command !== "string" || !command.trim()) return void 0;
|
|
16397
|
+
const toolName = TOOL_MAP[(data.toolName ?? "bash").toLowerCase()];
|
|
16398
|
+
if (!toolName) return void 0;
|
|
16399
|
+
return { toolName, command: command.trim() };
|
|
16400
|
+
} catch {
|
|
16401
|
+
return void 0;
|
|
16402
|
+
}
|
|
16403
|
+
}
|
|
16404
|
+
async function piHook() {
|
|
16405
|
+
const input = parseInput2(await readStdin());
|
|
16406
|
+
if (!input) return;
|
|
16407
|
+
const decision = decideCommand(input.toolName, input.command);
|
|
16408
|
+
const output = decision ? {
|
|
16409
|
+
decision: decision.permissionDecision,
|
|
16410
|
+
reason: decision.permissionDecisionReason
|
|
16411
|
+
} : { decision: "gate" };
|
|
16412
|
+
console.log(JSON.stringify(output));
|
|
16413
|
+
}
|
|
16414
|
+
|
|
16415
|
+
// src/commands/registerPiHook.ts
|
|
16416
|
+
function registerPiHook(program2) {
|
|
16417
|
+
program2.command("pi-hook").description(
|
|
16418
|
+
"pi tool-call permission gate: reads pi's tool-call JSON from stdin and emits an allow/deny/gate decision, auto-approving read-only CLI commands via the shared cli-hook allowlist"
|
|
16419
|
+
).action(() => {
|
|
16420
|
+
piHook();
|
|
16421
|
+
});
|
|
16422
|
+
}
|
|
16423
|
+
|
|
16357
16424
|
// src/commands/prompts/printPromptsTable.ts
|
|
16358
16425
|
import chalk153 from "chalk";
|
|
16359
16426
|
function truncate(str, max) {
|
|
@@ -16524,15 +16591,15 @@ function postComment(vars) {
|
|
|
16524
16591
|
const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
|
|
16525
16592
|
assertThreadCreated(stdout);
|
|
16526
16593
|
}
|
|
16527
|
-
function comment2(
|
|
16594
|
+
function comment2(path67, line, body, startLine) {
|
|
16528
16595
|
validateBody(body);
|
|
16529
16596
|
validateLine(line);
|
|
16530
16597
|
if (startLine !== void 0) validateLine(startLine);
|
|
16531
16598
|
try {
|
|
16532
16599
|
const prId = getCurrentPrNodeId();
|
|
16533
|
-
postComment({ prId, body, path:
|
|
16600
|
+
postComment({ prId, body, path: path67, line, startLine });
|
|
16534
16601
|
const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
|
|
16535
|
-
console.log(`Added review comment on ${
|
|
16602
|
+
console.log(`Added review comment on ${path67}:${range}`);
|
|
16536
16603
|
} catch (error) {
|
|
16537
16604
|
if (isGhNotInstalled(error)) {
|
|
16538
16605
|
console.error("Error: GitHub CLI (gh) is not installed.");
|
|
@@ -17393,8 +17460,8 @@ function registerPrs(program2) {
|
|
|
17393
17460
|
prsCommand.command("reply <comment-id> <body>").description("Reply to a comment thread without resolving it").action((commentId, body) => {
|
|
17394
17461
|
reply(Number.parseInt(commentId, 10), body);
|
|
17395
17462
|
});
|
|
17396
|
-
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((
|
|
17397
|
-
comment2(
|
|
17463
|
+
prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path67, line, body) => {
|
|
17464
|
+
comment2(path67, Number.parseInt(line, 10), body);
|
|
17398
17465
|
});
|
|
17399
17466
|
configHelp(prsCommand, prsConfigHelp);
|
|
17400
17467
|
}
|
|
@@ -17647,10 +17714,10 @@ function resolveOpSecret(reference) {
|
|
|
17647
17714
|
}
|
|
17648
17715
|
|
|
17649
17716
|
// src/commands/ravendb/ravenFetch.ts
|
|
17650
|
-
async function ravenFetch(connection,
|
|
17717
|
+
async function ravenFetch(connection, path67) {
|
|
17651
17718
|
const apiKey = resolveOpSecret(connection.apiKeyRef);
|
|
17652
17719
|
let accessToken = await getAccessToken(apiKey);
|
|
17653
|
-
const url = `${connection.url}${
|
|
17720
|
+
const url = `${connection.url}${path67}`;
|
|
17654
17721
|
const headers = {
|
|
17655
17722
|
Authorization: `Bearer ${accessToken}`,
|
|
17656
17723
|
"Content-Type": "application/json"
|
|
@@ -17754,16 +17821,16 @@ import chalk166 from "chalk";
|
|
|
17754
17821
|
// src/commands/ravendb/buildQueryPath.ts
|
|
17755
17822
|
function buildQueryPath(opts) {
|
|
17756
17823
|
const db = encodeURIComponent(opts.db);
|
|
17757
|
-
let
|
|
17824
|
+
let path67;
|
|
17758
17825
|
if (opts.collection) {
|
|
17759
|
-
|
|
17826
|
+
path67 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
|
|
17760
17827
|
} else {
|
|
17761
|
-
|
|
17828
|
+
path67 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
|
|
17762
17829
|
}
|
|
17763
17830
|
if (opts.query) {
|
|
17764
|
-
|
|
17831
|
+
path67 += `&query=${encodeURIComponent(opts.query)}`;
|
|
17765
17832
|
}
|
|
17766
|
-
return
|
|
17833
|
+
return path67;
|
|
17767
17834
|
}
|
|
17768
17835
|
|
|
17769
17836
|
// src/commands/ravendb/fetchAllPages.ts
|
|
@@ -17772,7 +17839,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
17772
17839
|
let start3 = 0;
|
|
17773
17840
|
while (true) {
|
|
17774
17841
|
const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
|
|
17775
|
-
const
|
|
17842
|
+
const path67 = buildQueryPath({
|
|
17776
17843
|
db: connection.database,
|
|
17777
17844
|
collection: opts.collection,
|
|
17778
17845
|
start: start3,
|
|
@@ -17780,7 +17847,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
17780
17847
|
sort: opts.sort,
|
|
17781
17848
|
query: opts.query
|
|
17782
17849
|
});
|
|
17783
|
-
const data = await ravenFetch(connection,
|
|
17850
|
+
const data = await ravenFetch(connection, path67);
|
|
17784
17851
|
const results = data.Results ?? [];
|
|
17785
17852
|
const totalResults = data.TotalResults ?? 0;
|
|
17786
17853
|
if (results.length === 0) break;
|
|
@@ -20168,8 +20235,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
20168
20235
|
// src/commands/review/prepareReviewDir.ts
|
|
20169
20236
|
import { existsSync as existsSync41, mkdirSync as mkdirSync17, unlinkSync as unlinkSync14, writeFileSync as writeFileSync34 } from "fs";
|
|
20170
20237
|
function clearReviewFiles(paths) {
|
|
20171
|
-
for (const
|
|
20172
|
-
if (existsSync41(
|
|
20238
|
+
for (const path67 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
20239
|
+
if (existsSync41(path67)) unlinkSync14(path67);
|
|
20173
20240
|
}
|
|
20174
20241
|
}
|
|
20175
20242
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -21317,8 +21384,8 @@ import chalk187 from "chalk";
|
|
|
21317
21384
|
|
|
21318
21385
|
// src/commands/seq/fetchSeq.ts
|
|
21319
21386
|
import chalk184 from "chalk";
|
|
21320
|
-
async function fetchSeq(conn,
|
|
21321
|
-
const url = `${conn.url}${
|
|
21387
|
+
async function fetchSeq(conn, path67, params) {
|
|
21388
|
+
const url = `${conn.url}${path67}?${params}`;
|
|
21322
21389
|
const response = await fetch(url, {
|
|
21323
21390
|
headers: {
|
|
21324
21391
|
Accept: "application/json",
|
|
@@ -22805,9 +22872,9 @@ function findPortFile(roamDir) {
|
|
|
22805
22872
|
return void 0;
|
|
22806
22873
|
}
|
|
22807
22874
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
22808
|
-
const
|
|
22875
|
+
const path67 = join60(roamDir, name);
|
|
22809
22876
|
try {
|
|
22810
|
-
return { path:
|
|
22877
|
+
return { path: path67, mtimeMs: statSync8(path67).mtimeMs };
|
|
22811
22878
|
} catch {
|
|
22812
22879
|
return void 0;
|
|
22813
22880
|
}
|
|
@@ -23226,11 +23293,11 @@ function findLinkIndex() {
|
|
|
23226
23293
|
function parseLinkArgs() {
|
|
23227
23294
|
const idx = findLinkIndex();
|
|
23228
23295
|
if (idx === -1) return null;
|
|
23229
|
-
const
|
|
23296
|
+
const path67 = process.argv[idx + 1];
|
|
23230
23297
|
const rest = process.argv.slice(idx + 2);
|
|
23231
23298
|
const { value: prefix2 } = extractOption(rest, "--prefix");
|
|
23232
23299
|
if (!prefix2) return null;
|
|
23233
|
-
return { path:
|
|
23300
|
+
return { path: path67, prefix: prefix2 };
|
|
23234
23301
|
}
|
|
23235
23302
|
function hasDuplicateLink(runList, linkPath) {
|
|
23236
23303
|
return runList.some(
|
|
@@ -23600,9 +23667,6 @@ function reportStrays(pids) {
|
|
|
23600
23667
|
// src/commands/sessions/daemon/drainDaemon.ts
|
|
23601
23668
|
import { createInterface as createInterface6 } from "readline";
|
|
23602
23669
|
|
|
23603
|
-
// src/commands/sessions/daemon/loadPersistedSessions.ts
|
|
23604
|
-
import { z as z5 } from "zod";
|
|
23605
|
-
|
|
23606
23670
|
// src/commands/sessions/daemon/daemonLog.ts
|
|
23607
23671
|
var RING_CAPACITY = 1e3;
|
|
23608
23672
|
var ring = [];
|
|
@@ -23626,13 +23690,14 @@ function recentDaemonLogLines() {
|
|
|
23626
23690
|
return [...ring];
|
|
23627
23691
|
}
|
|
23628
23692
|
|
|
23629
|
-
// src/commands/sessions/daemon/
|
|
23630
|
-
|
|
23693
|
+
// src/commands/sessions/daemon/persistedSessionSchema.ts
|
|
23694
|
+
import { z as z5 } from "zod";
|
|
23631
23695
|
var persistedSessionSchema = z5.object({
|
|
23632
23696
|
name: z5.string(),
|
|
23633
23697
|
title: z5.string().optional(),
|
|
23634
23698
|
subtitle: z5.string().optional(),
|
|
23635
23699
|
commandType: z5.enum(["claude", "run", "assist"]),
|
|
23700
|
+
harness: z5.enum(["claude", "codex", "pi"]).optional(),
|
|
23636
23701
|
status: z5.enum(["running", "waiting", "done", "error"]).optional(),
|
|
23637
23702
|
cwd: z5.string(),
|
|
23638
23703
|
startedAt: z5.number(),
|
|
@@ -23645,6 +23710,34 @@ var persistedSessionSchema = z5.object({
|
|
|
23645
23710
|
activity: activitySchema.optional(),
|
|
23646
23711
|
starred: z5.boolean().optional()
|
|
23647
23712
|
});
|
|
23713
|
+
|
|
23714
|
+
// src/commands/sessions/daemon/toPersistedSession.ts
|
|
23715
|
+
function toPersistedSession(session) {
|
|
23716
|
+
return {
|
|
23717
|
+
name: session.name,
|
|
23718
|
+
title: session.title,
|
|
23719
|
+
subtitle: session.subtitle,
|
|
23720
|
+
commandType: session.commandType,
|
|
23721
|
+
harness: session.harness,
|
|
23722
|
+
status: session.status,
|
|
23723
|
+
cwd: session.cwd ?? process.cwd(),
|
|
23724
|
+
startedAt: session.startedAt,
|
|
23725
|
+
runningMs: accumulatedRunningMs(session),
|
|
23726
|
+
claudeSessionId: session.claudeSessionId,
|
|
23727
|
+
initialPrompt: session.initialPrompt,
|
|
23728
|
+
runName: session.runName,
|
|
23729
|
+
runArgs: session.runArgs,
|
|
23730
|
+
assistArgs: session.assistArgs,
|
|
23731
|
+
activity: session.activity,
|
|
23732
|
+
starred: session.starred
|
|
23733
|
+
};
|
|
23734
|
+
}
|
|
23735
|
+
function accumulatedRunningMs(session) {
|
|
23736
|
+
return session.runningSince != null ? session.runningMs + Date.now() - session.runningSince : session.runningMs;
|
|
23737
|
+
}
|
|
23738
|
+
|
|
23739
|
+
// src/commands/sessions/daemon/loadPersistedSessions.ts
|
|
23740
|
+
var SESSIONS_FILE = "sessions.json";
|
|
23648
23741
|
function loadPersistedSessions() {
|
|
23649
23742
|
const data = loadJson(SESSIONS_FILE);
|
|
23650
23743
|
if (!Array.isArray(data)) return [];
|
|
@@ -23672,28 +23765,6 @@ function logPersist(live) {
|
|
|
23672
23765
|
live.length > 0 ? `persisted ${live.length} session(s): ${live.map((s) => s.name).join(", ")}` : "persisted 0 sessions (sessions.json cleared)"
|
|
23673
23766
|
);
|
|
23674
23767
|
}
|
|
23675
|
-
function toPersistedSession(session) {
|
|
23676
|
-
return {
|
|
23677
|
-
name: session.name,
|
|
23678
|
-
title: session.title,
|
|
23679
|
-
subtitle: session.subtitle,
|
|
23680
|
-
commandType: session.commandType,
|
|
23681
|
-
status: session.status,
|
|
23682
|
-
cwd: session.cwd ?? process.cwd(),
|
|
23683
|
-
startedAt: session.startedAt,
|
|
23684
|
-
runningMs: accumulatedRunningMs(session),
|
|
23685
|
-
claudeSessionId: session.claudeSessionId,
|
|
23686
|
-
initialPrompt: session.initialPrompt,
|
|
23687
|
-
runName: session.runName,
|
|
23688
|
-
runArgs: session.runArgs,
|
|
23689
|
-
assistArgs: session.assistArgs,
|
|
23690
|
-
activity: session.activity,
|
|
23691
|
-
starred: session.starred
|
|
23692
|
-
};
|
|
23693
|
-
}
|
|
23694
|
-
function accumulatedRunningMs(session) {
|
|
23695
|
-
return session.runningSince != null ? session.runningMs + Date.now() - session.runningSince : session.runningMs;
|
|
23696
|
-
}
|
|
23697
23768
|
|
|
23698
23769
|
// src/commands/sessions/daemon/drainDaemon.ts
|
|
23699
23770
|
var DRAIN_TIMEOUT_MS = 5e3;
|
|
@@ -23804,6 +23875,7 @@ function toSessionInfo({
|
|
|
23804
23875
|
title,
|
|
23805
23876
|
subtitle,
|
|
23806
23877
|
commandType,
|
|
23878
|
+
harness,
|
|
23807
23879
|
status: status3,
|
|
23808
23880
|
startedAt,
|
|
23809
23881
|
runningMs,
|
|
@@ -23827,6 +23899,7 @@ function toSessionInfo({
|
|
|
23827
23899
|
title,
|
|
23828
23900
|
subtitle,
|
|
23829
23901
|
commandType,
|
|
23902
|
+
harness,
|
|
23830
23903
|
status: status3,
|
|
23831
23904
|
startedAt,
|
|
23832
23905
|
runningMs,
|
|
@@ -24034,6 +24107,13 @@ function buildArgs3(opts) {
|
|
|
24034
24107
|
return base;
|
|
24035
24108
|
}
|
|
24036
24109
|
|
|
24110
|
+
// src/commands/sessions/daemon/spawnPi.ts
|
|
24111
|
+
function spawnPi2(opts = {}) {
|
|
24112
|
+
const args = ["pi"];
|
|
24113
|
+
if (opts.prompt) args.push(opts.prompt);
|
|
24114
|
+
return spawnPty(args, opts.cwd, opts.sessionId);
|
|
24115
|
+
}
|
|
24116
|
+
|
|
24037
24117
|
// src/commands/sessions/daemon/spawnRun.ts
|
|
24038
24118
|
function spawnRun(opts) {
|
|
24039
24119
|
return spawnPty(["assist", "run", opts.name, ...opts.args ?? []], opts.cwd);
|
|
@@ -24053,7 +24133,8 @@ function sessionBase(id, status3) {
|
|
|
24053
24133
|
scrollback: ""
|
|
24054
24134
|
};
|
|
24055
24135
|
}
|
|
24056
|
-
function createSession(id, prompt, cwd, design) {
|
|
24136
|
+
function createSession(id, prompt, cwd, design, harness) {
|
|
24137
|
+
if (harness === "pi") return createPiSession(id, prompt, cwd);
|
|
24057
24138
|
const claudeSessionId = randomUUID4();
|
|
24058
24139
|
return {
|
|
24059
24140
|
...sessionBase(id, prompt ? "running" : "waiting"),
|
|
@@ -24066,6 +24147,17 @@ function createSession(id, prompt, cwd, design) {
|
|
|
24066
24147
|
design
|
|
24067
24148
|
};
|
|
24068
24149
|
}
|
|
24150
|
+
function createPiSession(id, prompt, cwd) {
|
|
24151
|
+
return {
|
|
24152
|
+
...sessionBase(id, prompt ? "running" : "waiting"),
|
|
24153
|
+
name: prompt?.slice(0, 40) || `Session ${id}`,
|
|
24154
|
+
commandType: "claude",
|
|
24155
|
+
harness: "pi",
|
|
24156
|
+
pty: spawnPi2({ prompt, cwd, sessionId: id }),
|
|
24157
|
+
cwd,
|
|
24158
|
+
initialPrompt: prompt
|
|
24159
|
+
};
|
|
24160
|
+
}
|
|
24069
24161
|
function createRunSession(id, runName, runArgs, cwd) {
|
|
24070
24162
|
return {
|
|
24071
24163
|
...sessionBase(id, "running"),
|
|
@@ -24510,8 +24602,8 @@ async function seedRunningMsFromUsage(session, notify2) {
|
|
|
24510
24602
|
var DEBOUNCE_MS = 50;
|
|
24511
24603
|
function watchActivity(session, notify2) {
|
|
24512
24604
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
24513
|
-
const
|
|
24514
|
-
const dir = dirname29(
|
|
24605
|
+
const path67 = activityPath(session.id);
|
|
24606
|
+
const dir = dirname29(path67);
|
|
24515
24607
|
try {
|
|
24516
24608
|
mkdirSync24(dir, { recursive: true });
|
|
24517
24609
|
} catch {
|
|
@@ -24521,7 +24613,7 @@ function watchActivity(session, notify2) {
|
|
|
24521
24613
|
let timer = null;
|
|
24522
24614
|
const read = () => {
|
|
24523
24615
|
timer = null;
|
|
24524
|
-
const activity2 = readActivity(
|
|
24616
|
+
const activity2 = readActivity(path67);
|
|
24525
24617
|
if (!activity2) return;
|
|
24526
24618
|
session.activity = activity2;
|
|
24527
24619
|
if (activity2.claudeSessionId)
|
|
@@ -24531,11 +24623,11 @@ function watchActivity(session, notify2) {
|
|
|
24531
24623
|
notify2();
|
|
24532
24624
|
};
|
|
24533
24625
|
session.activityWatcher = watch(dir, (_event, filename) => {
|
|
24534
|
-
if (filename && !
|
|
24626
|
+
if (filename && !path67.endsWith(filename)) return;
|
|
24535
24627
|
if (timer) clearTimeout(timer);
|
|
24536
24628
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
24537
24629
|
});
|
|
24538
|
-
if (existsSync54(
|
|
24630
|
+
if (existsSync54(path67)) read();
|
|
24539
24631
|
}
|
|
24540
24632
|
function refreshActivity(session) {
|
|
24541
24633
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -24730,6 +24822,7 @@ function restoreBase(id, persisted) {
|
|
|
24730
24822
|
title: persisted.title,
|
|
24731
24823
|
subtitle: persisted.subtitle,
|
|
24732
24824
|
commandType: persisted.commandType,
|
|
24825
|
+
harness: persisted.harness,
|
|
24733
24826
|
scrollback: "",
|
|
24734
24827
|
cwd: persisted.cwd,
|
|
24735
24828
|
assistArgs: persisted.assistArgs,
|
|
@@ -25743,8 +25836,10 @@ var SessionManager = class {
|
|
|
25743
25836
|
return session.id;
|
|
25744
25837
|
}
|
|
25745
25838
|
spawnWith = (create) => this.add(create(sessionLimits.nextId(this.sessions.size, this.idCounter)));
|
|
25746
|
-
spawn(prompt, cwd, design) {
|
|
25747
|
-
return this.spawnWith(
|
|
25839
|
+
spawn(prompt, cwd, design, harness) {
|
|
25840
|
+
return this.spawnWith(
|
|
25841
|
+
(id) => createSession(id, prompt, cwd, design, harness)
|
|
25842
|
+
);
|
|
25748
25843
|
}
|
|
25749
25844
|
spawnRun(runName, runArgs, cwd) {
|
|
25750
25845
|
return this.spawnWith((id) => createRunSession(id, runName, runArgs, cwd));
|
|
@@ -25943,12 +26038,16 @@ var lifecycleHandlers = {
|
|
|
25943
26038
|
// src/commands/sessions/daemon/spawnCreate.ts
|
|
25944
26039
|
function spawnCreate(m, d) {
|
|
25945
26040
|
const design = d.design === true;
|
|
26041
|
+
const harness = d.harness;
|
|
25946
26042
|
if (design)
|
|
25947
26043
|
daemonLog(`create: design session (cwd=${d.cwd ?? ""})`);
|
|
26044
|
+
if (harness && harness !== "claude")
|
|
26045
|
+
daemonLog(`create: ${harness} session (cwd=${d.cwd ?? ""})`);
|
|
25948
26046
|
return m.spawn(
|
|
25949
26047
|
d.prompt,
|
|
25950
26048
|
d.cwd,
|
|
25951
|
-
design
|
|
26049
|
+
design,
|
|
26050
|
+
harness
|
|
25952
26051
|
);
|
|
25953
26052
|
}
|
|
25954
26053
|
|
|
@@ -26624,9 +26723,9 @@ async function statusLine() {
|
|
|
26624
26723
|
}
|
|
26625
26724
|
|
|
26626
26725
|
// src/commands/sync.ts
|
|
26627
|
-
import * as
|
|
26726
|
+
import * as fs45 from "fs";
|
|
26628
26727
|
import * as os3 from "os";
|
|
26629
|
-
import * as
|
|
26728
|
+
import * as path65 from "path";
|
|
26630
26729
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
26631
26730
|
|
|
26632
26731
|
// src/commands/sync/syncClaudeMd.ts
|
|
@@ -26660,12 +26759,33 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
26660
26759
|
}
|
|
26661
26760
|
|
|
26662
26761
|
// src/commands/sync/syncCodex.ts
|
|
26663
|
-
import * as
|
|
26664
|
-
import * as path59 from "path";
|
|
26762
|
+
import * as path60 from "path";
|
|
26665
26763
|
|
|
26666
|
-
// src/commands/sync/
|
|
26764
|
+
// src/commands/sync/installHarnessCommands.ts
|
|
26667
26765
|
import * as fs40 from "fs";
|
|
26668
26766
|
import * as path58 from "path";
|
|
26767
|
+
function installHarnessCommands(claudeDir, harness, transform) {
|
|
26768
|
+
const commandsSource = path58.join(claudeDir, "commands");
|
|
26769
|
+
const files = fs40.readdirSync(commandsSource);
|
|
26770
|
+
let synced = 0;
|
|
26771
|
+
for (const file of files) {
|
|
26772
|
+
if (!file.endsWith(".md")) continue;
|
|
26773
|
+
const name = file.replace(/\.md$/, "");
|
|
26774
|
+
const content = fs40.readFileSync(path58.join(commandsSource, file), "utf8");
|
|
26775
|
+
const target = path58.join(harness.homeDir, harness.sync.commandDest(name));
|
|
26776
|
+
fs40.mkdirSync(path58.dirname(target), { recursive: true });
|
|
26777
|
+
fs40.writeFileSync(target, transform(name, content));
|
|
26778
|
+
synced++;
|
|
26779
|
+
}
|
|
26780
|
+
const agentsTarget = path58.join(harness.homeDir, harness.sync.agentsFile);
|
|
26781
|
+
fs40.mkdirSync(path58.dirname(agentsTarget), { recursive: true });
|
|
26782
|
+
fs40.copyFileSync(path58.join(claudeDir, "CLAUDE.md"), agentsTarget);
|
|
26783
|
+
return { total: files.length, synced };
|
|
26784
|
+
}
|
|
26785
|
+
|
|
26786
|
+
// src/commands/sync/syncCodexHooks.ts
|
|
26787
|
+
import * as fs41 from "fs";
|
|
26788
|
+
import * as path59 from "path";
|
|
26669
26789
|
var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
|
|
26670
26790
|
var END = "# <<< assist codex hooks (managed) <<<";
|
|
26671
26791
|
function upsertManagedBlock(existing, body) {
|
|
@@ -26695,11 +26815,11 @@ ${rest}
|
|
|
26695
26815
|
`;
|
|
26696
26816
|
}
|
|
26697
26817
|
function syncCodexHooks(sourcePath) {
|
|
26698
|
-
const body =
|
|
26699
|
-
const configPath =
|
|
26700
|
-
const existing =
|
|
26701
|
-
|
|
26702
|
-
|
|
26818
|
+
const body = fs41.readFileSync(sourcePath, "utf8");
|
|
26819
|
+
const configPath = path59.join(harnesses.codex.homeDir, "config.toml");
|
|
26820
|
+
const existing = fs41.existsSync(configPath) ? fs41.readFileSync(configPath, "utf8") : "";
|
|
26821
|
+
fs41.mkdirSync(path59.dirname(configPath), { recursive: true });
|
|
26822
|
+
fs41.writeFileSync(configPath, upsertManagedBlock(existing, body));
|
|
26703
26823
|
console.log(
|
|
26704
26824
|
"Registered assist codex-hook in ~/.codex/config.toml (PreToolUse, PermissionRequest)"
|
|
26705
26825
|
);
|
|
@@ -26725,58 +26845,108 @@ description: ${quoteYaml(description)}
|
|
|
26725
26845
|
}
|
|
26726
26846
|
function syncCodex(claudeDir) {
|
|
26727
26847
|
if (!isHarnessAvailable("codex")) return;
|
|
26728
|
-
const
|
|
26729
|
-
|
|
26730
|
-
|
|
26731
|
-
|
|
26732
|
-
|
|
26733
|
-
|
|
26734
|
-
const content = fs41.readFileSync(path59.join(commandsSource, file), "utf8");
|
|
26735
|
-
const target = path59.join(codex.homeDir, codex.sync.commandDest(name));
|
|
26736
|
-
fs41.mkdirSync(path59.dirname(target), { recursive: true });
|
|
26737
|
-
fs41.writeFileSync(target, commandToSkill(name, content));
|
|
26738
|
-
}
|
|
26739
|
-
const agentsTarget = path59.join(codex.homeDir, codex.sync.agentsFile);
|
|
26740
|
-
fs41.mkdirSync(path59.dirname(agentsTarget), { recursive: true });
|
|
26741
|
-
fs41.copyFileSync(path59.join(claudeDir, "CLAUDE.md"), agentsTarget);
|
|
26742
|
-
syncCodexHooks(path59.join(claudeDir, "..", "codex", "config.toml"));
|
|
26848
|
+
const { total } = installHarnessCommands(
|
|
26849
|
+
claudeDir,
|
|
26850
|
+
harnesses.codex,
|
|
26851
|
+
commandToSkill
|
|
26852
|
+
);
|
|
26853
|
+
syncCodexHooks(path60.join(claudeDir, "..", "codex", "config.toml"));
|
|
26743
26854
|
console.log(
|
|
26744
|
-
`Synced ${
|
|
26855
|
+
`Synced ${total} skill(s) to ~/.codex/skills and CLAUDE.md to ~/.codex/AGENTS.md`
|
|
26745
26856
|
);
|
|
26746
26857
|
}
|
|
26747
26858
|
|
|
26748
26859
|
// src/commands/sync/syncDesign.ts
|
|
26749
26860
|
import * as fs42 from "fs";
|
|
26750
|
-
import * as
|
|
26861
|
+
import * as path61 from "path";
|
|
26751
26862
|
function syncDesign(claudeDir, targetBase) {
|
|
26752
|
-
const systemPromptSource =
|
|
26753
|
-
const systemPromptTarget =
|
|
26863
|
+
const systemPromptSource = path61.join(claudeDir, "system-prompt.md");
|
|
26864
|
+
const systemPromptTarget = path61.join(targetBase, "system-prompt.md");
|
|
26754
26865
|
fs42.copyFileSync(systemPromptSource, systemPromptTarget);
|
|
26755
26866
|
console.log("Copied system-prompt.md to ~/.claude/system-prompt.md");
|
|
26756
|
-
const skillsSource =
|
|
26757
|
-
const skillsTarget =
|
|
26867
|
+
const skillsSource = path61.join(claudeDir, "skills");
|
|
26868
|
+
const skillsTarget = path61.join(targetBase, "skills");
|
|
26758
26869
|
fs42.mkdirSync(skillsTarget, { recursive: true });
|
|
26759
26870
|
const files = fs42.readdirSync(skillsSource);
|
|
26760
26871
|
for (const file of files) {
|
|
26761
26872
|
fs42.copyFileSync(
|
|
26762
|
-
|
|
26763
|
-
|
|
26873
|
+
path61.join(skillsSource, file),
|
|
26874
|
+
path61.join(skillsTarget, file)
|
|
26764
26875
|
);
|
|
26765
26876
|
}
|
|
26766
26877
|
console.log(`Synced ${files.length} design skill(s) to ~/.claude/skills`);
|
|
26767
26878
|
}
|
|
26768
26879
|
|
|
26769
|
-
// src/commands/sync/
|
|
26880
|
+
// src/commands/sync/syncPi.ts
|
|
26881
|
+
import * as path63 from "path";
|
|
26882
|
+
|
|
26883
|
+
// src/commands/sync/syncPiHooks.ts
|
|
26770
26884
|
import * as fs43 from "fs";
|
|
26771
|
-
import * as
|
|
26885
|
+
import * as path62 from "path";
|
|
26886
|
+
function piExtensionsDir() {
|
|
26887
|
+
return path62.join(harnesses.pi.homeDir, "extensions");
|
|
26888
|
+
}
|
|
26889
|
+
function syncPiHooks(sourceDir) {
|
|
26890
|
+
const target = piExtensionsDir();
|
|
26891
|
+
fs43.mkdirSync(target, { recursive: true });
|
|
26892
|
+
const files = fs43.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
|
|
26893
|
+
for (const file of files) {
|
|
26894
|
+
fs43.copyFileSync(
|
|
26895
|
+
path62.join(sourceDir, file),
|
|
26896
|
+
path62.join(target, `assist-${file}`)
|
|
26897
|
+
);
|
|
26898
|
+
}
|
|
26899
|
+
console.log(
|
|
26900
|
+
`Registered ${files.length} assist extension(s) in ~/.pi/agent/extensions`
|
|
26901
|
+
);
|
|
26902
|
+
}
|
|
26903
|
+
|
|
26904
|
+
// src/commands/sync/syncPi.ts
|
|
26905
|
+
function unquote(value) {
|
|
26906
|
+
return value.trim().replace(/^["']|["']$/g, "");
|
|
26907
|
+
}
|
|
26908
|
+
function commandToPrompt(name, content) {
|
|
26909
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
26910
|
+
const frontmatter = match ? match[1] : "";
|
|
26911
|
+
const body = match ? content.slice(match[0].length) : content;
|
|
26912
|
+
const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
|
|
26913
|
+
const description = descriptionMatch ? unquote(descriptionMatch[1]) : name;
|
|
26914
|
+
const argsMatch = frontmatter.match(/^allowed_args:\s*(.*)$/m);
|
|
26915
|
+
const argumentHint = argsMatch ? unquote(argsMatch[1]) : void 0;
|
|
26916
|
+
const header = [
|
|
26917
|
+
"---",
|
|
26918
|
+
`description: ${description}`,
|
|
26919
|
+
...argumentHint ? [`argument-hint: ${argumentHint}`] : [],
|
|
26920
|
+
"---",
|
|
26921
|
+
"",
|
|
26922
|
+
""
|
|
26923
|
+
].join("\n");
|
|
26924
|
+
return header + body.replace(/^\r?\n+/, "");
|
|
26925
|
+
}
|
|
26926
|
+
function syncPi(claudeDir) {
|
|
26927
|
+
if (!isHarnessAvailable("pi")) return;
|
|
26928
|
+
const { synced } = installHarnessCommands(
|
|
26929
|
+
claudeDir,
|
|
26930
|
+
harnesses.pi,
|
|
26931
|
+
commandToPrompt
|
|
26932
|
+
);
|
|
26933
|
+
syncPiHooks(path63.join(claudeDir, "..", "pi"));
|
|
26934
|
+
console.log(
|
|
26935
|
+
`Synced ${synced} prompt(s) to ~/.pi/agent/prompts and CLAUDE.md to ~/.pi/agent/AGENTS.md`
|
|
26936
|
+
);
|
|
26937
|
+
}
|
|
26938
|
+
|
|
26939
|
+
// src/commands/sync/syncSettings.ts
|
|
26940
|
+
import * as fs44 from "fs";
|
|
26941
|
+
import * as path64 from "path";
|
|
26772
26942
|
import chalk200 from "chalk";
|
|
26773
26943
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
26774
|
-
const source =
|
|
26775
|
-
const target =
|
|
26776
|
-
const sourceContent =
|
|
26944
|
+
const source = path64.join(claudeDir, "settings.json");
|
|
26945
|
+
const target = path64.join(targetBase, "settings.json");
|
|
26946
|
+
const sourceContent = fs44.readFileSync(source, "utf8");
|
|
26777
26947
|
const sourceSettings = JSON.parse(sourceContent);
|
|
26778
|
-
const targetExists =
|
|
26779
|
-
const targetContent = targetExists ?
|
|
26948
|
+
const targetExists = fs44.existsSync(target);
|
|
26949
|
+
const targetContent = targetExists ? fs44.readFileSync(target, "utf8") : "";
|
|
26780
26950
|
const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
|
|
26781
26951
|
const mergedContent = JSON.stringify(
|
|
26782
26952
|
{ ...preservedUserSettings, ...sourceSettings },
|
|
@@ -26805,31 +26975,32 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
26805
26975
|
}
|
|
26806
26976
|
}
|
|
26807
26977
|
}
|
|
26808
|
-
|
|
26978
|
+
fs44.writeFileSync(target, mergedContent);
|
|
26809
26979
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
26810
26980
|
}
|
|
26811
26981
|
|
|
26812
26982
|
// src/commands/sync.ts
|
|
26813
26983
|
var __filename5 = fileURLToPath9(import.meta.url);
|
|
26814
|
-
var __dirname7 =
|
|
26984
|
+
var __dirname7 = path65.dirname(__filename5);
|
|
26815
26985
|
async function sync(options2) {
|
|
26816
26986
|
const config = loadConfig();
|
|
26817
26987
|
const yes = options2?.yes ?? config.sync.autoConfirm;
|
|
26818
|
-
const claudeDir =
|
|
26819
|
-
const targetBase =
|
|
26988
|
+
const claudeDir = path65.join(__dirname7, "..", "claude");
|
|
26989
|
+
const targetBase = path65.join(os3.homedir(), ".claude");
|
|
26820
26990
|
syncCommands(claudeDir, targetBase);
|
|
26821
26991
|
syncDesign(claudeDir, targetBase);
|
|
26822
26992
|
await syncSettings(claudeDir, targetBase, { yes });
|
|
26823
26993
|
await syncClaudeMd(claudeDir, targetBase, { yes });
|
|
26824
26994
|
syncCodex(claudeDir);
|
|
26995
|
+
syncPi(claudeDir);
|
|
26825
26996
|
}
|
|
26826
26997
|
function syncCommands(claudeDir, targetBase) {
|
|
26827
|
-
const sourceDir =
|
|
26828
|
-
const targetDir =
|
|
26829
|
-
|
|
26830
|
-
const files =
|
|
26998
|
+
const sourceDir = path65.join(claudeDir, "commands");
|
|
26999
|
+
const targetDir = path65.join(targetBase, "commands");
|
|
27000
|
+
fs45.mkdirSync(targetDir, { recursive: true });
|
|
27001
|
+
const files = fs45.readdirSync(sourceDir);
|
|
26831
27002
|
for (const file of files) {
|
|
26832
|
-
|
|
27003
|
+
fs45.copyFileSync(path65.join(sourceDir, file), path65.join(targetDir, file));
|
|
26833
27004
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
26834
27005
|
}
|
|
26835
27006
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -26837,7 +27008,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
26837
27008
|
|
|
26838
27009
|
// src/commands/update.ts
|
|
26839
27010
|
import { execSync as execSync57 } from "child_process";
|
|
26840
|
-
import * as
|
|
27011
|
+
import * as path66 from "path";
|
|
26841
27012
|
|
|
26842
27013
|
// src/commands/restartDaemonAfterUpdate.ts
|
|
26843
27014
|
async function restartDaemonAfterUpdate() {
|
|
@@ -26856,12 +27027,12 @@ async function restartDaemonAfterUpdate() {
|
|
|
26856
27027
|
// src/commands/update.ts
|
|
26857
27028
|
function isGlobalNpmInstall(dir) {
|
|
26858
27029
|
try {
|
|
26859
|
-
const resolved =
|
|
26860
|
-
if (resolved.split(
|
|
27030
|
+
const resolved = path66.resolve(dir);
|
|
27031
|
+
if (resolved.split(path66.sep).includes("node_modules")) {
|
|
26861
27032
|
return true;
|
|
26862
27033
|
}
|
|
26863
27034
|
const globalPrefix = execSync57("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
26864
|
-
return resolved.toLowerCase().startsWith(
|
|
27035
|
+
return resolved.toLowerCase().startsWith(path66.resolve(globalPrefix).toLowerCase());
|
|
26865
27036
|
} catch {
|
|
26866
27037
|
return false;
|
|
26867
27038
|
}
|
|
@@ -26907,7 +27078,7 @@ function reportCliError(error) {
|
|
|
26907
27078
|
var program = new Command();
|
|
26908
27079
|
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 }));
|
|
26909
27080
|
var syncCommand = program.command("sync").description(
|
|
26910
|
-
"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"
|
|
27081
|
+
"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"
|
|
26911
27082
|
).option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
|
|
26912
27083
|
configHelp(syncCommand, rootConfigHelp.sync);
|
|
26913
27084
|
program.command("init").description("Initialize VS Code and verify configurations").action(init5);
|
|
@@ -26935,6 +27106,7 @@ registerDb(program);
|
|
|
26935
27106
|
registerCliHook(program);
|
|
26936
27107
|
registerCodeComment(program);
|
|
26937
27108
|
registerCodexHook(program);
|
|
27109
|
+
registerPiHook(program);
|
|
26938
27110
|
registerEditHook(program);
|
|
26939
27111
|
registerGithub(program);
|
|
26940
27112
|
registerHandover(program);
|