codeam-cli 2.35.8 → 2.36.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 +633 -339
- 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.36.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(path51) {
|
|
1190
|
+
return path51.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(path51, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path51);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path50, 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(path51, 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(path51) {
|
|
3749
|
+
return path51.startsWith("node:") || path51.endsWith(".min.js") || path51.endsWith(".min.cjs") || path51.endsWith(".min.mjs") || path51.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.36.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 path51 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path51,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path51 ? 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 [, path51, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path51 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path51.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.`
|
|
@@ -14664,6 +14664,14 @@ var AcpClient = class {
|
|
|
14664
14664
|
* the turn alive while the adapter is demonstrably working. Null
|
|
14665
14665
|
* between prompts. */
|
|
14666
14666
|
promptIdle = null;
|
|
14667
|
+
/** Tool calls the adapter has started but not yet reported terminal
|
|
14668
|
+
* (`completed`/`failed`). A long-running tool — typecheck, build,
|
|
14669
|
+
* install, a big test run — emits NO `session/update` for its whole
|
|
14670
|
+
* duration, which can exceed the idle window and falsely trip the
|
|
14671
|
+
* watchdog. While ANY tool is outstanding we SUSPEND the watchdog
|
|
14672
|
+
* (the agent is demonstrably working, just blocked on the tool), and
|
|
14673
|
+
* re-arm only once the last one finishes. Reset per prompt. */
|
|
14674
|
+
pendingToolCalls = /* @__PURE__ */ new Set();
|
|
14667
14675
|
/**
|
|
14668
14676
|
* Spawn the adapter + perform the initial handshake (initialize
|
|
14669
14677
|
* → newSession). Returns the ACP-assigned sessionId so the caller
|
|
@@ -14778,6 +14786,7 @@ var AcpClient = class {
|
|
|
14778
14786
|
)
|
|
14779
14787
|
);
|
|
14780
14788
|
this.promptIdle = idle;
|
|
14789
|
+
this.pendingToolCalls.clear();
|
|
14781
14790
|
try {
|
|
14782
14791
|
const result = await Promise.race([send, idle.promise]);
|
|
14783
14792
|
log.info(
|
|
@@ -14880,11 +14889,35 @@ var AcpClient = class {
|
|
|
14880
14889
|
log.trace("acpClient", "stop teardown error", err);
|
|
14881
14890
|
}
|
|
14882
14891
|
}
|
|
14892
|
+
/**
|
|
14893
|
+
* Drive the idle watchdog off the tool-call lifecycle so a long but
|
|
14894
|
+
* alive tool (typecheck / build / install) can't trip it.
|
|
14895
|
+
*
|
|
14896
|
+
* - `tool_call` (a tool starts) → track + suspend
|
|
14897
|
+
* - `tool_call_update` completed/failed → untrack; re-arm iff
|
|
14898
|
+
* no tool still running
|
|
14899
|
+
* - anything else (thought / message / …) → re-arm, unless a tool
|
|
14900
|
+
* is still outstanding
|
|
14901
|
+
*/
|
|
14902
|
+
trackToolCallIdle(params) {
|
|
14903
|
+
const u2 = params.update;
|
|
14904
|
+
if (u2.sessionUpdate === "tool_call" && typeof u2.toolCallId === "string") {
|
|
14905
|
+
this.pendingToolCalls.add(u2.toolCallId);
|
|
14906
|
+
this.promptIdle?.suspend();
|
|
14907
|
+
return;
|
|
14908
|
+
}
|
|
14909
|
+
if (u2.sessionUpdate === "tool_call_update" && (u2.status === "completed" || u2.status === "failed")) {
|
|
14910
|
+
if (typeof u2.toolCallId === "string") this.pendingToolCalls.delete(u2.toolCallId);
|
|
14911
|
+
if (this.pendingToolCalls.size === 0) this.promptIdle?.bump();
|
|
14912
|
+
return;
|
|
14913
|
+
}
|
|
14914
|
+
if (this.pendingToolCalls.size === 0) this.promptIdle?.bump();
|
|
14915
|
+
}
|
|
14883
14916
|
// ─── Client surface (what the agent calls into) ───────────────────
|
|
14884
14917
|
buildClient() {
|
|
14885
14918
|
return {
|
|
14886
14919
|
sessionUpdate: async (params) => {
|
|
14887
|
-
this.
|
|
14920
|
+
this.trackToolCallIdle(params);
|
|
14888
14921
|
this.opts.onSessionUpdate(params);
|
|
14889
14922
|
},
|
|
14890
14923
|
requestPermission: async (params) => {
|
|
@@ -15797,11 +15830,11 @@ function extractSelectPrompt(text) {
|
|
|
15797
15830
|
}
|
|
15798
15831
|
|
|
15799
15832
|
// src/commands/start/handlers.ts
|
|
15800
|
-
var
|
|
15801
|
-
var
|
|
15802
|
-
var
|
|
15833
|
+
var fs33 = __toESM(require("fs"));
|
|
15834
|
+
var os27 = __toESM(require("os"));
|
|
15835
|
+
var path40 = __toESM(require("path"));
|
|
15803
15836
|
var import_crypto3 = require("crypto");
|
|
15804
|
-
var
|
|
15837
|
+
var import_child_process18 = require("child_process");
|
|
15805
15838
|
|
|
15806
15839
|
// src/lib/payload.ts
|
|
15807
15840
|
var import_zod = require("zod");
|
|
@@ -17476,7 +17509,8 @@ var BdAdapter = class {
|
|
|
17476
17509
|
}
|
|
17477
17510
|
const env = { ...process.env };
|
|
17478
17511
|
env.BEADS_DIR = this.opts.beadsDir ?? defaultBeadsHomeDir();
|
|
17479
|
-
|
|
17512
|
+
env.BEADS_DOLT_SHARED_SERVER = "1";
|
|
17513
|
+
log.trace("beads", `bd ${args2.join(" ")} (BEADS_DIR=${env.BEADS_DIR}, shared-server)`);
|
|
17480
17514
|
return _spawnSeam.run(binary, args2, { cwd: this.opts.cwd, env });
|
|
17481
17515
|
}
|
|
17482
17516
|
/**
|
|
@@ -17550,10 +17584,10 @@ function defaultBeadsHomeDir() {
|
|
|
17550
17584
|
}
|
|
17551
17585
|
|
|
17552
17586
|
// src/beads/provisioner.ts
|
|
17553
|
-
var
|
|
17554
|
-
var
|
|
17555
|
-
var
|
|
17556
|
-
var
|
|
17587
|
+
var import_child_process17 = require("child_process");
|
|
17588
|
+
var fs32 = __toESM(require("fs"));
|
|
17589
|
+
var os26 = __toESM(require("os"));
|
|
17590
|
+
var path38 = __toESM(require("path"));
|
|
17557
17591
|
|
|
17558
17592
|
// src/beads/install-bd.ts
|
|
17559
17593
|
var import_child_process14 = require("child_process");
|
|
@@ -17616,6 +17650,312 @@ async function installBd(platform2 = process.platform) {
|
|
|
17616
17650
|
return result;
|
|
17617
17651
|
}
|
|
17618
17652
|
|
|
17653
|
+
// src/beads/install-dolt.ts
|
|
17654
|
+
var import_child_process15 = require("child_process");
|
|
17655
|
+
var fs30 = __toESM(require("fs"));
|
|
17656
|
+
var os25 = __toESM(require("os"));
|
|
17657
|
+
var path36 = __toESM(require("path"));
|
|
17658
|
+
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17659
|
+
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17660
|
+
function resolveDoltInstallStrategy(platform2) {
|
|
17661
|
+
if (platform2 === "win32") {
|
|
17662
|
+
const script = [
|
|
17663
|
+
`$ErrorActionPreference='Stop';`,
|
|
17664
|
+
`$u='${DOLT_MSI_URL}';`,
|
|
17665
|
+
`$o="$env:TEMP\\dolt-install.msi";`,
|
|
17666
|
+
`Invoke-WebRequest -Uri $u -OutFile $o;`,
|
|
17667
|
+
`Start-Process msiexec.exe -ArgumentList '/i',('"'+$o+'"'),'/quiet','/norestart' -Wait`
|
|
17668
|
+
].join(" ");
|
|
17669
|
+
return {
|
|
17670
|
+
command: "powershell.exe",
|
|
17671
|
+
args: [
|
|
17672
|
+
"-NoProfile",
|
|
17673
|
+
"-NonInteractive",
|
|
17674
|
+
"-ExecutionPolicy",
|
|
17675
|
+
"Bypass",
|
|
17676
|
+
"-Command",
|
|
17677
|
+
script
|
|
17678
|
+
],
|
|
17679
|
+
description: "PowerShell: download official dolt MSI + silent msiexec"
|
|
17680
|
+
};
|
|
17681
|
+
}
|
|
17682
|
+
if (platform2 === "darwin") {
|
|
17683
|
+
return {
|
|
17684
|
+
command: "brew",
|
|
17685
|
+
args: ["install", "dolt"],
|
|
17686
|
+
description: "brew install dolt"
|
|
17687
|
+
};
|
|
17688
|
+
}
|
|
17689
|
+
return {
|
|
17690
|
+
command: "bash",
|
|
17691
|
+
args: ["-c", `curl -L ${DOLT_INSTALL_SH_URL} | sudo bash`],
|
|
17692
|
+
description: `curl -L ${DOLT_INSTALL_SH_URL} | sudo bash (\u2192 /usr/local/bin)`
|
|
17693
|
+
};
|
|
17694
|
+
}
|
|
17695
|
+
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17696
|
+
function doltPlatformTuple(platform2, arch) {
|
|
17697
|
+
const os32 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
|
|
17698
|
+
const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
17699
|
+
if (!a) return null;
|
|
17700
|
+
if (os32 === "windows" && a !== "amd64") return null;
|
|
17701
|
+
return `${os32}-${a}`;
|
|
17702
|
+
}
|
|
17703
|
+
function resolveDoltTarballStrategy(targetDir, platform2, arch) {
|
|
17704
|
+
const tuple = doltPlatformTuple(platform2, arch);
|
|
17705
|
+
if (!tuple) return null;
|
|
17706
|
+
if (platform2 === "win32") {
|
|
17707
|
+
const url2 = `${DOLT_RELEASE_BASE}/dolt-${tuple}.zip`;
|
|
17708
|
+
const script = [
|
|
17709
|
+
`$ErrorActionPreference='Stop';`,
|
|
17710
|
+
`New-Item -ItemType Directory -Force -Path '${targetDir}' | Out-Null;`,
|
|
17711
|
+
`$u='${url2}';`,
|
|
17712
|
+
`$o="$env:TEMP\\dolt-cs.zip";`,
|
|
17713
|
+
`Invoke-WebRequest -Uri $u -OutFile $o;`,
|
|
17714
|
+
`$x="$env:TEMP\\dolt-cs";`,
|
|
17715
|
+
`Expand-Archive -Path $o -DestinationPath $x -Force;`,
|
|
17716
|
+
`Copy-Item "$x\\dolt-${tuple}\\bin\\dolt.exe" '${targetDir}\\dolt.exe' -Force`
|
|
17717
|
+
].join(" ");
|
|
17718
|
+
return {
|
|
17719
|
+
command: "powershell.exe",
|
|
17720
|
+
args: ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", script],
|
|
17721
|
+
description: `download dolt ${tuple} zip \u2192 ${targetDir} (no sudo)`
|
|
17722
|
+
};
|
|
17723
|
+
}
|
|
17724
|
+
const url = `${DOLT_RELEASE_BASE}/dolt-${tuple}.tar.gz`;
|
|
17725
|
+
const cmd = `mkdir -p "${targetDir}" && curl -fsSL "${url}" | tar -xz -C "${targetDir}" --strip-components=2 "dolt-${tuple}/bin/dolt" && chmod +x "${targetDir}/dolt"`;
|
|
17726
|
+
return {
|
|
17727
|
+
command: "bash",
|
|
17728
|
+
args: ["-c", cmd],
|
|
17729
|
+
description: `download dolt ${tuple} tarball \u2192 ${targetDir} (no sudo)`
|
|
17730
|
+
};
|
|
17731
|
+
}
|
|
17732
|
+
async function installDoltToDir(targetDir, platform2 = process.platform, arch = process.arch) {
|
|
17733
|
+
const strategy = resolveDoltTarballStrategy(targetDir, platform2, arch);
|
|
17734
|
+
if (!strategy) {
|
|
17735
|
+
log.warn("beads", `no dolt prebuilt for ${platform2}/${arch} \u2014 cannot fall back`);
|
|
17736
|
+
return { ok: false, code: -1, stderr: `unsupported platform ${platform2}/${arch}` };
|
|
17737
|
+
}
|
|
17738
|
+
log.info("beads", `dolt fallback: ${strategy.description}`);
|
|
17739
|
+
const result = await _doltInstallSpawnSeam.run(strategy);
|
|
17740
|
+
if (!result.ok) {
|
|
17741
|
+
log.warn("beads", `dolt tarball fallback failed (code=${result.code}): ${result.stderr.slice(0, 200)}`);
|
|
17742
|
+
}
|
|
17743
|
+
return result;
|
|
17744
|
+
}
|
|
17745
|
+
var _doltPathSeam = {
|
|
17746
|
+
homedir: () => os25.homedir(),
|
|
17747
|
+
getPath: () => process.env.PATH ?? "",
|
|
17748
|
+
setPath: (p2) => {
|
|
17749
|
+
process.env.PATH = p2;
|
|
17750
|
+
},
|
|
17751
|
+
exists: (p2) => {
|
|
17752
|
+
try {
|
|
17753
|
+
fs30.accessSync(p2, fs30.constants.F_OK);
|
|
17754
|
+
return true;
|
|
17755
|
+
} catch {
|
|
17756
|
+
return false;
|
|
17757
|
+
}
|
|
17758
|
+
}
|
|
17759
|
+
};
|
|
17760
|
+
function doltBinaryNames(platform2) {
|
|
17761
|
+
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17762
|
+
}
|
|
17763
|
+
function knownDoltDirs(platform2) {
|
|
17764
|
+
const P3 = platform2 === "win32" ? path36.win32 : path36.posix;
|
|
17765
|
+
const home = _doltPathSeam.homedir();
|
|
17766
|
+
if (platform2 === "win32") {
|
|
17767
|
+
return [
|
|
17768
|
+
"C:\\Program Files\\Dolt\\bin",
|
|
17769
|
+
home ? P3.join(home, "AppData", "Local", "Programs", "dolt", "bin") : ""
|
|
17770
|
+
].filter(Boolean);
|
|
17771
|
+
}
|
|
17772
|
+
return [
|
|
17773
|
+
"/usr/local/bin",
|
|
17774
|
+
"/opt/homebrew/bin",
|
|
17775
|
+
home ? P3.join(home, ".local", "bin") : "",
|
|
17776
|
+
home ? P3.join(home, "bin") : ""
|
|
17777
|
+
].filter(Boolean);
|
|
17778
|
+
}
|
|
17779
|
+
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17780
|
+
const P3 = platform2 === "win32" ? path36.win32 : path36.posix;
|
|
17781
|
+
const delim = platform2 === "win32" ? ";" : ":";
|
|
17782
|
+
const names = doltBinaryNames(platform2);
|
|
17783
|
+
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
17784
|
+
for (const dir of pathDirs) {
|
|
17785
|
+
for (const n of names) {
|
|
17786
|
+
if (_doltPathSeam.exists(P3.join(dir, n))) return true;
|
|
17787
|
+
}
|
|
17788
|
+
}
|
|
17789
|
+
for (const dir of knownDoltDirs(platform2)) {
|
|
17790
|
+
for (const n of names) {
|
|
17791
|
+
if (_doltPathSeam.exists(P3.join(dir, n))) {
|
|
17792
|
+
_doltPathSeam.setPath(`${dir}${delim}${_doltPathSeam.getPath()}`);
|
|
17793
|
+
log.info("beads", `dolt found in ${dir} (not on PATH) \u2014 prepended to process PATH`);
|
|
17794
|
+
return true;
|
|
17795
|
+
}
|
|
17796
|
+
}
|
|
17797
|
+
}
|
|
17798
|
+
return false;
|
|
17799
|
+
}
|
|
17800
|
+
var _doltInstallSpawnSeam = {
|
|
17801
|
+
run: _defaultDoltInstallSpawn
|
|
17802
|
+
};
|
|
17803
|
+
function _defaultDoltInstallSpawn(strategy) {
|
|
17804
|
+
return new Promise((resolve7) => {
|
|
17805
|
+
let proc;
|
|
17806
|
+
try {
|
|
17807
|
+
proc = (0, import_child_process15.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
17808
|
+
} catch (err) {
|
|
17809
|
+
resolve7({ ok: false, code: -1, stderr: err.message });
|
|
17810
|
+
return;
|
|
17811
|
+
}
|
|
17812
|
+
let stderr = "";
|
|
17813
|
+
proc.stderr?.on("data", (c2) => {
|
|
17814
|
+
stderr += c2.toString();
|
|
17815
|
+
});
|
|
17816
|
+
proc.on("error", (err) => resolve7({ ok: false, code: -1, stderr: err.message }));
|
|
17817
|
+
proc.on("close", (code) => resolve7({ ok: code === 0, code: code ?? -1, stderr }));
|
|
17818
|
+
});
|
|
17819
|
+
}
|
|
17820
|
+
async function installDolt(platform2 = process.platform) {
|
|
17821
|
+
const strategy = resolveDoltInstallStrategy(platform2);
|
|
17822
|
+
log.info("beads", `installing dolt via ${strategy.description}`);
|
|
17823
|
+
const result = await _doltInstallSpawnSeam.run(strategy);
|
|
17824
|
+
if (!result.ok) {
|
|
17825
|
+
log.warn(
|
|
17826
|
+
"beads",
|
|
17827
|
+
`dolt install failed (code=${result.code}): ${result.stderr.slice(0, 200)}`
|
|
17828
|
+
);
|
|
17829
|
+
}
|
|
17830
|
+
return result;
|
|
17831
|
+
}
|
|
17832
|
+
|
|
17833
|
+
// src/beads/dolt-daemon.ts
|
|
17834
|
+
var _daemonSeam = {
|
|
17835
|
+
/**
|
|
17836
|
+
* Parse `bd dolt status` stdout. Running blocks lead with
|
|
17837
|
+
* `Dolt server: running`; down blocks say `Dolt server: not running`.
|
|
17838
|
+
* Match the affirmative form explicitly so "not running" can't false-positive.
|
|
17839
|
+
*/
|
|
17840
|
+
isRunning: (statusStdout) => /Dolt server:\s*running/i.test(statusStdout)
|
|
17841
|
+
};
|
|
17842
|
+
async function ensureSharedServer(adapter) {
|
|
17843
|
+
const status2 = await adapter.run(["dolt", "status"]);
|
|
17844
|
+
if (status2.code === 0 && _daemonSeam.isRunning(status2.stdout)) {
|
|
17845
|
+
log.trace("beads", "shared dolt sql-server already running \u2014 reusing");
|
|
17846
|
+
return { up: true, started: false };
|
|
17847
|
+
}
|
|
17848
|
+
log.info("beads", "shared dolt sql-server not running \u2014 starting (detached)");
|
|
17849
|
+
const start2 = await adapter.run(["dolt", "start"]);
|
|
17850
|
+
if (start2.code !== 0) {
|
|
17851
|
+
log.warn(
|
|
17852
|
+
"beads",
|
|
17853
|
+
`bd dolt start failed (code=${start2.code}): ${start2.stderr.slice(0, 200)} \u2014 beads memory unavailable this run`
|
|
17854
|
+
);
|
|
17855
|
+
return { up: false, started: false };
|
|
17856
|
+
}
|
|
17857
|
+
const recheck = await adapter.run(["dolt", "status"]);
|
|
17858
|
+
const up = recheck.code === 0 && _daemonSeam.isRunning(recheck.stdout);
|
|
17859
|
+
if (!up) {
|
|
17860
|
+
log.warn("beads", "shared dolt sql-server still not reachable after start \u2014 non-fatal");
|
|
17861
|
+
}
|
|
17862
|
+
return { up, started: up };
|
|
17863
|
+
}
|
|
17864
|
+
|
|
17865
|
+
// src/beads/project-key.ts
|
|
17866
|
+
var import_child_process16 = require("child_process");
|
|
17867
|
+
var crypto2 = __toESM(require("crypto"));
|
|
17868
|
+
var fs31 = __toESM(require("fs"));
|
|
17869
|
+
var path37 = __toESM(require("path"));
|
|
17870
|
+
function normalizeOrigin(raw) {
|
|
17871
|
+
const trimmed = raw.trim();
|
|
17872
|
+
if (!trimmed) return null;
|
|
17873
|
+
let host;
|
|
17874
|
+
let pathPart;
|
|
17875
|
+
const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
|
|
17876
|
+
if (scpLike && !trimmed.includes("://")) {
|
|
17877
|
+
host = scpLike[1];
|
|
17878
|
+
pathPart = scpLike[2];
|
|
17879
|
+
} else {
|
|
17880
|
+
let url;
|
|
17881
|
+
try {
|
|
17882
|
+
url = new URL(trimmed);
|
|
17883
|
+
} catch {
|
|
17884
|
+
return null;
|
|
17885
|
+
}
|
|
17886
|
+
host = url.hostname;
|
|
17887
|
+
pathPart = url.pathname;
|
|
17888
|
+
}
|
|
17889
|
+
host = host.toLowerCase();
|
|
17890
|
+
pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
17891
|
+
if (!host || !pathPart) return null;
|
|
17892
|
+
return `${host}/${pathPart}`;
|
|
17893
|
+
}
|
|
17894
|
+
function findRepoRoot(cwd) {
|
|
17895
|
+
let dir = path37.resolve(cwd);
|
|
17896
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17897
|
+
for (let i = 0; i < 256; i++) {
|
|
17898
|
+
if (seen.has(dir)) return null;
|
|
17899
|
+
seen.add(dir);
|
|
17900
|
+
try {
|
|
17901
|
+
const stat3 = fs31.statSync(path37.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17902
|
+
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17903
|
+
} catch {
|
|
17904
|
+
}
|
|
17905
|
+
const parent = path37.dirname(dir);
|
|
17906
|
+
if (parent === dir) return null;
|
|
17907
|
+
dir = parent;
|
|
17908
|
+
}
|
|
17909
|
+
return null;
|
|
17910
|
+
}
|
|
17911
|
+
var _execSeam2 = {
|
|
17912
|
+
exec: (file, args2, opts) => {
|
|
17913
|
+
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
17914
|
+
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17915
|
+
},
|
|
17916
|
+
realpath: (p2) => fs31.realpathSync(p2)
|
|
17917
|
+
};
|
|
17918
|
+
function readOrigin(cwd) {
|
|
17919
|
+
try {
|
|
17920
|
+
const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
|
|
17921
|
+
cwd,
|
|
17922
|
+
timeout: 1e3,
|
|
17923
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
17924
|
+
encoding: "utf8"
|
|
17925
|
+
});
|
|
17926
|
+
return raw.trim() || null;
|
|
17927
|
+
} catch {
|
|
17928
|
+
return null;
|
|
17929
|
+
}
|
|
17930
|
+
}
|
|
17931
|
+
function deriveProjectIdentity(cwd = process.cwd()) {
|
|
17932
|
+
const repoRoot = findRepoRoot(cwd) ?? cwd;
|
|
17933
|
+
const origin = readOrigin(repoRoot);
|
|
17934
|
+
const normalized = origin ? normalizeOrigin(origin) : null;
|
|
17935
|
+
if (normalized) {
|
|
17936
|
+
const label = normalized.split("/").pop() || normalized;
|
|
17937
|
+
return { projectKey: normalized, projectLabel: label };
|
|
17938
|
+
}
|
|
17939
|
+
let real = repoRoot;
|
|
17940
|
+
try {
|
|
17941
|
+
real = _execSeam2.realpath(repoRoot);
|
|
17942
|
+
} catch {
|
|
17943
|
+
}
|
|
17944
|
+
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17945
|
+
return { projectKey: `path:${hash}`, projectLabel: path37.basename(real) || "project" };
|
|
17946
|
+
}
|
|
17947
|
+
|
|
17948
|
+
// src/beads/project-prefix.ts
|
|
17949
|
+
var crypto3 = __toESM(require("crypto"));
|
|
17950
|
+
function prefixForProjectKey(projectKey) {
|
|
17951
|
+
const tail = projectKey.split("/").pop() ?? projectKey;
|
|
17952
|
+
let slug = tail.toLowerCase().replace(/\.git$/, "").replace(/[^a-z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
17953
|
+
if (!slug || !/^[a-z]/.test(slug)) slug = `p_${slug}`;
|
|
17954
|
+
slug = slug.replace(/_$/, "").slice(0, 24).replace(/_$/, "");
|
|
17955
|
+
const hash = crypto3.createHash("sha256").update(projectKey).digest("hex").slice(0, 8);
|
|
17956
|
+
return `${slug}_${hash}`;
|
|
17957
|
+
}
|
|
17958
|
+
|
|
17619
17959
|
// src/beads/provisioner.ts
|
|
17620
17960
|
var AGENT_SETUP_RECIPE = {
|
|
17621
17961
|
claude: "claude",
|
|
@@ -17628,7 +17968,15 @@ var AGENT_SETUP_RECIPE = {
|
|
|
17628
17968
|
};
|
|
17629
17969
|
var _provisionSeam = {
|
|
17630
17970
|
install: installBd,
|
|
17631
|
-
|
|
17971
|
+
installDolt,
|
|
17972
|
+
/** No-sudo fallback: extract the dolt tarball/zip into a user-writable dir. */
|
|
17973
|
+
installDoltToDir,
|
|
17974
|
+
// Probe dolt on PATH AND auto-prepend a known install dir if found off-PATH
|
|
17975
|
+
// (codespace: official install.sh drops dolt in /usr/local/bin, which the
|
|
17976
|
+
// bundled-node CLI's PATH can omit — mirrors the bd-on-PATH symlink fix).
|
|
17977
|
+
doltOnPath: ensureDoltResolvable,
|
|
17978
|
+
ensureSharedServer,
|
|
17979
|
+
deriveProjectIdentity,
|
|
17632
17980
|
/** GAP 1 — symlink the resolved bd onto PATH for the agent's own shell. */
|
|
17633
17981
|
linkBdOntoPath,
|
|
17634
17982
|
/** Silence bd's `beads.role not configured` warning. */
|
|
@@ -17636,17 +17984,17 @@ var _provisionSeam = {
|
|
|
17636
17984
|
};
|
|
17637
17985
|
var _linkSeam = {
|
|
17638
17986
|
platform: () => process.platform,
|
|
17639
|
-
homedir: () =>
|
|
17987
|
+
homedir: () => os26.homedir(),
|
|
17640
17988
|
isWritableDir: (dir) => {
|
|
17641
17989
|
try {
|
|
17642
|
-
|
|
17990
|
+
fs32.accessSync(dir, fs32.constants.W_OK);
|
|
17643
17991
|
return true;
|
|
17644
17992
|
} catch {
|
|
17645
17993
|
return false;
|
|
17646
17994
|
}
|
|
17647
17995
|
},
|
|
17648
17996
|
ensureDir: (dir) => {
|
|
17649
|
-
|
|
17997
|
+
fs32.mkdirSync(dir, { recursive: true });
|
|
17650
17998
|
},
|
|
17651
17999
|
/**
|
|
17652
18000
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -17667,12 +18015,12 @@ var _linkSeam = {
|
|
|
17667
18015
|
* which `linkBdOntoPath` creates if missing.
|
|
17668
18016
|
*/
|
|
17669
18017
|
cliBinDir: () => {
|
|
17670
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18018
|
+
const pathDirs = (process.env.PATH ?? "").split(path38.delimiter).filter(Boolean);
|
|
17671
18019
|
const home = _linkSeam.homedir();
|
|
17672
|
-
const localBin = home ?
|
|
18020
|
+
const localBin = home ? path38.join(home, ".local", "bin") : null;
|
|
17673
18021
|
const candidates = [];
|
|
17674
18022
|
try {
|
|
17675
|
-
candidates.push(
|
|
18023
|
+
candidates.push(path38.dirname(process.execPath));
|
|
17676
18024
|
} catch {
|
|
17677
18025
|
}
|
|
17678
18026
|
if (localBin) candidates.push(localBin);
|
|
@@ -17680,9 +18028,9 @@ var _linkSeam = {
|
|
|
17680
18028
|
const entry = process.argv[1];
|
|
17681
18029
|
if (entry) {
|
|
17682
18030
|
try {
|
|
17683
|
-
candidates.push(
|
|
18031
|
+
candidates.push(path38.dirname(fs32.realpathSync(entry)));
|
|
17684
18032
|
} catch {
|
|
17685
|
-
candidates.push(
|
|
18033
|
+
candidates.push(path38.dirname(entry));
|
|
17686
18034
|
}
|
|
17687
18035
|
}
|
|
17688
18036
|
const onPathWritable = candidates.find(
|
|
@@ -17694,20 +18042,20 @@ var _linkSeam = {
|
|
|
17694
18042
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
17695
18043
|
readlink: (linkPath) => {
|
|
17696
18044
|
try {
|
|
17697
|
-
return
|
|
18045
|
+
return fs32.readlinkSync(linkPath);
|
|
17698
18046
|
} catch {
|
|
17699
18047
|
return null;
|
|
17700
18048
|
}
|
|
17701
18049
|
},
|
|
17702
|
-
unlink: (linkPath) =>
|
|
17703
|
-
symlink: (target, linkPath) =>
|
|
18050
|
+
unlink: (linkPath) => fs32.unlinkSync(linkPath),
|
|
18051
|
+
symlink: (target, linkPath) => fs32.symlinkSync(target, linkPath)
|
|
17704
18052
|
};
|
|
17705
18053
|
function linkBdOntoPath(binaryPath) {
|
|
17706
18054
|
if (_linkSeam.platform() === "win32") return;
|
|
17707
18055
|
const binDir = _linkSeam.cliBinDir();
|
|
17708
18056
|
if (!binDir) return;
|
|
17709
18057
|
_linkSeam.ensureDir(binDir);
|
|
17710
|
-
const linkPath =
|
|
18058
|
+
const linkPath = path38.join(binDir, "bd");
|
|
17711
18059
|
if (linkPath === binaryPath) return;
|
|
17712
18060
|
const current = _linkSeam.readlink(linkPath);
|
|
17713
18061
|
if (current === binaryPath) return;
|
|
@@ -17716,22 +18064,17 @@ function linkBdOntoPath(binaryPath) {
|
|
|
17716
18064
|
log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
|
|
17717
18065
|
}
|
|
17718
18066
|
function setGitBeadsRole() {
|
|
17719
|
-
(0,
|
|
18067
|
+
(0, import_child_process17.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
|
|
17720
18068
|
stdio: "ignore"
|
|
17721
18069
|
});
|
|
17722
18070
|
}
|
|
17723
|
-
function homeBrainInitialized(beadsDir) {
|
|
17724
|
-
try {
|
|
17725
|
-
return fs30.statSync(path36.join(beadsDir, "embeddeddolt")).isDirectory();
|
|
17726
|
-
} catch {
|
|
17727
|
-
return false;
|
|
17728
|
-
}
|
|
17729
|
-
}
|
|
17730
18071
|
async function provisionBeads(opts = {}) {
|
|
17731
18072
|
const bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
17732
|
-
const beadsDir = opts.beadsDir ?? defaultBeadsHomeDir();
|
|
17733
18073
|
const result = {
|
|
17734
18074
|
bdAvailable: false,
|
|
18075
|
+
doltAvailable: false,
|
|
18076
|
+
serverUp: false,
|
|
18077
|
+
prefix: null,
|
|
17735
18078
|
initialized: false,
|
|
17736
18079
|
exportEnabled: false,
|
|
17737
18080
|
agentsWired: []
|
|
@@ -17762,24 +18105,57 @@ async function provisionBeads(opts = {}) {
|
|
|
17762
18105
|
} catch (err) {
|
|
17763
18106
|
log.trace("beads", `git config beads.role failed (non-fatal): ${err.message}`);
|
|
17764
18107
|
}
|
|
17765
|
-
if (_provisionSeam.
|
|
17766
|
-
log.
|
|
17767
|
-
|
|
17768
|
-
}
|
|
17769
|
-
|
|
17770
|
-
const
|
|
17771
|
-
if (
|
|
17772
|
-
|
|
17773
|
-
|
|
18108
|
+
if (!_provisionSeam.doltOnPath()) {
|
|
18109
|
+
log.info("beads", "dolt binary missing \u2014 running per-OS dolt installer");
|
|
18110
|
+
await _provisionSeam.installDolt();
|
|
18111
|
+
}
|
|
18112
|
+
if (!_provisionSeam.doltOnPath()) {
|
|
18113
|
+
const dir = _linkSeam.cliBinDir();
|
|
18114
|
+
if (dir) {
|
|
18115
|
+
try {
|
|
18116
|
+
_linkSeam.ensureDir(dir);
|
|
18117
|
+
} catch {
|
|
18118
|
+
}
|
|
18119
|
+
log.info("beads", `dolt still missing \u2014 no-sudo tarball fallback into ${dir}`);
|
|
18120
|
+
await _provisionSeam.installDoltToDir(dir);
|
|
17774
18121
|
}
|
|
17775
|
-
result.initialized = true;
|
|
17776
18122
|
}
|
|
18123
|
+
if (!_provisionSeam.doltOnPath()) {
|
|
18124
|
+
log.warn("beads", "dolt unavailable after install + tarball fallback \u2014 beads memory disabled this run");
|
|
18125
|
+
return result;
|
|
18126
|
+
}
|
|
18127
|
+
result.doltAvailable = true;
|
|
18128
|
+
const server = await _provisionSeam.ensureSharedServer(bd);
|
|
18129
|
+
result.serverUp = server.up;
|
|
18130
|
+
if (!server.up) {
|
|
18131
|
+
log.warn("beads", "shared dolt sql-server not up \u2014 beads disabled this run");
|
|
18132
|
+
return result;
|
|
18133
|
+
}
|
|
18134
|
+
const { projectKey } = _provisionSeam.deriveProjectIdentity(opts.cwd);
|
|
18135
|
+
const prefix = prefixForProjectKey(projectKey);
|
|
18136
|
+
result.prefix = prefix;
|
|
18137
|
+
log.info("beads", `initializing shared-server prefix DB '${prefix}' (projectKey=${projectKey})`);
|
|
18138
|
+
const init = await bd.run([
|
|
18139
|
+
"init",
|
|
18140
|
+
"-p",
|
|
18141
|
+
prefix,
|
|
18142
|
+
"--shared-server",
|
|
18143
|
+
"--skip-agents",
|
|
18144
|
+
"--skip-hooks",
|
|
18145
|
+
"--non-interactive"
|
|
18146
|
+
]);
|
|
18147
|
+
const alreadyInit = /already initialized|already exists/i.test(init.stderr + init.stdout);
|
|
18148
|
+
if (init.code !== 0 && !alreadyInit) {
|
|
18149
|
+
log.warn("beads", `bd init -p ${prefix} failed (code=${init.code}): ${init.stderr.slice(0, 200)}`);
|
|
18150
|
+
return result;
|
|
18151
|
+
}
|
|
18152
|
+
result.initialized = true;
|
|
17777
18153
|
const exp = await bd.run(["config", "set", "export.auto", "true"]);
|
|
17778
18154
|
result.exportEnabled = exp.code === 0;
|
|
17779
18155
|
result.agentsWired = await setupAgents(bd, opts.agents ?? []);
|
|
17780
18156
|
log.info(
|
|
17781
18157
|
"beads",
|
|
17782
|
-
`provision done initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
|
|
18158
|
+
`provision done dolt=${result.doltAvailable} server=${result.serverUp} prefix=${result.prefix} initialized=${result.initialized} export=${result.exportEnabled} agentsWired=[${result.agentsWired.join(",")}]`
|
|
17783
18159
|
);
|
|
17784
18160
|
return result;
|
|
17785
18161
|
}
|
|
@@ -17819,91 +18195,8 @@ function dedupeRecipes(agents) {
|
|
|
17819
18195
|
}
|
|
17820
18196
|
|
|
17821
18197
|
// src/beads/watcher.ts
|
|
17822
|
-
var
|
|
17823
|
-
var
|
|
17824
|
-
|
|
17825
|
-
// src/beads/project-key.ts
|
|
17826
|
-
var import_child_process16 = require("child_process");
|
|
17827
|
-
var crypto2 = __toESM(require("crypto"));
|
|
17828
|
-
var fs31 = __toESM(require("fs"));
|
|
17829
|
-
var path37 = __toESM(require("path"));
|
|
17830
|
-
function normalizeOrigin(raw) {
|
|
17831
|
-
const trimmed = raw.trim();
|
|
17832
|
-
if (!trimmed) return null;
|
|
17833
|
-
let host;
|
|
17834
|
-
let pathPart;
|
|
17835
|
-
const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
|
|
17836
|
-
if (scpLike && !trimmed.includes("://")) {
|
|
17837
|
-
host = scpLike[1];
|
|
17838
|
-
pathPart = scpLike[2];
|
|
17839
|
-
} else {
|
|
17840
|
-
let url;
|
|
17841
|
-
try {
|
|
17842
|
-
url = new URL(trimmed);
|
|
17843
|
-
} catch {
|
|
17844
|
-
return null;
|
|
17845
|
-
}
|
|
17846
|
-
host = url.hostname;
|
|
17847
|
-
pathPart = url.pathname;
|
|
17848
|
-
}
|
|
17849
|
-
host = host.toLowerCase();
|
|
17850
|
-
pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
17851
|
-
if (!host || !pathPart) return null;
|
|
17852
|
-
return `${host}/${pathPart}`;
|
|
17853
|
-
}
|
|
17854
|
-
function findRepoRoot(cwd) {
|
|
17855
|
-
let dir = path37.resolve(cwd);
|
|
17856
|
-
const seen = /* @__PURE__ */ new Set();
|
|
17857
|
-
for (let i = 0; i < 256; i++) {
|
|
17858
|
-
if (seen.has(dir)) return null;
|
|
17859
|
-
seen.add(dir);
|
|
17860
|
-
try {
|
|
17861
|
-
const stat3 = fs31.statSync(path37.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17862
|
-
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17863
|
-
} catch {
|
|
17864
|
-
}
|
|
17865
|
-
const parent = path37.dirname(dir);
|
|
17866
|
-
if (parent === dir) return null;
|
|
17867
|
-
dir = parent;
|
|
17868
|
-
}
|
|
17869
|
-
return null;
|
|
17870
|
-
}
|
|
17871
|
-
var _execSeam2 = {
|
|
17872
|
-
exec: (file, args2, opts) => {
|
|
17873
|
-
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
17874
|
-
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17875
|
-
},
|
|
17876
|
-
realpath: (p2) => fs31.realpathSync(p2)
|
|
17877
|
-
};
|
|
17878
|
-
function readOrigin(cwd) {
|
|
17879
|
-
try {
|
|
17880
|
-
const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
|
|
17881
|
-
cwd,
|
|
17882
|
-
timeout: 1e3,
|
|
17883
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
17884
|
-
encoding: "utf8"
|
|
17885
|
-
});
|
|
17886
|
-
return raw.trim() || null;
|
|
17887
|
-
} catch {
|
|
17888
|
-
return null;
|
|
17889
|
-
}
|
|
17890
|
-
}
|
|
17891
|
-
function deriveProjectIdentity(cwd = process.cwd()) {
|
|
17892
|
-
const repoRoot = findRepoRoot(cwd) ?? cwd;
|
|
17893
|
-
const origin = readOrigin(repoRoot);
|
|
17894
|
-
const normalized = origin ? normalizeOrigin(origin) : null;
|
|
17895
|
-
if (normalized) {
|
|
17896
|
-
const label = normalized.split("/").pop() || normalized;
|
|
17897
|
-
return { projectKey: normalized, projectLabel: label };
|
|
17898
|
-
}
|
|
17899
|
-
let real = repoRoot;
|
|
17900
|
-
try {
|
|
17901
|
-
real = _execSeam2.realpath(repoRoot);
|
|
17902
|
-
} catch {
|
|
17903
|
-
}
|
|
17904
|
-
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17905
|
-
return { projectKey: `path:${hash}`, projectLabel: path37.basename(real) || "project" };
|
|
17906
|
-
}
|
|
18198
|
+
var crypto4 = __toESM(require("crypto"));
|
|
18199
|
+
var path39 = __toESM(require("path"));
|
|
17907
18200
|
|
|
17908
18201
|
// src/services/file-watcher/transport.ts
|
|
17909
18202
|
var http5 = __toESM(require("http"));
|
|
@@ -17978,7 +18271,7 @@ var BeadsWatcher = class {
|
|
|
17978
18271
|
constructor(opts) {
|
|
17979
18272
|
this.opts = opts;
|
|
17980
18273
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
17981
|
-
this.feedPath = opts.feedPath ??
|
|
18274
|
+
this.feedPath = opts.feedPath ?? path39.join(defaultBeadsHomeDir(), "issues.jsonl");
|
|
17982
18275
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
17983
18276
|
}
|
|
17984
18277
|
opts;
|
|
@@ -18074,7 +18367,7 @@ var BeadsWatcher = class {
|
|
|
18074
18367
|
summary: summary ?? ZERO_SUMMARY
|
|
18075
18368
|
};
|
|
18076
18369
|
const body = JSON.stringify(payload);
|
|
18077
|
-
const hash =
|
|
18370
|
+
const hash = crypto4.createHash("sha256").update(body).digest("hex");
|
|
18078
18371
|
if (hash === this.lastPushedHash) {
|
|
18079
18372
|
log.trace("beads", "snapshot unchanged \u2014 skipping push");
|
|
18080
18373
|
return;
|
|
@@ -18192,6 +18485,7 @@ async function provisionBeadsForStart(ctx) {
|
|
|
18192
18485
|
return null;
|
|
18193
18486
|
}
|
|
18194
18487
|
process.env.BEADS_DIR = defaultBeadsHomeDir();
|
|
18488
|
+
process.env.BEADS_DOLT_SHARED_SERVER = "1";
|
|
18195
18489
|
if (!ctx.pluginAuthToken) {
|
|
18196
18490
|
log.trace("beads", "no pluginAuthToken \u2014 beads off");
|
|
18197
18491
|
return null;
|
|
@@ -18255,7 +18549,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18255
18549
|
function cleanupAttachmentTempFiles() {
|
|
18256
18550
|
for (const p2 of pendingAttachmentFiles) {
|
|
18257
18551
|
try {
|
|
18258
|
-
|
|
18552
|
+
fs33.unlinkSync(p2);
|
|
18259
18553
|
} catch {
|
|
18260
18554
|
}
|
|
18261
18555
|
}
|
|
@@ -18264,8 +18558,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18264
18558
|
function saveFilesTemp(files) {
|
|
18265
18559
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18266
18560
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18267
|
-
const tmpPath =
|
|
18268
|
-
|
|
18561
|
+
const tmpPath = path40.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18562
|
+
fs33.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18269
18563
|
pendingAttachmentFiles.add(tmpPath);
|
|
18270
18564
|
return tmpPath;
|
|
18271
18565
|
});
|
|
@@ -18285,7 +18579,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18285
18579
|
setTimeout(() => {
|
|
18286
18580
|
for (const p2 of paths) {
|
|
18287
18581
|
try {
|
|
18288
|
-
|
|
18582
|
+
fs33.unlinkSync(p2);
|
|
18289
18583
|
} catch {
|
|
18290
18584
|
}
|
|
18291
18585
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -18410,7 +18704,7 @@ var sessionTerminated = async (ctx, cmd) => {
|
|
|
18410
18704
|
} catch {
|
|
18411
18705
|
}
|
|
18412
18706
|
try {
|
|
18413
|
-
const proc = (0,
|
|
18707
|
+
const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
18414
18708
|
detached: true,
|
|
18415
18709
|
stdio: "ignore"
|
|
18416
18710
|
});
|
|
@@ -18432,7 +18726,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
18432
18726
|
}
|
|
18433
18727
|
if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
|
|
18434
18728
|
try {
|
|
18435
|
-
const stopProc = (0,
|
|
18729
|
+
const stopProc = (0, import_child_process18.spawn)(
|
|
18436
18730
|
"bash",
|
|
18437
18731
|
["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
|
|
18438
18732
|
{ detached: true, stdio: "ignore" }
|
|
@@ -18442,7 +18736,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
18442
18736
|
}
|
|
18443
18737
|
}
|
|
18444
18738
|
try {
|
|
18445
|
-
const proc = (0,
|
|
18739
|
+
const proc = (0, import_child_process18.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
18446
18740
|
detached: true,
|
|
18447
18741
|
stdio: "ignore"
|
|
18448
18742
|
});
|
|
@@ -18868,8 +19162,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
18868
19162
|
if (args2.length === 0) return detection;
|
|
18869
19163
|
const binName = args2[0];
|
|
18870
19164
|
if (binName.startsWith("-")) return detection;
|
|
18871
|
-
const binPath =
|
|
18872
|
-
if (!
|
|
19165
|
+
const binPath = path40.join(cwd, "node_modules", ".bin", binName);
|
|
19166
|
+
if (!fs33.existsSync(binPath)) return detection;
|
|
18873
19167
|
return {
|
|
18874
19168
|
...detection,
|
|
18875
19169
|
command: binPath,
|
|
@@ -18995,7 +19289,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
18995
19289
|
"BOOT_SEQUENCE",
|
|
18996
19290
|
`${spawnable.command} ${spawnable.args.join(" ")}`
|
|
18997
19291
|
);
|
|
18998
|
-
const devServer = (0,
|
|
19292
|
+
const devServer = (0, import_child_process18.spawn)(spawnable.command, spawnable.args, {
|
|
18999
19293
|
cwd: process.cwd(),
|
|
19000
19294
|
env: { ...process.env, ...spawnable.env ?? {} },
|
|
19001
19295
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -19123,7 +19417,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
19123
19417
|
});
|
|
19124
19418
|
return;
|
|
19125
19419
|
}
|
|
19126
|
-
tunnel = (0,
|
|
19420
|
+
tunnel = (0, import_child_process18.spawn)(bin, ["tunnel", "--url", `http://localhost:${detection.port}`], {
|
|
19127
19421
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19128
19422
|
});
|
|
19129
19423
|
let parsedUrl = null;
|
|
@@ -19298,10 +19592,10 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19298
19592
|
}
|
|
19299
19593
|
|
|
19300
19594
|
// src/services/file-watcher.service.ts
|
|
19301
|
-
var
|
|
19302
|
-
var
|
|
19303
|
-
var
|
|
19304
|
-
var
|
|
19595
|
+
var import_child_process19 = require("child_process");
|
|
19596
|
+
var fs34 = __toESM(require("fs"));
|
|
19597
|
+
var os28 = __toESM(require("os"));
|
|
19598
|
+
var path41 = __toESM(require("path"));
|
|
19305
19599
|
var import_ignore = __toESM(require("ignore"));
|
|
19306
19600
|
|
|
19307
19601
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19411,10 +19705,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19411
19705
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19412
19706
|
/[\\/]Templates([\\/]|$)/i
|
|
19413
19707
|
];
|
|
19414
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
19708
|
+
function isUnsafeWindowsWatchRoot(dir, homedir24) {
|
|
19415
19709
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19416
19710
|
const cwd = norm(dir);
|
|
19417
|
-
const home = norm(
|
|
19711
|
+
const home = norm(homedir24);
|
|
19418
19712
|
if (cwd === home) return true;
|
|
19419
19713
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19420
19714
|
const sysRoots = [
|
|
@@ -19444,18 +19738,18 @@ var _findGitRootSeam = {
|
|
|
19444
19738
|
resolve: _defaultFindGitRoot
|
|
19445
19739
|
};
|
|
19446
19740
|
function _defaultFindGitRoot(startDir) {
|
|
19447
|
-
let dir =
|
|
19741
|
+
let dir = path41.resolve(startDir);
|
|
19448
19742
|
const seen = /* @__PURE__ */ new Set();
|
|
19449
19743
|
for (let i = 0; i < 256; i++) {
|
|
19450
19744
|
if (seen.has(dir)) return null;
|
|
19451
19745
|
seen.add(dir);
|
|
19452
19746
|
try {
|
|
19453
|
-
const gitPath =
|
|
19454
|
-
const stat3 =
|
|
19747
|
+
const gitPath = path41.join(dir, ".git");
|
|
19748
|
+
const stat3 = fs34.statSync(gitPath, { throwIfNoEntry: false });
|
|
19455
19749
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19456
19750
|
} catch {
|
|
19457
19751
|
}
|
|
19458
|
-
const parent =
|
|
19752
|
+
const parent = path41.dirname(dir);
|
|
19459
19753
|
if (parent === dir) return null;
|
|
19460
19754
|
dir = parent;
|
|
19461
19755
|
}
|
|
@@ -19513,7 +19807,7 @@ var FileWatcherService = class {
|
|
|
19513
19807
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
19514
19808
|
}
|
|
19515
19809
|
const isWin = process.platform === "win32";
|
|
19516
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
19810
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os28.homedir())) {
|
|
19517
19811
|
log.warn(
|
|
19518
19812
|
"fileWatcher",
|
|
19519
19813
|
`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.`
|
|
@@ -19700,7 +19994,7 @@ var FileWatcherService = class {
|
|
|
19700
19994
|
}
|
|
19701
19995
|
async emitForFile(absPath, changeType) {
|
|
19702
19996
|
if (this.stopped) return;
|
|
19703
|
-
const fileDir =
|
|
19997
|
+
const fileDir = path41.dirname(absPath);
|
|
19704
19998
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
19705
19999
|
if (gitRoot === void 0) {
|
|
19706
20000
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -19713,19 +20007,19 @@ var FileWatcherService = class {
|
|
|
19713
20007
|
);
|
|
19714
20008
|
return;
|
|
19715
20009
|
}
|
|
19716
|
-
const relPathInRepo =
|
|
20010
|
+
const relPathInRepo = path41.relative(gitRoot, absPath);
|
|
19717
20011
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
19718
20012
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
19719
20013
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
19720
20014
|
log.trace(
|
|
19721
20015
|
"fileWatcher",
|
|
19722
|
-
`${relPathInRepo} ignored by ${
|
|
20016
|
+
`${relPathInRepo} ignored by ${path41.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
19723
20017
|
);
|
|
19724
20018
|
return;
|
|
19725
20019
|
}
|
|
19726
20020
|
this.opts.onRepoDirty?.(gitRoot);
|
|
19727
|
-
const repoPath =
|
|
19728
|
-
const repoName =
|
|
20021
|
+
const repoPath = path41.relative(this.opts.workingDir, gitRoot);
|
|
20022
|
+
const repoName = path41.basename(gitRoot);
|
|
19729
20023
|
let diffText = "";
|
|
19730
20024
|
let fileStatus = "modified";
|
|
19731
20025
|
if (changeType === "unlink") {
|
|
@@ -19900,7 +20194,7 @@ var FileWatcherService = class {
|
|
|
19900
20194
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
19901
20195
|
let entries;
|
|
19902
20196
|
try {
|
|
19903
|
-
entries =
|
|
20197
|
+
entries = fs34.readdirSync(dir, { withFileTypes: true });
|
|
19904
20198
|
} catch {
|
|
19905
20199
|
return;
|
|
19906
20200
|
}
|
|
@@ -19909,16 +20203,16 @@ var FileWatcherService = class {
|
|
|
19909
20203
|
);
|
|
19910
20204
|
if (gitignoreEntry) {
|
|
19911
20205
|
try {
|
|
19912
|
-
const body =
|
|
19913
|
-
const rel =
|
|
20206
|
+
const body = fs34.readFileSync(path41.join(dir, ".gitignore"), "utf8");
|
|
20207
|
+
const rel = path41.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
19914
20208
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
19915
20209
|
const trimmed = line.trim();
|
|
19916
20210
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
19917
20211
|
if (!rel) return line;
|
|
19918
20212
|
if (trimmed.startsWith("!")) {
|
|
19919
|
-
return "!" +
|
|
20213
|
+
return "!" + path41.posix.join(rel, trimmed.slice(1));
|
|
19920
20214
|
}
|
|
19921
|
-
return
|
|
20215
|
+
return path41.posix.join(rel, trimmed);
|
|
19922
20216
|
}).join("\n");
|
|
19923
20217
|
matcher.add(prefixed);
|
|
19924
20218
|
} catch {
|
|
@@ -19927,7 +20221,7 @@ var FileWatcherService = class {
|
|
|
19927
20221
|
for (const entry of entries) {
|
|
19928
20222
|
if (!entry.isDirectory()) continue;
|
|
19929
20223
|
if (entry.name === ".git") continue;
|
|
19930
|
-
const childAbs =
|
|
20224
|
+
const childAbs = path41.join(dir, entry.name);
|
|
19931
20225
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
19932
20226
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
19933
20227
|
}
|
|
@@ -20064,7 +20358,7 @@ async function _runGitImpl(cwd, args2, opts = {}) {
|
|
|
20064
20358
|
return new Promise((resolve7) => {
|
|
20065
20359
|
let proc;
|
|
20066
20360
|
try {
|
|
20067
|
-
proc = (0,
|
|
20361
|
+
proc = (0, import_child_process19.spawn)("git", args2, { cwd, env: process.env });
|
|
20068
20362
|
} catch {
|
|
20069
20363
|
resolve7(null);
|
|
20070
20364
|
return;
|
|
@@ -20096,8 +20390,8 @@ function _runGit(cwd, args2, opts = {}) {
|
|
|
20096
20390
|
var import_crypto4 = require("crypto");
|
|
20097
20391
|
|
|
20098
20392
|
// src/services/turn-files/git-changeset.ts
|
|
20099
|
-
var
|
|
20100
|
-
var
|
|
20393
|
+
var import_child_process20 = require("child_process");
|
|
20394
|
+
var path42 = __toESM(require("path"));
|
|
20101
20395
|
async function collectRepoChangeset(opts) {
|
|
20102
20396
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20103
20397
|
if (status2 === null) return null;
|
|
@@ -20180,7 +20474,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20180
20474
|
return new Promise((resolve7) => {
|
|
20181
20475
|
let proc;
|
|
20182
20476
|
try {
|
|
20183
|
-
proc = (0,
|
|
20477
|
+
proc = (0, import_child_process20.spawn)("git", args2, { cwd, env: process.env });
|
|
20184
20478
|
} catch {
|
|
20185
20479
|
resolve7(null);
|
|
20186
20480
|
return;
|
|
@@ -20208,7 +20502,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20208
20502
|
});
|
|
20209
20503
|
}
|
|
20210
20504
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20211
|
-
const
|
|
20505
|
+
const fs40 = await import("fs/promises");
|
|
20212
20506
|
const out2 = [];
|
|
20213
20507
|
await walk(workingDir, 0);
|
|
20214
20508
|
return out2;
|
|
@@ -20216,7 +20510,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20216
20510
|
if (depth > maxDepth) return;
|
|
20217
20511
|
let entries = [];
|
|
20218
20512
|
try {
|
|
20219
|
-
const dirents = await
|
|
20513
|
+
const dirents = await fs40.readdir(dir, { withFileTypes: true });
|
|
20220
20514
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20221
20515
|
} catch {
|
|
20222
20516
|
return;
|
|
@@ -20227,8 +20521,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20227
20521
|
if (hasGit) {
|
|
20228
20522
|
out2.push({
|
|
20229
20523
|
repoRoot: dir,
|
|
20230
|
-
repoPath:
|
|
20231
|
-
repoName:
|
|
20524
|
+
repoPath: path42.relative(workingDir, dir),
|
|
20525
|
+
repoName: path42.basename(dir)
|
|
20232
20526
|
});
|
|
20233
20527
|
return;
|
|
20234
20528
|
}
|
|
@@ -20236,14 +20530,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20236
20530
|
if (!entry.isDirectory) continue;
|
|
20237
20531
|
if (entry.name === "node_modules") continue;
|
|
20238
20532
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20239
|
-
await walk(
|
|
20533
|
+
await walk(path42.join(dir, entry.name), depth + 1);
|
|
20240
20534
|
}
|
|
20241
20535
|
}
|
|
20242
20536
|
}
|
|
20243
20537
|
|
|
20244
20538
|
// src/services/turn-files/files-outbox.ts
|
|
20245
|
-
var
|
|
20246
|
-
var
|
|
20539
|
+
var fs35 = __toESM(require("fs/promises"));
|
|
20540
|
+
var path43 = __toESM(require("path"));
|
|
20247
20541
|
var import_os7 = require("os");
|
|
20248
20542
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20249
20543
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20276,16 +20570,16 @@ var FilesOutbox = class {
|
|
|
20276
20570
|
backoffIndex = 0;
|
|
20277
20571
|
stopped = false;
|
|
20278
20572
|
constructor(opts) {
|
|
20279
|
-
const base = opts.baseDir ??
|
|
20280
|
-
this.filePath =
|
|
20573
|
+
const base = opts.baseDir ?? path43.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20574
|
+
this.filePath = path43.join(base, `${opts.sessionId}.jsonl`);
|
|
20281
20575
|
this.post = opts.post;
|
|
20282
20576
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20283
20577
|
}
|
|
20284
20578
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20285
20579
|
* line is durable on disk (not once the POST succeeds). */
|
|
20286
20580
|
async enqueue(entry) {
|
|
20287
|
-
await
|
|
20288
|
-
await
|
|
20581
|
+
await fs35.mkdir(path43.dirname(this.filePath), { recursive: true });
|
|
20582
|
+
await fs35.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20289
20583
|
this.backoffIndex = 0;
|
|
20290
20584
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20291
20585
|
}
|
|
@@ -20374,7 +20668,7 @@ var FilesOutbox = class {
|
|
|
20374
20668
|
async readAll() {
|
|
20375
20669
|
let raw = "";
|
|
20376
20670
|
try {
|
|
20377
|
-
raw = await
|
|
20671
|
+
raw = await fs35.readFile(this.filePath, "utf8");
|
|
20378
20672
|
} catch {
|
|
20379
20673
|
return [];
|
|
20380
20674
|
}
|
|
@@ -20398,12 +20692,12 @@ var FilesOutbox = class {
|
|
|
20398
20692
|
async rewrite(entries) {
|
|
20399
20693
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20400
20694
|
if (entries.length === 0) {
|
|
20401
|
-
await
|
|
20695
|
+
await fs35.unlink(this.filePath).catch(() => void 0);
|
|
20402
20696
|
return;
|
|
20403
20697
|
}
|
|
20404
20698
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20405
|
-
await
|
|
20406
|
-
await
|
|
20699
|
+
await fs35.writeFile(tmpPath, payload, "utf8");
|
|
20700
|
+
await fs35.rename(tmpPath, this.filePath);
|
|
20407
20701
|
}
|
|
20408
20702
|
};
|
|
20409
20703
|
function applyJitter(ms) {
|
|
@@ -22210,9 +22504,9 @@ var OutputService = class _OutputService {
|
|
|
22210
22504
|
};
|
|
22211
22505
|
|
|
22212
22506
|
// src/services/history.service.ts
|
|
22213
|
-
var
|
|
22214
|
-
var
|
|
22215
|
-
var
|
|
22507
|
+
var fs36 = __toESM(require("fs"));
|
|
22508
|
+
var path44 = __toESM(require("path"));
|
|
22509
|
+
var os29 = __toESM(require("os"));
|
|
22216
22510
|
var https7 = __toESM(require("https"));
|
|
22217
22511
|
var http7 = __toESM(require("http"));
|
|
22218
22512
|
var import_zod2 = require("zod");
|
|
@@ -22239,7 +22533,7 @@ function parseJsonl(filePath) {
|
|
|
22239
22533
|
const messages = [];
|
|
22240
22534
|
let raw;
|
|
22241
22535
|
try {
|
|
22242
|
-
raw =
|
|
22536
|
+
raw = fs36.readFileSync(filePath, "utf8");
|
|
22243
22537
|
} catch (err) {
|
|
22244
22538
|
if (err.code !== "ENOENT") {
|
|
22245
22539
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22374,7 +22668,7 @@ var HistoryService = class _HistoryService {
|
|
|
22374
22668
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22375
22669
|
}
|
|
22376
22670
|
get projectDir() {
|
|
22377
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
22671
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path44.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22378
22672
|
}
|
|
22379
22673
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22380
22674
|
setCurrentConversationId(id) {
|
|
@@ -22386,7 +22680,7 @@ var HistoryService = class _HistoryService {
|
|
|
22386
22680
|
/** Return the current message count in the active conversation. */
|
|
22387
22681
|
getCurrentMessageCount() {
|
|
22388
22682
|
if (!this.currentConversationId) return 0;
|
|
22389
|
-
const filePath =
|
|
22683
|
+
const filePath = path44.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22390
22684
|
return parseJsonl(filePath).length;
|
|
22391
22685
|
}
|
|
22392
22686
|
/**
|
|
@@ -22397,7 +22691,7 @@ var HistoryService = class _HistoryService {
|
|
|
22397
22691
|
const deadline = Date.now() + timeoutMs;
|
|
22398
22692
|
while (Date.now() < deadline) {
|
|
22399
22693
|
if (!this.currentConversationId) return null;
|
|
22400
|
-
const filePath =
|
|
22694
|
+
const filePath = path44.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22401
22695
|
const messages = parseJsonl(filePath);
|
|
22402
22696
|
if (messages.length > previousCount) {
|
|
22403
22697
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22423,16 +22717,16 @@ var HistoryService = class _HistoryService {
|
|
|
22423
22717
|
const dir = this.projectDir;
|
|
22424
22718
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22425
22719
|
try {
|
|
22426
|
-
const files =
|
|
22720
|
+
const files = fs36.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22427
22721
|
try {
|
|
22428
|
-
const stat3 =
|
|
22722
|
+
const stat3 = fs36.statSync(path44.join(dir, e.name));
|
|
22429
22723
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22430
22724
|
} catch {
|
|
22431
22725
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22432
22726
|
}
|
|
22433
22727
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22434
22728
|
if (files.length > 0) {
|
|
22435
|
-
this.currentConversationId =
|
|
22729
|
+
this.currentConversationId = path44.basename(files[0].name, ".jsonl");
|
|
22436
22730
|
}
|
|
22437
22731
|
} catch {
|
|
22438
22732
|
}
|
|
@@ -22466,13 +22760,13 @@ var HistoryService = class _HistoryService {
|
|
|
22466
22760
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22467
22761
|
let entries;
|
|
22468
22762
|
try {
|
|
22469
|
-
entries =
|
|
22763
|
+
entries = fs36.readdirSync(dir, { withFileTypes: true });
|
|
22470
22764
|
} catch {
|
|
22471
22765
|
return null;
|
|
22472
22766
|
}
|
|
22473
22767
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22474
22768
|
try {
|
|
22475
|
-
const stat3 =
|
|
22769
|
+
const stat3 = fs36.statSync(path44.join(dir, e.name));
|
|
22476
22770
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22477
22771
|
} catch {
|
|
22478
22772
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22481,12 +22775,12 @@ var HistoryService = class _HistoryService {
|
|
|
22481
22775
|
if (files.length === 0) return null;
|
|
22482
22776
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22483
22777
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22484
|
-
return this.extractUsageFromFile(
|
|
22778
|
+
return this.extractUsageFromFile(path44.join(dir, targetFile));
|
|
22485
22779
|
}
|
|
22486
22780
|
extractUsageFromFile(filePath) {
|
|
22487
22781
|
let raw;
|
|
22488
22782
|
try {
|
|
22489
|
-
raw =
|
|
22783
|
+
raw = fs36.readFileSync(filePath, "utf8");
|
|
22490
22784
|
} catch {
|
|
22491
22785
|
return null;
|
|
22492
22786
|
}
|
|
@@ -22531,9 +22825,9 @@ var HistoryService = class _HistoryService {
|
|
|
22531
22825
|
let totalCost = 0;
|
|
22532
22826
|
let files;
|
|
22533
22827
|
try {
|
|
22534
|
-
files =
|
|
22828
|
+
files = fs36.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22535
22829
|
try {
|
|
22536
|
-
return
|
|
22830
|
+
return fs36.statSync(path44.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22537
22831
|
} catch {
|
|
22538
22832
|
return false;
|
|
22539
22833
|
}
|
|
@@ -22544,7 +22838,7 @@ var HistoryService = class _HistoryService {
|
|
|
22544
22838
|
for (const file of files) {
|
|
22545
22839
|
let raw;
|
|
22546
22840
|
try {
|
|
22547
|
-
raw =
|
|
22841
|
+
raw = fs36.readFileSync(path44.join(projectDir, file), "utf8");
|
|
22548
22842
|
} catch {
|
|
22549
22843
|
continue;
|
|
22550
22844
|
}
|
|
@@ -22608,7 +22902,7 @@ var HistoryService = class _HistoryService {
|
|
|
22608
22902
|
* showing an empty conversation.
|
|
22609
22903
|
*/
|
|
22610
22904
|
async loadConversation(sessionId) {
|
|
22611
|
-
const filePath =
|
|
22905
|
+
const filePath = path44.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22612
22906
|
const messages = parseJsonl(filePath);
|
|
22613
22907
|
if (messages.length === 0) return;
|
|
22614
22908
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -22662,7 +22956,7 @@ var HistoryService = class _HistoryService {
|
|
|
22662
22956
|
if (!this.currentConversationId) return 0;
|
|
22663
22957
|
}
|
|
22664
22958
|
const sessionId = this.currentConversationId;
|
|
22665
|
-
const filePath =
|
|
22959
|
+
const filePath = path44.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22666
22960
|
const messages = parseJsonl(filePath);
|
|
22667
22961
|
if (messages.length === 0) return 0;
|
|
22668
22962
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -23088,13 +23382,13 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
23088
23382
|
}
|
|
23089
23383
|
|
|
23090
23384
|
// src/commands/start/keep-alive.ts
|
|
23091
|
-
var
|
|
23385
|
+
var import_child_process21 = require("child_process");
|
|
23092
23386
|
function buildKeepAlive(ctx) {
|
|
23093
23387
|
let timer = null;
|
|
23094
23388
|
async function setIdleTimeout(minutes) {
|
|
23095
23389
|
if (!ctx.inCodespace || !ctx.codespaceName) return;
|
|
23096
23390
|
await new Promise((resolve7) => {
|
|
23097
|
-
const proc = (0,
|
|
23391
|
+
const proc = (0, import_child_process21.spawn)(
|
|
23098
23392
|
"gh",
|
|
23099
23393
|
[
|
|
23100
23394
|
"api",
|
|
@@ -23579,8 +23873,8 @@ async function autoLinkAfterPair(opts) {
|
|
|
23579
23873
|
}
|
|
23580
23874
|
|
|
23581
23875
|
// src/commands/pair-auto.ts
|
|
23582
|
-
var
|
|
23583
|
-
var
|
|
23876
|
+
var fs37 = __toESM(require("fs"));
|
|
23877
|
+
var os30 = __toESM(require("os"));
|
|
23584
23878
|
var import_crypto7 = require("crypto");
|
|
23585
23879
|
|
|
23586
23880
|
// src/commands/start-infra-only.ts
|
|
@@ -23775,12 +24069,12 @@ function readTokenFromArgs(args2) {
|
|
|
23775
24069
|
}
|
|
23776
24070
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
23777
24071
|
if (fileFlag) {
|
|
23778
|
-
const
|
|
24072
|
+
const path51 = fileFlag.slice("--token-file=".length);
|
|
23779
24073
|
try {
|
|
23780
|
-
const content =
|
|
23781
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24074
|
+
const content = fs37.readFileSync(path51, "utf8").trim();
|
|
24075
|
+
if (content.length === 0) fail(`--token-file ${path51} is empty`);
|
|
23782
24076
|
try {
|
|
23783
|
-
|
|
24077
|
+
fs37.unlinkSync(path51);
|
|
23784
24078
|
} catch {
|
|
23785
24079
|
}
|
|
23786
24080
|
return content;
|
|
@@ -23806,7 +24100,7 @@ async function claimOnce(token, pluginId) {
|
|
|
23806
24100
|
pluginId,
|
|
23807
24101
|
ideName: "codeam-cli (codespace)",
|
|
23808
24102
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
23809
|
-
hostname:
|
|
24103
|
+
hostname: os30.hostname(),
|
|
23810
24104
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
23811
24105
|
// Current git branch of the codespace's working directory, so the
|
|
23812
24106
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24043,11 +24337,11 @@ async function logout() {
|
|
|
24043
24337
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
24044
24338
|
|
|
24045
24339
|
// src/services/providers/github-codespaces.ts
|
|
24046
|
-
var
|
|
24340
|
+
var import_child_process22 = require("child_process");
|
|
24047
24341
|
var import_util4 = require("util");
|
|
24048
24342
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24049
|
-
var
|
|
24050
|
-
var execFileP5 = (0, import_util4.promisify)(
|
|
24343
|
+
var path45 = __toESM(require("path"));
|
|
24344
|
+
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24051
24345
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24052
24346
|
function resetStdinForChild() {
|
|
24053
24347
|
if (process.stdin.isTTY) {
|
|
@@ -24091,7 +24385,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24091
24385
|
if (!isAuthed) {
|
|
24092
24386
|
resetStdinForChild();
|
|
24093
24387
|
await new Promise((resolve7, reject) => {
|
|
24094
|
-
const proc = (0,
|
|
24388
|
+
const proc = (0, import_child_process22.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
|
|
24095
24389
|
stdio: "inherit"
|
|
24096
24390
|
});
|
|
24097
24391
|
proc.on("exit", (code) => {
|
|
@@ -24125,7 +24419,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24125
24419
|
wt(noteLines.join("\n"), "One more permission needed");
|
|
24126
24420
|
resetStdinForChild();
|
|
24127
24421
|
const refreshCode = await new Promise((resolve7, reject) => {
|
|
24128
|
-
const proc = (0,
|
|
24422
|
+
const proc = (0, import_child_process22.spawn)(
|
|
24129
24423
|
"gh",
|
|
24130
24424
|
["auth", "refresh", "-h", "github.com", "-s", "codespace"],
|
|
24131
24425
|
{ stdio: "inherit" }
|
|
@@ -24275,7 +24569,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24275
24569
|
O2.step(`Installing gh via ${installCmd.describe}\u2026`);
|
|
24276
24570
|
resetStdinForChild();
|
|
24277
24571
|
const ok = await new Promise((resolve7) => {
|
|
24278
|
-
const proc = (0,
|
|
24572
|
+
const proc = (0, import_child_process22.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
|
|
24279
24573
|
proc.on("exit", (code) => resolve7(code === 0));
|
|
24280
24574
|
proc.on("error", () => resolve7(false));
|
|
24281
24575
|
});
|
|
@@ -24302,7 +24596,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24302
24596
|
);
|
|
24303
24597
|
resetStdinForChild();
|
|
24304
24598
|
await new Promise((resolve7, reject) => {
|
|
24305
|
-
const proc = (0,
|
|
24599
|
+
const proc = (0, import_child_process22.spawn)(
|
|
24306
24600
|
"gh",
|
|
24307
24601
|
["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
|
|
24308
24602
|
{ stdio: "inherit" }
|
|
@@ -24480,7 +24774,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24480
24774
|
async streamCommand(workspaceId, command2) {
|
|
24481
24775
|
resetStdinForChild();
|
|
24482
24776
|
return new Promise((resolve7, reject) => {
|
|
24483
|
-
const proc = (0,
|
|
24777
|
+
const proc = (0, import_child_process22.spawn)(
|
|
24484
24778
|
"gh",
|
|
24485
24779
|
["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
|
|
24486
24780
|
{ stdio: "inherit" }
|
|
@@ -24507,11 +24801,11 @@ var GitHubCodespacesProvider = class {
|
|
|
24507
24801
|
`mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
|
|
24508
24802
|
];
|
|
24509
24803
|
await new Promise((resolve7, reject) => {
|
|
24510
|
-
const tar = (0,
|
|
24804
|
+
const tar = (0, import_child_process22.spawn)("tar", tarArgs, {
|
|
24511
24805
|
stdio: ["ignore", "pipe", "pipe"],
|
|
24512
24806
|
env: tarEnv
|
|
24513
24807
|
});
|
|
24514
|
-
const ssh = (0,
|
|
24808
|
+
const ssh = (0, import_child_process22.spawn)("gh", sshArgs, {
|
|
24515
24809
|
stdio: [tar.stdout, "pipe", "pipe"]
|
|
24516
24810
|
});
|
|
24517
24811
|
let tarErr = "";
|
|
@@ -24535,7 +24829,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24535
24829
|
});
|
|
24536
24830
|
}
|
|
24537
24831
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24538
|
-
const remoteDir =
|
|
24832
|
+
const remoteDir = path45.posix.dirname(remotePath);
|
|
24539
24833
|
const parts = [
|
|
24540
24834
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
24541
24835
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -24545,7 +24839,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24545
24839
|
}
|
|
24546
24840
|
const cmd = parts.join(" && ");
|
|
24547
24841
|
await new Promise((resolve7, reject) => {
|
|
24548
|
-
const proc = (0,
|
|
24842
|
+
const proc = (0, import_child_process22.spawn)(
|
|
24549
24843
|
"gh",
|
|
24550
24844
|
["codespace", "ssh", "-c", workspaceId, "--", cmd],
|
|
24551
24845
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -24603,11 +24897,11 @@ function shellQuote(s) {
|
|
|
24603
24897
|
}
|
|
24604
24898
|
|
|
24605
24899
|
// src/services/providers/gitpod.ts
|
|
24606
|
-
var
|
|
24900
|
+
var import_child_process23 = require("child_process");
|
|
24607
24901
|
var import_util5 = require("util");
|
|
24608
|
-
var
|
|
24902
|
+
var path46 = __toESM(require("path"));
|
|
24609
24903
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
24610
|
-
var execFileP6 = (0, import_util5.promisify)(
|
|
24904
|
+
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
24611
24905
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
24612
24906
|
function resetStdinForChild2() {
|
|
24613
24907
|
if (process.stdin.isTTY) {
|
|
@@ -24647,7 +24941,7 @@ var GitpodProvider = class {
|
|
|
24647
24941
|
);
|
|
24648
24942
|
resetStdinForChild2();
|
|
24649
24943
|
await new Promise((resolve7, reject) => {
|
|
24650
|
-
const proc = (0,
|
|
24944
|
+
const proc = (0, import_child_process23.spawn)("gitpod", ["login"], { stdio: "inherit" });
|
|
24651
24945
|
proc.on("exit", (code) => {
|
|
24652
24946
|
if (code === 0) resolve7();
|
|
24653
24947
|
else reject(new Error("gitpod login failed."));
|
|
@@ -24799,7 +25093,7 @@ var GitpodProvider = class {
|
|
|
24799
25093
|
async streamCommand(workspaceId, command2) {
|
|
24800
25094
|
resetStdinForChild2();
|
|
24801
25095
|
return new Promise((resolve7, reject) => {
|
|
24802
|
-
const proc = (0,
|
|
25096
|
+
const proc = (0, import_child_process23.spawn)(
|
|
24803
25097
|
"gitpod",
|
|
24804
25098
|
["workspace", "ssh", workspaceId, "--", "-tt", command2],
|
|
24805
25099
|
{ stdio: "inherit" }
|
|
@@ -24819,11 +25113,11 @@ var GitpodProvider = class {
|
|
|
24819
25113
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
24820
25114
|
const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
|
|
24821
25115
|
await new Promise((resolve7, reject) => {
|
|
24822
|
-
const tar = (0,
|
|
25116
|
+
const tar = (0, import_child_process23.spawn)("tar", tarArgs, {
|
|
24823
25117
|
stdio: ["ignore", "pipe", "pipe"],
|
|
24824
25118
|
env: tarEnv
|
|
24825
25119
|
});
|
|
24826
|
-
const ssh = (0,
|
|
25120
|
+
const ssh = (0, import_child_process23.spawn)(
|
|
24827
25121
|
"gitpod",
|
|
24828
25122
|
["workspace", "ssh", workspaceId, "--", remoteCmd],
|
|
24829
25123
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -24845,7 +25139,7 @@ var GitpodProvider = class {
|
|
|
24845
25139
|
});
|
|
24846
25140
|
}
|
|
24847
25141
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24848
|
-
const remoteDir =
|
|
25142
|
+
const remoteDir = path46.posix.dirname(remotePath);
|
|
24849
25143
|
const parts = [
|
|
24850
25144
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
24851
25145
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -24855,7 +25149,7 @@ var GitpodProvider = class {
|
|
|
24855
25149
|
}
|
|
24856
25150
|
const cmd = parts.join(" && ");
|
|
24857
25151
|
await new Promise((resolve7, reject) => {
|
|
24858
|
-
const proc = (0,
|
|
25152
|
+
const proc = (0, import_child_process23.spawn)(
|
|
24859
25153
|
"gitpod",
|
|
24860
25154
|
["workspace", "ssh", workspaceId, "--", cmd],
|
|
24861
25155
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -24879,10 +25173,10 @@ function shellQuote2(s) {
|
|
|
24879
25173
|
}
|
|
24880
25174
|
|
|
24881
25175
|
// src/services/providers/gitlab-workspaces.ts
|
|
24882
|
-
var
|
|
25176
|
+
var import_child_process24 = require("child_process");
|
|
24883
25177
|
var import_util6 = require("util");
|
|
24884
|
-
var
|
|
24885
|
-
var execFileP7 = (0, import_util6.promisify)(
|
|
25178
|
+
var path47 = __toESM(require("path"));
|
|
25179
|
+
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
24886
25180
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
24887
25181
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
24888
25182
|
function resetStdinForChild3() {
|
|
@@ -24924,7 +25218,7 @@ var GitLabWorkspacesProvider = class {
|
|
|
24924
25218
|
);
|
|
24925
25219
|
resetStdinForChild3();
|
|
24926
25220
|
await new Promise((resolve7, reject) => {
|
|
24927
|
-
const proc = (0,
|
|
25221
|
+
const proc = (0, import_child_process24.spawn)(
|
|
24928
25222
|
"glab",
|
|
24929
25223
|
["auth", "login", "--scopes", "api,read_user,read_repository"],
|
|
24930
25224
|
{ stdio: "inherit" }
|
|
@@ -25096,7 +25390,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25096
25390
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25097
25391
|
resetStdinForChild3();
|
|
25098
25392
|
return new Promise((resolve7, reject) => {
|
|
25099
|
-
const proc = (0,
|
|
25393
|
+
const proc = (0, import_child_process24.spawn)(
|
|
25100
25394
|
"ssh",
|
|
25101
25395
|
["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
|
|
25102
25396
|
{ stdio: "inherit" }
|
|
@@ -25117,8 +25411,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25117
25411
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
25118
25412
|
const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
|
|
25119
25413
|
await new Promise((resolve7, reject) => {
|
|
25120
|
-
const tar = (0,
|
|
25121
|
-
const ssh = (0,
|
|
25414
|
+
const tar = (0, import_child_process24.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
25415
|
+
const ssh = (0, import_child_process24.spawn)(
|
|
25122
25416
|
"ssh",
|
|
25123
25417
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
|
|
25124
25418
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -25141,14 +25435,14 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25141
25435
|
}
|
|
25142
25436
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25143
25437
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25144
|
-
const remoteDir =
|
|
25438
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25145
25439
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25146
25440
|
if (options.mode != null) {
|
|
25147
25441
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
25148
25442
|
}
|
|
25149
25443
|
const cmd = parts.join(" && ");
|
|
25150
25444
|
await new Promise((resolve7, reject) => {
|
|
25151
|
-
const proc = (0,
|
|
25445
|
+
const proc = (0, import_child_process24.spawn)(
|
|
25152
25446
|
"ssh",
|
|
25153
25447
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
|
|
25154
25448
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -25207,10 +25501,10 @@ function shellQuote3(s) {
|
|
|
25207
25501
|
}
|
|
25208
25502
|
|
|
25209
25503
|
// src/services/providers/railway.ts
|
|
25210
|
-
var
|
|
25504
|
+
var import_child_process25 = require("child_process");
|
|
25211
25505
|
var import_util7 = require("util");
|
|
25212
|
-
var
|
|
25213
|
-
var execFileP8 = (0, import_util7.promisify)(
|
|
25506
|
+
var path48 = __toESM(require("path"));
|
|
25507
|
+
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25214
25508
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25215
25509
|
function resetStdinForChild4() {
|
|
25216
25510
|
if (process.stdin.isTTY) {
|
|
@@ -25251,7 +25545,7 @@ var RailwayProvider = class {
|
|
|
25251
25545
|
);
|
|
25252
25546
|
resetStdinForChild4();
|
|
25253
25547
|
await new Promise((resolve7, reject) => {
|
|
25254
|
-
const proc = (0,
|
|
25548
|
+
const proc = (0, import_child_process25.spawn)("railway", ["login"], { stdio: "inherit" });
|
|
25255
25549
|
proc.on("exit", (code) => {
|
|
25256
25550
|
if (code === 0) resolve7();
|
|
25257
25551
|
else reject(new Error("railway login failed."));
|
|
@@ -25394,7 +25688,7 @@ var RailwayProvider = class {
|
|
|
25394
25688
|
}
|
|
25395
25689
|
resetStdinForChild4();
|
|
25396
25690
|
return new Promise((resolve7, reject) => {
|
|
25397
|
-
const proc = (0,
|
|
25691
|
+
const proc = (0, import_child_process25.spawn)(
|
|
25398
25692
|
"railway",
|
|
25399
25693
|
["shell", "--project", projectId, "--service", serviceId, "--command", command2],
|
|
25400
25694
|
{ stdio: "inherit" }
|
|
@@ -25418,8 +25712,8 @@ var RailwayProvider = class {
|
|
|
25418
25712
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
25419
25713
|
const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
|
|
25420
25714
|
await new Promise((resolve7, reject) => {
|
|
25421
|
-
const tar = (0,
|
|
25422
|
-
const sh = (0,
|
|
25715
|
+
const tar = (0, import_child_process25.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
25716
|
+
const sh = (0, import_child_process25.spawn)(
|
|
25423
25717
|
"railway",
|
|
25424
25718
|
["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
|
|
25425
25719
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -25445,14 +25739,14 @@ var RailwayProvider = class {
|
|
|
25445
25739
|
if (!projectId || !serviceId) {
|
|
25446
25740
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25447
25741
|
}
|
|
25448
|
-
const remoteDir =
|
|
25742
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25449
25743
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25450
25744
|
if (options.mode != null) {
|
|
25451
25745
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
25452
25746
|
}
|
|
25453
25747
|
const cmd = parts.join(" && ");
|
|
25454
25748
|
await new Promise((resolve7, reject) => {
|
|
25455
|
-
const proc = (0,
|
|
25749
|
+
const proc = (0, import_child_process25.spawn)(
|
|
25456
25750
|
"railway",
|
|
25457
25751
|
["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
|
|
25458
25752
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -25988,8 +26282,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
25988
26282
|
var import_node_dns = require("dns");
|
|
25989
26283
|
var import_node_util4 = require("util");
|
|
25990
26284
|
var import_node_crypto8 = require("crypto");
|
|
25991
|
-
var
|
|
25992
|
-
var
|
|
26285
|
+
var fs38 = __toESM(require("fs"));
|
|
26286
|
+
var path49 = __toESM(require("path"));
|
|
25993
26287
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
25994
26288
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
25995
26289
|
async function checkDns(apiBase) {
|
|
@@ -26045,13 +26339,13 @@ async function checkHealth(apiBase) {
|
|
|
26045
26339
|
}
|
|
26046
26340
|
}
|
|
26047
26341
|
function checkConfigDir() {
|
|
26048
|
-
const dir =
|
|
26342
|
+
const dir = path49.join(require("os").homedir(), ".codeam");
|
|
26049
26343
|
try {
|
|
26050
|
-
|
|
26051
|
-
const probe =
|
|
26052
|
-
|
|
26053
|
-
const read =
|
|
26054
|
-
|
|
26344
|
+
fs38.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26345
|
+
const probe = path49.join(dir, ".doctor-probe");
|
|
26346
|
+
fs38.writeFileSync(probe, "ok", { mode: 384 });
|
|
26347
|
+
const read = fs38.readFileSync(probe, "utf8");
|
|
26348
|
+
fs38.unlinkSync(probe);
|
|
26055
26349
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26056
26350
|
return {
|
|
26057
26351
|
id: "config-dir",
|
|
@@ -26091,9 +26385,9 @@ function checkSessions() {
|
|
|
26091
26385
|
}
|
|
26092
26386
|
}
|
|
26093
26387
|
function checkAgentBinaries() {
|
|
26094
|
-
const
|
|
26388
|
+
const os32 = createOsStrategy();
|
|
26095
26389
|
return getEnabledAgents().map((meta) => {
|
|
26096
|
-
const found =
|
|
26390
|
+
const found = os32.findInPath(meta.binaryName);
|
|
26097
26391
|
return {
|
|
26098
26392
|
id: `agent-${meta.id}`,
|
|
26099
26393
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -26115,7 +26409,7 @@ function checkNodePty() {
|
|
|
26115
26409
|
detail: "not required on this platform"
|
|
26116
26410
|
};
|
|
26117
26411
|
}
|
|
26118
|
-
const vendoredPath =
|
|
26412
|
+
const vendoredPath = path49.join(__dirname, "vendor", "node-pty");
|
|
26119
26413
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26120
26414
|
try {
|
|
26121
26415
|
require(target);
|
|
@@ -26157,7 +26451,7 @@ function checkChokidar() {
|
|
|
26157
26451
|
}
|
|
26158
26452
|
async function doctor(args2 = []) {
|
|
26159
26453
|
const json = args2.includes("--json");
|
|
26160
|
-
const cliVersion = true ? "2.
|
|
26454
|
+
const cliVersion = true ? "2.36.0" : "0.0.0-dev";
|
|
26161
26455
|
const apiBase = resolveApiBaseUrl();
|
|
26162
26456
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26163
26457
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26356,7 +26650,7 @@ async function completion(args2) {
|
|
|
26356
26650
|
// src/commands/version.ts
|
|
26357
26651
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26358
26652
|
function version2() {
|
|
26359
|
-
const v = true ? "2.
|
|
26653
|
+
const v = true ? "2.36.0" : "unknown";
|
|
26360
26654
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26361
26655
|
}
|
|
26362
26656
|
|
|
@@ -26484,9 +26778,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26484
26778
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26485
26779
|
|
|
26486
26780
|
// src/lib/updateNotifier.ts
|
|
26487
|
-
var
|
|
26488
|
-
var
|
|
26489
|
-
var
|
|
26781
|
+
var fs39 = __toESM(require("fs"));
|
|
26782
|
+
var os31 = __toESM(require("os"));
|
|
26783
|
+
var path50 = __toESM(require("path"));
|
|
26490
26784
|
var https8 = __toESM(require("https"));
|
|
26491
26785
|
var import_node_child_process12 = require("child_process");
|
|
26492
26786
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26495,12 +26789,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26495
26789
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26496
26790
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26497
26791
|
function cachePath() {
|
|
26498
|
-
const dir =
|
|
26499
|
-
return
|
|
26792
|
+
const dir = path50.join(os31.homedir(), ".codeam");
|
|
26793
|
+
return path50.join(dir, "update-check.json");
|
|
26500
26794
|
}
|
|
26501
26795
|
function readCache() {
|
|
26502
26796
|
try {
|
|
26503
|
-
const raw =
|
|
26797
|
+
const raw = fs39.readFileSync(cachePath(), "utf8");
|
|
26504
26798
|
const parsed = JSON.parse(raw);
|
|
26505
26799
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26506
26800
|
return parsed;
|
|
@@ -26511,10 +26805,10 @@ function readCache() {
|
|
|
26511
26805
|
function writeCache(cache) {
|
|
26512
26806
|
try {
|
|
26513
26807
|
const file = cachePath();
|
|
26514
|
-
|
|
26808
|
+
fs39.mkdirSync(path50.dirname(file), { recursive: true });
|
|
26515
26809
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
26516
|
-
|
|
26517
|
-
|
|
26810
|
+
fs39.writeFileSync(tmp, JSON.stringify(cache));
|
|
26811
|
+
fs39.renameSync(tmp, file);
|
|
26518
26812
|
} catch {
|
|
26519
26813
|
}
|
|
26520
26814
|
}
|
|
@@ -26588,8 +26882,8 @@ function isLinkedInstall() {
|
|
|
26588
26882
|
timeout: 2e3
|
|
26589
26883
|
}).trim();
|
|
26590
26884
|
if (!root) return false;
|
|
26591
|
-
const pkgPath =
|
|
26592
|
-
return
|
|
26885
|
+
const pkgPath = path50.join(root, PKG_NAME);
|
|
26886
|
+
return fs39.lstatSync(pkgPath).isSymbolicLink();
|
|
26593
26887
|
} catch {
|
|
26594
26888
|
return false;
|
|
26595
26889
|
}
|
|
@@ -26625,7 +26919,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
26625
26919
|
return;
|
|
26626
26920
|
}
|
|
26627
26921
|
try {
|
|
26628
|
-
|
|
26922
|
+
fs39.unlinkSync(cachePath());
|
|
26629
26923
|
} catch {
|
|
26630
26924
|
}
|
|
26631
26925
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -26642,7 +26936,7 @@ function checkForUpdates() {
|
|
|
26642
26936
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
26643
26937
|
if (process.env.CI) return;
|
|
26644
26938
|
if (!process.stdout.isTTY) return;
|
|
26645
|
-
const current = true ? "2.
|
|
26939
|
+
const current = true ? "2.36.0" : null;
|
|
26646
26940
|
if (!current) return;
|
|
26647
26941
|
const cache = readCache();
|
|
26648
26942
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|