codeam-cli 2.49.5 → 2.50.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 +6 -0
- package/dist/index.js +397 -206
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -522,9 +522,9 @@ var _default = makeConfig();
|
|
|
522
522
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
523
523
|
|
|
524
524
|
// src/commands/pair-auto.ts
|
|
525
|
-
var
|
|
526
|
-
var
|
|
527
|
-
var
|
|
525
|
+
var fs42 = __toESM(require("fs"));
|
|
526
|
+
var os35 = __toESM(require("os"));
|
|
527
|
+
var path48 = __toESM(require("path"));
|
|
528
528
|
var import_crypto4 = require("crypto");
|
|
529
529
|
|
|
530
530
|
// src/services/telemetry.service.ts
|
|
@@ -560,8 +560,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
560
560
|
return decodedFile;
|
|
561
561
|
};
|
|
562
562
|
}
|
|
563
|
-
function normalizeWindowsPath(
|
|
564
|
-
return
|
|
563
|
+
function normalizeWindowsPath(path61) {
|
|
564
|
+
return path61.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
565
565
|
}
|
|
566
566
|
|
|
567
567
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3041,9 +3041,9 @@ async function addSourceContext(frames) {
|
|
|
3041
3041
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3042
3042
|
return frames;
|
|
3043
3043
|
}
|
|
3044
|
-
function getContextLinesFromFile(
|
|
3044
|
+
function getContextLinesFromFile(path61, ranges, output) {
|
|
3045
3045
|
return new Promise((resolve7) => {
|
|
3046
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3046
|
+
const stream = (0, import_node_fs.createReadStream)(path61);
|
|
3047
3047
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3048
3048
|
input: stream
|
|
3049
3049
|
});
|
|
@@ -3058,7 +3058,7 @@ function getContextLinesFromFile(path60, ranges, output) {
|
|
|
3058
3058
|
let rangeStart = range[0];
|
|
3059
3059
|
let rangeEnd = range[1];
|
|
3060
3060
|
function onStreamError() {
|
|
3061
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3061
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path61, 1);
|
|
3062
3062
|
lineReaded.close();
|
|
3063
3063
|
lineReaded.removeAllListeners();
|
|
3064
3064
|
destroyStreamAndResolve();
|
|
@@ -3119,8 +3119,8 @@ function clearLineContext(frame) {
|
|
|
3119
3119
|
delete frame.context_line;
|
|
3120
3120
|
delete frame.post_context;
|
|
3121
3121
|
}
|
|
3122
|
-
function shouldSkipContextLinesForFile(
|
|
3123
|
-
return
|
|
3122
|
+
function shouldSkipContextLinesForFile(path61) {
|
|
3123
|
+
return path61.startsWith("node:") || path61.endsWith(".min.js") || path61.endsWith(".min.cjs") || path61.endsWith(".min.mjs") || path61.startsWith("data:");
|
|
3124
3124
|
}
|
|
3125
3125
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3126
3126
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5397,7 +5397,7 @@ function readAnonId() {
|
|
|
5397
5397
|
}
|
|
5398
5398
|
function superProperties() {
|
|
5399
5399
|
return {
|
|
5400
|
-
cliVersion: true ? "2.
|
|
5400
|
+
cliVersion: true ? "2.50.0" : "0.0.0-dev",
|
|
5401
5401
|
nodeVersion: process.version,
|
|
5402
5402
|
platform: process.platform,
|
|
5403
5403
|
arch: process.arch,
|
|
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
|
|
|
5578
5578
|
// package.json
|
|
5579
5579
|
var package_default = {
|
|
5580
5580
|
name: "codeam-cli",
|
|
5581
|
-
version: "2.
|
|
5581
|
+
version: "2.50.0",
|
|
5582
5582
|
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.",
|
|
5583
5583
|
type: "commonjs",
|
|
5584
5584
|
main: "dist/index.js",
|
|
@@ -5871,6 +5871,28 @@ async function postHeadroomEvent(input) {
|
|
|
5871
5871
|
};
|
|
5872
5872
|
}
|
|
5873
5873
|
}
|
|
5874
|
+
async function postBeadsEvent(input) {
|
|
5875
|
+
try {
|
|
5876
|
+
await _transport.postJsonAuthed(
|
|
5877
|
+
`${API_BASE}/api/beads/events`,
|
|
5878
|
+
{
|
|
5879
|
+
sessionId: input.sessionId,
|
|
5880
|
+
pluginId: input.pluginId,
|
|
5881
|
+
type: input.type,
|
|
5882
|
+
payload: input.payload ?? {}
|
|
5883
|
+
},
|
|
5884
|
+
input.pluginAuthToken
|
|
5885
|
+
);
|
|
5886
|
+
return { ok: true };
|
|
5887
|
+
} catch (err) {
|
|
5888
|
+
const e = err;
|
|
5889
|
+
return {
|
|
5890
|
+
ok: false,
|
|
5891
|
+
status: typeof e.statusCode === "number" ? e.statusCode : 0,
|
|
5892
|
+
message: e.message || "unknown"
|
|
5893
|
+
};
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5874
5896
|
async function postBeadsProvisioning(input) {
|
|
5875
5897
|
try {
|
|
5876
5898
|
await _transport.postJsonAuthed(
|
|
@@ -7706,9 +7728,9 @@ function closeAllTerminals() {
|
|
|
7706
7728
|
}
|
|
7707
7729
|
|
|
7708
7730
|
// src/commands/start/handlers.ts
|
|
7709
|
-
var
|
|
7710
|
-
var
|
|
7711
|
-
var
|
|
7731
|
+
var fs41 = __toESM(require("fs"));
|
|
7732
|
+
var os34 = __toESM(require("os"));
|
|
7733
|
+
var path47 = __toESM(require("path"));
|
|
7712
7734
|
var import_crypto3 = require("crypto");
|
|
7713
7735
|
var import_child_process20 = require("child_process");
|
|
7714
7736
|
var import_which2 = __toESM(require("which"));
|
|
@@ -11142,10 +11164,10 @@ function buildForPlatform(platform3) {
|
|
|
11142
11164
|
var import_node_crypto4 = require("crypto");
|
|
11143
11165
|
|
|
11144
11166
|
// src/agents/claude/resolver.ts
|
|
11145
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11146
|
-
const found =
|
|
11167
|
+
function buildClaudeLaunch(extraArgs = [], os41 = createOsStrategy()) {
|
|
11168
|
+
const found = os41.findInPath("claude") ?? os41.findInPath("claude-code");
|
|
11147
11169
|
if (!found) return null;
|
|
11148
|
-
return
|
|
11170
|
+
return os41.buildLaunch(found, extraArgs);
|
|
11149
11171
|
}
|
|
11150
11172
|
|
|
11151
11173
|
// src/agents/claude/installer.ts
|
|
@@ -11738,8 +11760,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
11738
11760
|
meta = getAgent("claude");
|
|
11739
11761
|
mode = "interactive";
|
|
11740
11762
|
os;
|
|
11741
|
-
constructor(
|
|
11742
|
-
this.os =
|
|
11763
|
+
constructor(os41) {
|
|
11764
|
+
this.os = os41;
|
|
11743
11765
|
}
|
|
11744
11766
|
/**
|
|
11745
11767
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -12416,8 +12438,8 @@ function codexCredentialLocator() {
|
|
|
12416
12438
|
function codexLoginLauncher() {
|
|
12417
12439
|
return {
|
|
12418
12440
|
async ensureInstalled() {
|
|
12419
|
-
const
|
|
12420
|
-
return
|
|
12441
|
+
const os41 = createOsStrategy();
|
|
12442
|
+
return os41.findInPath("codex") !== null;
|
|
12421
12443
|
},
|
|
12422
12444
|
launch() {
|
|
12423
12445
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -12440,8 +12462,8 @@ var CodexRuntimeStrategy = class {
|
|
|
12440
12462
|
meta = getAgent("codex");
|
|
12441
12463
|
mode = "interactive";
|
|
12442
12464
|
os;
|
|
12443
|
-
constructor(
|
|
12444
|
-
this.os =
|
|
12465
|
+
constructor(os41) {
|
|
12466
|
+
this.os = os41;
|
|
12445
12467
|
}
|
|
12446
12468
|
async prepareLaunch() {
|
|
12447
12469
|
let binary = this.os.findInPath("codex");
|
|
@@ -12540,12 +12562,12 @@ var CodexRuntimeStrategy = class {
|
|
|
12540
12562
|
});
|
|
12541
12563
|
}
|
|
12542
12564
|
};
|
|
12543
|
-
function resolveNpm(
|
|
12544
|
-
return
|
|
12565
|
+
function resolveNpm(os41) {
|
|
12566
|
+
return os41.id === "win32" ? "npm.cmd" : "npm";
|
|
12545
12567
|
}
|
|
12546
|
-
async function installCodexViaNpm(
|
|
12568
|
+
async function installCodexViaNpm(os41) {
|
|
12547
12569
|
return new Promise((resolve7, reject) => {
|
|
12548
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
12570
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os41), ["install", "-g", "@openai/codex"], {
|
|
12549
12571
|
stdio: "inherit"
|
|
12550
12572
|
});
|
|
12551
12573
|
proc.on("close", (code) => {
|
|
@@ -12562,16 +12584,16 @@ async function installCodexViaNpm(os40) {
|
|
|
12562
12584
|
});
|
|
12563
12585
|
});
|
|
12564
12586
|
}
|
|
12565
|
-
function augmentNpmGlobalBin(
|
|
12587
|
+
function augmentNpmGlobalBin(os41) {
|
|
12566
12588
|
try {
|
|
12567
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
12589
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os41), ["prefix", "-g"], {
|
|
12568
12590
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12569
12591
|
});
|
|
12570
12592
|
if (result.status !== 0) return;
|
|
12571
12593
|
const prefix = result.stdout.toString().trim();
|
|
12572
12594
|
if (!prefix) return;
|
|
12573
|
-
const binDir =
|
|
12574
|
-
|
|
12595
|
+
const binDir = os41.id === "win32" ? prefix : path22.join(prefix, "bin");
|
|
12596
|
+
os41.augmentPath([binDir]);
|
|
12575
12597
|
} catch {
|
|
12576
12598
|
}
|
|
12577
12599
|
}
|
|
@@ -12655,9 +12677,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
12655
12677
|
// src/agents/coderabbit/installer.ts
|
|
12656
12678
|
var import_node_child_process5 = require("child_process");
|
|
12657
12679
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
12658
|
-
async function ensureCoderabbitInstalled(
|
|
12659
|
-
if (
|
|
12660
|
-
if (
|
|
12680
|
+
async function ensureCoderabbitInstalled(os41) {
|
|
12681
|
+
if (os41.findInPath("coderabbit")) return true;
|
|
12682
|
+
if (os41.id === "win32") {
|
|
12661
12683
|
console.error(
|
|
12662
12684
|
"\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"
|
|
12663
12685
|
);
|
|
@@ -12672,8 +12694,8 @@ async function ensureCoderabbitInstalled(os40) {
|
|
|
12672
12694
|
proc.on("error", () => resolve7(false));
|
|
12673
12695
|
});
|
|
12674
12696
|
if (!ok) return false;
|
|
12675
|
-
|
|
12676
|
-
return
|
|
12697
|
+
os41.augmentPath([`${os41.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
12698
|
+
return os41.findInPath("coderabbit") !== null;
|
|
12677
12699
|
}
|
|
12678
12700
|
|
|
12679
12701
|
// src/agents/coderabbit/link.ts
|
|
@@ -12708,10 +12730,10 @@ function coderabbitCredentialLocator() {
|
|
|
12708
12730
|
validate: validateNonEmptyCredential
|
|
12709
12731
|
};
|
|
12710
12732
|
}
|
|
12711
|
-
function coderabbitLoginLauncher(
|
|
12733
|
+
function coderabbitLoginLauncher(os41) {
|
|
12712
12734
|
return {
|
|
12713
12735
|
async ensureInstalled() {
|
|
12714
|
-
return ensureCoderabbitInstalled(
|
|
12736
|
+
return ensureCoderabbitInstalled(os41);
|
|
12715
12737
|
},
|
|
12716
12738
|
launch() {
|
|
12717
12739
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -12734,11 +12756,11 @@ function parseReview(stdout) {
|
|
|
12734
12756
|
for (const line of lines) {
|
|
12735
12757
|
const m = line.match(HUNK_LINE_RE);
|
|
12736
12758
|
if (!m) continue;
|
|
12737
|
-
const [,
|
|
12738
|
-
if (!
|
|
12759
|
+
const [, path61, lineNo, sevToken, message] = m;
|
|
12760
|
+
if (!path61 || !lineNo || !message) continue;
|
|
12739
12761
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
12740
12762
|
hunks.push({
|
|
12741
|
-
path:
|
|
12763
|
+
path: path61.trim(),
|
|
12742
12764
|
line: Number(lineNo),
|
|
12743
12765
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
12744
12766
|
message: cleanedMessage
|
|
@@ -12757,8 +12779,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
12757
12779
|
meta = getAgent("coderabbit");
|
|
12758
12780
|
mode = "batch";
|
|
12759
12781
|
os;
|
|
12760
|
-
constructor(
|
|
12761
|
-
this.os =
|
|
12782
|
+
constructor(os41) {
|
|
12783
|
+
this.os = os41;
|
|
12762
12784
|
}
|
|
12763
12785
|
getDefaultArgs() {
|
|
12764
12786
|
return ["review"];
|
|
@@ -12874,10 +12896,10 @@ function cursorCredentialLocator() {
|
|
|
12874
12896
|
validate: validateNonEmptyCredential
|
|
12875
12897
|
};
|
|
12876
12898
|
}
|
|
12877
|
-
function cursorLoginLauncher(
|
|
12899
|
+
function cursorLoginLauncher(os41) {
|
|
12878
12900
|
return {
|
|
12879
12901
|
async ensureInstalled() {
|
|
12880
|
-
if (
|
|
12902
|
+
if (os41.findInPath("cursor-agent")) return true;
|
|
12881
12903
|
console.error(
|
|
12882
12904
|
"\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"
|
|
12883
12905
|
);
|
|
@@ -12939,8 +12961,8 @@ var CursorRuntimeStrategy = class {
|
|
|
12939
12961
|
meta = getAgent("cursor");
|
|
12940
12962
|
mode = "interactive";
|
|
12941
12963
|
os;
|
|
12942
|
-
constructor(
|
|
12943
|
-
this.os =
|
|
12964
|
+
constructor(os41) {
|
|
12965
|
+
this.os = os41;
|
|
12944
12966
|
}
|
|
12945
12967
|
async prepareLaunch() {
|
|
12946
12968
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -13079,10 +13101,10 @@ function aiderCredentialLocator() {
|
|
|
13079
13101
|
validate: validateNonEmptyCredential
|
|
13080
13102
|
};
|
|
13081
13103
|
}
|
|
13082
|
-
function aiderLoginLauncher(
|
|
13104
|
+
function aiderLoginLauncher(os41) {
|
|
13083
13105
|
return {
|
|
13084
13106
|
async ensureInstalled() {
|
|
13085
|
-
if (
|
|
13107
|
+
if (os41.findInPath("aider")) return true;
|
|
13086
13108
|
console.error(
|
|
13087
13109
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
13088
13110
|
);
|
|
@@ -13092,7 +13114,7 @@ function aiderLoginLauncher(os40) {
|
|
|
13092
13114
|
console.error(
|
|
13093
13115
|
"\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"
|
|
13094
13116
|
);
|
|
13095
|
-
return (0, import_node_child_process9.spawn)(
|
|
13117
|
+
return (0, import_node_child_process9.spawn)(os41.id === "win32" ? "cmd.exe" : "sh", os41.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
13096
13118
|
stdio: "ignore"
|
|
13097
13119
|
});
|
|
13098
13120
|
}
|
|
@@ -13164,8 +13186,8 @@ var AiderRuntimeStrategy = class {
|
|
|
13164
13186
|
meta = getAgent("aider");
|
|
13165
13187
|
mode = "interactive";
|
|
13166
13188
|
os;
|
|
13167
|
-
constructor(
|
|
13168
|
-
this.os =
|
|
13189
|
+
constructor(os41) {
|
|
13190
|
+
this.os = os41;
|
|
13169
13191
|
}
|
|
13170
13192
|
async prepareLaunch() {
|
|
13171
13193
|
const binary = this.os.findInPath("aider");
|
|
@@ -13294,8 +13316,8 @@ function geminiCredentialLocator() {
|
|
|
13294
13316
|
function geminiLoginLauncher() {
|
|
13295
13317
|
return {
|
|
13296
13318
|
async ensureInstalled() {
|
|
13297
|
-
const
|
|
13298
|
-
return
|
|
13319
|
+
const os41 = createOsStrategy();
|
|
13320
|
+
return os41.findInPath("gemini") !== null;
|
|
13299
13321
|
},
|
|
13300
13322
|
launch() {
|
|
13301
13323
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13328,8 +13350,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
13328
13350
|
meta = getAgent("gemini");
|
|
13329
13351
|
mode = "interactive";
|
|
13330
13352
|
os;
|
|
13331
|
-
constructor(
|
|
13332
|
-
this.os =
|
|
13353
|
+
constructor(os41) {
|
|
13354
|
+
this.os = os41;
|
|
13333
13355
|
}
|
|
13334
13356
|
async prepareLaunch() {
|
|
13335
13357
|
const binary = this.os.findInPath("gemini");
|
|
@@ -13428,18 +13450,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
13428
13450
|
|
|
13429
13451
|
// src/agents/registry.ts
|
|
13430
13452
|
var runtimeBuilders = {
|
|
13431
|
-
claude: (
|
|
13432
|
-
codex: (
|
|
13433
|
-
coderabbit: (
|
|
13434
|
-
cursor: (
|
|
13435
|
-
aider: (
|
|
13436
|
-
gemini: (
|
|
13453
|
+
claude: (os41) => new ClaudeRuntimeStrategy(os41),
|
|
13454
|
+
codex: (os41) => new CodexRuntimeStrategy(os41),
|
|
13455
|
+
coderabbit: (os41) => new CoderabbitRuntimeStrategy(os41),
|
|
13456
|
+
cursor: (os41) => new CursorRuntimeStrategy(os41),
|
|
13457
|
+
aider: (os41) => new AiderRuntimeStrategy(os41),
|
|
13458
|
+
gemini: (os41) => new GeminiRuntimeStrategy(os41)
|
|
13437
13459
|
};
|
|
13438
13460
|
var deployBuilders = {
|
|
13439
13461
|
claude: () => new ClaudeDeployStrategy(),
|
|
13440
13462
|
codex: () => new CodexDeployStrategy()
|
|
13441
13463
|
};
|
|
13442
|
-
function createAgentStrategy(agent,
|
|
13464
|
+
function createAgentStrategy(agent, os41 = createOsStrategy()) {
|
|
13443
13465
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
13444
13466
|
throw new Error(
|
|
13445
13467
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -13449,10 +13471,10 @@ function createAgentStrategy(agent, os40 = createOsStrategy()) {
|
|
|
13449
13471
|
if (!build) {
|
|
13450
13472
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
13451
13473
|
}
|
|
13452
|
-
return build(
|
|
13474
|
+
return build(os41);
|
|
13453
13475
|
}
|
|
13454
|
-
function createInteractiveAgentStrategy(agent,
|
|
13455
|
-
const s = createAgentStrategy(agent,
|
|
13476
|
+
function createInteractiveAgentStrategy(agent, os41 = createOsStrategy()) {
|
|
13477
|
+
const s = createAgentStrategy(agent, os41);
|
|
13456
13478
|
if (s.mode !== "interactive") {
|
|
13457
13479
|
throw new Error(
|
|
13458
13480
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -14747,7 +14769,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
14747
14769
|
if (process.env.NODE_ENV === "test") return;
|
|
14748
14770
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
14749
14771
|
if (process.env.CI) return;
|
|
14750
|
-
const current = true ? "2.
|
|
14772
|
+
const current = true ? "2.50.0" : null;
|
|
14751
14773
|
if (!current) return;
|
|
14752
14774
|
const cache = readCache();
|
|
14753
14775
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -14764,7 +14786,7 @@ function checkForUpdates() {
|
|
|
14764
14786
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
14765
14787
|
if (process.env.CI) return;
|
|
14766
14788
|
if (!process.stdout.isTTY) return;
|
|
14767
|
-
const current = true ? "2.
|
|
14789
|
+
const current = true ? "2.50.0" : null;
|
|
14768
14790
|
if (!current) return;
|
|
14769
14791
|
const cache = readCache();
|
|
14770
14792
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15445,7 +15467,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.s
|
|
|
15445
15467
|
detached: false
|
|
15446
15468
|
});
|
|
15447
15469
|
function currentCliVersion() {
|
|
15448
|
-
return true ? "2.
|
|
15470
|
+
return true ? "2.50.0" : null;
|
|
15449
15471
|
}
|
|
15450
15472
|
function runCmd(cmd, args2, timeoutMs) {
|
|
15451
15473
|
return new Promise((resolve7) => {
|
|
@@ -17126,11 +17148,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
17126
17148
|
}
|
|
17127
17149
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17128
17150
|
function doltPlatformTuple(platform3, arch2) {
|
|
17129
|
-
const
|
|
17151
|
+
const os41 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
17130
17152
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
17131
17153
|
if (!a) return null;
|
|
17132
|
-
if (
|
|
17133
|
-
return `${
|
|
17154
|
+
if (os41 === "windows" && a !== "amd64") return null;
|
|
17155
|
+
return `${os41}-${a}`;
|
|
17134
17156
|
}
|
|
17135
17157
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
17136
17158
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -18009,6 +18031,30 @@ async function handleBeadsActionCommand(action, started) {
|
|
|
18009
18031
|
});
|
|
18010
18032
|
}
|
|
18011
18033
|
|
|
18034
|
+
// src/beads/config-store.ts
|
|
18035
|
+
var import_node_fs5 = __toESM(require("fs"));
|
|
18036
|
+
var import_node_os3 = __toESM(require("os"));
|
|
18037
|
+
var import_node_path4 = __toESM(require("path"));
|
|
18038
|
+
function beadsConfigPath() {
|
|
18039
|
+
return import_node_path4.default.join(import_node_os3.default.homedir(), ".codeam", "beads-config.json");
|
|
18040
|
+
}
|
|
18041
|
+
function readBeadsEnabled() {
|
|
18042
|
+
try {
|
|
18043
|
+
const raw = import_node_fs5.default.readFileSync(beadsConfigPath(), "utf8");
|
|
18044
|
+
const cfg = JSON.parse(raw);
|
|
18045
|
+
return cfg.enabled !== false;
|
|
18046
|
+
} catch {
|
|
18047
|
+
return true;
|
|
18048
|
+
}
|
|
18049
|
+
}
|
|
18050
|
+
function persistBeadsConfig(cfg) {
|
|
18051
|
+
const file = beadsConfigPath();
|
|
18052
|
+
import_node_fs5.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
|
|
18053
|
+
const tmp = `${file}.tmp`;
|
|
18054
|
+
import_node_fs5.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
|
|
18055
|
+
import_node_fs5.default.renameSync(tmp, file);
|
|
18056
|
+
}
|
|
18057
|
+
|
|
18012
18058
|
// src/beads/wiring.ts
|
|
18013
18059
|
function beadsKilled() {
|
|
18014
18060
|
const v = process.env.CODEAM_BEADS_DISABLED;
|
|
@@ -18019,6 +18065,10 @@ async function provisionBeadsForStart(ctx) {
|
|
|
18019
18065
|
log.trace("beads", "CODEAM_BEADS_DISABLED set \u2014 beads off this run");
|
|
18020
18066
|
return null;
|
|
18021
18067
|
}
|
|
18068
|
+
if (readBeadsEnabled() === false) {
|
|
18069
|
+
log.trace("beads", "beads disabled by persisted config \u2014 beads off this run");
|
|
18070
|
+
return null;
|
|
18071
|
+
}
|
|
18022
18072
|
delete process.env.BEADS_DIR;
|
|
18023
18073
|
process.env.BEADS_DOLT_SHARED_SERVER = "1";
|
|
18024
18074
|
if (!ctx.pluginAuthToken) {
|
|
@@ -18079,12 +18129,69 @@ function beadsActionFromPayload(payload) {
|
|
|
18079
18129
|
};
|
|
18080
18130
|
}
|
|
18081
18131
|
|
|
18132
|
+
// src/beads/configure.ts
|
|
18133
|
+
var _probeSeam = {
|
|
18134
|
+
resolveBd: (cwd) => new BdAdapter({ cwd }).isAvailable(),
|
|
18135
|
+
doltOnPath: () => ensureDoltResolvable(),
|
|
18136
|
+
ping: async (cwd) => {
|
|
18137
|
+
const adapter = new BdAdapter({ cwd });
|
|
18138
|
+
if (!adapter.isAvailable()) return false;
|
|
18139
|
+
const r = await adapter.run(["ping"]);
|
|
18140
|
+
return r.code === 0;
|
|
18141
|
+
},
|
|
18142
|
+
derivePrefix: (cwd) => {
|
|
18143
|
+
try {
|
|
18144
|
+
const { projectKey } = deriveProjectIdentity(cwd);
|
|
18145
|
+
return prefixForProjectKey(projectKey);
|
|
18146
|
+
} catch {
|
|
18147
|
+
return null;
|
|
18148
|
+
}
|
|
18149
|
+
}
|
|
18150
|
+
};
|
|
18151
|
+
async function probeBeadsStatus(cwd = process.cwd()) {
|
|
18152
|
+
const bdAvailable = _probeSeam.resolveBd(cwd);
|
|
18153
|
+
const doltAvailable = _probeSeam.doltOnPath();
|
|
18154
|
+
const serverUp = bdAvailable && doltAvailable ? await _probeSeam.ping(cwd) : false;
|
|
18155
|
+
const prefix = _probeSeam.derivePrefix(cwd);
|
|
18156
|
+
return { bdAvailable, doltAvailable, serverUp, prefix };
|
|
18157
|
+
}
|
|
18158
|
+
async function configureBeads(action, ctx, deps) {
|
|
18159
|
+
if (action === "status") {
|
|
18160
|
+
if (deps.readEnabled() === false) {
|
|
18161
|
+
deps.emit({ type: "beads_status", state: "disabled", running: false });
|
|
18162
|
+
return { enabled: false, running: false };
|
|
18163
|
+
}
|
|
18164
|
+
const p3 = await deps.probe();
|
|
18165
|
+
const running2 = p3.serverUp && p3.bdAvailable;
|
|
18166
|
+
deps.emit({ type: "beads_status", state: running2 ? "enabled" : "disabled", running: running2, ...p3 });
|
|
18167
|
+
return { enabled: running2, running: running2, ...p3 };
|
|
18168
|
+
}
|
|
18169
|
+
if (action === "disable") {
|
|
18170
|
+
deps.persist({ enabled: false });
|
|
18171
|
+
await deps.stopWatcher().catch(() => void 0);
|
|
18172
|
+
await deps.revertAgentHook(ctx.agent).catch(() => void 0);
|
|
18173
|
+
deps.emit({ type: "beads_status", state: "disabled" });
|
|
18174
|
+
return { enabled: false };
|
|
18175
|
+
}
|
|
18176
|
+
deps.persist({ enabled: true });
|
|
18177
|
+
deps.emit({ type: "beads_status", state: "provisioning" });
|
|
18178
|
+
const p2 = await deps.provision();
|
|
18179
|
+
if (!p2.serverUp || !p2.bdAvailable) {
|
|
18180
|
+
deps.emit({ type: "beads_status", state: "error", error: "Beads provisioning failed", ...p2 });
|
|
18181
|
+
return { enabled: false, ...p2 };
|
|
18182
|
+
}
|
|
18183
|
+
await deps.startWatcher().catch(() => void 0);
|
|
18184
|
+
const running = true;
|
|
18185
|
+
deps.emit({ type: "beads_status", state: "enabled", running, ...p2 });
|
|
18186
|
+
return { enabled: true, running, ...p2 };
|
|
18187
|
+
}
|
|
18188
|
+
|
|
18082
18189
|
// src/commands/start/handlers.ts
|
|
18083
18190
|
var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
18084
18191
|
function cleanupAttachmentTempFiles() {
|
|
18085
18192
|
for (const p2 of pendingAttachmentFiles) {
|
|
18086
18193
|
try {
|
|
18087
|
-
|
|
18194
|
+
fs41.unlinkSync(p2);
|
|
18088
18195
|
} catch {
|
|
18089
18196
|
}
|
|
18090
18197
|
}
|
|
@@ -18093,8 +18200,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18093
18200
|
function saveFilesTemp(files) {
|
|
18094
18201
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18095
18202
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18096
|
-
const tmpPath =
|
|
18097
|
-
|
|
18203
|
+
const tmpPath = path47.join(os34.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18204
|
+
fs41.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18098
18205
|
pendingAttachmentFiles.add(tmpPath);
|
|
18099
18206
|
return tmpPath;
|
|
18100
18207
|
});
|
|
@@ -18114,7 +18221,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18114
18221
|
setTimeout(() => {
|
|
18115
18222
|
for (const p2 of paths) {
|
|
18116
18223
|
try {
|
|
18117
|
-
|
|
18224
|
+
fs41.unlinkSync(p2);
|
|
18118
18225
|
} catch {
|
|
18119
18226
|
}
|
|
18120
18227
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -18315,9 +18422,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
18315
18422
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
18316
18423
|
};
|
|
18317
18424
|
var envReadH = async (ctx, cmd) => {
|
|
18318
|
-
const envPath =
|
|
18425
|
+
const envPath = path47.join(process.cwd(), ".env");
|
|
18319
18426
|
try {
|
|
18320
|
-
const raw = await
|
|
18427
|
+
const raw = await fs41.promises.readFile(envPath, "utf8");
|
|
18321
18428
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
18322
18429
|
exists: true,
|
|
18323
18430
|
vars: parseDotenv(raw)
|
|
@@ -18348,14 +18455,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
18348
18455
|
}
|
|
18349
18456
|
seen.add(v.key);
|
|
18350
18457
|
}
|
|
18351
|
-
const envPath =
|
|
18352
|
-
const tmpPath =
|
|
18458
|
+
const envPath = path47.join(process.cwd(), ".env");
|
|
18459
|
+
const tmpPath = path47.join(process.cwd(), ".env.codeam.tmp");
|
|
18353
18460
|
try {
|
|
18354
|
-
await
|
|
18355
|
-
await
|
|
18461
|
+
await fs41.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
18462
|
+
await fs41.promises.rename(tmpPath, envPath);
|
|
18356
18463
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
18357
18464
|
} catch (err) {
|
|
18358
|
-
await
|
|
18465
|
+
await fs41.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
18359
18466
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
18360
18467
|
}
|
|
18361
18468
|
};
|
|
@@ -18373,7 +18480,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18373
18480
|
let configuredAgent = rawAgentId;
|
|
18374
18481
|
if (!configuredAgent) {
|
|
18375
18482
|
try {
|
|
18376
|
-
const raw = JSON.parse(
|
|
18483
|
+
const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
|
|
18377
18484
|
configuredAgent = raw.agent ?? "";
|
|
18378
18485
|
} catch {
|
|
18379
18486
|
}
|
|
@@ -18407,7 +18514,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18407
18514
|
persist: persistHeadroomConfig,
|
|
18408
18515
|
readEnabled: () => {
|
|
18409
18516
|
try {
|
|
18410
|
-
const raw = JSON.parse(
|
|
18517
|
+
const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
|
|
18411
18518
|
return raw.enabled === true;
|
|
18412
18519
|
} catch {
|
|
18413
18520
|
return false;
|
|
@@ -18480,6 +18587,65 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18480
18587
|
});
|
|
18481
18588
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
18482
18589
|
};
|
|
18590
|
+
var _beadsEmitChain = Promise.resolve();
|
|
18591
|
+
var beadsConfigureH = async (ctx, cmd, parsed) => {
|
|
18592
|
+
const action = parsed.action;
|
|
18593
|
+
if (action !== "enable" && action !== "disable" && action !== "status") {
|
|
18594
|
+
await ctx.relay.sendResult(cmd.id, "failed", { error: "action must be enable|disable|status" });
|
|
18595
|
+
return;
|
|
18596
|
+
}
|
|
18597
|
+
let rawAgentId = ctx.agentId || (typeof parsed.agentId === "string" ? parsed.agentId : "");
|
|
18598
|
+
if (rawAgentId === "claude_code") rawAgentId = "claude";
|
|
18599
|
+
const agentIds = rawAgentId && isKnownAgentId(rawAgentId) ? [rawAgentId] : [];
|
|
18600
|
+
const deps = {
|
|
18601
|
+
provision: async () => {
|
|
18602
|
+
const r = await provisionBeads({ cwd: process.cwd(), agents: agentIds });
|
|
18603
|
+
return { bdAvailable: r.bdAvailable, doltAvailable: r.doltAvailable, serverUp: r.serverUp, prefix: r.prefix };
|
|
18604
|
+
},
|
|
18605
|
+
probe: async () => probeBeadsStatus(process.cwd()),
|
|
18606
|
+
startWatcher: async () => {
|
|
18607
|
+
if (!ctx.pluginAuthToken) return;
|
|
18608
|
+
const started = await startBeads({
|
|
18609
|
+
sessionId: ctx.sessionId,
|
|
18610
|
+
pluginId: ctx.pluginId,
|
|
18611
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
18612
|
+
cwd: process.cwd(),
|
|
18613
|
+
agents: agentIds
|
|
18614
|
+
});
|
|
18615
|
+
if (started) {
|
|
18616
|
+
ctx.beads = started;
|
|
18617
|
+
}
|
|
18618
|
+
},
|
|
18619
|
+
stopWatcher: async () => {
|
|
18620
|
+
if (ctx.beads) {
|
|
18621
|
+
await ctx.beads.watcher.stop();
|
|
18622
|
+
ctx.beads = null;
|
|
18623
|
+
}
|
|
18624
|
+
},
|
|
18625
|
+
revertAgentHook: async (agent) => {
|
|
18626
|
+
log.info("beads", `revertAgentHook: bd has no --remove flag \u2014 leaving ${agent} hook in place (no-op disable path)`);
|
|
18627
|
+
},
|
|
18628
|
+
persist: (cfg) => persistBeadsConfig(cfg),
|
|
18629
|
+
readEnabled: () => readBeadsEnabled(),
|
|
18630
|
+
emit: (event) => {
|
|
18631
|
+
const token = ctx.pluginAuthToken;
|
|
18632
|
+
if (!token) return;
|
|
18633
|
+
_beadsEmitChain = _beadsEmitChain.then(
|
|
18634
|
+
() => postBeadsEvent({
|
|
18635
|
+
sessionId: ctx.sessionId,
|
|
18636
|
+
pluginId: ctx.pluginId,
|
|
18637
|
+
pluginAuthToken: token,
|
|
18638
|
+
type: "beads_status",
|
|
18639
|
+
payload: Object.fromEntries(
|
|
18640
|
+
Object.entries(event).filter(([k2]) => k2 !== "type")
|
|
18641
|
+
)
|
|
18642
|
+
})
|
|
18643
|
+
);
|
|
18644
|
+
}
|
|
18645
|
+
};
|
|
18646
|
+
const result = await configureBeads(action, { agent: rawAgentId, cwd: process.cwd(), pluginAuthToken: ctx.pluginAuthToken }, deps);
|
|
18647
|
+
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
18648
|
+
};
|
|
18483
18649
|
var terminalOpenH = async (ctx, cmd, parsed) => {
|
|
18484
18650
|
const r = openTerminal({
|
|
18485
18651
|
cols: typeof parsed.cols === "number" ? parsed.cols : void 0,
|
|
@@ -18916,8 +19082,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
18916
19082
|
if (args2.length === 0) return detection;
|
|
18917
19083
|
const binName = args2[0];
|
|
18918
19084
|
if (binName.startsWith("-")) return detection;
|
|
18919
|
-
const binPath =
|
|
18920
|
-
if (!
|
|
19085
|
+
const binPath = path47.join(cwd, "node_modules", ".bin", binName);
|
|
19086
|
+
if (!fs41.existsSync(binPath)) return detection;
|
|
18921
19087
|
return {
|
|
18922
19088
|
...detection,
|
|
18923
19089
|
command: binPath,
|
|
@@ -19465,7 +19631,8 @@ var handlers = {
|
|
|
19465
19631
|
save_preview_config: savePreviewConfigH,
|
|
19466
19632
|
env_read: envReadH,
|
|
19467
19633
|
env_write: envWriteH,
|
|
19468
|
-
headroom_configure: headroomConfigureH
|
|
19634
|
+
headroom_configure: headroomConfigureH,
|
|
19635
|
+
beads_configure: beadsConfigureH
|
|
19469
19636
|
};
|
|
19470
19637
|
async function dispatchCommand(ctx, cmd) {
|
|
19471
19638
|
if (cmd.type === "beads_action") {
|
|
@@ -19733,12 +19900,12 @@ function readTokenFromArgs(args2) {
|
|
|
19733
19900
|
}
|
|
19734
19901
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
19735
19902
|
if (fileFlag) {
|
|
19736
|
-
const
|
|
19903
|
+
const path61 = fileFlag.slice("--token-file=".length);
|
|
19737
19904
|
try {
|
|
19738
|
-
const content =
|
|
19739
|
-
if (content.length === 0) fail(`--token-file ${
|
|
19905
|
+
const content = fs42.readFileSync(path61, "utf8").trim();
|
|
19906
|
+
if (content.length === 0) fail(`--token-file ${path61} is empty`);
|
|
19740
19907
|
try {
|
|
19741
|
-
|
|
19908
|
+
fs42.unlinkSync(path61);
|
|
19742
19909
|
} catch {
|
|
19743
19910
|
}
|
|
19744
19911
|
return content;
|
|
@@ -19764,7 +19931,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
19764
19931
|
pluginId,
|
|
19765
19932
|
ideName: "codeam-cli (codespace)",
|
|
19766
19933
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
19767
|
-
hostname:
|
|
19934
|
+
hostname: os35.hostname(),
|
|
19768
19935
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
19769
19936
|
// Current git branch of the codespace's working directory, so the
|
|
19770
19937
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -19825,7 +19992,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
19825
19992
|
}
|
|
19826
19993
|
}
|
|
19827
19994
|
function pairAutoLockPath() {
|
|
19828
|
-
return
|
|
19995
|
+
return path48.join(os35.homedir(), ".codeam", "pair-auto.lock");
|
|
19829
19996
|
}
|
|
19830
19997
|
function isLivePairAuto(pid) {
|
|
19831
19998
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -19835,7 +20002,7 @@ function isLivePairAuto(pid) {
|
|
|
19835
20002
|
if (e.code !== "EPERM") return false;
|
|
19836
20003
|
}
|
|
19837
20004
|
try {
|
|
19838
|
-
return
|
|
20005
|
+
return fs42.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
19839
20006
|
} catch {
|
|
19840
20007
|
return true;
|
|
19841
20008
|
}
|
|
@@ -19845,24 +20012,24 @@ function isLiveCodeam(pid) {
|
|
|
19845
20012
|
}
|
|
19846
20013
|
function daemonLockPath(sessionId) {
|
|
19847
20014
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
19848
|
-
return
|
|
20015
|
+
return path48.join(os35.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
19849
20016
|
}
|
|
19850
20017
|
function acquireDaemonLock(sessionId) {
|
|
19851
20018
|
const lockPath = daemonLockPath(sessionId);
|
|
19852
20019
|
try {
|
|
19853
|
-
|
|
20020
|
+
fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
|
|
19854
20021
|
try {
|
|
19855
|
-
|
|
20022
|
+
fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
19856
20023
|
} catch (e) {
|
|
19857
20024
|
if (e.code !== "EEXIST") throw e;
|
|
19858
|
-
const holder = Number(
|
|
20025
|
+
const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
|
|
19859
20026
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
19860
|
-
|
|
20027
|
+
fs42.writeFileSync(lockPath, String(process.pid));
|
|
19861
20028
|
}
|
|
19862
20029
|
const release3 = () => {
|
|
19863
20030
|
try {
|
|
19864
|
-
if (
|
|
19865
|
-
|
|
20031
|
+
if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20032
|
+
fs42.unlinkSync(lockPath);
|
|
19866
20033
|
}
|
|
19867
20034
|
} catch {
|
|
19868
20035
|
}
|
|
@@ -19884,19 +20051,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
19884
20051
|
function acquireSingletonLock() {
|
|
19885
20052
|
const lockPath = pairAutoLockPath();
|
|
19886
20053
|
try {
|
|
19887
|
-
|
|
20054
|
+
fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
|
|
19888
20055
|
try {
|
|
19889
|
-
|
|
20056
|
+
fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
19890
20057
|
} catch (e) {
|
|
19891
20058
|
if (e.code !== "EEXIST") throw e;
|
|
19892
|
-
const holder = Number(
|
|
20059
|
+
const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
|
|
19893
20060
|
if (isLivePairAuto(holder)) return false;
|
|
19894
|
-
|
|
20061
|
+
fs42.writeFileSync(lockPath, String(process.pid));
|
|
19895
20062
|
}
|
|
19896
20063
|
process.once("exit", () => {
|
|
19897
20064
|
try {
|
|
19898
|
-
if (
|
|
19899
|
-
|
|
20065
|
+
if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20066
|
+
fs42.unlinkSync(lockPath);
|
|
19900
20067
|
}
|
|
19901
20068
|
} catch {
|
|
19902
20069
|
}
|
|
@@ -20341,19 +20508,19 @@ var AgentService = class _AgentService {
|
|
|
20341
20508
|
};
|
|
20342
20509
|
|
|
20343
20510
|
// src/agents/acp/adapters.ts
|
|
20344
|
-
var
|
|
20511
|
+
var path49 = __toESM(require("path"));
|
|
20345
20512
|
var require_ = require;
|
|
20346
20513
|
function resolveBin(pkgName, binName) {
|
|
20347
20514
|
try {
|
|
20348
20515
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
20349
20516
|
const manifest = require_(`${pkgName}/package.json`);
|
|
20350
|
-
const pkgDir =
|
|
20517
|
+
const pkgDir = path49.dirname(manifestPath);
|
|
20351
20518
|
const bin = manifest.bin;
|
|
20352
20519
|
if (!bin) return null;
|
|
20353
|
-
if (typeof bin === "string") return
|
|
20520
|
+
if (typeof bin === "string") return path49.resolve(pkgDir, bin);
|
|
20354
20521
|
const target = binName ?? Object.keys(bin)[0];
|
|
20355
20522
|
if (!target || !bin[target]) return null;
|
|
20356
|
-
return
|
|
20523
|
+
return path49.resolve(pkgDir, bin[target]);
|
|
20357
20524
|
} catch {
|
|
20358
20525
|
return null;
|
|
20359
20526
|
}
|
|
@@ -20423,9 +20590,9 @@ function requiresAcp(agent) {
|
|
|
20423
20590
|
var import_node_crypto7 = require("crypto");
|
|
20424
20591
|
|
|
20425
20592
|
// src/services/history.service.ts
|
|
20426
|
-
var
|
|
20427
|
-
var
|
|
20428
|
-
var
|
|
20593
|
+
var fs43 = __toESM(require("fs"));
|
|
20594
|
+
var path50 = __toESM(require("path"));
|
|
20595
|
+
var os36 = __toESM(require("os"));
|
|
20429
20596
|
var https7 = __toESM(require("https"));
|
|
20430
20597
|
var http6 = __toESM(require("http"));
|
|
20431
20598
|
var import_zod2 = require("zod");
|
|
@@ -20452,7 +20619,7 @@ function parseJsonl(filePath) {
|
|
|
20452
20619
|
const messages = [];
|
|
20453
20620
|
let raw;
|
|
20454
20621
|
try {
|
|
20455
|
-
raw =
|
|
20622
|
+
raw = fs43.readFileSync(filePath, "utf8");
|
|
20456
20623
|
} catch (err) {
|
|
20457
20624
|
if (err.code !== "ENOENT") {
|
|
20458
20625
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -20593,7 +20760,7 @@ var HistoryService = class _HistoryService {
|
|
|
20593
20760
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
20594
20761
|
}
|
|
20595
20762
|
get projectDir() {
|
|
20596
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
20763
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path50.join(os36.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
20597
20764
|
}
|
|
20598
20765
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
20599
20766
|
setCurrentConversationId(id) {
|
|
@@ -20605,7 +20772,7 @@ var HistoryService = class _HistoryService {
|
|
|
20605
20772
|
/** Return the current message count in the active conversation. */
|
|
20606
20773
|
getCurrentMessageCount() {
|
|
20607
20774
|
if (!this.currentConversationId) return 0;
|
|
20608
|
-
const filePath =
|
|
20775
|
+
const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
20609
20776
|
return parseJsonl(filePath).length;
|
|
20610
20777
|
}
|
|
20611
20778
|
/**
|
|
@@ -20616,7 +20783,7 @@ var HistoryService = class _HistoryService {
|
|
|
20616
20783
|
const deadline = Date.now() + timeoutMs;
|
|
20617
20784
|
while (Date.now() < deadline) {
|
|
20618
20785
|
if (!this.currentConversationId) return null;
|
|
20619
|
-
const filePath =
|
|
20786
|
+
const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
20620
20787
|
const messages = parseJsonl(filePath);
|
|
20621
20788
|
if (messages.length > previousCount) {
|
|
20622
20789
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -20642,16 +20809,16 @@ var HistoryService = class _HistoryService {
|
|
|
20642
20809
|
const dir = this.projectDir;
|
|
20643
20810
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
20644
20811
|
try {
|
|
20645
|
-
const files =
|
|
20812
|
+
const files = fs43.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
20646
20813
|
try {
|
|
20647
|
-
const stat3 =
|
|
20814
|
+
const stat3 = fs43.statSync(path50.join(dir, e.name));
|
|
20648
20815
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
20649
20816
|
} catch {
|
|
20650
20817
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
20651
20818
|
}
|
|
20652
20819
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
20653
20820
|
if (files.length > 0) {
|
|
20654
|
-
this.currentConversationId =
|
|
20821
|
+
this.currentConversationId = path50.basename(files[0].name, ".jsonl");
|
|
20655
20822
|
}
|
|
20656
20823
|
} catch {
|
|
20657
20824
|
}
|
|
@@ -20685,13 +20852,13 @@ var HistoryService = class _HistoryService {
|
|
|
20685
20852
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
20686
20853
|
let entries;
|
|
20687
20854
|
try {
|
|
20688
|
-
entries =
|
|
20855
|
+
entries = fs43.readdirSync(dir, { withFileTypes: true });
|
|
20689
20856
|
} catch {
|
|
20690
20857
|
return null;
|
|
20691
20858
|
}
|
|
20692
20859
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
20693
20860
|
try {
|
|
20694
|
-
const stat3 =
|
|
20861
|
+
const stat3 = fs43.statSync(path50.join(dir, e.name));
|
|
20695
20862
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
20696
20863
|
} catch {
|
|
20697
20864
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -20700,12 +20867,12 @@ var HistoryService = class _HistoryService {
|
|
|
20700
20867
|
if (files.length === 0) return null;
|
|
20701
20868
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
20702
20869
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
20703
|
-
return this.extractUsageFromFile(
|
|
20870
|
+
return this.extractUsageFromFile(path50.join(dir, targetFile));
|
|
20704
20871
|
}
|
|
20705
20872
|
extractUsageFromFile(filePath) {
|
|
20706
20873
|
let raw;
|
|
20707
20874
|
try {
|
|
20708
|
-
raw =
|
|
20875
|
+
raw = fs43.readFileSync(filePath, "utf8");
|
|
20709
20876
|
} catch {
|
|
20710
20877
|
return null;
|
|
20711
20878
|
}
|
|
@@ -20750,9 +20917,9 @@ var HistoryService = class _HistoryService {
|
|
|
20750
20917
|
let totalCost = 0;
|
|
20751
20918
|
let files;
|
|
20752
20919
|
try {
|
|
20753
|
-
files =
|
|
20920
|
+
files = fs43.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
20754
20921
|
try {
|
|
20755
|
-
return
|
|
20922
|
+
return fs43.statSync(path50.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
20756
20923
|
} catch {
|
|
20757
20924
|
return false;
|
|
20758
20925
|
}
|
|
@@ -20763,7 +20930,7 @@ var HistoryService = class _HistoryService {
|
|
|
20763
20930
|
for (const file of files) {
|
|
20764
20931
|
let raw;
|
|
20765
20932
|
try {
|
|
20766
|
-
raw =
|
|
20933
|
+
raw = fs43.readFileSync(path50.join(projectDir, file), "utf8");
|
|
20767
20934
|
} catch {
|
|
20768
20935
|
continue;
|
|
20769
20936
|
}
|
|
@@ -20842,7 +21009,7 @@ var HistoryService = class _HistoryService {
|
|
|
20842
21009
|
if (this.runtime.resolveHistoryFile) {
|
|
20843
21010
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
20844
21011
|
}
|
|
20845
|
-
return
|
|
21012
|
+
return path50.join(this.projectDir, `${sessionId}.jsonl`);
|
|
20846
21013
|
}
|
|
20847
21014
|
/**
|
|
20848
21015
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -20876,7 +21043,7 @@ var HistoryService = class _HistoryService {
|
|
|
20876
21043
|
};
|
|
20877
21044
|
});
|
|
20878
21045
|
}
|
|
20879
|
-
return parseJsonl(
|
|
21046
|
+
return parseJsonl(path50.join(this.projectDir, `${sessionId}.jsonl`));
|
|
20880
21047
|
}
|
|
20881
21048
|
async loadConversation(sessionId) {
|
|
20882
21049
|
const messages = this.readConversation(sessionId);
|
|
@@ -20932,7 +21099,7 @@ var HistoryService = class _HistoryService {
|
|
|
20932
21099
|
if (!filePath) return false;
|
|
20933
21100
|
let mtimeMs;
|
|
20934
21101
|
try {
|
|
20935
|
-
mtimeMs =
|
|
21102
|
+
mtimeMs = fs43.statSync(filePath).mtimeMs;
|
|
20936
21103
|
} catch {
|
|
20937
21104
|
return false;
|
|
20938
21105
|
}
|
|
@@ -21001,10 +21168,10 @@ var HistoryService = class _HistoryService {
|
|
|
21001
21168
|
|
|
21002
21169
|
// src/agents/acp/client.ts
|
|
21003
21170
|
var import_node_child_process16 = require("child_process");
|
|
21004
|
-
var
|
|
21171
|
+
var fs44 = __toESM(require("fs/promises"));
|
|
21005
21172
|
var fsSync = __toESM(require("fs"));
|
|
21006
|
-
var
|
|
21007
|
-
var
|
|
21173
|
+
var os37 = __toESM(require("os"));
|
|
21174
|
+
var path51 = __toESM(require("path"));
|
|
21008
21175
|
var import_node_stream = require("stream");
|
|
21009
21176
|
|
|
21010
21177
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -23837,7 +24004,7 @@ var AcpClient = class {
|
|
|
23837
24004
|
},
|
|
23838
24005
|
readTextFile: async (params) => {
|
|
23839
24006
|
try {
|
|
23840
|
-
const content = await
|
|
24007
|
+
const content = await fs44.readFile(params.path, "utf8");
|
|
23841
24008
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
23842
24009
|
} catch (err) {
|
|
23843
24010
|
const code = err.code;
|
|
@@ -23857,7 +24024,7 @@ var AcpClient = class {
|
|
|
23857
24024
|
},
|
|
23858
24025
|
writeTextFile: async (params) => {
|
|
23859
24026
|
try {
|
|
23860
|
-
await
|
|
24027
|
+
await fs44.writeFile(params.path, params.content, "utf8");
|
|
23861
24028
|
return {};
|
|
23862
24029
|
} catch (err) {
|
|
23863
24030
|
const code = err.code;
|
|
@@ -23906,25 +24073,25 @@ function applyLineRange(content, line, limit) {
|
|
|
23906
24073
|
return { content: lines.slice(start2, end).join("\n") };
|
|
23907
24074
|
}
|
|
23908
24075
|
function knownAgentBinaryDirs() {
|
|
23909
|
-
const home =
|
|
24076
|
+
const home = os37.homedir();
|
|
23910
24077
|
const out2 = [];
|
|
23911
24078
|
out2.push("/tmp/codeam-node20/bin");
|
|
23912
24079
|
for (const root of [
|
|
23913
24080
|
"/usr/local/share/nvm/versions/node",
|
|
23914
|
-
|
|
24081
|
+
path51.join(home, ".nvm/versions/node")
|
|
23915
24082
|
]) {
|
|
23916
24083
|
try {
|
|
23917
24084
|
for (const child of fsSync.readdirSync(root)) {
|
|
23918
|
-
out2.push(
|
|
24085
|
+
out2.push(path51.join(root, child, "bin"));
|
|
23919
24086
|
}
|
|
23920
24087
|
} catch {
|
|
23921
24088
|
}
|
|
23922
24089
|
}
|
|
23923
|
-
out2.push(
|
|
24090
|
+
out2.push(path51.join(home, ".volta/bin"));
|
|
23924
24091
|
out2.push("/usr/local/bin");
|
|
23925
24092
|
out2.push("/usr/bin");
|
|
23926
|
-
out2.push(
|
|
23927
|
-
out2.push(
|
|
24093
|
+
out2.push(path51.join(home, ".local/bin"));
|
|
24094
|
+
out2.push(path51.join(home, "bin"));
|
|
23928
24095
|
return out2.filter((p2) => {
|
|
23929
24096
|
try {
|
|
23930
24097
|
return fsSync.statSync(p2).isDirectory();
|
|
@@ -23935,7 +24102,7 @@ function knownAgentBinaryDirs() {
|
|
|
23935
24102
|
}
|
|
23936
24103
|
function expandPathForAgentBinaries(existingPath) {
|
|
23937
24104
|
const existing = new Set(
|
|
23938
|
-
existingPath.split(
|
|
24105
|
+
existingPath.split(path51.delimiter).filter((p2) => p2.length > 0)
|
|
23939
24106
|
);
|
|
23940
24107
|
const additions = [];
|
|
23941
24108
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -23945,7 +24112,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
23945
24112
|
}
|
|
23946
24113
|
}
|
|
23947
24114
|
if (additions.length === 0) return existingPath;
|
|
23948
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
24115
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path51.delimiter);
|
|
23949
24116
|
}
|
|
23950
24117
|
|
|
23951
24118
|
// src/services/streaming/transport.ts
|
|
@@ -24357,15 +24524,15 @@ function commonPrefixLength(a, b) {
|
|
|
24357
24524
|
|
|
24358
24525
|
// src/agents/acp/onboarding.ts
|
|
24359
24526
|
var import_child_process22 = require("child_process");
|
|
24360
|
-
var
|
|
24361
|
-
var
|
|
24362
|
-
var
|
|
24527
|
+
var fs45 = __toESM(require("fs"));
|
|
24528
|
+
var os38 = __toESM(require("os"));
|
|
24529
|
+
var path52 = __toESM(require("path"));
|
|
24363
24530
|
var _onboardingSeam = {
|
|
24364
|
-
markerPath: (sessionId) =>
|
|
24365
|
-
exists: (p2) =>
|
|
24531
|
+
markerPath: (sessionId) => path52.join(os38.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
24532
|
+
exists: (p2) => fs45.existsSync(p2),
|
|
24366
24533
|
write: (p2) => {
|
|
24367
|
-
|
|
24368
|
-
|
|
24534
|
+
fs45.mkdirSync(path52.dirname(p2), { recursive: true });
|
|
24535
|
+
fs45.writeFileSync(p2, "");
|
|
24369
24536
|
},
|
|
24370
24537
|
disabled: () => {
|
|
24371
24538
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -24402,7 +24569,7 @@ function resolveRepoName(cwd) {
|
|
|
24402
24569
|
if (name) return name;
|
|
24403
24570
|
}
|
|
24404
24571
|
}
|
|
24405
|
-
const base =
|
|
24572
|
+
const base = path52.basename(cwd || "");
|
|
24406
24573
|
if (base && !isUuid(base)) return base;
|
|
24407
24574
|
return "this project";
|
|
24408
24575
|
}
|
|
@@ -24675,13 +24842,28 @@ function extractSelectPrompt(text) {
|
|
|
24675
24842
|
};
|
|
24676
24843
|
}
|
|
24677
24844
|
|
|
24845
|
+
// src/agents/acp/inputSuggestion.ts
|
|
24846
|
+
var MIN_LEN = 8;
|
|
24847
|
+
var MAX_LEN = 200;
|
|
24848
|
+
function deriveInputSuggestion(finalText) {
|
|
24849
|
+
if (finalText.length === 0) return null;
|
|
24850
|
+
const lines = finalText.split("\n");
|
|
24851
|
+
let i = lines.length - 1;
|
|
24852
|
+
while (i >= 0 && lines[i].trim() === "") i--;
|
|
24853
|
+
if (i < 0) return null;
|
|
24854
|
+
const lastLine = lines[i].trim();
|
|
24855
|
+
if (!lastLine.endsWith("?")) return null;
|
|
24856
|
+
if (lastLine.length < MIN_LEN || lastLine.length > MAX_LEN) return null;
|
|
24857
|
+
return lastLine;
|
|
24858
|
+
}
|
|
24859
|
+
|
|
24678
24860
|
// src/services/turn-files/turn-file-aggregator.ts
|
|
24679
24861
|
var import_crypto5 = require("crypto");
|
|
24680
24862
|
|
|
24681
24863
|
// src/services/turn-files/git-changeset.ts
|
|
24682
24864
|
var import_child_process23 = require("child_process");
|
|
24683
|
-
var
|
|
24684
|
-
var
|
|
24865
|
+
var fs46 = __toESM(require("fs/promises"));
|
|
24866
|
+
var path53 = __toESM(require("path"));
|
|
24685
24867
|
async function collectRepoChangeset(opts) {
|
|
24686
24868
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
24687
24869
|
if (status2 === null) return null;
|
|
@@ -24699,7 +24881,7 @@ async function collectRepoChangeset(opts) {
|
|
|
24699
24881
|
let stats;
|
|
24700
24882
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
24701
24883
|
const lineCount = await readUntrackedLineCount(
|
|
24702
|
-
|
|
24884
|
+
path53.join(opts.repoRoot, row.filePath)
|
|
24703
24885
|
);
|
|
24704
24886
|
stats = { added: lineCount, removed: 0 };
|
|
24705
24887
|
} else {
|
|
@@ -24730,7 +24912,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
24730
24912
|
}
|
|
24731
24913
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
24732
24914
|
try {
|
|
24733
|
-
const content = await
|
|
24915
|
+
const content = await fs46.readFile(absPath, "utf8");
|
|
24734
24916
|
let count = 0;
|
|
24735
24917
|
let pos = -1;
|
|
24736
24918
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -24822,7 +25004,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
24822
25004
|
});
|
|
24823
25005
|
}
|
|
24824
25006
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
24825
|
-
const
|
|
25007
|
+
const fs50 = await import("fs/promises");
|
|
24826
25008
|
const out2 = [];
|
|
24827
25009
|
await walk(workingDir, 0);
|
|
24828
25010
|
return out2;
|
|
@@ -24830,7 +25012,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
24830
25012
|
if (depth > maxDepth) return;
|
|
24831
25013
|
let entries = [];
|
|
24832
25014
|
try {
|
|
24833
|
-
const dirents = await
|
|
25015
|
+
const dirents = await fs50.readdir(dir, { withFileTypes: true });
|
|
24834
25016
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
24835
25017
|
} catch {
|
|
24836
25018
|
return;
|
|
@@ -24841,8 +25023,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
24841
25023
|
if (hasGit) {
|
|
24842
25024
|
out2.push({
|
|
24843
25025
|
repoRoot: dir,
|
|
24844
|
-
repoPath:
|
|
24845
|
-
repoName:
|
|
25026
|
+
repoPath: path53.relative(workingDir, dir),
|
|
25027
|
+
repoName: path53.basename(dir)
|
|
24846
25028
|
});
|
|
24847
25029
|
return;
|
|
24848
25030
|
}
|
|
@@ -24850,14 +25032,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
24850
25032
|
if (!entry.isDirectory) continue;
|
|
24851
25033
|
if (entry.name === "node_modules") continue;
|
|
24852
25034
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
24853
|
-
await walk(
|
|
25035
|
+
await walk(path53.join(dir, entry.name), depth + 1);
|
|
24854
25036
|
}
|
|
24855
25037
|
}
|
|
24856
25038
|
}
|
|
24857
25039
|
|
|
24858
25040
|
// src/services/turn-files/files-outbox.ts
|
|
24859
|
-
var
|
|
24860
|
-
var
|
|
25041
|
+
var fs47 = __toESM(require("fs/promises"));
|
|
25042
|
+
var path54 = __toESM(require("path"));
|
|
24861
25043
|
var import_os7 = require("os");
|
|
24862
25044
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
24863
25045
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -24890,16 +25072,16 @@ var FilesOutbox = class {
|
|
|
24890
25072
|
backoffIndex = 0;
|
|
24891
25073
|
stopped = false;
|
|
24892
25074
|
constructor(opts) {
|
|
24893
|
-
const base = opts.baseDir ??
|
|
24894
|
-
this.filePath =
|
|
25075
|
+
const base = opts.baseDir ?? path54.join(homeDir(), HOME_OUTBOX_DIR);
|
|
25076
|
+
this.filePath = path54.join(base, `${opts.sessionId}.jsonl`);
|
|
24895
25077
|
this.post = opts.post;
|
|
24896
25078
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
24897
25079
|
}
|
|
24898
25080
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
24899
25081
|
* line is durable on disk (not once the POST succeeds). */
|
|
24900
25082
|
async enqueue(entry) {
|
|
24901
|
-
await
|
|
24902
|
-
await
|
|
25083
|
+
await fs47.mkdir(path54.dirname(this.filePath), { recursive: true });
|
|
25084
|
+
await fs47.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
24903
25085
|
this.backoffIndex = 0;
|
|
24904
25086
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
24905
25087
|
}
|
|
@@ -24988,7 +25170,7 @@ var FilesOutbox = class {
|
|
|
24988
25170
|
async readAll() {
|
|
24989
25171
|
let raw = "";
|
|
24990
25172
|
try {
|
|
24991
|
-
raw = await
|
|
25173
|
+
raw = await fs47.readFile(this.filePath, "utf8");
|
|
24992
25174
|
} catch {
|
|
24993
25175
|
return [];
|
|
24994
25176
|
}
|
|
@@ -25012,12 +25194,12 @@ var FilesOutbox = class {
|
|
|
25012
25194
|
async rewrite(entries) {
|
|
25013
25195
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
25014
25196
|
if (entries.length === 0) {
|
|
25015
|
-
await
|
|
25197
|
+
await fs47.unlink(this.filePath).catch(() => void 0);
|
|
25016
25198
|
return;
|
|
25017
25199
|
}
|
|
25018
25200
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
25019
|
-
await
|
|
25020
|
-
await
|
|
25201
|
+
await fs47.writeFile(tmpPath, payload, "utf8");
|
|
25202
|
+
await fs47.rename(tmpPath, this.filePath);
|
|
25021
25203
|
}
|
|
25022
25204
|
};
|
|
25023
25205
|
function applyJitter(ms) {
|
|
@@ -25546,7 +25728,7 @@ var StreamingState = class {
|
|
|
25546
25728
|
this.publisher.publishOutput({ type: "text", content: finalText, done: true }),
|
|
25547
25729
|
flushSc
|
|
25548
25730
|
]);
|
|
25549
|
-
return;
|
|
25731
|
+
return false;
|
|
25550
25732
|
}
|
|
25551
25733
|
log.info(
|
|
25552
25734
|
"acpRunner",
|
|
@@ -25573,6 +25755,7 @@ var StreamingState = class {
|
|
|
25573
25755
|
done: true
|
|
25574
25756
|
});
|
|
25575
25757
|
await flushSc;
|
|
25758
|
+
return true;
|
|
25576
25759
|
}
|
|
25577
25760
|
};
|
|
25578
25761
|
var PERMISSION_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
@@ -25946,7 +26129,9 @@ async function runAcpSession(opts) {
|
|
|
25946
26129
|
flushHistory: () => void history.flush(),
|
|
25947
26130
|
beginTurn: () => streaming.beginTurn(),
|
|
25948
26131
|
getCurrentText: () => streaming.getCurrentText(),
|
|
25949
|
-
closeTurn: () =>
|
|
26132
|
+
closeTurn: async () => {
|
|
26133
|
+
await streaming.closeTurnWithInteractiveDetection();
|
|
26134
|
+
},
|
|
25950
26135
|
recoverFromFailedTurn: () => recoverFromFailedTurn(client2, streaming),
|
|
25951
26136
|
reconnectWith1mDisabled,
|
|
25952
26137
|
promptAgent: (blocks) => client2.prompt(blocks),
|
|
@@ -26147,13 +26332,19 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
|
|
|
26147
26332
|
} else if (shouldOfferOneMRecovery({ detail: "", recentStderr: recentStderr.join("\n"), finalText })) {
|
|
26148
26333
|
await oneMRecovery.offer(cmd.id, blocks);
|
|
26149
26334
|
} else {
|
|
26150
|
-
await streaming.closeTurnWithInteractiveDetection();
|
|
26335
|
+
const emittedSelectPrompt = await streaming.closeTurnWithInteractiveDetection();
|
|
26151
26336
|
const replyLine = formatAgentReplyLine(finalText);
|
|
26152
26337
|
if (replyLine.length > 0) {
|
|
26153
26338
|
showInfo(replyLine);
|
|
26154
26339
|
}
|
|
26155
26340
|
history.appendAgentReply(finalText);
|
|
26156
26341
|
void history.flush();
|
|
26342
|
+
if (!emittedSelectPrompt) {
|
|
26343
|
+
const suggestion = deriveInputSuggestion(finalText);
|
|
26344
|
+
if (suggestion !== null) {
|
|
26345
|
+
void publisher.publishOutput({ type: "input_suggestion", content: suggestion, done: true });
|
|
26346
|
+
}
|
|
26347
|
+
}
|
|
26157
26348
|
turnFiles.flushTurn().catch((err) => {
|
|
26158
26349
|
log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
|
|
26159
26350
|
});
|
|
@@ -27527,15 +27718,15 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
27527
27718
|
}
|
|
27528
27719
|
|
|
27529
27720
|
// src/agents/claude/onboarding.ts
|
|
27530
|
-
var
|
|
27531
|
-
var
|
|
27532
|
-
var
|
|
27721
|
+
var fs48 = __toESM(require("fs"));
|
|
27722
|
+
var os39 = __toESM(require("os"));
|
|
27723
|
+
var path55 = __toESM(require("path"));
|
|
27533
27724
|
function ensureClaudeOnboarded() {
|
|
27534
27725
|
try {
|
|
27535
|
-
const file =
|
|
27726
|
+
const file = path55.join(os39.homedir(), ".claude.json");
|
|
27536
27727
|
let config = {};
|
|
27537
27728
|
try {
|
|
27538
|
-
config = JSON.parse(
|
|
27729
|
+
config = JSON.parse(fs48.readFileSync(file, "utf8"));
|
|
27539
27730
|
} catch {
|
|
27540
27731
|
}
|
|
27541
27732
|
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
@@ -27546,8 +27737,8 @@ function ensureClaudeOnboarded() {
|
|
|
27546
27737
|
if (typeof config.lastOnboardingVersion !== "string") {
|
|
27547
27738
|
config.lastOnboardingVersion = "2.1.177";
|
|
27548
27739
|
}
|
|
27549
|
-
|
|
27550
|
-
|
|
27740
|
+
fs48.mkdirSync(path55.dirname(file), { recursive: true });
|
|
27741
|
+
fs48.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
27551
27742
|
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
27552
27743
|
} catch (err) {
|
|
27553
27744
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
@@ -28197,7 +28388,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
28197
28388
|
var import_child_process24 = require("child_process");
|
|
28198
28389
|
var import_util4 = require("util");
|
|
28199
28390
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
28200
|
-
var
|
|
28391
|
+
var path56 = __toESM(require("path"));
|
|
28201
28392
|
var execFileP6 = (0, import_util4.promisify)(import_child_process24.execFile);
|
|
28202
28393
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
28203
28394
|
function resetStdinForChild() {
|
|
@@ -28686,7 +28877,7 @@ var GitHubCodespacesProvider = class {
|
|
|
28686
28877
|
});
|
|
28687
28878
|
}
|
|
28688
28879
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
28689
|
-
const remoteDir =
|
|
28880
|
+
const remoteDir = path56.posix.dirname(remotePath);
|
|
28690
28881
|
const parts = [
|
|
28691
28882
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
28692
28883
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -28756,7 +28947,7 @@ function shellQuote(s) {
|
|
|
28756
28947
|
// src/services/providers/gitpod.ts
|
|
28757
28948
|
var import_child_process25 = require("child_process");
|
|
28758
28949
|
var import_util5 = require("util");
|
|
28759
|
-
var
|
|
28950
|
+
var path57 = __toESM(require("path"));
|
|
28760
28951
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
28761
28952
|
var execFileP7 = (0, import_util5.promisify)(import_child_process25.execFile);
|
|
28762
28953
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -28996,7 +29187,7 @@ var GitpodProvider = class {
|
|
|
28996
29187
|
});
|
|
28997
29188
|
}
|
|
28998
29189
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
28999
|
-
const remoteDir =
|
|
29190
|
+
const remoteDir = path57.posix.dirname(remotePath);
|
|
29000
29191
|
const parts = [
|
|
29001
29192
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
29002
29193
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -29032,7 +29223,7 @@ function shellQuote2(s) {
|
|
|
29032
29223
|
// src/services/providers/gitlab-workspaces.ts
|
|
29033
29224
|
var import_child_process26 = require("child_process");
|
|
29034
29225
|
var import_util6 = require("util");
|
|
29035
|
-
var
|
|
29226
|
+
var path58 = __toESM(require("path"));
|
|
29036
29227
|
var execFileP8 = (0, import_util6.promisify)(import_child_process26.execFile);
|
|
29037
29228
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
29038
29229
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -29292,7 +29483,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
29292
29483
|
}
|
|
29293
29484
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
29294
29485
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
29295
|
-
const remoteDir =
|
|
29486
|
+
const remoteDir = path58.posix.dirname(remotePath);
|
|
29296
29487
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
29297
29488
|
if (options.mode != null) {
|
|
29298
29489
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -29360,7 +29551,7 @@ function shellQuote3(s) {
|
|
|
29360
29551
|
// src/services/providers/railway.ts
|
|
29361
29552
|
var import_child_process27 = require("child_process");
|
|
29362
29553
|
var import_util7 = require("util");
|
|
29363
|
-
var
|
|
29554
|
+
var path59 = __toESM(require("path"));
|
|
29364
29555
|
var execFileP9 = (0, import_util7.promisify)(import_child_process27.execFile);
|
|
29365
29556
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
29366
29557
|
function resetStdinForChild4() {
|
|
@@ -29596,7 +29787,7 @@ var RailwayProvider = class {
|
|
|
29596
29787
|
if (!projectId || !serviceId) {
|
|
29597
29788
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
29598
29789
|
}
|
|
29599
|
-
const remoteDir =
|
|
29790
|
+
const remoteDir = path59.posix.dirname(remotePath);
|
|
29600
29791
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
29601
29792
|
if (options.mode != null) {
|
|
29602
29793
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -30242,8 +30433,8 @@ async function invite() {
|
|
|
30242
30433
|
var import_node_dns = require("dns");
|
|
30243
30434
|
var import_node_util5 = require("util");
|
|
30244
30435
|
var import_node_crypto8 = require("crypto");
|
|
30245
|
-
var
|
|
30246
|
-
var
|
|
30436
|
+
var fs49 = __toESM(require("fs"));
|
|
30437
|
+
var path60 = __toESM(require("path"));
|
|
30247
30438
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
30248
30439
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
30249
30440
|
async function checkDns(apiBase2) {
|
|
@@ -30299,13 +30490,13 @@ async function checkHealth(apiBase2) {
|
|
|
30299
30490
|
}
|
|
30300
30491
|
}
|
|
30301
30492
|
function checkConfigDir() {
|
|
30302
|
-
const dir =
|
|
30493
|
+
const dir = path60.join(require("os").homedir(), ".codeam");
|
|
30303
30494
|
try {
|
|
30304
|
-
|
|
30305
|
-
const probe =
|
|
30306
|
-
|
|
30307
|
-
const read2 =
|
|
30308
|
-
|
|
30495
|
+
fs49.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
30496
|
+
const probe = path60.join(dir, ".doctor-probe");
|
|
30497
|
+
fs49.writeFileSync(probe, "ok", { mode: 384 });
|
|
30498
|
+
const read2 = fs49.readFileSync(probe, "utf8");
|
|
30499
|
+
fs49.unlinkSync(probe);
|
|
30309
30500
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
30310
30501
|
return {
|
|
30311
30502
|
id: "config-dir",
|
|
@@ -30345,9 +30536,9 @@ function checkSessions() {
|
|
|
30345
30536
|
}
|
|
30346
30537
|
}
|
|
30347
30538
|
function checkAgentBinaries() {
|
|
30348
|
-
const
|
|
30539
|
+
const os41 = createOsStrategy();
|
|
30349
30540
|
return getEnabledAgents().map((meta) => {
|
|
30350
|
-
const found =
|
|
30541
|
+
const found = os41.findInPath(meta.binaryName);
|
|
30351
30542
|
return {
|
|
30352
30543
|
id: `agent-${meta.id}`,
|
|
30353
30544
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -30369,7 +30560,7 @@ function checkNodePty() {
|
|
|
30369
30560
|
detail: "not required on this platform"
|
|
30370
30561
|
};
|
|
30371
30562
|
}
|
|
30372
|
-
const vendoredPath =
|
|
30563
|
+
const vendoredPath = path60.join(__dirname, "vendor", "node-pty");
|
|
30373
30564
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
30374
30565
|
try {
|
|
30375
30566
|
require(target);
|
|
@@ -30411,7 +30602,7 @@ function checkChokidar() {
|
|
|
30411
30602
|
}
|
|
30412
30603
|
async function doctor(args2 = []) {
|
|
30413
30604
|
const json = args2.includes("--json");
|
|
30414
|
-
const cliVersion = true ? "2.
|
|
30605
|
+
const cliVersion = true ? "2.50.0" : "0.0.0-dev";
|
|
30415
30606
|
const apiBase2 = resolveApiBaseUrl();
|
|
30416
30607
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
30417
30608
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -30610,7 +30801,7 @@ async function completion(args2) {
|
|
|
30610
30801
|
// src/commands/version.ts
|
|
30611
30802
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
30612
30803
|
function version2() {
|
|
30613
|
-
const v = true ? "2.
|
|
30804
|
+
const v = true ? "2.50.0" : "unknown";
|
|
30614
30805
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
30615
30806
|
}
|
|
30616
30807
|
|
|
@@ -30759,10 +30950,10 @@ var EXIT_CODE_NAMES = {
|
|
|
30759
30950
|
};
|
|
30760
30951
|
|
|
30761
30952
|
// src/index.ts
|
|
30762
|
-
var
|
|
30953
|
+
var os40 = __toESM(require("os"));
|
|
30763
30954
|
if (!process.env.HOME) {
|
|
30764
30955
|
try {
|
|
30765
|
-
const home =
|
|
30956
|
+
const home = os40.homedir();
|
|
30766
30957
|
if (home) process.env.HOME = home;
|
|
30767
30958
|
} catch {
|
|
30768
30959
|
}
|