codeam-cli 2.36.5 → 2.37.1
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 +6 -0
- package/dist/index.js +348 -252
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -498,7 +498,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
498
498
|
// package.json
|
|
499
499
|
var package_default = {
|
|
500
500
|
name: "codeam-cli",
|
|
501
|
-
version: "2.
|
|
501
|
+
version: "2.37.1",
|
|
502
502
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
503
503
|
type: "commonjs",
|
|
504
504
|
main: "dist/index.js",
|
|
@@ -1186,8 +1186,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1186
1186
|
return decodedFile;
|
|
1187
1187
|
};
|
|
1188
1188
|
}
|
|
1189
|
-
function normalizeWindowsPath(
|
|
1190
|
-
return
|
|
1189
|
+
function normalizeWindowsPath(path52) {
|
|
1190
|
+
return path52.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1191
1191
|
}
|
|
1192
1192
|
|
|
1193
1193
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3667,9 +3667,9 @@ async function addSourceContext(frames) {
|
|
|
3667
3667
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3668
3668
|
return frames;
|
|
3669
3669
|
}
|
|
3670
|
-
function getContextLinesFromFile(
|
|
3670
|
+
function getContextLinesFromFile(path52, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path52);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path51, ranges, output) {
|
|
|
3684
3684
|
let rangeStart = range[0];
|
|
3685
3685
|
let rangeEnd = range[1];
|
|
3686
3686
|
function onStreamError() {
|
|
3687
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3687
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path52, 1);
|
|
3688
3688
|
lineReaded.close();
|
|
3689
3689
|
lineReaded.removeAllListeners();
|
|
3690
3690
|
destroyStreamAndResolve();
|
|
@@ -3745,8 +3745,8 @@ function clearLineContext(frame) {
|
|
|
3745
3745
|
delete frame.context_line;
|
|
3746
3746
|
delete frame.post_context;
|
|
3747
3747
|
}
|
|
3748
|
-
function shouldSkipContextLinesForFile(
|
|
3749
|
-
return
|
|
3748
|
+
function shouldSkipContextLinesForFile(path52) {
|
|
3749
|
+
return path52.startsWith("node:") || path52.endsWith(".min.js") || path52.endsWith(".min.cjs") || path52.endsWith(".min.mjs") || path52.startsWith("data:");
|
|
3750
3750
|
}
|
|
3751
3751
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3752
3752
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5900,7 +5900,7 @@ function readAnonId() {
|
|
|
5900
5900
|
}
|
|
5901
5901
|
function superProperties() {
|
|
5902
5902
|
return {
|
|
5903
|
-
cliVersion: true ? "2.
|
|
5903
|
+
cliVersion: true ? "2.37.1" : "0.0.0-dev",
|
|
5904
5904
|
nodeVersion: process.version,
|
|
5905
5905
|
platform: process.platform,
|
|
5906
5906
|
arch: process.arch,
|
|
@@ -7248,10 +7248,10 @@ function buildForPlatform(platform2) {
|
|
|
7248
7248
|
var import_node_crypto4 = require("crypto");
|
|
7249
7249
|
|
|
7250
7250
|
// src/agents/claude/resolver.ts
|
|
7251
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
7252
|
-
const found =
|
|
7251
|
+
function buildClaudeLaunch(extraArgs = [], os32 = createOsStrategy()) {
|
|
7252
|
+
const found = os32.findInPath("claude") ?? os32.findInPath("claude-code");
|
|
7253
7253
|
if (!found) return null;
|
|
7254
|
-
return
|
|
7254
|
+
return os32.buildLaunch(found, extraArgs);
|
|
7255
7255
|
}
|
|
7256
7256
|
|
|
7257
7257
|
// src/agents/claude/installer.ts
|
|
@@ -9978,13 +9978,13 @@ function detectStartupBanner(lines) {
|
|
|
9978
9978
|
while (artStart > 0 && BANNER_ART_RE.test(lines[artStart - 1])) artStart--;
|
|
9979
9979
|
if (metaIdx - artStart < 2) return null;
|
|
9980
9980
|
const pathLine = (lines[metaIdx + 1] ?? "").trim();
|
|
9981
|
-
const
|
|
9981
|
+
const path52 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path52,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path52 ? 1 : 0)
|
|
9988
9988
|
};
|
|
9989
9989
|
}
|
|
9990
9990
|
|
|
@@ -9994,8 +9994,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9994
9994
|
meta = getAgent("claude");
|
|
9995
9995
|
mode = "interactive";
|
|
9996
9996
|
os;
|
|
9997
|
-
constructor(
|
|
9998
|
-
this.os =
|
|
9997
|
+
constructor(os32) {
|
|
9998
|
+
this.os = os32;
|
|
9999
9999
|
}
|
|
10000
10000
|
/**
|
|
10001
10001
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -11025,8 +11025,8 @@ function codexCredentialLocator() {
|
|
|
11025
11025
|
function codexLoginLauncher() {
|
|
11026
11026
|
return {
|
|
11027
11027
|
async ensureInstalled() {
|
|
11028
|
-
const
|
|
11029
|
-
return
|
|
11028
|
+
const os32 = createOsStrategy();
|
|
11029
|
+
return os32.findInPath("codex") !== null;
|
|
11030
11030
|
},
|
|
11031
11031
|
launch() {
|
|
11032
11032
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -11049,8 +11049,8 @@ var CodexRuntimeStrategy = class {
|
|
|
11049
11049
|
meta = getAgent("codex");
|
|
11050
11050
|
mode = "interactive";
|
|
11051
11051
|
os;
|
|
11052
|
-
constructor(
|
|
11053
|
-
this.os =
|
|
11052
|
+
constructor(os32) {
|
|
11053
|
+
this.os = os32;
|
|
11054
11054
|
}
|
|
11055
11055
|
async prepareLaunch() {
|
|
11056
11056
|
let binary = this.os.findInPath("codex");
|
|
@@ -11156,12 +11156,12 @@ var CodexRuntimeStrategy = class {
|
|
|
11156
11156
|
});
|
|
11157
11157
|
}
|
|
11158
11158
|
};
|
|
11159
|
-
function resolveNpm(
|
|
11160
|
-
return
|
|
11159
|
+
function resolveNpm(os32) {
|
|
11160
|
+
return os32.id === "win32" ? "npm.cmd" : "npm";
|
|
11161
11161
|
}
|
|
11162
|
-
async function installCodexViaNpm(
|
|
11162
|
+
async function installCodexViaNpm(os32) {
|
|
11163
11163
|
return new Promise((resolve7, reject) => {
|
|
11164
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
11164
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os32), ["install", "-g", "@openai/codex"], {
|
|
11165
11165
|
stdio: "inherit"
|
|
11166
11166
|
});
|
|
11167
11167
|
proc.on("close", (code) => {
|
|
@@ -11178,16 +11178,16 @@ async function installCodexViaNpm(os31) {
|
|
|
11178
11178
|
});
|
|
11179
11179
|
});
|
|
11180
11180
|
}
|
|
11181
|
-
function augmentNpmGlobalBin(
|
|
11181
|
+
function augmentNpmGlobalBin(os32) {
|
|
11182
11182
|
try {
|
|
11183
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
11183
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os32), ["prefix", "-g"], {
|
|
11184
11184
|
stdio: ["ignore", "pipe", "ignore"]
|
|
11185
11185
|
});
|
|
11186
11186
|
if (result.status !== 0) return;
|
|
11187
11187
|
const prefix = result.stdout.toString().trim();
|
|
11188
11188
|
if (!prefix) return;
|
|
11189
|
-
const binDir =
|
|
11190
|
-
|
|
11189
|
+
const binDir = os32.id === "win32" ? prefix : path17.join(prefix, "bin");
|
|
11190
|
+
os32.augmentPath([binDir]);
|
|
11191
11191
|
} catch {
|
|
11192
11192
|
}
|
|
11193
11193
|
}
|
|
@@ -11271,9 +11271,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
11271
11271
|
// src/agents/coderabbit/installer.ts
|
|
11272
11272
|
var import_node_child_process5 = require("child_process");
|
|
11273
11273
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
11274
|
-
async function ensureCoderabbitInstalled(
|
|
11275
|
-
if (
|
|
11276
|
-
if (
|
|
11274
|
+
async function ensureCoderabbitInstalled(os32) {
|
|
11275
|
+
if (os32.findInPath("coderabbit")) return true;
|
|
11276
|
+
if (os32.id === "win32") {
|
|
11277
11277
|
console.error(
|
|
11278
11278
|
"\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
|
|
11279
11279
|
);
|
|
@@ -11288,8 +11288,8 @@ async function ensureCoderabbitInstalled(os31) {
|
|
|
11288
11288
|
proc.on("error", () => resolve7(false));
|
|
11289
11289
|
});
|
|
11290
11290
|
if (!ok) return false;
|
|
11291
|
-
|
|
11292
|
-
return
|
|
11291
|
+
os32.augmentPath([`${os32.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
11292
|
+
return os32.findInPath("coderabbit") !== null;
|
|
11293
11293
|
}
|
|
11294
11294
|
|
|
11295
11295
|
// src/agents/coderabbit/link.ts
|
|
@@ -11316,10 +11316,10 @@ function coderabbitCredentialLocator() {
|
|
|
11316
11316
|
extract: extractLocalCoderabbitToken
|
|
11317
11317
|
};
|
|
11318
11318
|
}
|
|
11319
|
-
function coderabbitLoginLauncher(
|
|
11319
|
+
function coderabbitLoginLauncher(os32) {
|
|
11320
11320
|
return {
|
|
11321
11321
|
async ensureInstalled() {
|
|
11322
|
-
return ensureCoderabbitInstalled(
|
|
11322
|
+
return ensureCoderabbitInstalled(os32);
|
|
11323
11323
|
},
|
|
11324
11324
|
launch() {
|
|
11325
11325
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -11342,11 +11342,11 @@ function parseReview(stdout) {
|
|
|
11342
11342
|
for (const line of lines) {
|
|
11343
11343
|
const m = line.match(HUNK_LINE_RE);
|
|
11344
11344
|
if (!m) continue;
|
|
11345
|
-
const [,
|
|
11346
|
-
if (!
|
|
11345
|
+
const [, path52, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path52 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path52.trim(),
|
|
11350
11350
|
line: Number(lineNo),
|
|
11351
11351
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
11352
11352
|
message: cleanedMessage
|
|
@@ -11365,8 +11365,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
11365
11365
|
meta = getAgent("coderabbit");
|
|
11366
11366
|
mode = "batch";
|
|
11367
11367
|
os;
|
|
11368
|
-
constructor(
|
|
11369
|
-
this.os =
|
|
11368
|
+
constructor(os32) {
|
|
11369
|
+
this.os = os32;
|
|
11370
11370
|
}
|
|
11371
11371
|
getDefaultArgs() {
|
|
11372
11372
|
return ["review"];
|
|
@@ -11481,10 +11481,10 @@ function cursorCredentialLocator() {
|
|
|
11481
11481
|
extract: extractLocalCursorToken
|
|
11482
11482
|
};
|
|
11483
11483
|
}
|
|
11484
|
-
function cursorLoginLauncher(
|
|
11484
|
+
function cursorLoginLauncher(os32) {
|
|
11485
11485
|
return {
|
|
11486
11486
|
async ensureInstalled() {
|
|
11487
|
-
if (
|
|
11487
|
+
if (os32.findInPath("cursor-agent")) return true;
|
|
11488
11488
|
console.error(
|
|
11489
11489
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
11490
11490
|
);
|
|
@@ -11546,8 +11546,8 @@ var CursorRuntimeStrategy = class {
|
|
|
11546
11546
|
meta = getAgent("cursor");
|
|
11547
11547
|
mode = "interactive";
|
|
11548
11548
|
os;
|
|
11549
|
-
constructor(
|
|
11550
|
-
this.os =
|
|
11549
|
+
constructor(os32) {
|
|
11550
|
+
this.os = os32;
|
|
11551
11551
|
}
|
|
11552
11552
|
async prepareLaunch() {
|
|
11553
11553
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -11667,10 +11667,10 @@ function aiderCredentialLocator() {
|
|
|
11667
11667
|
extract: extractLocalAiderToken
|
|
11668
11668
|
};
|
|
11669
11669
|
}
|
|
11670
|
-
function aiderLoginLauncher(
|
|
11670
|
+
function aiderLoginLauncher(os32) {
|
|
11671
11671
|
return {
|
|
11672
11672
|
async ensureInstalled() {
|
|
11673
|
-
if (
|
|
11673
|
+
if (os32.findInPath("aider")) return true;
|
|
11674
11674
|
console.error(
|
|
11675
11675
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
11676
11676
|
);
|
|
@@ -11680,7 +11680,7 @@ function aiderLoginLauncher(os31) {
|
|
|
11680
11680
|
console.error(
|
|
11681
11681
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
11682
11682
|
);
|
|
11683
|
-
return (0, import_node_child_process9.spawn)(
|
|
11683
|
+
return (0, import_node_child_process9.spawn)(os32.id === "win32" ? "cmd.exe" : "sh", os32.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
11684
11684
|
stdio: "ignore"
|
|
11685
11685
|
});
|
|
11686
11686
|
}
|
|
@@ -11752,8 +11752,8 @@ var AiderRuntimeStrategy = class {
|
|
|
11752
11752
|
meta = getAgent("aider");
|
|
11753
11753
|
mode = "interactive";
|
|
11754
11754
|
os;
|
|
11755
|
-
constructor(
|
|
11756
|
-
this.os =
|
|
11755
|
+
constructor(os32) {
|
|
11756
|
+
this.os = os32;
|
|
11757
11757
|
}
|
|
11758
11758
|
async prepareLaunch() {
|
|
11759
11759
|
const binary = this.os.findInPath("aider");
|
|
@@ -11882,8 +11882,8 @@ function geminiCredentialLocator() {
|
|
|
11882
11882
|
function geminiLoginLauncher() {
|
|
11883
11883
|
return {
|
|
11884
11884
|
async ensureInstalled() {
|
|
11885
|
-
const
|
|
11886
|
-
return
|
|
11885
|
+
const os32 = createOsStrategy();
|
|
11886
|
+
return os32.findInPath("gemini") !== null;
|
|
11887
11887
|
},
|
|
11888
11888
|
launch() {
|
|
11889
11889
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -11916,8 +11916,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
11916
11916
|
meta = getAgent("gemini");
|
|
11917
11917
|
mode = "interactive";
|
|
11918
11918
|
os;
|
|
11919
|
-
constructor(
|
|
11920
|
-
this.os =
|
|
11919
|
+
constructor(os32) {
|
|
11920
|
+
this.os = os32;
|
|
11921
11921
|
}
|
|
11922
11922
|
async prepareLaunch() {
|
|
11923
11923
|
const binary = this.os.findInPath("gemini");
|
|
@@ -12017,18 +12017,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
12017
12017
|
|
|
12018
12018
|
// src/agents/registry.ts
|
|
12019
12019
|
var runtimeBuilders = {
|
|
12020
|
-
claude: (
|
|
12021
|
-
codex: (
|
|
12022
|
-
coderabbit: (
|
|
12023
|
-
cursor: (
|
|
12024
|
-
aider: (
|
|
12025
|
-
gemini: (
|
|
12020
|
+
claude: (os32) => new ClaudeRuntimeStrategy(os32),
|
|
12021
|
+
codex: (os32) => new CodexRuntimeStrategy(os32),
|
|
12022
|
+
coderabbit: (os32) => new CoderabbitRuntimeStrategy(os32),
|
|
12023
|
+
cursor: (os32) => new CursorRuntimeStrategy(os32),
|
|
12024
|
+
aider: (os32) => new AiderRuntimeStrategy(os32),
|
|
12025
|
+
gemini: (os32) => new GeminiRuntimeStrategy(os32)
|
|
12026
12026
|
};
|
|
12027
12027
|
var deployBuilders = {
|
|
12028
12028
|
claude: () => new ClaudeDeployStrategy(),
|
|
12029
12029
|
codex: () => new CodexDeployStrategy()
|
|
12030
12030
|
};
|
|
12031
|
-
function createAgentStrategy(agent,
|
|
12031
|
+
function createAgentStrategy(agent, os32 = createOsStrategy()) {
|
|
12032
12032
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
12033
12033
|
throw new Error(
|
|
12034
12034
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -12038,10 +12038,10 @@ function createAgentStrategy(agent, os31 = createOsStrategy()) {
|
|
|
12038
12038
|
if (!build) {
|
|
12039
12039
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
12040
12040
|
}
|
|
12041
|
-
return build(
|
|
12041
|
+
return build(os32);
|
|
12042
12042
|
}
|
|
12043
|
-
function createInteractiveAgentStrategy(agent,
|
|
12044
|
-
const s = createAgentStrategy(agent,
|
|
12043
|
+
function createInteractiveAgentStrategy(agent, os32 = createOsStrategy()) {
|
|
12044
|
+
const s = createAgentStrategy(agent, os32);
|
|
12045
12045
|
if (s.mode !== "interactive") {
|
|
12046
12046
|
throw new Error(
|
|
12047
12047
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -15356,6 +15356,78 @@ function buildAcpPromptBlocks(payload) {
|
|
|
15356
15356
|
return blocks;
|
|
15357
15357
|
}
|
|
15358
15358
|
|
|
15359
|
+
// src/agents/acp/onboarding.ts
|
|
15360
|
+
var fs22 = __toESM(require("fs"));
|
|
15361
|
+
var os23 = __toESM(require("os"));
|
|
15362
|
+
var path27 = __toESM(require("path"));
|
|
15363
|
+
var _onboardingSeam = {
|
|
15364
|
+
markerPath: (sessionId) => path27.join(os23.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
15365
|
+
exists: (p2) => fs22.existsSync(p2),
|
|
15366
|
+
write: (p2) => {
|
|
15367
|
+
fs22.mkdirSync(path27.dirname(p2), { recursive: true });
|
|
15368
|
+
fs22.writeFileSync(p2, "");
|
|
15369
|
+
},
|
|
15370
|
+
disabled: () => {
|
|
15371
|
+
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
15372
|
+
return !!v && v !== "0" && v.toLowerCase() !== "false";
|
|
15373
|
+
}
|
|
15374
|
+
};
|
|
15375
|
+
function buildOnboardingPrompt(cwd) {
|
|
15376
|
+
const repo = path27.basename(cwd || "") || "this project";
|
|
15377
|
+
return [
|
|
15378
|
+
"SYSTEM / BACKGROUND TASK \u2014 this message is NOT from the user. The user just",
|
|
15379
|
+
"connected this session through CodeAgent Mobile and has only seen a welcome",
|
|
15380
|
+
"card. Take the initiative and write THEIR first message: a short, warm",
|
|
15381
|
+
"onboarding welcome that you (the agent) send proactively to invite them to start.",
|
|
15382
|
+
"",
|
|
15383
|
+
"Write it for a phone screen \u2014 under ~110 words, friendly, easy to scan, a little",
|
|
15384
|
+
"energy. Cover briefly, in your own words:",
|
|
15385
|
+
"- Glad they spun up this session.",
|
|
15386
|
+
"- Through CodeAgent Mobile, agents like you get native context, persistent",
|
|
15387
|
+
" memory, and an issue tracker \u2014 powered by Beads on Dolt \u2014 out of the box, zero setup.",
|
|
15388
|
+
"- They can drive you from their phone: live preview, rich visual output, a file viewer.",
|
|
15389
|
+
`- End with a SHORT, concrete invitation tied to THIS project (working dir: ${cwd},`,
|
|
15390
|
+
` repo: "${repo}") \u2014 suggest 1\u20132 specific things you could help with here.`,
|
|
15391
|
+
"",
|
|
15392
|
+
"Rules: do NOT run any tools or shell commands \u2014 base the project hint only on the",
|
|
15393
|
+
'repo name/path above so your reply is instant. No preamble like "Sure" or "Of',
|
|
15394
|
+
'course" \u2014 start directly with the greeting. Use light markdown (one intro line +',
|
|
15395
|
+
"a few bullets). Keep it tight."
|
|
15396
|
+
].join("\n");
|
|
15397
|
+
}
|
|
15398
|
+
function maybeSendOnboardingWelcome(opts) {
|
|
15399
|
+
if (_onboardingSeam.disabled()) return;
|
|
15400
|
+
const marker = _onboardingSeam.markerPath(opts.sessionId);
|
|
15401
|
+
try {
|
|
15402
|
+
if (_onboardingSeam.exists(marker)) return;
|
|
15403
|
+
_onboardingSeam.write(marker);
|
|
15404
|
+
} catch (err) {
|
|
15405
|
+
log.trace("acpRunner", `onboarding marker check failed: ${err.message}`);
|
|
15406
|
+
return;
|
|
15407
|
+
}
|
|
15408
|
+
log.info("acpRunner", `sending first-pair onboarding welcome for session=${opts.sessionId.slice(0, 8)}`);
|
|
15409
|
+
void runOnboardingTurn(opts).catch((err) => {
|
|
15410
|
+
log.warn(
|
|
15411
|
+
"acpRunner",
|
|
15412
|
+
`onboarding welcome turn failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
15413
|
+
);
|
|
15414
|
+
});
|
|
15415
|
+
}
|
|
15416
|
+
async function runOnboardingTurn(opts) {
|
|
15417
|
+
const { client: client2, streaming, history, cwd } = opts;
|
|
15418
|
+
await streaming.beginTurn();
|
|
15419
|
+
try {
|
|
15420
|
+
await client2.prompt(buildOnboardingPrompt(cwd));
|
|
15421
|
+
const reply = streaming.getCurrentText();
|
|
15422
|
+
await streaming.closeAll();
|
|
15423
|
+
history.appendAgentInitiatedReply(reply);
|
|
15424
|
+
await history.flush();
|
|
15425
|
+
} catch (err) {
|
|
15426
|
+
await streaming.closeAll().catch(() => void 0);
|
|
15427
|
+
throw err;
|
|
15428
|
+
}
|
|
15429
|
+
}
|
|
15430
|
+
|
|
15359
15431
|
// src/agents/acp/promptEcho.ts
|
|
15360
15432
|
var MAX_PROMPT_CHARS = 200;
|
|
15361
15433
|
function formatPromptEchoLine(payload) {
|
|
@@ -15830,9 +15902,9 @@ function extractSelectPrompt(text) {
|
|
|
15830
15902
|
}
|
|
15831
15903
|
|
|
15832
15904
|
// src/commands/start/handlers.ts
|
|
15833
|
-
var
|
|
15834
|
-
var
|
|
15835
|
-
var
|
|
15905
|
+
var fs34 = __toESM(require("fs"));
|
|
15906
|
+
var os27 = __toESM(require("os"));
|
|
15907
|
+
var path41 = __toESM(require("path"));
|
|
15836
15908
|
var import_crypto3 = require("crypto");
|
|
15837
15909
|
var import_child_process18 = require("child_process");
|
|
15838
15910
|
|
|
@@ -15956,8 +16028,8 @@ function parsePayload2(schema, raw) {
|
|
|
15956
16028
|
}
|
|
15957
16029
|
|
|
15958
16030
|
// src/services/file-ops.service.ts
|
|
15959
|
-
var
|
|
15960
|
-
var
|
|
16031
|
+
var fs23 = __toESM(require("fs/promises"));
|
|
16032
|
+
var path29 = __toESM(require("path"));
|
|
15961
16033
|
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
15962
16034
|
var MAX_WALK_DEPTH = 6;
|
|
15963
16035
|
var MAX_VISITED_DIRS = 5e3;
|
|
@@ -15992,12 +16064,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
|
|
|
15992
16064
|
"__pycache__"
|
|
15993
16065
|
]);
|
|
15994
16066
|
function isUnder(parent, candidate) {
|
|
15995
|
-
const rel =
|
|
15996
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
16067
|
+
const rel = path29.relative(parent, candidate);
|
|
16068
|
+
return rel === "" || !rel.startsWith("..") && !path29.isAbsolute(rel);
|
|
15997
16069
|
}
|
|
15998
16070
|
async function isExistingFile(absPath) {
|
|
15999
16071
|
try {
|
|
16000
|
-
const stat3 = await
|
|
16072
|
+
const stat3 = await fs23.stat(absPath);
|
|
16001
16073
|
return stat3.isFile();
|
|
16002
16074
|
} catch {
|
|
16003
16075
|
return false;
|
|
@@ -16010,13 +16082,13 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
16010
16082
|
ctx.visited++;
|
|
16011
16083
|
let entries = [];
|
|
16012
16084
|
try {
|
|
16013
|
-
entries = await
|
|
16085
|
+
entries = await fs23.readdir(dir, { withFileTypes: true });
|
|
16014
16086
|
} catch {
|
|
16015
16087
|
return;
|
|
16016
16088
|
}
|
|
16017
16089
|
for (const e of entries) {
|
|
16018
16090
|
if (!e.isFile()) continue;
|
|
16019
|
-
const full =
|
|
16091
|
+
const full = path29.join(dir, e.name);
|
|
16020
16092
|
if (needleVariants.some((needle) => full.endsWith(needle))) {
|
|
16021
16093
|
ctx.matches.push(full);
|
|
16022
16094
|
if (ctx.matches.length >= ctx.cap) return;
|
|
@@ -16026,21 +16098,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
16026
16098
|
if (!e.isDirectory()) continue;
|
|
16027
16099
|
if (SUBDIR_IGNORE.has(e.name)) continue;
|
|
16028
16100
|
if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
|
|
16029
|
-
await walkForSuffix(
|
|
16101
|
+
await walkForSuffix(path29.join(dir, e.name), needleVariants, depth + 1, ctx);
|
|
16030
16102
|
if (ctx.matches.length >= ctx.cap) return;
|
|
16031
16103
|
}
|
|
16032
16104
|
}
|
|
16033
16105
|
async function findFile(rawPath) {
|
|
16034
16106
|
const cwd = process.cwd();
|
|
16035
|
-
if (
|
|
16036
|
-
const abs =
|
|
16107
|
+
if (path29.isAbsolute(rawPath)) {
|
|
16108
|
+
const abs = path29.normalize(rawPath);
|
|
16037
16109
|
if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
|
|
16038
16110
|
}
|
|
16039
|
-
const direct =
|
|
16111
|
+
const direct = path29.resolve(cwd, rawPath);
|
|
16040
16112
|
if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
|
|
16041
|
-
const normalized =
|
|
16113
|
+
const normalized = path29.normalize(rawPath).replace(/^[./\\]+/, "");
|
|
16042
16114
|
const needles = [
|
|
16043
|
-
`${
|
|
16115
|
+
`${path29.sep}${normalized}`,
|
|
16044
16116
|
`/${normalized}`
|
|
16045
16117
|
].filter((v, i, a) => a.indexOf(v) === i);
|
|
16046
16118
|
const ctx = { visited: 0, matches: [], cap: 16 };
|
|
@@ -16054,7 +16126,7 @@ async function findWriteTarget(rawPath) {
|
|
|
16054
16126
|
const found = await findFile(rawPath);
|
|
16055
16127
|
if (found) return found;
|
|
16056
16128
|
const cwd = process.cwd();
|
|
16057
|
-
const fallback =
|
|
16129
|
+
const fallback = path29.isAbsolute(rawPath) ? path29.normalize(rawPath) : path29.resolve(cwd, rawPath);
|
|
16058
16130
|
if (!isUnder(cwd, fallback)) return null;
|
|
16059
16131
|
return fallback;
|
|
16060
16132
|
}
|
|
@@ -16071,11 +16143,11 @@ async function readProjectFile(rawPath) {
|
|
|
16071
16143
|
if (!abs) {
|
|
16072
16144
|
return { error: `File not found in the project tree: ${rawPath}` };
|
|
16073
16145
|
}
|
|
16074
|
-
const stat3 = await
|
|
16146
|
+
const stat3 = await fs23.stat(abs);
|
|
16075
16147
|
if (stat3.size > MAX_FILE_BYTES) {
|
|
16076
16148
|
return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
|
|
16077
16149
|
}
|
|
16078
|
-
const buf = await
|
|
16150
|
+
const buf = await fs23.readFile(abs);
|
|
16079
16151
|
if (looksBinary(buf)) {
|
|
16080
16152
|
return { error: "Binary file \u2014 refusing to open in a code editor." };
|
|
16081
16153
|
}
|
|
@@ -16094,8 +16166,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
16094
16166
|
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
|
|
16095
16167
|
return { error: "Content too large." };
|
|
16096
16168
|
}
|
|
16097
|
-
await
|
|
16098
|
-
await
|
|
16169
|
+
await fs23.mkdir(path29.dirname(abs), { recursive: true });
|
|
16170
|
+
await fs23.writeFile(abs, content, "utf-8");
|
|
16099
16171
|
return { ok: true };
|
|
16100
16172
|
} catch (e) {
|
|
16101
16173
|
const msg = e instanceof Error ? e.message : "Write failed";
|
|
@@ -16106,8 +16178,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
16106
16178
|
// src/services/project-ops.service.ts
|
|
16107
16179
|
var import_child_process9 = require("child_process");
|
|
16108
16180
|
var import_util2 = require("util");
|
|
16109
|
-
var
|
|
16110
|
-
var
|
|
16181
|
+
var fs24 = __toESM(require("fs/promises"));
|
|
16182
|
+
var path30 = __toESM(require("path"));
|
|
16111
16183
|
var execFileP3 = (0, import_util2.promisify)(import_child_process9.execFile);
|
|
16112
16184
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
16113
16185
|
"node_modules",
|
|
@@ -16155,7 +16227,7 @@ async function listProjectFiles(opts = {}) {
|
|
|
16155
16227
|
}
|
|
16156
16228
|
let entries = [];
|
|
16157
16229
|
try {
|
|
16158
|
-
entries = await
|
|
16230
|
+
entries = await fs24.readdir(dir, { withFileTypes: true });
|
|
16159
16231
|
} catch {
|
|
16160
16232
|
return;
|
|
16161
16233
|
}
|
|
@@ -16165,18 +16237,18 @@ async function listProjectFiles(opts = {}) {
|
|
|
16165
16237
|
return;
|
|
16166
16238
|
}
|
|
16167
16239
|
if (PROJECT_IGNORE.has(e.name)) continue;
|
|
16168
|
-
const full =
|
|
16240
|
+
const full = path30.join(dir, e.name);
|
|
16169
16241
|
if (e.isDirectory()) {
|
|
16170
16242
|
if (depth >= 12) continue;
|
|
16171
16243
|
await walk(full, depth + 1);
|
|
16172
16244
|
} else if (e.isFile()) {
|
|
16173
|
-
const rel =
|
|
16245
|
+
const rel = path30.relative(root, full);
|
|
16174
16246
|
if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
|
|
16175
16247
|
continue;
|
|
16176
16248
|
}
|
|
16177
16249
|
let size = 0;
|
|
16178
16250
|
try {
|
|
16179
|
-
const st3 = await
|
|
16251
|
+
const st3 = await fs24.stat(full);
|
|
16180
16252
|
size = st3.size;
|
|
16181
16253
|
} catch {
|
|
16182
16254
|
}
|
|
@@ -16278,8 +16350,8 @@ async function gitStatus(cwd) {
|
|
|
16278
16350
|
let hasMergeInProgress = false;
|
|
16279
16351
|
try {
|
|
16280
16352
|
const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
|
|
16281
|
-
const mergeHead =
|
|
16282
|
-
await
|
|
16353
|
+
const mergeHead = path30.isAbsolute(gitDir) ? path30.join(gitDir, "MERGE_HEAD") : path30.join(root, gitDir, "MERGE_HEAD");
|
|
16354
|
+
await fs24.access(mergeHead);
|
|
16283
16355
|
hasMergeInProgress = true;
|
|
16284
16356
|
} catch {
|
|
16285
16357
|
}
|
|
@@ -16425,7 +16497,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
16425
16497
|
}
|
|
16426
16498
|
let content = "";
|
|
16427
16499
|
try {
|
|
16428
|
-
content = await
|
|
16500
|
+
content = await fs24.readFile(path30.join(cwd, f.path), "utf8");
|
|
16429
16501
|
} catch {
|
|
16430
16502
|
continue;
|
|
16431
16503
|
}
|
|
@@ -16449,14 +16521,14 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
16449
16521
|
|
|
16450
16522
|
// src/services/apply-file-review.service.ts
|
|
16451
16523
|
var import_child_process10 = require("child_process");
|
|
16452
|
-
var
|
|
16453
|
-
var
|
|
16524
|
+
var fs25 = __toESM(require("fs"));
|
|
16525
|
+
var path31 = __toESM(require("path"));
|
|
16454
16526
|
async function applyFileReview(workingDir, filePath, action) {
|
|
16455
|
-
if (filePath.includes("..") ||
|
|
16527
|
+
if (filePath.includes("..") || path31.isAbsolute(filePath)) {
|
|
16456
16528
|
return { ok: false, action, filePath, error: "invalid file path" };
|
|
16457
16529
|
}
|
|
16458
|
-
const absFile =
|
|
16459
|
-
const repoRoot = findGitRoot(
|
|
16530
|
+
const absFile = path31.resolve(workingDir, filePath);
|
|
16531
|
+
const repoRoot = findGitRoot(path31.dirname(absFile));
|
|
16460
16532
|
if (!repoRoot) {
|
|
16461
16533
|
return {
|
|
16462
16534
|
ok: false,
|
|
@@ -16465,7 +16537,7 @@ async function applyFileReview(workingDir, filePath, action) {
|
|
|
16465
16537
|
error: `no enclosing git repo for ${filePath}`
|
|
16466
16538
|
};
|
|
16467
16539
|
}
|
|
16468
|
-
const relInRepo =
|
|
16540
|
+
const relInRepo = path31.relative(repoRoot, absFile);
|
|
16469
16541
|
if (!relInRepo || relInRepo.startsWith("..")) {
|
|
16470
16542
|
return { ok: false, action, filePath, error: "path escapes repo root" };
|
|
16471
16543
|
}
|
|
@@ -16514,17 +16586,17 @@ function runGit(cwd, args2) {
|
|
|
16514
16586
|
});
|
|
16515
16587
|
}
|
|
16516
16588
|
function findGitRoot(startDir) {
|
|
16517
|
-
let dir =
|
|
16589
|
+
let dir = path31.resolve(startDir);
|
|
16518
16590
|
const seen = /* @__PURE__ */ new Set();
|
|
16519
16591
|
for (let i = 0; i < 256; i++) {
|
|
16520
16592
|
if (seen.has(dir)) return null;
|
|
16521
16593
|
seen.add(dir);
|
|
16522
16594
|
try {
|
|
16523
|
-
const stat3 =
|
|
16595
|
+
const stat3 = fs25.statSync(path31.join(dir, ".git"), { throwIfNoEntry: false });
|
|
16524
16596
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
16525
16597
|
} catch {
|
|
16526
16598
|
}
|
|
16527
|
-
const parent =
|
|
16599
|
+
const parent = path31.dirname(dir);
|
|
16528
16600
|
if (parent === dir) return null;
|
|
16529
16601
|
dir = parent;
|
|
16530
16602
|
}
|
|
@@ -16533,8 +16605,8 @@ function findGitRoot(startDir) {
|
|
|
16533
16605
|
|
|
16534
16606
|
// src/commands/link.ts
|
|
16535
16607
|
var import_node_crypto6 = require("crypto");
|
|
16536
|
-
var
|
|
16537
|
-
var
|
|
16608
|
+
var fs26 = __toESM(require("fs"));
|
|
16609
|
+
var path32 = __toESM(require("path"));
|
|
16538
16610
|
var import_chokidar = __toESM(require("chokidar"));
|
|
16539
16611
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
16540
16612
|
|
|
@@ -16713,7 +16785,7 @@ function parseLinkArgs(args2) {
|
|
|
16713
16785
|
if (apiKeyFileArg) {
|
|
16714
16786
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
16715
16787
|
try {
|
|
16716
|
-
apiKey =
|
|
16788
|
+
apiKey = fs26.readFileSync(path32.resolve(filePath), "utf8").trim();
|
|
16717
16789
|
} catch (err) {
|
|
16718
16790
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
16719
16791
|
}
|
|
@@ -16817,7 +16889,7 @@ async function link(args2 = []) {
|
|
|
16817
16889
|
return;
|
|
16818
16890
|
}
|
|
16819
16891
|
if (parsed.tokenFile) {
|
|
16820
|
-
const credential =
|
|
16892
|
+
const credential = fs26.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
|
|
16821
16893
|
if (!credential) {
|
|
16822
16894
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
16823
16895
|
process.exit(1);
|
|
@@ -17394,8 +17466,8 @@ function activePreviewSessionIds() {
|
|
|
17394
17466
|
|
|
17395
17467
|
// src/beads/bd-adapter.ts
|
|
17396
17468
|
var import_child_process13 = require("child_process");
|
|
17397
|
-
var
|
|
17398
|
-
var
|
|
17469
|
+
var fs30 = __toESM(require("fs"));
|
|
17470
|
+
var path36 = __toESM(require("path"));
|
|
17399
17471
|
var BD_PACKAGE = "@beads/bd";
|
|
17400
17472
|
function resolveBundledBdBinary() {
|
|
17401
17473
|
return _resolveSeam.resolveBundled();
|
|
@@ -17407,11 +17479,11 @@ function _defaultResolveBundled() {
|
|
|
17407
17479
|
} catch {
|
|
17408
17480
|
return null;
|
|
17409
17481
|
}
|
|
17410
|
-
const binDir =
|
|
17482
|
+
const binDir = path36.join(path36.dirname(pkgJsonPath), "bin");
|
|
17411
17483
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17412
|
-
const binaryPath =
|
|
17484
|
+
const binaryPath = path36.join(binDir, binaryName);
|
|
17413
17485
|
try {
|
|
17414
|
-
|
|
17486
|
+
fs30.accessSync(binaryPath, fs30.constants.F_OK);
|
|
17415
17487
|
return binaryPath;
|
|
17416
17488
|
} catch {
|
|
17417
17489
|
return null;
|
|
@@ -17421,13 +17493,13 @@ function resolveBdOnPath() {
|
|
|
17421
17493
|
return _resolveSeam.resolveOnPath();
|
|
17422
17494
|
}
|
|
17423
17495
|
function _defaultResolveOnPath() {
|
|
17424
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17496
|
+
const dirs = (process.env.PATH ?? "").split(path36.delimiter).filter(Boolean);
|
|
17425
17497
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17426
17498
|
for (const dir of dirs) {
|
|
17427
17499
|
for (const candidate of candidates) {
|
|
17428
|
-
const full =
|
|
17500
|
+
const full = path36.join(dir, candidate);
|
|
17429
17501
|
try {
|
|
17430
|
-
|
|
17502
|
+
fs30.accessSync(full, fs30.constants.F_OK);
|
|
17431
17503
|
return full;
|
|
17432
17504
|
} catch {
|
|
17433
17505
|
}
|
|
@@ -17593,9 +17665,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17593
17665
|
|
|
17594
17666
|
// src/beads/provisioner.ts
|
|
17595
17667
|
var import_child_process17 = require("child_process");
|
|
17596
|
-
var
|
|
17597
|
-
var
|
|
17598
|
-
var
|
|
17668
|
+
var fs33 = __toESM(require("fs"));
|
|
17669
|
+
var os26 = __toESM(require("os"));
|
|
17670
|
+
var path39 = __toESM(require("path"));
|
|
17599
17671
|
|
|
17600
17672
|
// src/beads/install-bd.ts
|
|
17601
17673
|
var import_child_process14 = require("child_process");
|
|
@@ -17660,9 +17732,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17660
17732
|
|
|
17661
17733
|
// src/beads/install-dolt.ts
|
|
17662
17734
|
var import_child_process15 = require("child_process");
|
|
17663
|
-
var
|
|
17664
|
-
var
|
|
17665
|
-
var
|
|
17735
|
+
var fs31 = __toESM(require("fs"));
|
|
17736
|
+
var os25 = __toESM(require("os"));
|
|
17737
|
+
var path37 = __toESM(require("path"));
|
|
17666
17738
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17667
17739
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17668
17740
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -17702,11 +17774,11 @@ function resolveDoltInstallStrategy(platform2) {
|
|
|
17702
17774
|
}
|
|
17703
17775
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17704
17776
|
function doltPlatformTuple(platform2, arch) {
|
|
17705
|
-
const
|
|
17777
|
+
const os32 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
|
|
17706
17778
|
const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
17707
17779
|
if (!a) return null;
|
|
17708
|
-
if (
|
|
17709
|
-
return `${
|
|
17780
|
+
if (os32 === "windows" && a !== "amd64") return null;
|
|
17781
|
+
return `${os32}-${a}`;
|
|
17710
17782
|
}
|
|
17711
17783
|
function resolveDoltTarballStrategy(targetDir, platform2, arch) {
|
|
17712
17784
|
const tuple = doltPlatformTuple(platform2, arch);
|
|
@@ -17751,14 +17823,14 @@ async function installDoltToDir(targetDir, platform2 = process.platform, arch =
|
|
|
17751
17823
|
return result;
|
|
17752
17824
|
}
|
|
17753
17825
|
var _doltPathSeam = {
|
|
17754
|
-
homedir: () =>
|
|
17826
|
+
homedir: () => os25.homedir(),
|
|
17755
17827
|
getPath: () => process.env.PATH ?? "",
|
|
17756
17828
|
setPath: (p2) => {
|
|
17757
17829
|
process.env.PATH = p2;
|
|
17758
17830
|
},
|
|
17759
17831
|
exists: (p2) => {
|
|
17760
17832
|
try {
|
|
17761
|
-
|
|
17833
|
+
fs31.accessSync(p2, fs31.constants.F_OK);
|
|
17762
17834
|
return true;
|
|
17763
17835
|
} catch {
|
|
17764
17836
|
return false;
|
|
@@ -17769,7 +17841,7 @@ function doltBinaryNames(platform2) {
|
|
|
17769
17841
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17770
17842
|
}
|
|
17771
17843
|
function knownDoltDirs(platform2) {
|
|
17772
|
-
const P3 = platform2 === "win32" ?
|
|
17844
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
17773
17845
|
const home = _doltPathSeam.homedir();
|
|
17774
17846
|
if (platform2 === "win32") {
|
|
17775
17847
|
return [
|
|
@@ -17785,7 +17857,7 @@ function knownDoltDirs(platform2) {
|
|
|
17785
17857
|
].filter(Boolean);
|
|
17786
17858
|
}
|
|
17787
17859
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17788
|
-
const P3 = platform2 === "win32" ?
|
|
17860
|
+
const P3 = platform2 === "win32" ? path37.win32 : path37.posix;
|
|
17789
17861
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
17790
17862
|
const names = doltBinaryNames(platform2);
|
|
17791
17863
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17896,8 +17968,8 @@ async function ensureSharedServer(adapter) {
|
|
|
17896
17968
|
// src/beads/project-key.ts
|
|
17897
17969
|
var import_child_process16 = require("child_process");
|
|
17898
17970
|
var crypto2 = __toESM(require("crypto"));
|
|
17899
|
-
var
|
|
17900
|
-
var
|
|
17971
|
+
var fs32 = __toESM(require("fs"));
|
|
17972
|
+
var path38 = __toESM(require("path"));
|
|
17901
17973
|
function normalizeOrigin(raw) {
|
|
17902
17974
|
const trimmed = raw.trim();
|
|
17903
17975
|
if (!trimmed) return null;
|
|
@@ -17923,17 +17995,17 @@ function normalizeOrigin(raw) {
|
|
|
17923
17995
|
return `${host}/${pathPart}`;
|
|
17924
17996
|
}
|
|
17925
17997
|
function findRepoRoot(cwd) {
|
|
17926
|
-
let dir =
|
|
17998
|
+
let dir = path38.resolve(cwd);
|
|
17927
17999
|
const seen = /* @__PURE__ */ new Set();
|
|
17928
18000
|
for (let i = 0; i < 256; i++) {
|
|
17929
18001
|
if (seen.has(dir)) return null;
|
|
17930
18002
|
seen.add(dir);
|
|
17931
18003
|
try {
|
|
17932
|
-
const stat3 =
|
|
18004
|
+
const stat3 = fs32.statSync(path38.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17933
18005
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17934
18006
|
} catch {
|
|
17935
18007
|
}
|
|
17936
|
-
const parent =
|
|
18008
|
+
const parent = path38.dirname(dir);
|
|
17937
18009
|
if (parent === dir) return null;
|
|
17938
18010
|
dir = parent;
|
|
17939
18011
|
}
|
|
@@ -17944,7 +18016,7 @@ var _execSeam2 = {
|
|
|
17944
18016
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
17945
18017
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17946
18018
|
},
|
|
17947
|
-
realpath: (p2) =>
|
|
18019
|
+
realpath: (p2) => fs32.realpathSync(p2)
|
|
17948
18020
|
};
|
|
17949
18021
|
function readOrigin(cwd) {
|
|
17950
18022
|
try {
|
|
@@ -17973,7 +18045,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
17973
18045
|
} catch {
|
|
17974
18046
|
}
|
|
17975
18047
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17976
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18048
|
+
return { projectKey: `path:${hash}`, projectLabel: path38.basename(real) || "project" };
|
|
17977
18049
|
}
|
|
17978
18050
|
|
|
17979
18051
|
// src/beads/project-prefix.ts
|
|
@@ -18015,17 +18087,17 @@ var _provisionSeam = {
|
|
|
18015
18087
|
};
|
|
18016
18088
|
var _linkSeam = {
|
|
18017
18089
|
platform: () => process.platform,
|
|
18018
|
-
homedir: () =>
|
|
18090
|
+
homedir: () => os26.homedir(),
|
|
18019
18091
|
isWritableDir: (dir) => {
|
|
18020
18092
|
try {
|
|
18021
|
-
|
|
18093
|
+
fs33.accessSync(dir, fs33.constants.W_OK);
|
|
18022
18094
|
return true;
|
|
18023
18095
|
} catch {
|
|
18024
18096
|
return false;
|
|
18025
18097
|
}
|
|
18026
18098
|
},
|
|
18027
18099
|
ensureDir: (dir) => {
|
|
18028
|
-
|
|
18100
|
+
fs33.mkdirSync(dir, { recursive: true });
|
|
18029
18101
|
},
|
|
18030
18102
|
/**
|
|
18031
18103
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18046,12 +18118,12 @@ var _linkSeam = {
|
|
|
18046
18118
|
* which `linkBdOntoPath` creates if missing.
|
|
18047
18119
|
*/
|
|
18048
18120
|
cliBinDir: () => {
|
|
18049
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18121
|
+
const pathDirs = (process.env.PATH ?? "").split(path39.delimiter).filter(Boolean);
|
|
18050
18122
|
const home = _linkSeam.homedir();
|
|
18051
|
-
const localBin = home ?
|
|
18123
|
+
const localBin = home ? path39.join(home, ".local", "bin") : null;
|
|
18052
18124
|
const candidates = [];
|
|
18053
18125
|
try {
|
|
18054
|
-
candidates.push(
|
|
18126
|
+
candidates.push(path39.dirname(process.execPath));
|
|
18055
18127
|
} catch {
|
|
18056
18128
|
}
|
|
18057
18129
|
if (localBin) candidates.push(localBin);
|
|
@@ -18059,9 +18131,9 @@ var _linkSeam = {
|
|
|
18059
18131
|
const entry = process.argv[1];
|
|
18060
18132
|
if (entry) {
|
|
18061
18133
|
try {
|
|
18062
|
-
candidates.push(
|
|
18134
|
+
candidates.push(path39.dirname(fs33.realpathSync(entry)));
|
|
18063
18135
|
} catch {
|
|
18064
|
-
candidates.push(
|
|
18136
|
+
candidates.push(path39.dirname(entry));
|
|
18065
18137
|
}
|
|
18066
18138
|
}
|
|
18067
18139
|
const onPathWritable = candidates.find(
|
|
@@ -18073,20 +18145,20 @@ var _linkSeam = {
|
|
|
18073
18145
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18074
18146
|
readlink: (linkPath) => {
|
|
18075
18147
|
try {
|
|
18076
|
-
return
|
|
18148
|
+
return fs33.readlinkSync(linkPath);
|
|
18077
18149
|
} catch {
|
|
18078
18150
|
return null;
|
|
18079
18151
|
}
|
|
18080
18152
|
},
|
|
18081
|
-
unlink: (linkPath) =>
|
|
18082
|
-
symlink: (target, linkPath) =>
|
|
18153
|
+
unlink: (linkPath) => fs33.unlinkSync(linkPath),
|
|
18154
|
+
symlink: (target, linkPath) => fs33.symlinkSync(target, linkPath)
|
|
18083
18155
|
};
|
|
18084
18156
|
function linkBdOntoPath(binaryPath) {
|
|
18085
18157
|
if (_linkSeam.platform() === "win32") return;
|
|
18086
18158
|
const binDir = _linkSeam.cliBinDir();
|
|
18087
18159
|
if (!binDir) return;
|
|
18088
18160
|
_linkSeam.ensureDir(binDir);
|
|
18089
|
-
const linkPath =
|
|
18161
|
+
const linkPath = path39.join(binDir, "bd");
|
|
18090
18162
|
if (linkPath === binaryPath) return;
|
|
18091
18163
|
const current = _linkSeam.readlink(linkPath);
|
|
18092
18164
|
if (current === binaryPath) return;
|
|
@@ -18227,7 +18299,7 @@ function dedupeRecipes(agents) {
|
|
|
18227
18299
|
|
|
18228
18300
|
// src/beads/watcher.ts
|
|
18229
18301
|
var crypto4 = __toESM(require("crypto"));
|
|
18230
|
-
var
|
|
18302
|
+
var path40 = __toESM(require("path"));
|
|
18231
18303
|
|
|
18232
18304
|
// src/services/file-watcher/transport.ts
|
|
18233
18305
|
var http5 = __toESM(require("http"));
|
|
@@ -18302,7 +18374,7 @@ var BeadsWatcher = class {
|
|
|
18302
18374
|
constructor(opts) {
|
|
18303
18375
|
this.opts = opts;
|
|
18304
18376
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18305
|
-
this.feedPath = opts.feedPath ??
|
|
18377
|
+
this.feedPath = opts.feedPath ?? path40.join(opts.cwd ?? process.cwd(), ".beads", "issues.jsonl");
|
|
18306
18378
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18307
18379
|
}
|
|
18308
18380
|
opts;
|
|
@@ -18580,7 +18652,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18580
18652
|
function cleanupAttachmentTempFiles() {
|
|
18581
18653
|
for (const p2 of pendingAttachmentFiles) {
|
|
18582
18654
|
try {
|
|
18583
|
-
|
|
18655
|
+
fs34.unlinkSync(p2);
|
|
18584
18656
|
} catch {
|
|
18585
18657
|
}
|
|
18586
18658
|
}
|
|
@@ -18589,8 +18661,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18589
18661
|
function saveFilesTemp(files) {
|
|
18590
18662
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18591
18663
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18592
|
-
const tmpPath =
|
|
18593
|
-
|
|
18664
|
+
const tmpPath = path41.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18665
|
+
fs34.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18594
18666
|
pendingAttachmentFiles.add(tmpPath);
|
|
18595
18667
|
return tmpPath;
|
|
18596
18668
|
});
|
|
@@ -18610,7 +18682,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18610
18682
|
setTimeout(() => {
|
|
18611
18683
|
for (const p2 of paths) {
|
|
18612
18684
|
try {
|
|
18613
|
-
|
|
18685
|
+
fs34.unlinkSync(p2);
|
|
18614
18686
|
} catch {
|
|
18615
18687
|
}
|
|
18616
18688
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19193,8 +19265,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19193
19265
|
if (args2.length === 0) return detection;
|
|
19194
19266
|
const binName = args2[0];
|
|
19195
19267
|
if (binName.startsWith("-")) return detection;
|
|
19196
|
-
const binPath =
|
|
19197
|
-
if (!
|
|
19268
|
+
const binPath = path41.join(cwd, "node_modules", ".bin", binName);
|
|
19269
|
+
if (!fs34.existsSync(binPath)) return detection;
|
|
19198
19270
|
return {
|
|
19199
19271
|
...detection,
|
|
19200
19272
|
command: binPath,
|
|
@@ -19624,9 +19696,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19624
19696
|
|
|
19625
19697
|
// src/services/file-watcher.service.ts
|
|
19626
19698
|
var import_child_process19 = require("child_process");
|
|
19627
|
-
var
|
|
19628
|
-
var
|
|
19629
|
-
var
|
|
19699
|
+
var fs35 = __toESM(require("fs"));
|
|
19700
|
+
var os28 = __toESM(require("os"));
|
|
19701
|
+
var path42 = __toESM(require("path"));
|
|
19630
19702
|
var import_ignore = __toESM(require("ignore"));
|
|
19631
19703
|
|
|
19632
19704
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19736,10 +19808,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19736
19808
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19737
19809
|
/[\\/]Templates([\\/]|$)/i
|
|
19738
19810
|
];
|
|
19739
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
19811
|
+
function isUnsafeWindowsWatchRoot(dir, homedir24) {
|
|
19740
19812
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19741
19813
|
const cwd = norm(dir);
|
|
19742
|
-
const home = norm(
|
|
19814
|
+
const home = norm(homedir24);
|
|
19743
19815
|
if (cwd === home) return true;
|
|
19744
19816
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19745
19817
|
const sysRoots = [
|
|
@@ -19769,18 +19841,18 @@ var _findGitRootSeam = {
|
|
|
19769
19841
|
resolve: _defaultFindGitRoot
|
|
19770
19842
|
};
|
|
19771
19843
|
function _defaultFindGitRoot(startDir) {
|
|
19772
|
-
let dir =
|
|
19844
|
+
let dir = path42.resolve(startDir);
|
|
19773
19845
|
const seen = /* @__PURE__ */ new Set();
|
|
19774
19846
|
for (let i = 0; i < 256; i++) {
|
|
19775
19847
|
if (seen.has(dir)) return null;
|
|
19776
19848
|
seen.add(dir);
|
|
19777
19849
|
try {
|
|
19778
|
-
const gitPath =
|
|
19779
|
-
const stat3 =
|
|
19850
|
+
const gitPath = path42.join(dir, ".git");
|
|
19851
|
+
const stat3 = fs35.statSync(gitPath, { throwIfNoEntry: false });
|
|
19780
19852
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19781
19853
|
} catch {
|
|
19782
19854
|
}
|
|
19783
|
-
const parent =
|
|
19855
|
+
const parent = path42.dirname(dir);
|
|
19784
19856
|
if (parent === dir) return null;
|
|
19785
19857
|
dir = parent;
|
|
19786
19858
|
}
|
|
@@ -19838,7 +19910,7 @@ var FileWatcherService = class {
|
|
|
19838
19910
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
19839
19911
|
}
|
|
19840
19912
|
const isWin = process.platform === "win32";
|
|
19841
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
19913
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os28.homedir())) {
|
|
19842
19914
|
log.warn(
|
|
19843
19915
|
"fileWatcher",
|
|
19844
19916
|
`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.`
|
|
@@ -20025,7 +20097,7 @@ var FileWatcherService = class {
|
|
|
20025
20097
|
}
|
|
20026
20098
|
async emitForFile(absPath, changeType) {
|
|
20027
20099
|
if (this.stopped) return;
|
|
20028
|
-
const fileDir =
|
|
20100
|
+
const fileDir = path42.dirname(absPath);
|
|
20029
20101
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20030
20102
|
if (gitRoot === void 0) {
|
|
20031
20103
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20038,19 +20110,19 @@ var FileWatcherService = class {
|
|
|
20038
20110
|
);
|
|
20039
20111
|
return;
|
|
20040
20112
|
}
|
|
20041
|
-
const relPathInRepo =
|
|
20113
|
+
const relPathInRepo = path42.relative(gitRoot, absPath);
|
|
20042
20114
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20043
20115
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20044
20116
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20045
20117
|
log.trace(
|
|
20046
20118
|
"fileWatcher",
|
|
20047
|
-
`${relPathInRepo} ignored by ${
|
|
20119
|
+
`${relPathInRepo} ignored by ${path42.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20048
20120
|
);
|
|
20049
20121
|
return;
|
|
20050
20122
|
}
|
|
20051
20123
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20052
|
-
const repoPath =
|
|
20053
|
-
const repoName =
|
|
20124
|
+
const repoPath = path42.relative(this.opts.workingDir, gitRoot);
|
|
20125
|
+
const repoName = path42.basename(gitRoot);
|
|
20054
20126
|
let diffText = "";
|
|
20055
20127
|
let fileStatus = "modified";
|
|
20056
20128
|
if (changeType === "unlink") {
|
|
@@ -20225,7 +20297,7 @@ var FileWatcherService = class {
|
|
|
20225
20297
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20226
20298
|
let entries;
|
|
20227
20299
|
try {
|
|
20228
|
-
entries =
|
|
20300
|
+
entries = fs35.readdirSync(dir, { withFileTypes: true });
|
|
20229
20301
|
} catch {
|
|
20230
20302
|
return;
|
|
20231
20303
|
}
|
|
@@ -20234,16 +20306,16 @@ var FileWatcherService = class {
|
|
|
20234
20306
|
);
|
|
20235
20307
|
if (gitignoreEntry) {
|
|
20236
20308
|
try {
|
|
20237
|
-
const body =
|
|
20238
|
-
const rel =
|
|
20309
|
+
const body = fs35.readFileSync(path42.join(dir, ".gitignore"), "utf8");
|
|
20310
|
+
const rel = path42.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20239
20311
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20240
20312
|
const trimmed = line.trim();
|
|
20241
20313
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20242
20314
|
if (!rel) return line;
|
|
20243
20315
|
if (trimmed.startsWith("!")) {
|
|
20244
|
-
return "!" +
|
|
20316
|
+
return "!" + path42.posix.join(rel, trimmed.slice(1));
|
|
20245
20317
|
}
|
|
20246
|
-
return
|
|
20318
|
+
return path42.posix.join(rel, trimmed);
|
|
20247
20319
|
}).join("\n");
|
|
20248
20320
|
matcher.add(prefixed);
|
|
20249
20321
|
} catch {
|
|
@@ -20252,7 +20324,7 @@ var FileWatcherService = class {
|
|
|
20252
20324
|
for (const entry of entries) {
|
|
20253
20325
|
if (!entry.isDirectory()) continue;
|
|
20254
20326
|
if (entry.name === ".git") continue;
|
|
20255
|
-
const childAbs =
|
|
20327
|
+
const childAbs = path42.join(dir, entry.name);
|
|
20256
20328
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20257
20329
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20258
20330
|
}
|
|
@@ -20422,7 +20494,7 @@ var import_crypto4 = require("crypto");
|
|
|
20422
20494
|
|
|
20423
20495
|
// src/services/turn-files/git-changeset.ts
|
|
20424
20496
|
var import_child_process20 = require("child_process");
|
|
20425
|
-
var
|
|
20497
|
+
var path43 = __toESM(require("path"));
|
|
20426
20498
|
async function collectRepoChangeset(opts) {
|
|
20427
20499
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20428
20500
|
if (status2 === null) return null;
|
|
@@ -20533,7 +20605,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20533
20605
|
});
|
|
20534
20606
|
}
|
|
20535
20607
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20536
|
-
const
|
|
20608
|
+
const fs41 = await import("fs/promises");
|
|
20537
20609
|
const out2 = [];
|
|
20538
20610
|
await walk(workingDir, 0);
|
|
20539
20611
|
return out2;
|
|
@@ -20541,7 +20613,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20541
20613
|
if (depth > maxDepth) return;
|
|
20542
20614
|
let entries = [];
|
|
20543
20615
|
try {
|
|
20544
|
-
const dirents = await
|
|
20616
|
+
const dirents = await fs41.readdir(dir, { withFileTypes: true });
|
|
20545
20617
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20546
20618
|
} catch {
|
|
20547
20619
|
return;
|
|
@@ -20552,8 +20624,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20552
20624
|
if (hasGit) {
|
|
20553
20625
|
out2.push({
|
|
20554
20626
|
repoRoot: dir,
|
|
20555
|
-
repoPath:
|
|
20556
|
-
repoName:
|
|
20627
|
+
repoPath: path43.relative(workingDir, dir),
|
|
20628
|
+
repoName: path43.basename(dir)
|
|
20557
20629
|
});
|
|
20558
20630
|
return;
|
|
20559
20631
|
}
|
|
@@ -20561,14 +20633,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20561
20633
|
if (!entry.isDirectory) continue;
|
|
20562
20634
|
if (entry.name === "node_modules") continue;
|
|
20563
20635
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20564
|
-
await walk(
|
|
20636
|
+
await walk(path43.join(dir, entry.name), depth + 1);
|
|
20565
20637
|
}
|
|
20566
20638
|
}
|
|
20567
20639
|
}
|
|
20568
20640
|
|
|
20569
20641
|
// src/services/turn-files/files-outbox.ts
|
|
20570
|
-
var
|
|
20571
|
-
var
|
|
20642
|
+
var fs36 = __toESM(require("fs/promises"));
|
|
20643
|
+
var path44 = __toESM(require("path"));
|
|
20572
20644
|
var import_os7 = require("os");
|
|
20573
20645
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20574
20646
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20601,16 +20673,16 @@ var FilesOutbox = class {
|
|
|
20601
20673
|
backoffIndex = 0;
|
|
20602
20674
|
stopped = false;
|
|
20603
20675
|
constructor(opts) {
|
|
20604
|
-
const base = opts.baseDir ??
|
|
20605
|
-
this.filePath =
|
|
20676
|
+
const base = opts.baseDir ?? path44.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20677
|
+
this.filePath = path44.join(base, `${opts.sessionId}.jsonl`);
|
|
20606
20678
|
this.post = opts.post;
|
|
20607
20679
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20608
20680
|
}
|
|
20609
20681
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20610
20682
|
* line is durable on disk (not once the POST succeeds). */
|
|
20611
20683
|
async enqueue(entry) {
|
|
20612
|
-
await
|
|
20613
|
-
await
|
|
20684
|
+
await fs36.mkdir(path44.dirname(this.filePath), { recursive: true });
|
|
20685
|
+
await fs36.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20614
20686
|
this.backoffIndex = 0;
|
|
20615
20687
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20616
20688
|
}
|
|
@@ -20699,7 +20771,7 @@ var FilesOutbox = class {
|
|
|
20699
20771
|
async readAll() {
|
|
20700
20772
|
let raw = "";
|
|
20701
20773
|
try {
|
|
20702
|
-
raw = await
|
|
20774
|
+
raw = await fs36.readFile(this.filePath, "utf8");
|
|
20703
20775
|
} catch {
|
|
20704
20776
|
return [];
|
|
20705
20777
|
}
|
|
@@ -20723,12 +20795,12 @@ var FilesOutbox = class {
|
|
|
20723
20795
|
async rewrite(entries) {
|
|
20724
20796
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20725
20797
|
if (entries.length === 0) {
|
|
20726
|
-
await
|
|
20798
|
+
await fs36.unlink(this.filePath).catch(() => void 0);
|
|
20727
20799
|
return;
|
|
20728
20800
|
}
|
|
20729
20801
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20730
|
-
await
|
|
20731
|
-
await
|
|
20802
|
+
await fs36.writeFile(tmpPath, payload, "utf8");
|
|
20803
|
+
await fs36.rename(tmpPath, this.filePath);
|
|
20732
20804
|
}
|
|
20733
20805
|
};
|
|
20734
20806
|
function applyJitter(ms) {
|
|
@@ -21185,6 +21257,23 @@ var AcpHistory = class {
|
|
|
21185
21257
|
timestamp: Date.now()
|
|
21186
21258
|
});
|
|
21187
21259
|
}
|
|
21260
|
+
/**
|
|
21261
|
+
* Record an agent-initiated reply that has NO preceding user prompt
|
|
21262
|
+
* — the first-pair onboarding welcome the agent sends on its own.
|
|
21263
|
+
* Seeds the RECENT summary from the reply itself (so {@link flush}
|
|
21264
|
+
* isn't skipped for lack of a user prompt) and appends ONLY the
|
|
21265
|
+
* agent message: the background instruction that produced this reply
|
|
21266
|
+
* must never surface as a user bubble on mobile.
|
|
21267
|
+
*/
|
|
21268
|
+
appendAgentInitiatedReply(text) {
|
|
21269
|
+
const trimmed = text.trim();
|
|
21270
|
+
if (trimmed.length === 0) return;
|
|
21271
|
+
if (this.summary === null) {
|
|
21272
|
+
const oneLine = trimmed.replace(/\s+/g, " ");
|
|
21273
|
+
this.summary = oneLine.length > 120 ? oneLine.slice(0, 117) + "\u2026" : oneLine;
|
|
21274
|
+
}
|
|
21275
|
+
this.appendAgentReply(text);
|
|
21276
|
+
}
|
|
21188
21277
|
/**
|
|
21189
21278
|
* Push both the session list (RECENT entry) and the cumulative
|
|
21190
21279
|
* conversation to the backend. Fire-and-forget — failures land in
|
|
@@ -21330,6 +21419,13 @@ async function runAcpSession(opts) {
|
|
|
21330
21419
|
const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
|
|
21331
21420
|
const models = await runtime.listModels();
|
|
21332
21421
|
const history = new AcpHistory(publisher, { agent: opts.agent, acpSessionId });
|
|
21422
|
+
maybeSendOnboardingWelcome({
|
|
21423
|
+
client: client2,
|
|
21424
|
+
streaming,
|
|
21425
|
+
history,
|
|
21426
|
+
sessionId: opts.sessionId,
|
|
21427
|
+
cwd: opts.cwd
|
|
21428
|
+
});
|
|
21333
21429
|
const turnFiles = new TurnFileAggregator({
|
|
21334
21430
|
workingDir: opts.cwd,
|
|
21335
21431
|
sessionId: opts.sessionId,
|
|
@@ -22549,9 +22645,9 @@ var OutputService = class _OutputService {
|
|
|
22549
22645
|
};
|
|
22550
22646
|
|
|
22551
22647
|
// src/services/history.service.ts
|
|
22552
|
-
var
|
|
22553
|
-
var
|
|
22554
|
-
var
|
|
22648
|
+
var fs37 = __toESM(require("fs"));
|
|
22649
|
+
var path45 = __toESM(require("path"));
|
|
22650
|
+
var os29 = __toESM(require("os"));
|
|
22555
22651
|
var https7 = __toESM(require("https"));
|
|
22556
22652
|
var http7 = __toESM(require("http"));
|
|
22557
22653
|
var import_zod2 = require("zod");
|
|
@@ -22578,7 +22674,7 @@ function parseJsonl(filePath) {
|
|
|
22578
22674
|
const messages = [];
|
|
22579
22675
|
let raw;
|
|
22580
22676
|
try {
|
|
22581
|
-
raw =
|
|
22677
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
22582
22678
|
} catch (err) {
|
|
22583
22679
|
if (err.code !== "ENOENT") {
|
|
22584
22680
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22713,7 +22809,7 @@ var HistoryService = class _HistoryService {
|
|
|
22713
22809
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22714
22810
|
}
|
|
22715
22811
|
get projectDir() {
|
|
22716
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
22812
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path45.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22717
22813
|
}
|
|
22718
22814
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22719
22815
|
setCurrentConversationId(id) {
|
|
@@ -22725,7 +22821,7 @@ var HistoryService = class _HistoryService {
|
|
|
22725
22821
|
/** Return the current message count in the active conversation. */
|
|
22726
22822
|
getCurrentMessageCount() {
|
|
22727
22823
|
if (!this.currentConversationId) return 0;
|
|
22728
|
-
const filePath =
|
|
22824
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22729
22825
|
return parseJsonl(filePath).length;
|
|
22730
22826
|
}
|
|
22731
22827
|
/**
|
|
@@ -22736,7 +22832,7 @@ var HistoryService = class _HistoryService {
|
|
|
22736
22832
|
const deadline = Date.now() + timeoutMs;
|
|
22737
22833
|
while (Date.now() < deadline) {
|
|
22738
22834
|
if (!this.currentConversationId) return null;
|
|
22739
|
-
const filePath =
|
|
22835
|
+
const filePath = path45.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22740
22836
|
const messages = parseJsonl(filePath);
|
|
22741
22837
|
if (messages.length > previousCount) {
|
|
22742
22838
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22762,16 +22858,16 @@ var HistoryService = class _HistoryService {
|
|
|
22762
22858
|
const dir = this.projectDir;
|
|
22763
22859
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22764
22860
|
try {
|
|
22765
|
-
const files =
|
|
22861
|
+
const files = fs37.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22766
22862
|
try {
|
|
22767
|
-
const stat3 =
|
|
22863
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
22768
22864
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22769
22865
|
} catch {
|
|
22770
22866
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22771
22867
|
}
|
|
22772
22868
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22773
22869
|
if (files.length > 0) {
|
|
22774
|
-
this.currentConversationId =
|
|
22870
|
+
this.currentConversationId = path45.basename(files[0].name, ".jsonl");
|
|
22775
22871
|
}
|
|
22776
22872
|
} catch {
|
|
22777
22873
|
}
|
|
@@ -22805,13 +22901,13 @@ var HistoryService = class _HistoryService {
|
|
|
22805
22901
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22806
22902
|
let entries;
|
|
22807
22903
|
try {
|
|
22808
|
-
entries =
|
|
22904
|
+
entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
22809
22905
|
} catch {
|
|
22810
22906
|
return null;
|
|
22811
22907
|
}
|
|
22812
22908
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22813
22909
|
try {
|
|
22814
|
-
const stat3 =
|
|
22910
|
+
const stat3 = fs37.statSync(path45.join(dir, e.name));
|
|
22815
22911
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22816
22912
|
} catch {
|
|
22817
22913
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22820,12 +22916,12 @@ var HistoryService = class _HistoryService {
|
|
|
22820
22916
|
if (files.length === 0) return null;
|
|
22821
22917
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22822
22918
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22823
|
-
return this.extractUsageFromFile(
|
|
22919
|
+
return this.extractUsageFromFile(path45.join(dir, targetFile));
|
|
22824
22920
|
}
|
|
22825
22921
|
extractUsageFromFile(filePath) {
|
|
22826
22922
|
let raw;
|
|
22827
22923
|
try {
|
|
22828
|
-
raw =
|
|
22924
|
+
raw = fs37.readFileSync(filePath, "utf8");
|
|
22829
22925
|
} catch {
|
|
22830
22926
|
return null;
|
|
22831
22927
|
}
|
|
@@ -22870,9 +22966,9 @@ var HistoryService = class _HistoryService {
|
|
|
22870
22966
|
let totalCost = 0;
|
|
22871
22967
|
let files;
|
|
22872
22968
|
try {
|
|
22873
|
-
files =
|
|
22969
|
+
files = fs37.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
22874
22970
|
try {
|
|
22875
|
-
return
|
|
22971
|
+
return fs37.statSync(path45.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
22876
22972
|
} catch {
|
|
22877
22973
|
return false;
|
|
22878
22974
|
}
|
|
@@ -22883,7 +22979,7 @@ var HistoryService = class _HistoryService {
|
|
|
22883
22979
|
for (const file of files) {
|
|
22884
22980
|
let raw;
|
|
22885
22981
|
try {
|
|
22886
|
-
raw =
|
|
22982
|
+
raw = fs37.readFileSync(path45.join(projectDir, file), "utf8");
|
|
22887
22983
|
} catch {
|
|
22888
22984
|
continue;
|
|
22889
22985
|
}
|
|
@@ -22947,7 +23043,7 @@ var HistoryService = class _HistoryService {
|
|
|
22947
23043
|
* showing an empty conversation.
|
|
22948
23044
|
*/
|
|
22949
23045
|
async loadConversation(sessionId) {
|
|
22950
|
-
const filePath =
|
|
23046
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
22951
23047
|
const messages = parseJsonl(filePath);
|
|
22952
23048
|
if (messages.length === 0) return;
|
|
22953
23049
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23001,7 +23097,7 @@ var HistoryService = class _HistoryService {
|
|
|
23001
23097
|
if (!this.currentConversationId) return 0;
|
|
23002
23098
|
}
|
|
23003
23099
|
const sessionId = this.currentConversationId;
|
|
23004
|
-
const filePath =
|
|
23100
|
+
const filePath = path45.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23005
23101
|
const messages = parseJsonl(filePath);
|
|
23006
23102
|
if (messages.length === 0) return 0;
|
|
23007
23103
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -23922,8 +24018,8 @@ async function autoLinkAfterPair(opts) {
|
|
|
23922
24018
|
}
|
|
23923
24019
|
|
|
23924
24020
|
// src/commands/pair-auto.ts
|
|
23925
|
-
var
|
|
23926
|
-
var
|
|
24021
|
+
var fs38 = __toESM(require("fs"));
|
|
24022
|
+
var os30 = __toESM(require("os"));
|
|
23927
24023
|
var import_crypto7 = require("crypto");
|
|
23928
24024
|
|
|
23929
24025
|
// src/commands/start-infra-only.ts
|
|
@@ -24118,12 +24214,12 @@ function readTokenFromArgs(args2) {
|
|
|
24118
24214
|
}
|
|
24119
24215
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24120
24216
|
if (fileFlag) {
|
|
24121
|
-
const
|
|
24217
|
+
const path52 = fileFlag.slice("--token-file=".length);
|
|
24122
24218
|
try {
|
|
24123
|
-
const content =
|
|
24124
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24219
|
+
const content = fs38.readFileSync(path52, "utf8").trim();
|
|
24220
|
+
if (content.length === 0) fail(`--token-file ${path52} is empty`);
|
|
24125
24221
|
try {
|
|
24126
|
-
|
|
24222
|
+
fs38.unlinkSync(path52);
|
|
24127
24223
|
} catch {
|
|
24128
24224
|
}
|
|
24129
24225
|
return content;
|
|
@@ -24149,7 +24245,7 @@ async function claimOnce(token, pluginId) {
|
|
|
24149
24245
|
pluginId,
|
|
24150
24246
|
ideName: "codeam-cli (codespace)",
|
|
24151
24247
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
24152
|
-
hostname:
|
|
24248
|
+
hostname: os30.hostname(),
|
|
24153
24249
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
24154
24250
|
// Current git branch of the codespace's working directory, so the
|
|
24155
24251
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24389,7 +24485,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24389
24485
|
var import_child_process22 = require("child_process");
|
|
24390
24486
|
var import_util4 = require("util");
|
|
24391
24487
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24392
|
-
var
|
|
24488
|
+
var path46 = __toESM(require("path"));
|
|
24393
24489
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24394
24490
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24395
24491
|
function resetStdinForChild() {
|
|
@@ -24878,7 +24974,7 @@ var GitHubCodespacesProvider = class {
|
|
|
24878
24974
|
});
|
|
24879
24975
|
}
|
|
24880
24976
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
24881
|
-
const remoteDir =
|
|
24977
|
+
const remoteDir = path46.posix.dirname(remotePath);
|
|
24882
24978
|
const parts = [
|
|
24883
24979
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
24884
24980
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -24948,7 +25044,7 @@ function shellQuote(s) {
|
|
|
24948
25044
|
// src/services/providers/gitpod.ts
|
|
24949
25045
|
var import_child_process23 = require("child_process");
|
|
24950
25046
|
var import_util5 = require("util");
|
|
24951
|
-
var
|
|
25047
|
+
var path47 = __toESM(require("path"));
|
|
24952
25048
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
24953
25049
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
24954
25050
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25188,7 +25284,7 @@ var GitpodProvider = class {
|
|
|
25188
25284
|
});
|
|
25189
25285
|
}
|
|
25190
25286
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25191
|
-
const remoteDir =
|
|
25287
|
+
const remoteDir = path47.posix.dirname(remotePath);
|
|
25192
25288
|
const parts = [
|
|
25193
25289
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25194
25290
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25224,7 +25320,7 @@ function shellQuote2(s) {
|
|
|
25224
25320
|
// src/services/providers/gitlab-workspaces.ts
|
|
25225
25321
|
var import_child_process24 = require("child_process");
|
|
25226
25322
|
var import_util6 = require("util");
|
|
25227
|
-
var
|
|
25323
|
+
var path48 = __toESM(require("path"));
|
|
25228
25324
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25229
25325
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25230
25326
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25484,7 +25580,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25484
25580
|
}
|
|
25485
25581
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25486
25582
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25487
|
-
const remoteDir =
|
|
25583
|
+
const remoteDir = path48.posix.dirname(remotePath);
|
|
25488
25584
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25489
25585
|
if (options.mode != null) {
|
|
25490
25586
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25552,7 +25648,7 @@ function shellQuote3(s) {
|
|
|
25552
25648
|
// src/services/providers/railway.ts
|
|
25553
25649
|
var import_child_process25 = require("child_process");
|
|
25554
25650
|
var import_util7 = require("util");
|
|
25555
|
-
var
|
|
25651
|
+
var path49 = __toESM(require("path"));
|
|
25556
25652
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25557
25653
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25558
25654
|
function resetStdinForChild4() {
|
|
@@ -25788,7 +25884,7 @@ var RailwayProvider = class {
|
|
|
25788
25884
|
if (!projectId || !serviceId) {
|
|
25789
25885
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
25790
25886
|
}
|
|
25791
|
-
const remoteDir =
|
|
25887
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25792
25888
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
25793
25889
|
if (options.mode != null) {
|
|
25794
25890
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26331,8 +26427,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26331
26427
|
var import_node_dns = require("dns");
|
|
26332
26428
|
var import_node_util4 = require("util");
|
|
26333
26429
|
var import_node_crypto8 = require("crypto");
|
|
26334
|
-
var
|
|
26335
|
-
var
|
|
26430
|
+
var fs39 = __toESM(require("fs"));
|
|
26431
|
+
var path50 = __toESM(require("path"));
|
|
26336
26432
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26337
26433
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26338
26434
|
async function checkDns(apiBase) {
|
|
@@ -26388,13 +26484,13 @@ async function checkHealth(apiBase) {
|
|
|
26388
26484
|
}
|
|
26389
26485
|
}
|
|
26390
26486
|
function checkConfigDir() {
|
|
26391
|
-
const dir =
|
|
26487
|
+
const dir = path50.join(require("os").homedir(), ".codeam");
|
|
26392
26488
|
try {
|
|
26393
|
-
|
|
26394
|
-
const probe =
|
|
26395
|
-
|
|
26396
|
-
const read =
|
|
26397
|
-
|
|
26489
|
+
fs39.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26490
|
+
const probe = path50.join(dir, ".doctor-probe");
|
|
26491
|
+
fs39.writeFileSync(probe, "ok", { mode: 384 });
|
|
26492
|
+
const read = fs39.readFileSync(probe, "utf8");
|
|
26493
|
+
fs39.unlinkSync(probe);
|
|
26398
26494
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26399
26495
|
return {
|
|
26400
26496
|
id: "config-dir",
|
|
@@ -26434,9 +26530,9 @@ function checkSessions() {
|
|
|
26434
26530
|
}
|
|
26435
26531
|
}
|
|
26436
26532
|
function checkAgentBinaries() {
|
|
26437
|
-
const
|
|
26533
|
+
const os32 = createOsStrategy();
|
|
26438
26534
|
return getEnabledAgents().map((meta) => {
|
|
26439
|
-
const found =
|
|
26535
|
+
const found = os32.findInPath(meta.binaryName);
|
|
26440
26536
|
return {
|
|
26441
26537
|
id: `agent-${meta.id}`,
|
|
26442
26538
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -26458,7 +26554,7 @@ function checkNodePty() {
|
|
|
26458
26554
|
detail: "not required on this platform"
|
|
26459
26555
|
};
|
|
26460
26556
|
}
|
|
26461
|
-
const vendoredPath =
|
|
26557
|
+
const vendoredPath = path50.join(__dirname, "vendor", "node-pty");
|
|
26462
26558
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26463
26559
|
try {
|
|
26464
26560
|
require(target);
|
|
@@ -26500,7 +26596,7 @@ function checkChokidar() {
|
|
|
26500
26596
|
}
|
|
26501
26597
|
async function doctor(args2 = []) {
|
|
26502
26598
|
const json = args2.includes("--json");
|
|
26503
|
-
const cliVersion = true ? "2.
|
|
26599
|
+
const cliVersion = true ? "2.37.1" : "0.0.0-dev";
|
|
26504
26600
|
const apiBase = resolveApiBaseUrl();
|
|
26505
26601
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26506
26602
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26699,7 +26795,7 @@ async function completion(args2) {
|
|
|
26699
26795
|
// src/commands/version.ts
|
|
26700
26796
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26701
26797
|
function version2() {
|
|
26702
|
-
const v = true ? "2.
|
|
26798
|
+
const v = true ? "2.37.1" : "unknown";
|
|
26703
26799
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26704
26800
|
}
|
|
26705
26801
|
|
|
@@ -26827,9 +26923,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
26827
26923
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
26828
26924
|
|
|
26829
26925
|
// src/lib/updateNotifier.ts
|
|
26830
|
-
var
|
|
26831
|
-
var
|
|
26832
|
-
var
|
|
26926
|
+
var fs40 = __toESM(require("fs"));
|
|
26927
|
+
var os31 = __toESM(require("os"));
|
|
26928
|
+
var path51 = __toESM(require("path"));
|
|
26833
26929
|
var https8 = __toESM(require("https"));
|
|
26834
26930
|
var import_node_child_process12 = require("child_process");
|
|
26835
26931
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -26838,12 +26934,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
26838
26934
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26839
26935
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
26840
26936
|
function cachePath() {
|
|
26841
|
-
const dir =
|
|
26842
|
-
return
|
|
26937
|
+
const dir = path51.join(os31.homedir(), ".codeam");
|
|
26938
|
+
return path51.join(dir, "update-check.json");
|
|
26843
26939
|
}
|
|
26844
26940
|
function readCache() {
|
|
26845
26941
|
try {
|
|
26846
|
-
const raw =
|
|
26942
|
+
const raw = fs40.readFileSync(cachePath(), "utf8");
|
|
26847
26943
|
const parsed = JSON.parse(raw);
|
|
26848
26944
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
26849
26945
|
return parsed;
|
|
@@ -26854,10 +26950,10 @@ function readCache() {
|
|
|
26854
26950
|
function writeCache(cache) {
|
|
26855
26951
|
try {
|
|
26856
26952
|
const file = cachePath();
|
|
26857
|
-
|
|
26953
|
+
fs40.mkdirSync(path51.dirname(file), { recursive: true });
|
|
26858
26954
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
26859
|
-
|
|
26860
|
-
|
|
26955
|
+
fs40.writeFileSync(tmp, JSON.stringify(cache));
|
|
26956
|
+
fs40.renameSync(tmp, file);
|
|
26861
26957
|
} catch {
|
|
26862
26958
|
}
|
|
26863
26959
|
}
|
|
@@ -26931,8 +27027,8 @@ function isLinkedInstall() {
|
|
|
26931
27027
|
timeout: 2e3
|
|
26932
27028
|
}).trim();
|
|
26933
27029
|
if (!root) return false;
|
|
26934
|
-
const pkgPath =
|
|
26935
|
-
return
|
|
27030
|
+
const pkgPath = path51.join(root, PKG_NAME);
|
|
27031
|
+
return fs40.lstatSync(pkgPath).isSymbolicLink();
|
|
26936
27032
|
} catch {
|
|
26937
27033
|
return false;
|
|
26938
27034
|
}
|
|
@@ -26968,7 +27064,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
26968
27064
|
return;
|
|
26969
27065
|
}
|
|
26970
27066
|
try {
|
|
26971
|
-
|
|
27067
|
+
fs40.unlinkSync(cachePath());
|
|
26972
27068
|
} catch {
|
|
26973
27069
|
}
|
|
26974
27070
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -26985,7 +27081,7 @@ function checkForUpdates() {
|
|
|
26985
27081
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
26986
27082
|
if (process.env.CI) return;
|
|
26987
27083
|
if (!process.stdout.isTTY) return;
|
|
26988
|
-
const current = true ? "2.
|
|
27084
|
+
const current = true ? "2.37.1" : null;
|
|
26989
27085
|
if (!current) return;
|
|
26990
27086
|
const cache = readCache();
|
|
26991
27087
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|