codeam-cli 2.36.4 → 2.37.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/CHANGELOG.md +12 -0
- package/dist/index.js +322 -264
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.
|
|
501
|
+
version: "2.37.0",
|
|
502
502
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -1186,8 +1186,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1186
1186
|
return decodedFile;
|
|
1187
1187
|
};
|
|
1188
1188
|
}
|
|
1189
|
-
function normalizeWindowsPath(
|
|
1190
|
-
return
|
|
1189
|
+
function normalizeWindowsPath(path52) {
|
|
1190
|
+
return path52.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1191
1191
|
}
|
|
1192
1192
|
|
|
1193
1193
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3667,9 +3667,9 @@ async function addSourceContext(frames) {
|
|
|
3667
3667
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3668
3668
|
return frames;
|
|
3669
3669
|
}
|
|
3670
|
-
function getContextLinesFromFile(
|
|
3670
|
+
function getContextLinesFromFile(path52, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path52);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path51, ranges, output) {
|
|
|
3684
3684
|
let rangeStart = range[0];
|
|
3685
3685
|
let rangeEnd = range[1];
|
|
3686
3686
|
function onStreamError() {
|
|
3687
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3687
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path52, 1);
|
|
3688
3688
|
lineReaded.close();
|
|
3689
3689
|
lineReaded.removeAllListeners();
|
|
3690
3690
|
destroyStreamAndResolve();
|
|
@@ -3745,8 +3745,8 @@ function clearLineContext(frame) {
|
|
|
3745
3745
|
delete frame.context_line;
|
|
3746
3746
|
delete frame.post_context;
|
|
3747
3747
|
}
|
|
3748
|
-
function shouldSkipContextLinesForFile(
|
|
3749
|
-
return
|
|
3748
|
+
function shouldSkipContextLinesForFile(path52) {
|
|
3749
|
+
return path52.startsWith("node:") || path52.endsWith(".min.js") || path52.endsWith(".min.cjs") || path52.endsWith(".min.mjs") || path52.startsWith("data:");
|
|
3750
3750
|
}
|
|
3751
3751
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3752
3752
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5900,7 +5900,7 @@ function readAnonId() {
|
|
|
5900
5900
|
}
|
|
5901
5901
|
function superProperties() {
|
|
5902
5902
|
return {
|
|
5903
|
-
cliVersion: true ? "2.
|
|
5903
|
+
cliVersion: true ? "2.37.0" : "0.0.0-dev",
|
|
5904
5904
|
nodeVersion: process.version,
|
|
5905
5905
|
platform: process.platform,
|
|
5906
5906
|
arch: process.arch,
|
|
@@ -7248,10 +7248,10 @@ function buildForPlatform(platform2) {
|
|
|
7248
7248
|
var import_node_crypto4 = require("crypto");
|
|
7249
7249
|
|
|
7250
7250
|
// src/agents/claude/resolver.ts
|
|
7251
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
7252
|
-
const found =
|
|
7251
|
+
function buildClaudeLaunch(extraArgs = [], os32 = createOsStrategy()) {
|
|
7252
|
+
const found = os32.findInPath("claude") ?? os32.findInPath("claude-code");
|
|
7253
7253
|
if (!found) return null;
|
|
7254
|
-
return
|
|
7254
|
+
return os32.buildLaunch(found, extraArgs);
|
|
7255
7255
|
}
|
|
7256
7256
|
|
|
7257
7257
|
// src/agents/claude/installer.ts
|
|
@@ -9978,13 +9978,13 @@ function detectStartupBanner(lines) {
|
|
|
9978
9978
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9979
9979
|
if (metaIdx - artStart < 2) return null;
|
|
9980
9980
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9981
|
-
const
|
|
9981
|
+
const path52 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path52,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path52 ? 1 : 0)
|
|
9988
9988
|
};
|
|
9989
9989
|
}
|
|
9990
9990
|
|
|
@@ -9994,8 +9994,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9994
9994
|
meta = getAgent("claude");
|
|
9995
9995
|
mode = "interactive";
|
|
9996
9996
|
os;
|
|
9997
|
-
constructor(
|
|
9998
|
-
this.os =
|
|
9997
|
+
constructor(os32) {
|
|
9998
|
+
this.os = os32;
|
|
9999
9999
|
}
|
|
10000
10000
|
/**
|
|
10001
10001
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -11025,8 +11025,8 @@ function codexCredentialLocator() {
|
|
|
11025
11025
|
function codexLoginLauncher() {
|
|
11026
11026
|
return {
|
|
11027
11027
|
async ensureInstalled() {
|
|
11028
|
-
const
|
|
11029
|
-
return
|
|
11028
|
+
const os32 = createOsStrategy();
|
|
11029
|
+
return os32.findInPath("codex") !== null;
|
|
11030
11030
|
},
|
|
11031
11031
|
launch() {
|
|
11032
11032
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -11049,8 +11049,8 @@ var CodexRuntimeStrategy = class {
|
|
|
11049
11049
|
meta = getAgent("codex");
|
|
11050
11050
|
mode = "interactive";
|
|
11051
11051
|
os;
|
|
11052
|
-
constructor(
|
|
11053
|
-
this.os =
|
|
11052
|
+
constructor(os32) {
|
|
11053
|
+
this.os = os32;
|
|
11054
11054
|
}
|
|
11055
11055
|
async prepareLaunch() {
|
|
11056
11056
|
let binary = this.os.findInPath("codex");
|
|
@@ -11156,12 +11156,12 @@ var CodexRuntimeStrategy = class {
|
|
|
11156
11156
|
});
|
|
11157
11157
|
}
|
|
11158
11158
|
};
|
|
11159
|
-
function resolveNpm(
|
|
11160
|
-
return
|
|
11159
|
+
function resolveNpm(os32) {
|
|
11160
|
+
return os32.id === "win32" ? "npm.cmd" : "npm";
|
|
11161
11161
|
}
|
|
11162
|
-
async function installCodexViaNpm(
|
|
11162
|
+
async function installCodexViaNpm(os32) {
|
|
11163
11163
|
return new Promise((resolve7, reject) => {
|
|
11164
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
11164
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os32), ["install", "-g", "@openai/codex"], {
|
|
11165
11165
|
stdio: "inherit"
|
|
11166
11166
|
});
|
|
11167
11167
|
proc.on("close", (code) => {
|
|
@@ -11178,16 +11178,16 @@ async function installCodexViaNpm(os31) {
|
|
|
11178
11178
|
});
|
|
11179
11179
|
});
|
|
11180
11180
|
}
|
|
11181
|
-
function augmentNpmGlobalBin(
|
|
11181
|
+
function augmentNpmGlobalBin(os32) {
|
|
11182
11182
|
try {
|
|
11183
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
11183
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os32), ["prefix", "-g"], {
|
|
11184
11184
|
stdio: ["ignore", "pipe", "ignore"]
|
|
11185
11185
|
});
|
|
11186
11186
|
if (result.status !== 0) return;
|
|
11187
11187
|
const prefix = result.stdout.toString().trim();
|
|
11188
11188
|
if (!prefix) return;
|
|
11189
|
-
const binDir =
|
|
11190
|
-
|
|
11189
|
+
const binDir = os32.id === "win32" ? prefix : path17.join(prefix, "bin");
|
|
11190
|
+
os32.augmentPath([binDir]);
|
|
11191
11191
|
} catch {
|
|
11192
11192
|
}
|
|
11193
11193
|
}
|
|
@@ -11271,9 +11271,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
11271
11271
|
// src/agents/coderabbit/installer.ts
|
|
11272
11272
|
var import_node_child_process5 = require("child_process");
|
|
11273
11273
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
11274
|
-
async function ensureCoderabbitInstalled(
|
|
11275
|
-
if (
|
|
11276
|
-
if (
|
|
11274
|
+
async function ensureCoderabbitInstalled(os32) {
|
|
11275
|
+
if (os32.findInPath("coderabbit")) return true;
|
|
11276
|
+
if (os32.id === "win32") {
|
|
11277
11277
|
console.error(
|
|
11278
11278
|
"\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
|
|
11279
11279
|
);
|
|
@@ -11288,8 +11288,8 @@ async function ensureCoderabbitInstalled(os31) {
|
|
|
11288
11288
|
proc.on("error", () => resolve7(false));
|
|
11289
11289
|
});
|
|
11290
11290
|
if (!ok) return false;
|
|
11291
|
-
|
|
11292
|
-
return
|
|
11291
|
+
os32.augmentPath([`${os32.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
11292
|
+
return os32.findInPath("coderabbit") !== null;
|
|
11293
11293
|
}
|
|
11294
11294
|
|
|
11295
11295
|
// src/agents/coderabbit/link.ts
|
|
@@ -11316,10 +11316,10 @@ function coderabbitCredentialLocator() {
|
|
|
11316
11316
|
extract: extractLocalCoderabbitToken
|
|
11317
11317
|
};
|
|
11318
11318
|
}
|
|
11319
|
-
function coderabbitLoginLauncher(
|
|
11319
|
+
function coderabbitLoginLauncher(os32) {
|
|
11320
11320
|
return {
|
|
11321
11321
|
async ensureInstalled() {
|
|
11322
|
-
return ensureCoderabbitInstalled(
|
|
11322
|
+
return ensureCoderabbitInstalled(os32);
|
|
11323
11323
|
},
|
|
11324
11324
|
launch() {
|
|
11325
11325
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -11342,11 +11342,11 @@ function parseReview(stdout) {
|
|
|
11342
11342
|
for (const line of lines) {
|
|
11343
11343
|
const m = line.match(HUNK_LINE_RE);
|
|
11344
11344
|
if (!m) continue;
|
|
11345
|
-
const [,
|
|
11346
|
-
if (!
|
|
11345
|
+
const [, path52, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path52 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path52.trim(),
|
|
11350
11350
|
line: Number(lineNo),
|
|
11351
11351
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11352
|
message: cleanedMessage
|
|
@@ -11365,8 +11365,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
11365
11365
|
meta = getAgent("coderabbit");
|
|
11366
11366
|
mode = "batch";
|
|
11367
11367
|
os;
|
|
11368
|
-
constructor(
|
|
11369
|
-
this.os =
|
|
11368
|
+
constructor(os32) {
|
|
11369
|
+
this.os = os32;
|
|
11370
11370
|
}
|
|
11371
11371
|
getDefaultArgs() {
|
|
11372
11372
|
return ["review"];
|
|
@@ -11481,10 +11481,10 @@ function cursorCredentialLocator() {
|
|
|
11481
11481
|
extract: extractLocalCursorToken
|
|
11482
11482
|
};
|
|
11483
11483
|
}
|
|
11484
|
-
function cursorLoginLauncher(
|
|
11484
|
+
function cursorLoginLauncher(os32) {
|
|
11485
11485
|
return {
|
|
11486
11486
|
async ensureInstalled() {
|
|
11487
|
-
if (
|
|
11487
|
+
if (os32.findInPath("cursor-agent")) return true;
|
|
11488
11488
|
console.error(
|
|
11489
11489
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
11490
11490
|
);
|
|
@@ -11546,8 +11546,8 @@ var CursorRuntimeStrategy = class {
|
|
|
11546
11546
|
meta = getAgent("cursor");
|
|
11547
11547
|
mode = "interactive";
|
|
11548
11548
|
os;
|
|
11549
|
-
constructor(
|
|
11550
|
-
this.os =
|
|
11549
|
+
constructor(os32) {
|
|
11550
|
+
this.os = os32;
|
|
11551
11551
|
}
|
|
11552
11552
|
async prepareLaunch() {
|
|
11553
11553
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -11667,10 +11667,10 @@ function aiderCredentialLocator() {
|
|
|
11667
11667
|
extract: extractLocalAiderToken
|
|
11668
11668
|
};
|
|
11669
11669
|
}
|
|
11670
|
-
function aiderLoginLauncher(
|
|
11670
|
+
function aiderLoginLauncher(os32) {
|
|
11671
11671
|
return {
|
|
11672
11672
|
async ensureInstalled() {
|
|
11673
|
-
if (
|
|
11673
|
+
if (os32.findInPath("aider")) return true;
|
|
11674
11674
|
console.error(
|
|
11675
11675
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
11676
11676
|
);
|
|
@@ -11680,7 +11680,7 @@ function aiderLoginLauncher(os31) {
|
|
|
11680
11680
|
console.error(
|
|
11681
11681
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
11682
11682
|
);
|
|
11683
|
-
return (0, import_node_child_process9.spawn)(
|
|
11683
|
+
return (0, import_node_child_process9.spawn)(os32.id === "win32" ? "cmd.exe" : "sh", os32.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
11684
11684
|
stdio: "ignore"
|
|
11685
11685
|
});
|
|
11686
11686
|
}
|
|
@@ -11752,8 +11752,8 @@ var AiderRuntimeStrategy = class {
|
|
|
11752
11752
|
meta = getAgent("aider");
|
|
11753
11753
|
mode = "interactive";
|
|
11754
11754
|
os;
|
|
11755
|
-
constructor(
|
|
11756
|
-
this.os =
|
|
11755
|
+
constructor(os32) {
|
|
11756
|
+
this.os = os32;
|
|
11757
11757
|
}
|
|
11758
11758
|
async prepareLaunch() {
|
|
11759
11759
|
const binary = this.os.findInPath("aider");
|
|
@@ -11882,8 +11882,8 @@ function geminiCredentialLocator() {
|
|
|
11882
11882
|
function geminiLoginLauncher() {
|
|
11883
11883
|
return {
|
|
11884
11884
|
async ensureInstalled() {
|
|
11885
|
-
const
|
|
11886
|
-
return
|
|
11885
|
+
const os32 = createOsStrategy();
|
|
11886
|
+
return os32.findInPath("gemini") !== null;
|
|
11887
11887
|
},
|
|
11888
11888
|
launch() {
|
|
11889
11889
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -11916,8 +11916,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
11916
11916
|
meta = getAgent("gemini");
|
|
11917
11917
|
mode = "interactive";
|
|
11918
11918
|
os;
|
|
11919
|
-
constructor(
|
|
11920
|
-
this.os =
|
|
11919
|
+
constructor(os32) {
|
|
11920
|
+
this.os = os32;
|
|
11921
11921
|
}
|
|
11922
11922
|
async prepareLaunch() {
|
|
11923
11923
|
const binary = this.os.findInPath("gemini");
|
|
@@ -12017,18 +12017,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
12017
12017
|
|
|
12018
12018
|
// src/agents/registry.ts
|
|
12019
12019
|
var runtimeBuilders = {
|
|
12020
|
-
claude: (
|
|
12021
|
-
codex: (
|
|
12022
|
-
coderabbit: (
|
|
12023
|
-
cursor: (
|
|
12024
|
-
aider: (
|
|
12025
|
-
gemini: (
|
|
12020
|
+
claude: (os32) => new ClaudeRuntimeStrategy(os32),
|
|
12021
|
+
codex: (os32) => new CodexRuntimeStrategy(os32),
|
|
12022
|
+
coderabbit: (os32) => new CoderabbitRuntimeStrategy(os32),
|
|
12023
|
+
cursor: (os32) => new CursorRuntimeStrategy(os32),
|
|
12024
|
+
aider: (os32) => new AiderRuntimeStrategy(os32),
|
|
12025
|
+
gemini: (os32) => new GeminiRuntimeStrategy(os32)
|
|
12026
12026
|
};
|
|
12027
12027
|
var deployBuilders = {
|
|
12028
12028
|
claude: () => new ClaudeDeployStrategy(),
|
|
12029
12029
|
codex: () => new CodexDeployStrategy()
|
|
12030
12030
|
};
|
|
12031
|
-
function createAgentStrategy(agent,
|
|
12031
|
+
function createAgentStrategy(agent, os32 = createOsStrategy()) {
|
|
12032
12032
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
12033
12033
|
throw new Error(
|
|
12034
12034
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -12038,10 +12038,10 @@ function createAgentStrategy(agent, os31 = createOsStrategy()) {
|
|
|
12038
12038
|
if (!build) {
|
|
12039
12039
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
12040
12040
|
}
|
|
12041
|
-
return build(
|
|
12041
|
+
return build(os32);
|
|
12042
12042
|
}
|
|
12043
|
-
function createInteractiveAgentStrategy(agent,
|
|
12044
|
-
const s = createAgentStrategy(agent,
|
|
12043
|
+
function createInteractiveAgentStrategy(agent, os32 = createOsStrategy()) {
|
|
12044
|
+
const s = createAgentStrategy(agent, os32);
|
|
12045
12045
|
if (s.mode !== "interactive") {
|
|
12046
12046
|
throw new Error(
|
|
12047
12047
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -15356,6 +15356,64 @@ function buildAcpPromptBlocks(payload) {
|
|
|
15356
15356
|
return blocks;
|
|
15357
15357
|
}
|
|
15358
15358
|
|
|
15359
|
+
// src/agents/acp/onboarding.ts
|
|
15360
|
+
var fs22 = __toESM(require("fs"));
|
|
15361
|
+
var os23 = __toESM(require("os"));
|
|
15362
|
+
var path27 = __toESM(require("path"));
|
|
15363
|
+
var _onboardingSeam = {
|
|
15364
|
+
markerPath: (sessionId) => path27.join(os23.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
15365
|
+
exists: (p2) => fs22.existsSync(p2),
|
|
15366
|
+
write: (p2) => {
|
|
15367
|
+
fs22.mkdirSync(path27.dirname(p2), { recursive: true });
|
|
15368
|
+
fs22.writeFileSync(p2, "");
|
|
15369
|
+
},
|
|
15370
|
+
disabled: () => {
|
|
15371
|
+
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
15372
|
+
return !!v && v !== "0" && v.toLowerCase() !== "false";
|
|
15373
|
+
}
|
|
15374
|
+
};
|
|
15375
|
+
function buildOnboardingPrompt(cwd) {
|
|
15376
|
+
const repo = path27.basename(cwd || "") || "this project";
|
|
15377
|
+
return [
|
|
15378
|
+
"SYSTEM / BACKGROUND TASK \u2014 this message is NOT from the user. The user just",
|
|
15379
|
+
"connected this session through CodeAgent Mobile and has only seen a welcome",
|
|
15380
|
+
"card. Take the initiative and write THEIR first message: a short, warm",
|
|
15381
|
+
"onboarding welcome that you (the agent) send proactively to invite them to start.",
|
|
15382
|
+
"",
|
|
15383
|
+
"Write it for a phone screen \u2014 under ~110 words, friendly, easy to scan, a little",
|
|
15384
|
+
"energy. Cover briefly, in your own words:",
|
|
15385
|
+
"- Glad they spun up this session.",
|
|
15386
|
+
"- Through CodeAgent Mobile, agents like you get native context, persistent",
|
|
15387
|
+
" memory, and an issue tracker \u2014 powered by Beads on Dolt \u2014 out of the box, zero setup.",
|
|
15388
|
+
"- They can drive you from their phone: live preview, rich visual output, a file viewer.",
|
|
15389
|
+
`- End with a SHORT, concrete invitation tied to THIS project (working dir: ${cwd},`,
|
|
15390
|
+
` repo: "${repo}") \u2014 suggest 1\u20132 specific things you could help with here.`,
|
|
15391
|
+
"",
|
|
15392
|
+
"Rules: do NOT run any tools or shell commands \u2014 base the project hint only on the",
|
|
15393
|
+
'repo name/path above so your reply is instant. No preamble like "Sure" or "Of',
|
|
15394
|
+
'course" \u2014 start directly with the greeting. Use light markdown (one intro line +',
|
|
15395
|
+
"a few bullets). Keep it tight."
|
|
15396
|
+
].join("\n");
|
|
15397
|
+
}
|
|
15398
|
+
function maybeSendOnboardingWelcome(opts) {
|
|
15399
|
+
if (_onboardingSeam.disabled()) return;
|
|
15400
|
+
const marker = _onboardingSeam.markerPath(opts.sessionId);
|
|
15401
|
+
try {
|
|
15402
|
+
if (_onboardingSeam.exists(marker)) return;
|
|
15403
|
+
_onboardingSeam.write(marker);
|
|
15404
|
+
} catch (err) {
|
|
15405
|
+
log.trace("acpRunner", `onboarding marker check failed: ${err.message}`);
|
|
15406
|
+
return;
|
|
15407
|
+
}
|
|
15408
|
+
log.info("acpRunner", `sending first-pair onboarding welcome for session=${opts.sessionId.slice(0, 8)}`);
|
|
15409
|
+
void opts.client.prompt(buildOnboardingPrompt(opts.cwd)).catch((err) => {
|
|
15410
|
+
log.warn(
|
|
15411
|
+
"acpRunner",
|
|
15412
|
+
`onboarding welcome prompt failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
15413
|
+
);
|
|
15414
|
+
});
|
|
15415
|
+
}
|
|
15416
|
+
|
|
15359
15417
|
// src/agents/acp/promptEcho.ts
|
|
15360
15418
|
var MAX_PROMPT_CHARS = 200;
|
|
15361
15419
|
function formatPromptEchoLine(payload) {
|
|
@@ -15830,9 +15888,9 @@ function extractSelectPrompt(text) {
|
|
|
15830
15888
|
}
|
|
15831
15889
|
|
|
15832
15890
|
// src/commands/start/handlers.ts
|
|
15833
|
-
var
|
|
15834
|
-
var
|
|
15835
|
-
var
|
|
15891
|
+
var fs34 = __toESM(require("fs"));
|
|
15892
|
+
var os27 = __toESM(require("os"));
|
|
15893
|
+
var path41 = __toESM(require("path"));
|
|
15836
15894
|
var import_crypto3 = require("crypto");
|
|
15837
15895
|
var import_child_process18 = require("child_process");
|
|
15838
15896
|
|
|
@@ -15956,8 +16014,8 @@ function parsePayload2(schema, raw) {
|
|
|
15956
16014
|
}
|
|
15957
16015
|
|
|
15958
16016
|
// src/services/file-ops.service.ts
|
|
15959
|
-
var
|
|
15960
|
-
var
|
|
16017
|
+
var fs23 = __toESM(require("fs/promises"));
|
|
16018
|
+
var path29 = __toESM(require("path"));
|
|
15961
16019
|
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
15962
16020
|
var MAX_WALK_DEPTH = 6;
|
|
15963
16021
|
var MAX_VISITED_DIRS = 5e3;
|
|
@@ -15992,12 +16050,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
|
|
|
15992
16050
|
"__pycache__"
|
|
15993
16051
|
]);
|
|
15994
16052
|
function isUnder(parent, candidate) {
|
|
15995
|
-
const rel =
|
|
15996
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
16053
|
+
const rel = path29.relative(parent, candidate);
|
|
16054
|
+
return rel === "" || !rel.startsWith("..") && !path29.isAbsolute(rel);
|
|
15997
16055
|
}
|
|
15998
16056
|
async function isExistingFile(absPath) {
|
|
15999
16057
|
try {
|
|
16000
|
-
const stat3 = await
|
|
16058
|
+
const stat3 = await fs23.stat(absPath);
|
|
16001
16059
|
return stat3.isFile();
|
|
16002
16060
|
} catch {
|
|
16003
16061
|
return false;
|
|
@@ -16010,13 +16068,13 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
16010
16068
|
ctx.visited++;
|
|
16011
16069
|
let entries = [];
|
|
16012
16070
|
try {
|
|
16013
|
-
entries = await
|
|
16071
|
+
entries = await fs23.readdir(dir, { withFileTypes: true });
|
|
16014
16072
|
} catch {
|
|
16015
16073
|
return;
|
|
16016
16074
|
}
|
|
16017
16075
|
for (const e of entries) {
|
|
16018
16076
|
if (!e.isFile()) continue;
|
|
16019
|
-
const full =
|
|
16077
|
+
const full = path29.join(dir, e.name);
|
|
16020
16078
|
if (needleVariants.some((needle) => full.endsWith(needle))) {
|
|
16021
16079
|
ctx.matches.push(full);
|
|
16022
16080
|
if (ctx.matches.length >= ctx.cap) return;
|
|
@@ -16026,21 +16084,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
16026
16084
|
if (!e.isDirectory()) continue;
|
|
16027
16085
|
if (SUBDIR_IGNORE.has(e.name)) continue;
|
|
16028
16086
|
if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
|
|
16029
|
-
await walkForSuffix(
|
|
16087
|
+
await walkForSuffix(path29.join(dir, e.name), needleVariants, depth + 1, ctx);
|
|
16030
16088
|
if (ctx.matches.length >= ctx.cap) return;
|
|
16031
16089
|
}
|
|
16032
16090
|
}
|
|
16033
16091
|
async function findFile(rawPath) {
|
|
16034
16092
|
const cwd = process.cwd();
|
|
16035
|
-
if (
|
|
16036
|
-
const abs =
|
|
16093
|
+
if (path29.isAbsolute(rawPath)) {
|
|
16094
|
+
const abs = path29.normalize(rawPath);
|
|
16037
16095
|
if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
|
|
16038
16096
|
}
|
|
16039
|
-
const direct =
|
|
16097
|
+
const direct = path29.resolve(cwd, rawPath);
|
|
16040
16098
|
if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
|
|
16041
|
-
const normalized =
|
|
16099
|
+
const normalized = path29.normalize(rawPath).replace(/^[./\\]+/, "");
|
|
16042
16100
|
const needles = [
|
|
16043
|
-
`${
|
|
16101
|
+
`${path29.sep}${normalized}`,
|
|
16044
16102
|
`/${normalized}`
|
|
16045
16103
|
].filter((v, i, a) => a.indexOf(v) === i);
|
|
16046
16104
|
const ctx = { visited: 0, matches: [], cap: 16 };
|
|
@@ -16054,7 +16112,7 @@ async function findWriteTarget(rawPath) {
|
|
|
16054
16112
|
const found = await findFile(rawPath);
|
|
16055
16113
|
if (found) return found;
|
|
16056
16114
|
const cwd = process.cwd();
|
|
16057
|
-
const fallback =
|
|
16115
|
+
const fallback = path29.isAbsolute(rawPath) ? path29.normalize(rawPath) : path29.resolve(cwd, rawPath);
|
|
16058
16116
|
if (!isUnder(cwd, fallback)) return null;
|
|
16059
16117
|
return fallback;
|
|
16060
16118
|
}
|
|
@@ -16071,11 +16129,11 @@ async function readProjectFile(rawPath) {
|
|
|
16071
16129
|
if (!abs) {
|
|
16072
16130
|
return { error: `File not found in the project tree: ${rawPath}` };
|
|
16073
16131
|
}
|
|
16074
|
-
const stat3 = await
|
|
16132
|
+
const stat3 = await fs23.stat(abs);
|
|
16075
16133
|
if (stat3.size > MAX_FILE_BYTES) {
|
|
16076
16134
|
return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
|
|
16077
16135
|
}
|
|
16078
|
-
const buf = await
|
|
16136
|
+
const buf = await fs23.readFile(abs);
|
|
16079
16137
|
if (looksBinary(buf)) {
|
|
16080
16138
|
return { error: "Binary file \u2014 refusing to open in a code editor." };
|
|
16081
16139
|
}
|
|
@@ -16094,8 +16152,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
16094
16152
|
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
|
|
16095
16153
|
return { error: "Content too large." };
|
|
16096
16154
|
}
|
|
16097
|
-
await
|
|
16098
|
-
await
|
|
16155
|
+
await fs23.mkdir(path29.dirname(abs), { recursive: true });
|
|
16156
|
+
await fs23.writeFile(abs, content, "utf-8");
|
|
16099
16157
|
return { ok: true };
|
|
16100
16158
|
} catch (e) {
|
|
16101
16159
|
const msg = e instanceof Error ? e.message : "Write failed";
|
|
@@ -16106,8 +16164,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
16106
16164
|
// src/services/project-ops.service.ts
|
|
16107
16165
|
var import_child_process9 = require("child_process");
|
|
16108
16166
|
var import_util2 = require("util");
|
|
16109
|
-
var
|
|
16110
|
-
var
|
|
16167
|
+
var fs24 = __toESM(require("fs/promises"));
|
|
16168
|
+
var path30 = __toESM(require("path"));
|
|
16111
16169
|
var execFileP3 = (0, import_util2.promisify)(import_child_process9.execFile);
|
|
16112
16170
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
16113
16171
|
"node_modules",
|
|
@@ -16155,7 +16213,7 @@ async function listProjectFiles(opts = {}) {
|
|
|
16155
16213
|
}
|
|
16156
16214
|
let entries = [];
|
|
16157
16215
|
try {
|
|
16158
|
-
entries = await
|
|
16216
|
+
entries = await fs24.readdir(dir, { withFileTypes: true });
|
|
16159
16217
|
} catch {
|
|
16160
16218
|
return;
|
|
16161
16219
|
}
|
|
@@ -16165,18 +16223,18 @@ async function listProjectFiles(opts = {}) {
|
|
|
16165
16223
|
return;
|
|
16166
16224
|
}
|
|
16167
16225
|
if (PROJECT_IGNORE.has(e.name)) continue;
|
|
16168
|
-
const full =
|
|
16226
|
+
const full = path30.join(dir, e.name);
|
|
16169
16227
|
if (e.isDirectory()) {
|
|
16170
16228
|
if (depth >= 12) continue;
|
|
16171
16229
|
await walk(full, depth + 1);
|
|
16172
16230
|
} else if (e.isFile()) {
|
|
16173
|
-
const rel =
|
|
16231
|
+
const rel = path30.relative(root, full);
|
|
16174
16232
|
if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
|
|
16175
16233
|
continue;
|
|
16176
16234
|
}
|
|
16177
16235
|
let size = 0;
|
|
16178
16236
|
try {
|
|
16179
|
-
const st3 = await
|
|
16237
|
+
const st3 = await fs24.stat(full);
|
|
16180
16238
|
size = st3.size;
|
|
16181
16239
|
} catch {
|
|
16182
16240
|
}
|
|
@@ -16278,8 +16336,8 @@ async function gitStatus(cwd) {
|
|
|
16278
16336
|
let hasMergeInProgress = false;
|
|
16279
16337
|
try {
|
|
16280
16338
|
const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
|
|
16281
|
-
const mergeHead =
|
|
16282
|
-
await
|
|
16339
|
+
const mergeHead = path30.isAbsolute(gitDir) ? path30.join(gitDir, "MERGE_HEAD") : path30.join(root, gitDir, "MERGE_HEAD");
|
|
16340
|
+
await fs24.access(mergeHead);
|
|
16283
16341
|
hasMergeInProgress = true;
|
|
16284
16342
|
} catch {
|
|
16285
16343
|
}
|
|
@@ -16425,7 +16483,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
16425
16483
|
}
|
|
16426
16484
|
let content = "";
|
|
16427
16485
|
try {
|
|
16428
|
-
content = await
|
|
16486
|
+
content = await fs24.readFile(path30.join(cwd, f.path), "utf8");
|
|
16429
16487
|
} catch {
|
|
16430
16488
|
continue;
|
|
16431
16489
|
}
|
|
@@ -16449,14 +16507,14 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
16449
16507
|
|
|
16450
16508
|
// src/services/apply-file-review.service.ts
|
|
16451
16509
|
var import_child_process10 = require("child_process");
|
|
16452
|
-
var
|
|
16453
|
-
var
|
|
16510
|
+
var fs25 = __toESM(require("fs"));
|
|
16511
|
+
var path31 = __toESM(require("path"));
|
|
16454
16512
|
async function applyFileReview(workingDir, filePath, action) {
|
|
16455
|
-
if (filePath.includes("..") ||
|
|
16513
|
+
if (filePath.includes("..") || path31.isAbsolute(filePath)) {
|
|
16456
16514
|
return { ok: false, action, filePath, error: "invalid file path" };
|
|
16457
16515
|
}
|
|
16458
|
-
const absFile =
|
|
16459
|
-
const repoRoot = findGitRoot(
|
|
16516
|
+
const absFile = path31.resolve(workingDir, filePath);
|
|
16517
|
+
const repoRoot = findGitRoot(path31.dirname(absFile));
|
|
16460
16518
|
if (!repoRoot) {
|
|
16461
16519
|
return {
|
|
16462
16520
|
ok: false,
|
|
@@ -16465,7 +16523,7 @@ async function applyFileReview(workingDir, filePath, action) {
|
|
|
16465
16523
|
error: `no enclosing git repo for ${filePath}`
|
|
16466
16524
|
};
|
|
16467
16525
|
}
|
|
16468
|
-
const relInRepo =
|
|
16526
|
+
const relInRepo = path31.relative(repoRoot, absFile);
|
|
16469
16527
|
if (!relInRepo || relInRepo.startsWith("..")) {
|
|
16470
16528
|
return { ok: false, action, filePath, error: "path escapes repo root" };
|
|
16471
16529
|
}
|
|
@@ -16514,17 +16572,17 @@ function runGit(cwd, args2) {
|
|
|
16514
16572
|
});
|
|
16515
16573
|
}
|
|
16516
16574
|
function findGitRoot(startDir) {
|
|
16517
|
-
let dir =
|
|
16575
|
+
let dir = path31.resolve(startDir);
|
|
16518
16576
|
const seen = /* @__PURE__ */ new Set();
|
|
16519
16577
|
for (let i = 0; i < 256; i++) {
|
|
16520
16578
|
if (seen.has(dir)) return null;
|
|
16521
16579
|
seen.add(dir);
|
|
16522
16580
|
try {
|
|
16523
|
-
const stat3 =
|
|
16581
|
+
const stat3 = fs25.statSync(path31.join(dir, ".git"), { throwIfNoEntry: false });
|
|
16524
16582
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
16525
16583
|
} catch {
|
|
16526
16584
|
}
|
|
16527
|
-
const parent =
|
|
16585
|
+
const parent = path31.dirname(dir);
|
|
16528
16586
|
if (parent === dir) return null;
|
|
16529
16587
|
dir = parent;
|
|
16530
16588
|
}
|
|
@@ -16533,8 +16591,8 @@ function findGitRoot(startDir) {
|
|
|
16533
16591
|
|
|
16534
16592
|
// src/commands/link.ts
|
|
16535
16593
|
var import_node_crypto6 = require("crypto");
|
|
16536
|
-
var
|
|
16537
|
-
var
|
|
16594
|
+
var fs26 = __toESM(require("fs"));
|
|
16595
|
+
var path32 = __toESM(require("path"));
|
|
16538
16596
|
var import_chokidar = __toESM(require("chokidar"));
|
|
16539
16597
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
16540
16598
|
|
|
@@ -16713,7 +16771,7 @@ function parseLinkArgs(args2) {
|
|
|
16713
16771
|
if (apiKeyFileArg) {
|
|
16714
16772
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
16715
16773
|
try {
|
|
16716
|
-
apiKey =
|
|
16774
|
+
apiKey = fs26.readFileSync(path32.resolve(filePath), "utf8").trim();
|
|
16717
16775
|
} catch (err) {
|
|
16718
16776
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
16719
16777
|
}
|
|
@@ -16817,7 +16875,7 @@ async function link(args2 = []) {
|
|
|
16817
16875
|
return;
|
|
16818
16876
|
}
|
|
16819
16877
|
if (parsed.tokenFile) {
|
|
16820
|
-
const credential =
|
|
16878
|
+
const credential = fs26.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
|
|
16821
16879
|
if (!credential) {
|
|
16822
16880
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
16823
16881
|
process.exit(1);
|
|
@@ -17394,8 +17452,8 @@ function activePreviewSessionIds() {
|
|
|
17394
17452
|
|
|
17395
17453
|
// src/beads/bd-adapter.ts
|
|
17396
17454
|
var import_child_process13 = require("child_process");
|
|
17397
|
-
var
|
|
17398
|
-
var
|
|
17455
|
+
var fs30 = __toESM(require("fs"));
|
|
17456
|
+
var path36 = __toESM(require("path"));
|
|
17399
17457
|
var BD_PACKAGE = "@beads/bd";
|
|
17400
17458
|
function resolveBundledBdBinary() {
|
|
17401
17459
|
return _resolveSeam.resolveBundled();
|
|
@@ -17407,11 +17465,11 @@ function _defaultResolveBundled() {
|
|
|
17407
17465
|
} catch {
|
|
17408
17466
|
return null;
|
|
17409
17467
|
}
|
|
17410
|
-
const binDir =
|
|
17468
|
+
const binDir = path36.join(path36.dirname(pkgJsonPath), "bin");
|
|
17411
17469
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17412
|
-
const binaryPath =
|
|
17470
|
+
const binaryPath = path36.join(binDir, binaryName);
|
|
17413
17471
|
try {
|
|
17414
|
-
|
|
17472
|
+
fs30.accessSync(binaryPath, fs30.constants.F_OK);
|
|
17415
17473
|
return binaryPath;
|
|
17416
17474
|
} catch {
|
|
17417
17475
|
return null;
|
|
@@ -17421,13 +17479,13 @@ function resolveBdOnPath() {
|
|
|
17421
17479
|
return _resolveSeam.resolveOnPath();
|
|
17422
17480
|
}
|
|
17423
17481
|
function _defaultResolveOnPath() {
|
|
17424
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17482
|
+
const dirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
|
|
17425
17483
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17426
17484
|
for (const dir of dirs) {
|
|
17427
17485
|
for (const candidate of candidates) {
|
|
17428
|
-
const full =
|
|
17486
|
+
const full = path36.join(dir, candidate);
|
|
17429
17487
|
try {
|
|
17430
|
-
|
|
17488
|
+
fs30.accessSync(full, fs30.constants.F_OK);
|
|
17431
17489
|
return full;
|
|
17432
17490
|
} catch {
|
|
17433
17491
|
}
|
|
@@ -17463,6 +17521,9 @@ function _defaultSpawn(binaryPath, args2, opts) {
|
|
|
17463
17521
|
proc.on("close", (code) => resolve7({ code: code ?? -1, stdout, stderr }));
|
|
17464
17522
|
});
|
|
17465
17523
|
}
|
|
17524
|
+
var _adapterSeam = {
|
|
17525
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms))
|
|
17526
|
+
};
|
|
17466
17527
|
var BdAdapter = class {
|
|
17467
17528
|
constructor(opts = {}) {
|
|
17468
17529
|
this.opts = opts;
|
|
@@ -17513,7 +17574,13 @@ var BdAdapter = class {
|
|
|
17513
17574
|
"beads",
|
|
17514
17575
|
`bd ${args2.join(" ")} (cwd=${this.opts.cwd ?? process.cwd()}, shared-server)`
|
|
17515
17576
|
);
|
|
17516
|
-
|
|
17577
|
+
let res = await _spawnSeam.run(binary, args2, { cwd: this.opts.cwd, env });
|
|
17578
|
+
for (let attempt = 1; attempt <= 3 && res.code === -1 && res.stderr.includes("ENOENT"); attempt++) {
|
|
17579
|
+
log.info("beads", `bd ${args2[0]} spawn ENOENT (transient binary) \u2014 retry ${attempt}/3`);
|
|
17580
|
+
await _adapterSeam.sleep(750 * attempt);
|
|
17581
|
+
res = await _spawnSeam.run(binary, args2, { cwd: this.opts.cwd, env });
|
|
17582
|
+
}
|
|
17583
|
+
return res;
|
|
17517
17584
|
}
|
|
17518
17585
|
/**
|
|
17519
17586
|
* `bd ready --json` → typed issue array. `bd list --json` shares the shape,
|
|
@@ -17584,9 +17651,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17584
17651
|
|
|
17585
17652
|
// src/beads/provisioner.ts
|
|
17586
17653
|
var import_child_process17 = require("child_process");
|
|
17587
|
-
var
|
|
17588
|
-
var
|
|
17589
|
-
var
|
|
17654
|
+
var fs33 = __toESM(require("fs"));
|
|
17655
|
+
var os26 = __toESM(require("os"));
|
|
17656
|
+
var path39 = __toESM(require("path"));
|
|
17590
17657
|
|
|
17591
17658
|
// src/beads/install-bd.ts
|
|
17592
17659
|
var import_child_process14 = require("child_process");
|
|
@@ -17651,9 +17718,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17651
17718
|
|
|
17652
17719
|
// src/beads/install-dolt.ts
|
|
17653
17720
|
var import_child_process15 = require("child_process");
|
|
17654
|
-
var
|
|
17655
|
-
var
|
|
17656
|
-
var
|
|
17721
|
+
var fs31 = __toESM(require("fs"));
|
|
17722
|
+
var os25 = __toESM(require("os"));
|
|
17723
|
+
var path37 = __toESM(require("path"));
|
|
17657
17724
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17658
17725
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17659
17726
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -17693,11 +17760,11 @@ function resolveDoltInstallStrategy(platform2) {
|
|
|
17693
17760
|
}
|
|
17694
17761
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17695
17762
|
function doltPlatformTuple(platform2, arch) {
|
|
17696
|
-
const
|
|
17763
|
+
const os32 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
|
|
17697
17764
|
const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
17698
17765
|
if (!a) return null;
|
|
17699
|
-
if (
|
|
17700
|
-
return `${
|
|
17766
|
+
if (os32 === "windows" && a !== "amd64") return null;
|
|
17767
|
+
return `${os32}-${a}`;
|
|
17701
17768
|
}
|
|
17702
17769
|
function resolveDoltTarballStrategy(targetDir, platform2, arch) {
|
|
17703
17770
|
const tuple = doltPlatformTuple(platform2, arch);
|
|
@@ -17742,14 +17809,14 @@ async function installDoltToDir(targetDir, platform2 = process.platform, arch =
|
|
|
17742
17809
|
return result;
|
|
17743
17810
|
}
|
|
17744
17811
|
var _doltPathSeam = {
|
|
17745
|
-
homedir: () =>
|
|
17812
|
+
homedir: () => os25.homedir(),
|
|
17746
17813
|
getPath: () => process.env.PATH ?? "",
|
|
17747
17814
|
setPath: (p2) => {
|
|
17748
17815
|
process.env.PATH = p2;
|
|
17749
17816
|
},
|
|
17750
17817
|
exists: (p2) => {
|
|
17751
17818
|
try {
|
|
17752
|
-
|
|
17819
|
+
fs31.accessSync(p2, fs31.constants.F_OK);
|
|
17753
17820
|
return true;
|
|
17754
17821
|
} catch {
|
|
17755
17822
|
return false;
|
|
@@ -17760,7 +17827,7 @@ function doltBinaryNames(platform2) {
|
|
|
17760
17827
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17761
17828
|
}
|
|
17762
17829
|
function knownDoltDirs(platform2) {
|
|
17763
|
-
const P3 = platform2 === "win32" ?
|
|
17830
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
17764
17831
|
const home = _doltPathSeam.homedir();
|
|
17765
17832
|
if (platform2 === "win32") {
|
|
17766
17833
|
return [
|
|
@@ -17776,7 +17843,7 @@ function knownDoltDirs(platform2) {
|
|
|
17776
17843
|
].filter(Boolean);
|
|
17777
17844
|
}
|
|
17778
17845
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17779
|
-
const P3 = platform2 === "win32" ?
|
|
17846
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
17780
17847
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
17781
17848
|
const names = doltBinaryNames(platform2);
|
|
17782
17849
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17887,8 +17954,8 @@ async function ensureSharedServer(adapter) {
|
|
|
17887
17954
|
// src/beads/project-key.ts
|
|
17888
17955
|
var import_child_process16 = require("child_process");
|
|
17889
17956
|
var crypto2 = __toESM(require("crypto"));
|
|
17890
|
-
var
|
|
17891
|
-
var
|
|
17957
|
+
var fs32 = __toESM(require("fs"));
|
|
17958
|
+
var path38 = __toESM(require("path"));
|
|
17892
17959
|
function normalizeOrigin(raw) {
|
|
17893
17960
|
const trimmed = raw.trim();
|
|
17894
17961
|
if (!trimmed) return null;
|
|
@@ -17914,17 +17981,17 @@ function normalizeOrigin(raw) {
|
|
|
17914
17981
|
return `${host}/${pathPart}`;
|
|
17915
17982
|
}
|
|
17916
17983
|
function findRepoRoot(cwd) {
|
|
17917
|
-
let dir =
|
|
17984
|
+
let dir = path38.resolve(cwd);
|
|
17918
17985
|
const seen = /* @__PURE__ */ new Set();
|
|
17919
17986
|
for (let i = 0; i < 256; i++) {
|
|
17920
17987
|
if (seen.has(dir)) return null;
|
|
17921
17988
|
seen.add(dir);
|
|
17922
17989
|
try {
|
|
17923
|
-
const stat3 =
|
|
17990
|
+
const stat3 = fs32.statSync(path38.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17924
17991
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17925
17992
|
} catch {
|
|
17926
17993
|
}
|
|
17927
|
-
const parent =
|
|
17994
|
+
const parent = path38.dirname(dir);
|
|
17928
17995
|
if (parent === dir) return null;
|
|
17929
17996
|
dir = parent;
|
|
17930
17997
|
}
|
|
@@ -17935,7 +18002,7 @@ var _execSeam2 = {
|
|
|
17935
18002
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
17936
18003
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17937
18004
|
},
|
|
17938
|
-
realpath: (p2) =>
|
|
18005
|
+
realpath: (p2) => fs32.realpathSync(p2)
|
|
17939
18006
|
};
|
|
17940
18007
|
function readOrigin(cwd) {
|
|
17941
18008
|
try {
|
|
@@ -17964,7 +18031,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
17964
18031
|
} catch {
|
|
17965
18032
|
}
|
|
17966
18033
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17967
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18034
|
+
return { projectKey: `path:${hash}`, projectLabel: path38.basename(real) || "project" };
|
|
17968
18035
|
}
|
|
17969
18036
|
|
|
17970
18037
|
// src/beads/project-prefix.ts
|
|
@@ -17993,8 +18060,6 @@ var _provisionSeam = {
|
|
|
17993
18060
|
installDolt,
|
|
17994
18061
|
/** No-sudo fallback: extract the dolt tarball/zip into a user-writable dir. */
|
|
17995
18062
|
installDoltToDir,
|
|
17996
|
-
/** Async sleep — behind the seam so the spawn-retry backoff is instant in tests. */
|
|
17997
|
-
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
17998
18063
|
// Probe dolt on PATH AND auto-prepend a known install dir if found off-PATH
|
|
17999
18064
|
// (codespace: official install.sh drops dolt in /usr/local/bin, which the
|
|
18000
18065
|
// bundled-node CLI's PATH can omit — mirrors the bd-on-PATH symlink fix).
|
|
@@ -18008,17 +18073,17 @@ var _provisionSeam = {
|
|
|
18008
18073
|
};
|
|
18009
18074
|
var _linkSeam = {
|
|
18010
18075
|
platform: () => process.platform,
|
|
18011
|
-
homedir: () =>
|
|
18076
|
+
homedir: () => os26.homedir(),
|
|
18012
18077
|
isWritableDir: (dir) => {
|
|
18013
18078
|
try {
|
|
18014
|
-
|
|
18079
|
+
fs33.accessSync(dir, fs33.constants.W_OK);
|
|
18015
18080
|
return true;
|
|
18016
18081
|
} catch {
|
|
18017
18082
|
return false;
|
|
18018
18083
|
}
|
|
18019
18084
|
},
|
|
18020
18085
|
ensureDir: (dir) => {
|
|
18021
|
-
|
|
18086
|
+
fs33.mkdirSync(dir, { recursive: true });
|
|
18022
18087
|
},
|
|
18023
18088
|
/**
|
|
18024
18089
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18039,12 +18104,12 @@ var _linkSeam = {
|
|
|
18039
18104
|
* which `linkBdOntoPath` creates if missing.
|
|
18040
18105
|
*/
|
|
18041
18106
|
cliBinDir: () => {
|
|
18042
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18107
|
+
const pathDirs = (process.env.PATH ?? "").split(path39.delimiter).filter(Boolean);
|
|
18043
18108
|
const home = _linkSeam.homedir();
|
|
18044
|
-
const localBin = home ?
|
|
18109
|
+
const localBin = home ? path39.join(home, ".local", "bin") : null;
|
|
18045
18110
|
const candidates = [];
|
|
18046
18111
|
try {
|
|
18047
|
-
candidates.push(
|
|
18112
|
+
candidates.push(path39.dirname(process.execPath));
|
|
18048
18113
|
} catch {
|
|
18049
18114
|
}
|
|
18050
18115
|
if (localBin) candidates.push(localBin);
|
|
@@ -18052,9 +18117,9 @@ var _linkSeam = {
|
|
|
18052
18117
|
const entry = process.argv[1];
|
|
18053
18118
|
if (entry) {
|
|
18054
18119
|
try {
|
|
18055
|
-
candidates.push(
|
|
18120
|
+
candidates.push(path39.dirname(fs33.realpathSync(entry)));
|
|
18056
18121
|
} catch {
|
|
18057
|
-
candidates.push(
|
|
18122
|
+
candidates.push(path39.dirname(entry));
|
|
18058
18123
|
}
|
|
18059
18124
|
}
|
|
18060
18125
|
const onPathWritable = candidates.find(
|
|
@@ -18066,20 +18131,20 @@ var _linkSeam = {
|
|
|
18066
18131
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18067
18132
|
readlink: (linkPath) => {
|
|
18068
18133
|
try {
|
|
18069
|
-
return
|
|
18134
|
+
return fs33.readlinkSync(linkPath);
|
|
18070
18135
|
} catch {
|
|
18071
18136
|
return null;
|
|
18072
18137
|
}
|
|
18073
18138
|
},
|
|
18074
|
-
unlink: (linkPath) =>
|
|
18075
|
-
symlink: (target, linkPath) =>
|
|
18139
|
+
unlink: (linkPath) => fs33.unlinkSync(linkPath),
|
|
18140
|
+
symlink: (target, linkPath) => fs33.symlinkSync(target, linkPath)
|
|
18076
18141
|
};
|
|
18077
18142
|
function linkBdOntoPath(binaryPath) {
|
|
18078
18143
|
if (_linkSeam.platform() === "win32") return;
|
|
18079
18144
|
const binDir = _linkSeam.cliBinDir();
|
|
18080
18145
|
if (!binDir) return;
|
|
18081
18146
|
_linkSeam.ensureDir(binDir);
|
|
18082
|
-
const linkPath =
|
|
18147
|
+
const linkPath = path39.join(binDir, "bd");
|
|
18083
18148
|
if (linkPath === binaryPath) return;
|
|
18084
18149
|
const current = _linkSeam.readlink(linkPath);
|
|
18085
18150
|
if (current === binaryPath) return;
|
|
@@ -18194,15 +18259,7 @@ async function setupAgents(bd, agents) {
|
|
|
18194
18259
|
continue;
|
|
18195
18260
|
}
|
|
18196
18261
|
log.info("beads", `wiring agent natively: bd setup ${recipe} --global`);
|
|
18197
|
-
|
|
18198
|
-
for (let attempt = 1; setup.code === -1 && attempt <= 2; attempt++) {
|
|
18199
|
-
log.info(
|
|
18200
|
-
"beads",
|
|
18201
|
-
`bd setup ${recipe} --global spawn failed (transient: ${setup.stderr.slice(0, 80)}) \u2014 retry ${attempt}/2`
|
|
18202
|
-
);
|
|
18203
|
-
await _provisionSeam.sleep(1500);
|
|
18204
|
-
setup = await bd.run(["setup", recipe, "--global"]);
|
|
18205
|
-
}
|
|
18262
|
+
const setup = await bd.run(["setup", recipe, "--global"]);
|
|
18206
18263
|
if (setup.code === 0) {
|
|
18207
18264
|
wired.push(recipe);
|
|
18208
18265
|
} else {
|
|
@@ -18228,7 +18285,7 @@ function dedupeRecipes(agents) {
|
|
|
18228
18285
|
|
|
18229
18286
|
// src/beads/watcher.ts
|
|
18230
18287
|
var crypto4 = __toESM(require("crypto"));
|
|
18231
|
-
var
|
|
18288
|
+
var path40 = __toESM(require("path"));
|
|
18232
18289
|
|
|
18233
18290
|
// src/services/file-watcher/transport.ts
|
|
18234
18291
|
var http5 = __toESM(require("http"));
|
|
@@ -18303,7 +18360,7 @@ var BeadsWatcher = class {
|
|
|
18303
18360
|
constructor(opts) {
|
|
18304
18361
|
this.opts = opts;
|
|
18305
18362
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18306
|
-
this.feedPath = opts.feedPath ??
|
|
18363
|
+
this.feedPath = opts.feedPath ?? path40.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
|
|
18307
18364
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18308
18365
|
}
|
|
18309
18366
|
opts;
|
|
@@ -18581,7 +18638,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18581
18638
|
function cleanupAttachmentTempFiles() {
|
|
18582
18639
|
for (const p2 of pendingAttachmentFiles) {
|
|
18583
18640
|
try {
|
|
18584
|
-
|
|
18641
|
+
fs34.unlinkSync(p2);
|
|
18585
18642
|
} catch {
|
|
18586
18643
|
}
|
|
18587
18644
|
}
|
|
@@ -18590,8 +18647,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18590
18647
|
function saveFilesTemp(files) {
|
|
18591
18648
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18592
18649
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18593
|
-
const tmpPath =
|
|
18594
|
-
|
|
18650
|
+
const tmpPath = path41.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18651
|
+
fs34.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18595
18652
|
pendingAttachmentFiles.add(tmpPath);
|
|
18596
18653
|
return tmpPath;
|
|
18597
18654
|
});
|
|
@@ -18611,7 +18668,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18611
18668
|
setTimeout(() => {
|
|
18612
18669
|
for (const p2 of paths) {
|
|
18613
18670
|
try {
|
|
18614
|
-
|
|
18671
|
+
fs34.unlinkSync(p2);
|
|
18615
18672
|
} catch {
|
|
18616
18673
|
}
|
|
18617
18674
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19194,8 +19251,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19194
19251
|
if (args2.length === 0) return detection;
|
|
19195
19252
|
const binName = args2[0];
|
|
19196
19253
|
if (binName.startsWith("-")) return detection;
|
|
19197
|
-
const binPath =
|
|
19198
|
-
if (!
|
|
19254
|
+
const binPath = path41.join(cwd, "node_modules", ".bin", binName);
|
|
19255
|
+
if (!fs34.existsSync(binPath)) return detection;
|
|
19199
19256
|
return {
|
|
19200
19257
|
...detection,
|
|
19201
19258
|
command: binPath,
|
|
@@ -19625,9 +19682,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19625
19682
|
|
|
19626
19683
|
// src/services/file-watcher.service.ts
|
|
19627
19684
|
var import_child_process19 = require("child_process");
|
|
19628
|
-
var
|
|
19629
|
-
var
|
|
19630
|
-
var
|
|
19685
|
+
var fs35 = __toESM(require("fs"));
|
|
19686
|
+
var os28 = __toESM(require("os"));
|
|
19687
|
+
var path42 = __toESM(require("path"));
|
|
19631
19688
|
var import_ignore = __toESM(require("ignore"));
|
|
19632
19689
|
|
|
19633
19690
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19737,10 +19794,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19737
19794
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19738
19795
|
/[\\/]Templates([\\/]|$)/i
|
|
19739
19796
|
];
|
|
19740
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
19797
|
+
function isUnsafeWindowsWatchRoot(dir, homedir24) {
|
|
19741
19798
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19742
19799
|
const cwd = norm(dir);
|
|
19743
|
-
const home = norm(
|
|
19800
|
+
const home = norm(homedir24);
|
|
19744
19801
|
if (cwd === home) return true;
|
|
19745
19802
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19746
19803
|
const sysRoots = [
|
|
@@ -19770,18 +19827,18 @@ var _findGitRootSeam = {
|
|
|
19770
19827
|
resolve: _defaultFindGitRoot
|
|
19771
19828
|
};
|
|
19772
19829
|
function _defaultFindGitRoot(startDir) {
|
|
19773
|
-
let dir =
|
|
19830
|
+
let dir = path42.resolve(startDir);
|
|
19774
19831
|
const seen = /* @__PURE__ */ new Set();
|
|
19775
19832
|
for (let i = 0; i < 256; i++) {
|
|
19776
19833
|
if (seen.has(dir)) return null;
|
|
19777
19834
|
seen.add(dir);
|
|
19778
19835
|
try {
|
|
19779
|
-
const gitPath =
|
|
19780
|
-
const stat3 =
|
|
19836
|
+
const gitPath = path42.join(dir, ".git");
|
|
19837
|
+
const stat3 = fs35.statSync(gitPath, { throwIfNoEntry: false });
|
|
19781
19838
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19782
19839
|
} catch {
|
|
19783
19840
|
}
|
|
19784
|
-
const parent =
|
|
19841
|
+
const parent = path42.dirname(dir);
|
|
19785
19842
|
if (parent === dir) return null;
|
|
19786
19843
|
dir = parent;
|
|
19787
19844
|
}
|
|
@@ -19839,7 +19896,7 @@ var FileWatcherService = class {
|
|
|
19839
19896
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
19840
19897
|
}
|
|
19841
19898
|
const isWin = process.platform === "win32";
|
|
19842
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
19899
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os28.homedir())) {
|
|
19843
19900
|
log.warn(
|
|
19844
19901
|
"fileWatcher",
|
|
19845
19902
|
`refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
|
|
@@ -20026,7 +20083,7 @@ var FileWatcherService = class {
|
|
|
20026
20083
|
}
|
|
20027
20084
|
async emitForFile(absPath, changeType) {
|
|
20028
20085
|
if (this.stopped) return;
|
|
20029
|
-
const fileDir =
|
|
20086
|
+
const fileDir = path42.dirname(absPath);
|
|
20030
20087
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20031
20088
|
if (gitRoot === void 0) {
|
|
20032
20089
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20039,19 +20096,19 @@ var FileWatcherService = class {
|
|
|
20039
20096
|
);
|
|
20040
20097
|
return;
|
|
20041
20098
|
}
|
|
20042
|
-
const relPathInRepo =
|
|
20099
|
+
const relPathInRepo = path42.relative(gitRoot, absPath);
|
|
20043
20100
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20044
20101
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20045
20102
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20046
20103
|
log.trace(
|
|
20047
20104
|
"fileWatcher",
|
|
20048
|
-
`${relPathInRepo} ignored by ${
|
|
20105
|
+
`${relPathInRepo} ignored by ${path42.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20049
20106
|
);
|
|
20050
20107
|
return;
|
|
20051
20108
|
}
|
|
20052
20109
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20053
|
-
const repoPath =
|
|
20054
|
-
const repoName =
|
|
20110
|
+
const repoPath = path42.relative(this.opts.workingDir, gitRoot);
|
|
20111
|
+
const repoName = path42.basename(gitRoot);
|
|
20055
20112
|
let diffText = "";
|
|
20056
20113
|
let fileStatus = "modified";
|
|
20057
20114
|
if (changeType === "unlink") {
|
|
@@ -20226,7 +20283,7 @@ var FileWatcherService = class {
|
|
|
20226
20283
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20227
20284
|
let entries;
|
|
20228
20285
|
try {
|
|
20229
|
-
entries =
|
|
20286
|
+
entries = fs35.readdirSync(dir, { withFileTypes: true });
|
|
20230
20287
|
} catch {
|
|
20231
20288
|
return;
|
|
20232
20289
|
}
|
|
@@ -20235,16 +20292,16 @@ var FileWatcherService = class {
|
|
|
20235
20292
|
);
|
|
20236
20293
|
if (gitignoreEntry) {
|
|
20237
20294
|
try {
|
|
20238
|
-
const body =
|
|
20239
|
-
const rel =
|
|
20295
|
+
const body = fs35.readFileSync(path42.join(dir, ".gitignore"), "utf8");
|
|
20296
|
+
const rel = path42.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20240
20297
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20241
20298
|
const trimmed = line.trim();
|
|
20242
20299
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20243
20300
|
if (!rel) return line;
|
|
20244
20301
|
if (trimmed.startsWith("!")) {
|
|
20245
|
-
return "!" +
|
|
20302
|
+
return "!" + path42.posix.join(rel, trimmed.slice(1));
|
|
20246
20303
|
}
|
|
20247
|
-
return
|
|
20304
|
+
return path42.posix.join(rel, trimmed);
|
|
20248
20305
|
}).join("\n");
|
|
20249
20306
|
matcher.add(prefixed);
|
|
20250
20307
|
} catch {
|
|
@@ -20253,7 +20310,7 @@ var FileWatcherService = class {
|
|
|
20253
20310
|
for (const entry of entries) {
|
|
20254
20311
|
if (!entry.isDirectory()) continue;
|
|
20255
20312
|
if (entry.name === ".git") continue;
|
|
20256
|
-
const childAbs =
|
|
20313
|
+
const childAbs = path42.join(dir, entry.name);
|
|
20257
20314
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20258
20315
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20259
20316
|
}
|
|
@@ -20423,7 +20480,7 @@ var import_crypto4 = require("crypto");
|
|
|
20423
20480
|
|
|
20424
20481
|
// src/services/turn-files/git-changeset.ts
|
|
20425
20482
|
var import_child_process20 = require("child_process");
|
|
20426
|
-
var
|
|
20483
|
+
var path43 = __toESM(require("path"));
|
|
20427
20484
|
async function collectRepoChangeset(opts) {
|
|
20428
20485
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20429
20486
|
if (status2 === null) return null;
|
|
@@ -20534,7 +20591,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20534
20591
|
});
|
|
20535
20592
|
}
|
|
20536
20593
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20537
|
-
const
|
|
20594
|
+
const fs41 = await import("fs/promises");
|
|
20538
20595
|
const out2 = [];
|
|
20539
20596
|
await walk(workingDir, 0);
|
|
20540
20597
|
return out2;
|
|
@@ -20542,7 +20599,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20542
20599
|
if (depth > maxDepth) return;
|
|
20543
20600
|
let entries = [];
|
|
20544
20601
|
try {
|
|
20545
|
-
const dirents = await
|
|
20602
|
+
const dirents = await fs41.readdir(dir, { withFileTypes: true });
|
|
20546
20603
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20547
20604
|
} catch {
|
|
20548
20605
|
return;
|
|
@@ -20553,8 +20610,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20553
20610
|
if (hasGit) {
|
|
20554
20611
|
out2.push({
|
|
20555
20612
|
repoRoot: dir,
|
|
20556
|
-
repoPath:
|
|
20557
|
-
repoName:
|
|
20613
|
+
repoPath: path43.relative(workingDir, dir),
|
|
20614
|
+
repoName: path43.basename(dir)
|
|
20558
20615
|
});
|
|
20559
20616
|
return;
|
|
20560
20617
|
}
|
|
@@ -20562,14 +20619,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20562
20619
|
if (!entry.isDirectory) continue;
|
|
20563
20620
|
if (entry.name === "node_modules") continue;
|
|
20564
20621
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20565
|
-
await walk(
|
|
20622
|
+
await walk(path43.join(dir, entry.name), depth + 1);
|
|
20566
20623
|
}
|
|
20567
20624
|
}
|
|
20568
20625
|
}
|
|
20569
20626
|
|
|
20570
20627
|
// src/services/turn-files/files-outbox.ts
|
|
20571
|
-
var
|
|
20572
|
-
var
|
|
20628
|
+
var fs36 = __toESM(require("fs/promises"));
|
|
20629
|
+
var path44 = __toESM(require("path"));
|
|
20573
20630
|
var import_os7 = require("os");
|
|
20574
20631
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20575
20632
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20602,16 +20659,16 @@ var FilesOutbox = class {
|
|
|
20602
20659
|
backoffIndex = 0;
|
|
20603
20660
|
stopped = false;
|
|
20604
20661
|
constructor(opts) {
|
|
20605
|
-
const base = opts.baseDir ??
|
|
20606
|
-
this.filePath =
|
|
20662
|
+
const base = opts.baseDir ?? path44.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20663
|
+
this.filePath = path44.join(base, `${opts.sessionId}.jsonl`);
|
|
20607
20664
|
this.post = opts.post;
|
|
20608
20665
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20609
20666
|
}
|
|
20610
20667
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20611
20668
|
* line is durable on disk (not once the POST succeeds). */
|
|
20612
20669
|
async enqueue(entry) {
|
|
20613
|
-
await
|
|
20614
|
-
await
|
|
20670
|
+
await fs36.mkdir(path44.dirname(this.filePath), { recursive: true });
|
|
20671
|
+
await fs36.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20615
20672
|
this.backoffIndex = 0;
|
|
20616
20673
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20617
20674
|
}
|
|
@@ -20700,7 +20757,7 @@ var FilesOutbox = class {
|
|
|
20700
20757
|
async readAll() {
|
|
20701
20758
|
let raw = "";
|
|
20702
20759
|
try {
|
|
20703
|
-
raw = await
|
|
20760
|
+
raw = await fs36.readFile(this.filePath, "utf8");
|
|
20704
20761
|
} catch {
|
|
20705
20762
|
return [];
|
|
20706
20763
|
}
|
|
@@ -20724,12 +20781,12 @@ var FilesOutbox = class {
|
|
|
20724
20781
|
async rewrite(entries) {
|
|
20725
20782
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20726
20783
|
if (entries.length === 0) {
|
|
20727
|
-
await
|
|
20784
|
+
await fs36.unlink(this.filePath).catch(() => void 0);
|
|
20728
20785
|
return;
|
|
20729
20786
|
}
|
|
20730
20787
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20731
|
-
await
|
|
20732
|
-
await
|
|
20788
|
+
await fs36.writeFile(tmpPath, payload, "utf8");
|
|
20789
|
+
await fs36.rename(tmpPath, this.filePath);
|
|
20733
20790
|
}
|
|
20734
20791
|
};
|
|
20735
20792
|
function applyJitter(ms) {
|
|
@@ -21328,6 +21385,7 @@ async function runAcpSession(opts) {
|
|
|
21328
21385
|
path: opts.cwd,
|
|
21329
21386
|
done: true
|
|
21330
21387
|
});
|
|
21388
|
+
maybeSendOnboardingWelcome({ client: client2, sessionId: opts.sessionId, cwd: opts.cwd });
|
|
21331
21389
|
const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
|
|
21332
21390
|
const models = await runtime.listModels();
|
|
21333
21391
|
const history = new AcpHistory(publisher, { agent: opts.agent, acpSessionId });
|
|
@@ -22550,9 +22608,9 @@ var OutputService = class _OutputService {
|
|
|
22550
22608
|
};
|
|
22551
22609
|
|
|
22552
22610
|
// src/services/history.service.ts
|
|
22553
|
-
var
|
|
22554
|
-
var
|
|
22555
|
-
var
|
|
22611
|
+
var fs37 = __toESM(require("fs"));
|
|
22612
|
+
var path45 = __toESM(require("path"));
|
|
22613
|
+
var os29 = __toESM(require("os"));
|
|
22556
22614
|
var https7 = __toESM(require("https"));
|
|
22557
22615
|
var http7 = __toESM(require("http"));
|
|
22558
22616
|
var import_zod2 = require("zod");
|
|
@@ -22579,7 +22637,7 @@ function parseJsonl(filePath) {
|
|
|
22579
22637
|
const messages = [];
|
|
22580
22638
|
let raw;
|
|
22581
22639
|
try {
|
|
22582
|
-
raw =
|
|
22640
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
22583
22641
|
} catch (err) {
|
|
22584
22642
|
if (err.code !== "ENOENT") {
|
|
22585
22643
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22714,7 +22772,7 @@ var HistoryService = class _HistoryService {
|
|
|
22714
22772
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22715
22773
|
}
|
|
22716
22774
|
get projectDir() {
|
|
22717
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
22775
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path45.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22718
22776
|
}
|
|
22719
22777
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22720
22778
|
setCurrentConversationId(id) {
|
|
@@ -22726,7 +22784,7 @@ var HistoryService = class _HistoryService {
|
|
|
22726
22784
|
/** Return the current message count in the active conversation. */
|
|
22727
22785
|
getCurrentMessageCount() {
|
|
22728
22786
|
if (!this.currentConversationId) return 0;
|
|
22729
|
-
const filePath =
|
|
22787
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22730
22788
|
return parseJsonl(filePath).length;
|
|
22731
22789
|
}
|
|
22732
22790
|
/**
|
|
@@ -22737,7 +22795,7 @@ var HistoryService = class _HistoryService {
|
|
|
22737
22795
|
const deadline = Date.now() + timeoutMs;
|
|
22738
22796
|
while (Date.now() < deadline) {
|
|
22739
22797
|
if (!this.currentConversationId) return null;
|
|
22740
|
-
const filePath =
|
|
22798
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22741
22799
|
const messages = parseJsonl(filePath);
|
|
22742
22800
|
if (messages.length > previousCount) {
|
|
22743
22801
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22763,16 +22821,16 @@ var HistoryService = class _HistoryService {
|
|
|
22763
22821
|
const dir = this.projectDir;
|
|
22764
22822
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22765
22823
|
try {
|
|
22766
|
-
const files =
|
|
22824
|
+
const files = fs37.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22767
22825
|
try {
|
|
22768
|
-
const stat3 =
|
|
22826
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
22769
22827
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22770
22828
|
} catch {
|
|
22771
22829
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22772
22830
|
}
|
|
22773
22831
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22774
22832
|
if (files.length > 0) {
|
|
22775
|
-
this.currentConversationId =
|
|
22833
|
+
this.currentConversationId = path45.basename(files[0].name, ".jsonl");
|
|
22776
22834
|
}
|
|
22777
22835
|
} catch {
|
|
22778
22836
|
}
|
|
@@ -22806,13 +22864,13 @@ var HistoryService = class _HistoryService {
|
|
|
22806
22864
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22807
22865
|
let entries;
|
|
22808
22866
|
try {
|
|
22809
|
-
entries =
|
|
22867
|
+
entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
22810
22868
|
} catch {
|
|
22811
22869
|
return null;
|
|
22812
22870
|
}
|
|
22813
22871
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22814
22872
|
try {
|
|
22815
|
-
const stat3 =
|
|
22873
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
22816
22874
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22817
22875
|
} catch {
|
|
22818
22876
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22821,12 +22879,12 @@ var HistoryService = class _HistoryService {
|
|
|
22821
22879
|
if (files.length === 0) return null;
|
|
22822
22880
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22823
22881
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22824
|
-
return this.extractUsageFromFile(
|
|
22882
|
+
return this.extractUsageFromFile(path45.join(dir, targetFile));
|
|
22825
22883
|
}
|
|
22826
22884
|
extractUsageFromFile(filePath) {
|
|
22827
22885
|
let raw;
|
|
22828
22886
|
try {
|
|
22829
|
-
raw =
|
|
22887
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
22830
22888
|
} catch {
|
|
22831
22889
|
return null;
|
|
22832
22890
|
}
|
|
@@ -22871,9 +22929,9 @@ var HistoryService = class _HistoryService {
|
|
|
22871
22929
|
let totalCost = 0;
|
|
22872
22930
|
let files;
|
|
22873
22931
|
try {
|
|
22874
|
-
files =
|
|
22932
|
+
files = fs37.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22875
22933
|
try {
|
|
22876
|
-
return
|
|
22934
|
+
return fs37.statSync(path45.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22877
22935
|
} catch {
|
|
22878
22936
|
return false;
|
|
22879
22937
|
}
|
|
@@ -22884,7 +22942,7 @@ var HistoryService = class _HistoryService {
|
|
|
22884
22942
|
for (const file of files) {
|
|
22885
22943
|
let raw;
|
|
22886
22944
|
try {
|
|
22887
|
-
raw =
|
|
22945
|
+
raw = fs37.readFileSync(path45.join(projectDir, file), "utf8");
|
|
22888
22946
|
} catch {
|
|
22889
22947
|
continue;
|
|
22890
22948
|
}
|
|
@@ -22948,7 +23006,7 @@ var HistoryService = class _HistoryService {
|
|
|
22948
23006
|
* showing an empty conversation.
|
|
22949
23007
|
*/
|
|
22950
23008
|
async loadConversation(sessionId) {
|
|
22951
|
-
const filePath =
|
|
23009
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22952
23010
|
const messages = parseJsonl(filePath);
|
|
22953
23011
|
if (messages.length === 0) return;
|
|
22954
23012
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23002,7 +23060,7 @@ var HistoryService = class _HistoryService {
|
|
|
23002
23060
|
if (!this.currentConversationId) return 0;
|
|
23003
23061
|
}
|
|
23004
23062
|
const sessionId = this.currentConversationId;
|
|
23005
|
-
const filePath =
|
|
23063
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23006
23064
|
const messages = parseJsonl(filePath);
|
|
23007
23065
|
if (messages.length === 0) return 0;
|
|
23008
23066
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -23923,8 +23981,8 @@ async function autoLinkAfterPair(opts) {
|
|
|
23923
23981
|
}
|
|
23924
23982
|
|
|
23925
23983
|
// src/commands/pair-auto.ts
|
|
23926
|
-
var
|
|
23927
|
-
var
|
|
23984
|
+
var fs38 = __toESM(require("fs"));
|
|
23985
|
+
var os30 = __toESM(require("os"));
|
|
23928
23986
|
var import_crypto7 = require("crypto");
|
|
23929
23987
|
|
|
23930
23988
|
// src/commands/start-infra-only.ts
|
|
@@ -24119,12 +24177,12 @@ function readTokenFromArgs(args2) {
|
|
|
24119
24177
|
}
|
|
24120
24178
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24121
24179
|
if (fileFlag) {
|
|
24122
|
-
const
|
|
24180
|
+
const path52 = fileFlag.slice("--token-file=".length);
|
|
24123
24181
|
try {
|
|
24124
|
-
const content =
|
|
24125
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24182
|
+
const content = fs38.readFileSync(path52, "utf8").trim();
|
|
24183
|
+
if (content.length === 0) fail(`--token-file ${path52} is empty`);
|
|
24126
24184
|
try {
|
|
24127
|
-
|
|
24185
|
+
fs38.unlinkSync(path52);
|
|
24128
24186
|
} catch {
|
|
24129
24187
|
}
|
|
24130
24188
|
return content;
|
|
@@ -24150,7 +24208,7 @@ async function claimOnce(token, pluginId) {
|
|
|
24150
24208
|
pluginId,
|
|
24151
24209
|
ideName: "codeam-cli (codespace)",
|
|
24152
24210
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
24153
|
-
hostname:
|
|
24211
|
+
hostname: os30.hostname(),
|
|
24154
24212
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
24155
24213
|
// Current git branch of the codespace's working directory, so the
|
|
24156
24214
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24390,7 +24448,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24390
24448
|
var import_child_process22 = require("child_process");
|
|
24391
24449
|
var import_util4 = require("util");
|
|
24392
24450
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24393
|
-
var
|
|
24451
|
+
var path46 = __toESM(require("path"));
|
|
24394
24452
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24395
24453
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24396
24454
|
function resetStdinForChild() {
|
|
@@ -24879,7 +24937,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24879
24937
|
});
|
|
24880
24938
|
}
|
|
24881
24939
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24882
|
-
const remoteDir =
|
|
24940
|
+
const remoteDir = path46.posix.dirname(remotePath);
|
|
24883
24941
|
const parts = [
|
|
24884
24942
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
24885
24943
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -24949,7 +25007,7 @@ function shellQuote(s) {
|
|
|
24949
25007
|
// src/services/providers/gitpod.ts
|
|
24950
25008
|
var import_child_process23 = require("child_process");
|
|
24951
25009
|
var import_util5 = require("util");
|
|
24952
|
-
var
|
|
25010
|
+
var path47 = __toESM(require("path"));
|
|
24953
25011
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
24954
25012
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
24955
25013
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25189,7 +25247,7 @@ var GitpodProvider = class {
|
|
|
25189
25247
|
});
|
|
25190
25248
|
}
|
|
25191
25249
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25192
|
-
const remoteDir =
|
|
25250
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25193
25251
|
const parts = [
|
|
25194
25252
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25195
25253
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25225,7 +25283,7 @@ function shellQuote2(s) {
|
|
|
25225
25283
|
// src/services/providers/gitlab-workspaces.ts
|
|
25226
25284
|
var import_child_process24 = require("child_process");
|
|
25227
25285
|
var import_util6 = require("util");
|
|
25228
|
-
var
|
|
25286
|
+
var path48 = __toESM(require("path"));
|
|
25229
25287
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25230
25288
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25231
25289
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25485,7 +25543,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25485
25543
|
}
|
|
25486
25544
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25487
25545
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25488
|
-
const remoteDir =
|
|
25546
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25489
25547
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25490
25548
|
if (options.mode != null) {
|
|
25491
25549
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25553,7 +25611,7 @@ function shellQuote3(s) {
|
|
|
25553
25611
|
// src/services/providers/railway.ts
|
|
25554
25612
|
var import_child_process25 = require("child_process");
|
|
25555
25613
|
var import_util7 = require("util");
|
|
25556
|
-
var
|
|
25614
|
+
var path49 = __toESM(require("path"));
|
|
25557
25615
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25558
25616
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25559
25617
|
function resetStdinForChild4() {
|
|
@@ -25789,7 +25847,7 @@ var RailwayProvider = class {
|
|
|
25789
25847
|
if (!projectId || !serviceId) {
|
|
25790
25848
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25791
25849
|
}
|
|
25792
|
-
const remoteDir =
|
|
25850
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25793
25851
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25794
25852
|
if (options.mode != null) {
|
|
25795
25853
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26332,8 +26390,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26332
26390
|
var import_node_dns = require("dns");
|
|
26333
26391
|
var import_node_util4 = require("util");
|
|
26334
26392
|
var import_node_crypto8 = require("crypto");
|
|
26335
|
-
var
|
|
26336
|
-
var
|
|
26393
|
+
var fs39 = __toESM(require("fs"));
|
|
26394
|
+
var path50 = __toESM(require("path"));
|
|
26337
26395
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26338
26396
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26339
26397
|
async function checkDns(apiBase) {
|
|
@@ -26389,13 +26447,13 @@ async function checkHealth(apiBase) {
|
|
|
26389
26447
|
}
|
|
26390
26448
|
}
|
|
26391
26449
|
function checkConfigDir() {
|
|
26392
|
-
const dir =
|
|
26450
|
+
const dir = path50.join(require("os").homedir(), ".codeam");
|
|
26393
26451
|
try {
|
|
26394
|
-
|
|
26395
|
-
const probe =
|
|
26396
|
-
|
|
26397
|
-
const read =
|
|
26398
|
-
|
|
26452
|
+
fs39.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26453
|
+
const probe = path50.join(dir, ".doctor-probe");
|
|
26454
|
+
fs39.writeFileSync(probe, "ok", { mode: 384 });
|
|
26455
|
+
const read = fs39.readFileSync(probe, "utf8");
|
|
26456
|
+
fs39.unlinkSync(probe);
|
|
26399
26457
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26400
26458
|
return {
|
|
26401
26459
|
id: "config-dir",
|
|
@@ -26435,9 +26493,9 @@ function checkSessions() {
|
|
|
26435
26493
|
}
|
|
26436
26494
|
}
|
|
26437
26495
|
function checkAgentBinaries() {
|
|
26438
|
-
const
|
|
26496
|
+
const os32 = createOsStrategy();
|
|
26439
26497
|
return getEnabledAgents().map((meta) => {
|
|
26440
|
-
const found =
|
|
26498
|
+
const found = os32.findInPath(meta.binaryName);
|
|
26441
26499
|
return {
|
|
26442
26500
|
id: `agent-${meta.id}`,
|
|
26443
26501
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -26459,7 +26517,7 @@ function checkNodePty() {
|
|
|
26459
26517
|
detail: "not required on this platform"
|
|
26460
26518
|
};
|
|
26461
26519
|
}
|
|
26462
|
-
const vendoredPath =
|
|
26520
|
+
const vendoredPath = path50.join(__dirname, "vendor", "node-pty");
|
|
26463
26521
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26464
26522
|
try {
|
|
26465
26523
|
require(target);
|
|
@@ -26501,7 +26559,7 @@ function checkChokidar() {
|
|
|
26501
26559
|
}
|
|
26502
26560
|
async function doctor(args2 = []) {
|
|
26503
26561
|
const json = args2.includes("--json");
|
|
26504
|
-
const cliVersion = true ? "2.
|
|
26562
|
+
const cliVersion = true ? "2.37.0" : "0.0.0-dev";
|
|
26505
26563
|
const apiBase = resolveApiBaseUrl();
|
|
26506
26564
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26507
26565
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26700,7 +26758,7 @@ async function completion(args2) {
|
|
|
26700
26758
|
// src/commands/version.ts
|
|
26701
26759
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26702
26760
|
function version2() {
|
|
26703
|
-
const v = true ? "2.
|
|
26761
|
+
const v = true ? "2.37.0" : "unknown";
|
|
26704
26762
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26705
26763
|
}
|
|
26706
26764
|
|
|
@@ -26828,9 +26886,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26828
26886
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26829
26887
|
|
|
26830
26888
|
// src/lib/updateNotifier.ts
|
|
26831
|
-
var
|
|
26832
|
-
var
|
|
26833
|
-
var
|
|
26889
|
+
var fs40 = __toESM(require("fs"));
|
|
26890
|
+
var os31 = __toESM(require("os"));
|
|
26891
|
+
var path51 = __toESM(require("path"));
|
|
26834
26892
|
var https8 = __toESM(require("https"));
|
|
26835
26893
|
var import_node_child_process12 = require("child_process");
|
|
26836
26894
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26839,12 +26897,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26839
26897
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26840
26898
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26841
26899
|
function cachePath() {
|
|
26842
|
-
const dir =
|
|
26843
|
-
return
|
|
26900
|
+
const dir = path51.join(os31.homedir(), ".codeam");
|
|
26901
|
+
return path51.join(dir, "update-check.json");
|
|
26844
26902
|
}
|
|
26845
26903
|
function readCache() {
|
|
26846
26904
|
try {
|
|
26847
|
-
const raw =
|
|
26905
|
+
const raw = fs40.readFileSync(cachePath(), "utf8");
|
|
26848
26906
|
const parsed = JSON.parse(raw);
|
|
26849
26907
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26850
26908
|
return parsed;
|
|
@@ -26855,10 +26913,10 @@ function readCache() {
|
|
|
26855
26913
|
function writeCache(cache) {
|
|
26856
26914
|
try {
|
|
26857
26915
|
const file = cachePath();
|
|
26858
|
-
|
|
26916
|
+
fs40.mkdirSync(path51.dirname(file), { recursive: true });
|
|
26859
26917
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
26860
|
-
|
|
26861
|
-
|
|
26918
|
+
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
26919
|
+
fs40.renameSync(tmp, file);
|
|
26862
26920
|
} catch {
|
|
26863
26921
|
}
|
|
26864
26922
|
}
|
|
@@ -26932,8 +26990,8 @@ function isLinkedInstall() {
|
|
|
26932
26990
|
timeout: 2e3
|
|
26933
26991
|
}).trim();
|
|
26934
26992
|
if (!root) return false;
|
|
26935
|
-
const pkgPath =
|
|
26936
|
-
return
|
|
26993
|
+
const pkgPath = path51.join(root, PKG_NAME);
|
|
26994
|
+
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
26937
26995
|
} catch {
|
|
26938
26996
|
return false;
|
|
26939
26997
|
}
|
|
@@ -26969,7 +27027,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
26969
27027
|
return;
|
|
26970
27028
|
}
|
|
26971
27029
|
try {
|
|
26972
|
-
|
|
27030
|
+
fs40.unlinkSync(cachePath());
|
|
26973
27031
|
} catch {
|
|
26974
27032
|
}
|
|
26975
27033
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -26986,7 +27044,7 @@ function checkForUpdates() {
|
|
|
26986
27044
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
26987
27045
|
if (process.env.CI) return;
|
|
26988
27046
|
if (!process.stdout.isTTY) return;
|
|
26989
|
-
const current = true ? "2.
|
|
27047
|
+
const current = true ? "2.37.0" : null;
|
|
26990
27048
|
if (!current) return;
|
|
26991
27049
|
const cache = readCache();
|
|
26992
27050
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|