codeam-cli 2.39.8 → 2.39.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +463 -226
- 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.39.
|
|
501
|
+
version: "2.39.10",
|
|
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(path55) {
|
|
1190
|
+
return path55.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(path55, ranges, output) {
|
|
3671
3671
|
return new Promise((resolve7) => {
|
|
3672
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3672
|
+
const stream = (0, import_node_fs.createReadStream)(path55);
|
|
3673
3673
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3674
3674
|
input: stream
|
|
3675
3675
|
});
|
|
@@ -3684,7 +3684,7 @@ function getContextLinesFromFile(path53, 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(path55, 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(path55) {
|
|
3749
|
+
return path55.startsWith("node:") || path55.endsWith(".min.js") || path55.endsWith(".min.cjs") || path55.endsWith(".min.mjs") || path55.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.39.
|
|
5903
|
+
cliVersion: true ? "2.39.10" : "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 = [], os33 = createOsStrategy()) {
|
|
7252
|
+
const found = os33.findInPath("claude") ?? os33.findInPath("claude-code");
|
|
7253
7253
|
if (!found) return null;
|
|
7254
|
-
return
|
|
7254
|
+
return os33.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 path55 = pathLine && !BANNER_ART_RE.test(pathLine) ? pathLine : "";
|
|
9982
9982
|
return {
|
|
9983
9983
|
title: "",
|
|
9984
9984
|
subtitle: lines[metaIdx].trim(),
|
|
9985
|
-
path:
|
|
9985
|
+
path: path55,
|
|
9986
9986
|
startIdx: artStart,
|
|
9987
|
-
endIdx: metaIdx + (
|
|
9987
|
+
endIdx: metaIdx + (path55 ? 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(os33) {
|
|
9998
|
+
this.os = os33;
|
|
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 os33 = createOsStrategy();
|
|
11029
|
+
return os33.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(os33) {
|
|
11053
|
+
this.os = os33;
|
|
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(os33) {
|
|
11160
|
+
return os33.id === "win32" ? "npm.cmd" : "npm";
|
|
11161
11161
|
}
|
|
11162
|
-
async function installCodexViaNpm(
|
|
11162
|
+
async function installCodexViaNpm(os33) {
|
|
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(os33), ["install", "-g", "@openai/codex"], {
|
|
11165
11165
|
stdio: "inherit"
|
|
11166
11166
|
});
|
|
11167
11167
|
proc.on("close", (code) => {
|
|
@@ -11178,16 +11178,16 @@ async function installCodexViaNpm(os32) {
|
|
|
11178
11178
|
});
|
|
11179
11179
|
});
|
|
11180
11180
|
}
|
|
11181
|
-
function augmentNpmGlobalBin(
|
|
11181
|
+
function augmentNpmGlobalBin(os33) {
|
|
11182
11182
|
try {
|
|
11183
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
11183
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os33), ["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 = os33.id === "win32" ? prefix : path17.join(prefix, "bin");
|
|
11190
|
+
os33.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(os33) {
|
|
11275
|
+
if (os33.findInPath("coderabbit")) return true;
|
|
11276
|
+
if (os33.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(os32) {
|
|
|
11288
11288
|
proc.on("error", () => resolve7(false));
|
|
11289
11289
|
});
|
|
11290
11290
|
if (!ok) return false;
|
|
11291
|
-
|
|
11292
|
-
return
|
|
11291
|
+
os33.augmentPath([`${os33.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
11292
|
+
return os33.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(os33) {
|
|
11320
11320
|
return {
|
|
11321
11321
|
async ensureInstalled() {
|
|
11322
|
-
return ensureCoderabbitInstalled(
|
|
11322
|
+
return ensureCoderabbitInstalled(os33);
|
|
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 [, path55, lineNo, sevToken, message] = m;
|
|
11346
|
+
if (!path55 || !lineNo || !message) continue;
|
|
11347
11347
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
11348
11348
|
hunks.push({
|
|
11349
|
-
path:
|
|
11349
|
+
path: path55.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(os33) {
|
|
11369
|
+
this.os = os33;
|
|
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(os33) {
|
|
11485
11485
|
return {
|
|
11486
11486
|
async ensureInstalled() {
|
|
11487
|
-
if (
|
|
11487
|
+
if (os33.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(os33) {
|
|
11550
|
+
this.os = os33;
|
|
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(os33) {
|
|
11671
11671
|
return {
|
|
11672
11672
|
async ensureInstalled() {
|
|
11673
|
-
if (
|
|
11673
|
+
if (os33.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(os32) {
|
|
|
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)(os33.id === "win32" ? "cmd.exe" : "sh", os33.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(os33) {
|
|
11756
|
+
this.os = os33;
|
|
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 os33 = createOsStrategy();
|
|
11886
|
+
return os33.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(os33) {
|
|
11920
|
+
this.os = os33;
|
|
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: (os33) => new ClaudeRuntimeStrategy(os33),
|
|
12021
|
+
codex: (os33) => new CodexRuntimeStrategy(os33),
|
|
12022
|
+
coderabbit: (os33) => new CoderabbitRuntimeStrategy(os33),
|
|
12023
|
+
cursor: (os33) => new CursorRuntimeStrategy(os33),
|
|
12024
|
+
aider: (os33) => new AiderRuntimeStrategy(os33),
|
|
12025
|
+
gemini: (os33) => new GeminiRuntimeStrategy(os33)
|
|
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, os33 = 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, os32 = 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(os33);
|
|
12042
12042
|
}
|
|
12043
|
-
function createInteractiveAgentStrategy(agent,
|
|
12044
|
-
const s = createAgentStrategy(agent,
|
|
12043
|
+
function createInteractiveAgentStrategy(agent, os33 = createOsStrategy()) {
|
|
12044
|
+
const s = createAgentStrategy(agent, os33);
|
|
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.`
|
|
@@ -15896,9 +15896,9 @@ function extractSelectPrompt(text) {
|
|
|
15896
15896
|
}
|
|
15897
15897
|
|
|
15898
15898
|
// src/commands/start/handlers.ts
|
|
15899
|
-
var
|
|
15899
|
+
var fs35 = __toESM(require("fs"));
|
|
15900
15900
|
var os27 = __toESM(require("os"));
|
|
15901
|
-
var
|
|
15901
|
+
var path42 = __toESM(require("path"));
|
|
15902
15902
|
var import_crypto3 = require("crypto");
|
|
15903
15903
|
var import_child_process18 = require("child_process");
|
|
15904
15904
|
|
|
@@ -17349,6 +17349,10 @@ async function waitForPortListening(port, opts) {
|
|
|
17349
17349
|
}
|
|
17350
17350
|
}
|
|
17351
17351
|
|
|
17352
|
+
// src/services/preview/provision-deps.ts
|
|
17353
|
+
var import_fs2 = require("fs");
|
|
17354
|
+
var import_path6 = __toESM(require("path"));
|
|
17355
|
+
|
|
17352
17356
|
// src/services/preview/run-setup.ts
|
|
17353
17357
|
var import_child_process12 = require("child_process");
|
|
17354
17358
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
@@ -17393,19 +17397,216 @@ function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
|
17393
17397
|
});
|
|
17394
17398
|
}
|
|
17395
17399
|
|
|
17400
|
+
// src/services/preview/provision-deps.ts
|
|
17401
|
+
var COMPOSE_FILES = [
|
|
17402
|
+
"docker-compose.yml",
|
|
17403
|
+
"docker-compose.yaml",
|
|
17404
|
+
"compose.yaml",
|
|
17405
|
+
"compose.yml"
|
|
17406
|
+
];
|
|
17407
|
+
var ENV_SAMPLES = [".env.example", ".env.sample", ".env.local.example", ".env.template"];
|
|
17408
|
+
var POSTGRES = {
|
|
17409
|
+
name: "postgres",
|
|
17410
|
+
image: "postgres:16",
|
|
17411
|
+
port: 5432,
|
|
17412
|
+
environment: { POSTGRES_USER: "postgres", POSTGRES_PASSWORD: "postgres", POSTGRES_DB: "app" },
|
|
17413
|
+
healthTest: ["CMD-SHELL", "pg_isready -U postgres"],
|
|
17414
|
+
envLines: [
|
|
17415
|
+
"DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app",
|
|
17416
|
+
"DB_HOST=localhost",
|
|
17417
|
+
"DB_PORT=5432",
|
|
17418
|
+
"DB_USERNAME=postgres",
|
|
17419
|
+
"DB_PASSWORD=postgres",
|
|
17420
|
+
"DB_NAME=app"
|
|
17421
|
+
]
|
|
17422
|
+
};
|
|
17423
|
+
var MYSQL = {
|
|
17424
|
+
name: "mysql",
|
|
17425
|
+
image: "mysql:8",
|
|
17426
|
+
port: 3306,
|
|
17427
|
+
environment: { MYSQL_ROOT_PASSWORD: "mysql", MYSQL_DATABASE: "app" },
|
|
17428
|
+
healthTest: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pmysql"],
|
|
17429
|
+
envLines: ["DATABASE_URL=mysql://root:mysql@localhost:3306/app"]
|
|
17430
|
+
};
|
|
17431
|
+
var MONGO = {
|
|
17432
|
+
name: "mongo",
|
|
17433
|
+
image: "mongo:7",
|
|
17434
|
+
port: 27017,
|
|
17435
|
+
environment: {},
|
|
17436
|
+
healthTest: ["CMD", "mongosh", "--eval", 'db.adminCommand("ping")'],
|
|
17437
|
+
envLines: ["MONGODB_URI=mongodb://localhost:27017/app", "MONGO_URL=mongodb://localhost:27017/app"]
|
|
17438
|
+
};
|
|
17439
|
+
var REDIS = {
|
|
17440
|
+
name: "redis",
|
|
17441
|
+
image: "redis:7",
|
|
17442
|
+
port: 6379,
|
|
17443
|
+
environment: {},
|
|
17444
|
+
healthTest: ["CMD", "redis-cli", "ping"],
|
|
17445
|
+
envLines: ["REDIS_URL=redis://localhost:6379", "REDIS_HOST=localhost", "REDIS_PORT=6379"]
|
|
17446
|
+
};
|
|
17447
|
+
function detectServicesFromDeps(pkg) {
|
|
17448
|
+
const deps = /* @__PURE__ */ new Set([
|
|
17449
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
17450
|
+
...Object.keys(pkg.devDependencies ?? {})
|
|
17451
|
+
]);
|
|
17452
|
+
const has = (...names) => names.some((n) => deps.has(n));
|
|
17453
|
+
const out2 = [];
|
|
17454
|
+
if (has("pg", "typeorm", "@nestjs/typeorm", "sequelize", "postgres", "postgres.js", "pg-promise"))
|
|
17455
|
+
out2.push(POSTGRES);
|
|
17456
|
+
if (has("mysql", "mysql2")) out2.push(MYSQL);
|
|
17457
|
+
if (has("mongoose", "mongodb")) out2.push(MONGO);
|
|
17458
|
+
if (has("ioredis", "redis", "cache-manager-ioredis-yet", "cache-manager-redis-store"))
|
|
17459
|
+
out2.push(REDIS);
|
|
17460
|
+
return out2;
|
|
17461
|
+
}
|
|
17462
|
+
function renderComposeYaml(services) {
|
|
17463
|
+
const blocks = services.map((s) => {
|
|
17464
|
+
const env = Object.entries(s.environment);
|
|
17465
|
+
const envYaml = env.length ? " environment:\n" + env.map(([k2, v]) => ` ${k2}: "${v}"`).join("\n") + "\n" : "";
|
|
17466
|
+
const health = JSON.stringify(s.healthTest);
|
|
17467
|
+
return ` ${s.name}:
|
|
17468
|
+
image: ${s.image}
|
|
17469
|
+
restart: unless-stopped
|
|
17470
|
+
ports:
|
|
17471
|
+
- "${s.port}:${s.port}"
|
|
17472
|
+
` + envYaml + ` healthcheck:
|
|
17473
|
+
test: ${health}
|
|
17474
|
+
interval: 5s
|
|
17475
|
+
timeout: 3s
|
|
17476
|
+
retries: 12
|
|
17477
|
+
`;
|
|
17478
|
+
});
|
|
17479
|
+
return `# Generated by codeam \u2014 auto-provisioned project dependencies.
|
|
17480
|
+
# Do not edit; regenerated on each provision. See .codeam/provision/.
|
|
17481
|
+
services:
|
|
17482
|
+
${blocks.join("")}`;
|
|
17483
|
+
}
|
|
17484
|
+
function pickMigrationScript(scripts) {
|
|
17485
|
+
const preferred = [
|
|
17486
|
+
"migration:run",
|
|
17487
|
+
"db:migrate",
|
|
17488
|
+
"migrate:deploy",
|
|
17489
|
+
"migrate:latest",
|
|
17490
|
+
"migrate:up",
|
|
17491
|
+
"prisma:migrate",
|
|
17492
|
+
"migrate"
|
|
17493
|
+
];
|
|
17494
|
+
for (const k2 of preferred) if (scripts[k2]) return k2;
|
|
17495
|
+
for (const k2 of Object.keys(scripts)) {
|
|
17496
|
+
if (/migrat/i.test(k2) && /(run|deploy|latest|up)/i.test(k2) && !/(generate|create|revert|rollback|undo|down|reset|drop)/i.test(k2)) {
|
|
17497
|
+
return k2;
|
|
17498
|
+
}
|
|
17499
|
+
}
|
|
17500
|
+
return null;
|
|
17501
|
+
}
|
|
17502
|
+
async function exists(p2) {
|
|
17503
|
+
try {
|
|
17504
|
+
await import_fs2.promises.access(p2);
|
|
17505
|
+
return true;
|
|
17506
|
+
} catch {
|
|
17507
|
+
return false;
|
|
17508
|
+
}
|
|
17509
|
+
}
|
|
17510
|
+
async function firstExisting(cwd, names) {
|
|
17511
|
+
for (const n of names) if (await exists(import_path6.default.join(cwd, n))) return n;
|
|
17512
|
+
return null;
|
|
17513
|
+
}
|
|
17514
|
+
async function ensureEnvFile(cwd, generated) {
|
|
17515
|
+
if (await exists(import_path6.default.join(cwd, ".env"))) {
|
|
17516
|
+
log.info("provision", ".env already present \u2014 leaving it untouched");
|
|
17517
|
+
return;
|
|
17518
|
+
}
|
|
17519
|
+
const sample = await firstExisting(cwd, ENV_SAMPLES);
|
|
17520
|
+
if (sample) {
|
|
17521
|
+
const body = await import_fs2.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
|
|
17522
|
+
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17523
|
+
log.info("provision", `wrote .env from ${sample}`);
|
|
17524
|
+
return;
|
|
17525
|
+
}
|
|
17526
|
+
if (generated.length > 0) {
|
|
17527
|
+
const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
|
|
17528
|
+
await import_fs2.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
17529
|
+
log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
|
|
17530
|
+
}
|
|
17531
|
+
}
|
|
17532
|
+
async function readPackageJson(cwd) {
|
|
17533
|
+
try {
|
|
17534
|
+
return JSON.parse(await import_fs2.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
|
|
17535
|
+
} catch {
|
|
17536
|
+
return null;
|
|
17537
|
+
}
|
|
17538
|
+
}
|
|
17539
|
+
async function runMigrationsIfPresent(cwd, scripts) {
|
|
17540
|
+
const script = pickMigrationScript(scripts);
|
|
17541
|
+
if (!script) return;
|
|
17542
|
+
log.info("provision", `running migrations: npm run ${script}`);
|
|
17543
|
+
const res = await runSetupCommand("npm", ["run", script], cwd, void 0, { timeoutMs: 12e4 });
|
|
17544
|
+
if (res.status !== "ok") log.warn("provision", `migration script "${script}" \u2192 ${res.status} (non-fatal)`);
|
|
17545
|
+
}
|
|
17546
|
+
function runDockerComposeUp(cwd, composeArgs) {
|
|
17547
|
+
return runSetupCommand(
|
|
17548
|
+
"nice",
|
|
17549
|
+
["-n", "19", "ionice", "-c", "3", "docker", "compose", ...composeArgs],
|
|
17550
|
+
cwd,
|
|
17551
|
+
void 0,
|
|
17552
|
+
{ timeoutMs: 18e4 }
|
|
17553
|
+
);
|
|
17554
|
+
}
|
|
17555
|
+
async function provisionProjectDependencies(cwd) {
|
|
17556
|
+
try {
|
|
17557
|
+
const docker = await runSetupCommand("docker", ["info"], cwd, void 0, { timeoutMs: 15e3 });
|
|
17558
|
+
if (docker.status !== "ok") {
|
|
17559
|
+
log.info("provision", "docker not usable \u2014 skipping dependency provisioning");
|
|
17560
|
+
return;
|
|
17561
|
+
}
|
|
17562
|
+
const pkg = await readPackageJson(cwd);
|
|
17563
|
+
let started = false;
|
|
17564
|
+
let generated = [];
|
|
17565
|
+
const composeFile = await firstExisting(cwd, COMPOSE_FILES);
|
|
17566
|
+
if (composeFile) {
|
|
17567
|
+
log.info("provision", `compose found (${composeFile}) \u2014 docker compose up -d --wait (idle prio)`);
|
|
17568
|
+
const up = await runDockerComposeUp(cwd, ["up", "-d", "--wait"]);
|
|
17569
|
+
started = up.status === "ok";
|
|
17570
|
+
if (!started) log.warn("provision", `compose up \u2192 ${up.status} (non-fatal)`);
|
|
17571
|
+
} else if (pkg) {
|
|
17572
|
+
generated = detectServicesFromDeps(pkg);
|
|
17573
|
+
if (generated.length > 0) {
|
|
17574
|
+
const dir = import_path6.default.join(cwd, ".codeam", "provision");
|
|
17575
|
+
await import_fs2.promises.mkdir(dir, { recursive: true });
|
|
17576
|
+
const file = import_path6.default.join(dir, "compose.generated.yaml");
|
|
17577
|
+
await import_fs2.promises.writeFile(file, renderComposeYaml(generated));
|
|
17578
|
+
log.info(
|
|
17579
|
+
"provision",
|
|
17580
|
+
`no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
|
|
17581
|
+
);
|
|
17582
|
+
const up = await runDockerComposeUp(cwd, ["-f", file, "up", "-d", "--wait"]);
|
|
17583
|
+
started = up.status === "ok";
|
|
17584
|
+
if (!started) log.warn("provision", `generated compose up \u2192 ${up.status} (non-fatal)`);
|
|
17585
|
+
} else {
|
|
17586
|
+
log.info("provision", "no compose + no known service deps \u2014 nothing to provision");
|
|
17587
|
+
}
|
|
17588
|
+
}
|
|
17589
|
+
await ensureEnvFile(cwd, generated);
|
|
17590
|
+
if (started && pkg?.scripts) await runMigrationsIfPresent(cwd, pkg.scripts);
|
|
17591
|
+
log.info("provision", "project dependency provisioning complete");
|
|
17592
|
+
} catch (err) {
|
|
17593
|
+
log.warn("provision", "provisionProjectDependencies failed (non-fatal)", err);
|
|
17594
|
+
}
|
|
17595
|
+
}
|
|
17596
|
+
|
|
17396
17597
|
// src/services/preview/setup-deps.ts
|
|
17397
|
-
var
|
|
17398
|
-
var
|
|
17598
|
+
var import_fs3 = __toESM(require("fs"));
|
|
17599
|
+
var import_path7 = __toESM(require("path"));
|
|
17399
17600
|
function detectMissingNodeDeps(cwd) {
|
|
17400
|
-
if (!
|
|
17401
|
-
if (
|
|
17402
|
-
if (
|
|
17601
|
+
if (!import_fs3.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
|
|
17602
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
|
|
17603
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
17403
17604
|
return { cmd: "pnpm", args: ["install"] };
|
|
17404
17605
|
}
|
|
17405
|
-
if (
|
|
17606
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
|
|
17406
17607
|
return { cmd: "yarn", args: ["install"] };
|
|
17407
17608
|
}
|
|
17408
|
-
if (
|
|
17609
|
+
if (import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lockb")) || import_fs3.default.existsSync(import_path7.default.join(cwd, "bun.lock"))) {
|
|
17409
17610
|
return { cmd: "bun", args: ["install"] };
|
|
17410
17611
|
}
|
|
17411
17612
|
return { cmd: "npm", args: ["install"] };
|
|
@@ -17460,8 +17661,8 @@ function activePreviewSessionIds() {
|
|
|
17460
17661
|
|
|
17461
17662
|
// src/beads/bd-adapter.ts
|
|
17462
17663
|
var import_child_process13 = require("child_process");
|
|
17463
|
-
var
|
|
17464
|
-
var
|
|
17664
|
+
var fs31 = __toESM(require("fs"));
|
|
17665
|
+
var path37 = __toESM(require("path"));
|
|
17465
17666
|
var BD_PACKAGE = "@beads/bd";
|
|
17466
17667
|
function resolveBundledBdBinary() {
|
|
17467
17668
|
return _resolveSeam.resolveBundled();
|
|
@@ -17473,11 +17674,11 @@ function _defaultResolveBundled() {
|
|
|
17473
17674
|
} catch {
|
|
17474
17675
|
return null;
|
|
17475
17676
|
}
|
|
17476
|
-
const binDir =
|
|
17677
|
+
const binDir = path37.join(path37.dirname(pkgJsonPath), "bin");
|
|
17477
17678
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17478
|
-
const binaryPath =
|
|
17679
|
+
const binaryPath = path37.join(binDir, binaryName);
|
|
17479
17680
|
try {
|
|
17480
|
-
|
|
17681
|
+
fs31.accessSync(binaryPath, fs31.constants.F_OK);
|
|
17481
17682
|
return binaryPath;
|
|
17482
17683
|
} catch {
|
|
17483
17684
|
return null;
|
|
@@ -17487,13 +17688,13 @@ function resolveBdOnPath() {
|
|
|
17487
17688
|
return _resolveSeam.resolveOnPath();
|
|
17488
17689
|
}
|
|
17489
17690
|
function _defaultResolveOnPath() {
|
|
17490
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17691
|
+
const dirs = (process.env.PATH ?? "").split(path37.delimiter).filter(Boolean);
|
|
17491
17692
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17492
17693
|
for (const dir of dirs) {
|
|
17493
17694
|
for (const candidate of candidates) {
|
|
17494
|
-
const full =
|
|
17695
|
+
const full = path37.join(dir, candidate);
|
|
17495
17696
|
try {
|
|
17496
|
-
|
|
17697
|
+
fs31.accessSync(full, fs31.constants.F_OK);
|
|
17497
17698
|
return full;
|
|
17498
17699
|
} catch {
|
|
17499
17700
|
}
|
|
@@ -17660,9 +17861,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17660
17861
|
|
|
17661
17862
|
// src/beads/provisioner.ts
|
|
17662
17863
|
var import_child_process17 = require("child_process");
|
|
17663
|
-
var
|
|
17864
|
+
var fs34 = __toESM(require("fs"));
|
|
17664
17865
|
var os26 = __toESM(require("os"));
|
|
17665
|
-
var
|
|
17866
|
+
var path40 = __toESM(require("path"));
|
|
17666
17867
|
|
|
17667
17868
|
// src/beads/install-bd.ts
|
|
17668
17869
|
var import_child_process14 = require("child_process");
|
|
@@ -17727,9 +17928,9 @@ async function installBd(platform2 = process.platform) {
|
|
|
17727
17928
|
|
|
17728
17929
|
// src/beads/install-dolt.ts
|
|
17729
17930
|
var import_child_process15 = require("child_process");
|
|
17730
|
-
var
|
|
17931
|
+
var fs32 = __toESM(require("fs"));
|
|
17731
17932
|
var os25 = __toESM(require("os"));
|
|
17732
|
-
var
|
|
17933
|
+
var path38 = __toESM(require("path"));
|
|
17733
17934
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17734
17935
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17735
17936
|
function resolveDoltInstallStrategy(platform2) {
|
|
@@ -17769,11 +17970,11 @@ function resolveDoltInstallStrategy(platform2) {
|
|
|
17769
17970
|
}
|
|
17770
17971
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17771
17972
|
function doltPlatformTuple(platform2, arch) {
|
|
17772
|
-
const
|
|
17973
|
+
const os33 = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "darwin" : "linux";
|
|
17773
17974
|
const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
17774
17975
|
if (!a) return null;
|
|
17775
|
-
if (
|
|
17776
|
-
return `${
|
|
17976
|
+
if (os33 === "windows" && a !== "amd64") return null;
|
|
17977
|
+
return `${os33}-${a}`;
|
|
17777
17978
|
}
|
|
17778
17979
|
function resolveDoltTarballStrategy(targetDir, platform2, arch) {
|
|
17779
17980
|
const tuple = doltPlatformTuple(platform2, arch);
|
|
@@ -17825,7 +18026,7 @@ var _doltPathSeam = {
|
|
|
17825
18026
|
},
|
|
17826
18027
|
exists: (p2) => {
|
|
17827
18028
|
try {
|
|
17828
|
-
|
|
18029
|
+
fs32.accessSync(p2, fs32.constants.F_OK);
|
|
17829
18030
|
return true;
|
|
17830
18031
|
} catch {
|
|
17831
18032
|
return false;
|
|
@@ -17836,7 +18037,7 @@ function doltBinaryNames(platform2) {
|
|
|
17836
18037
|
return platform2 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17837
18038
|
}
|
|
17838
18039
|
function knownDoltDirs(platform2) {
|
|
17839
|
-
const P3 = platform2 === "win32" ?
|
|
18040
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17840
18041
|
const home = _doltPathSeam.homedir();
|
|
17841
18042
|
if (platform2 === "win32") {
|
|
17842
18043
|
return [
|
|
@@ -17852,7 +18053,7 @@ function knownDoltDirs(platform2) {
|
|
|
17852
18053
|
].filter(Boolean);
|
|
17853
18054
|
}
|
|
17854
18055
|
function ensureDoltResolvable(platform2 = process.platform) {
|
|
17855
|
-
const P3 = platform2 === "win32" ?
|
|
18056
|
+
const P3 = platform2 === "win32" ? path38.win32 : path38.posix;
|
|
17856
18057
|
const delim = platform2 === "win32" ? ";" : ":";
|
|
17857
18058
|
const names = doltBinaryNames(platform2);
|
|
17858
18059
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17963,8 +18164,8 @@ async function ensureSharedServer(adapter) {
|
|
|
17963
18164
|
// src/beads/project-key.ts
|
|
17964
18165
|
var import_child_process16 = require("child_process");
|
|
17965
18166
|
var crypto2 = __toESM(require("crypto"));
|
|
17966
|
-
var
|
|
17967
|
-
var
|
|
18167
|
+
var fs33 = __toESM(require("fs"));
|
|
18168
|
+
var path39 = __toESM(require("path"));
|
|
17968
18169
|
function normalizeOrigin(raw) {
|
|
17969
18170
|
const trimmed = raw.trim();
|
|
17970
18171
|
if (!trimmed) return null;
|
|
@@ -17990,17 +18191,17 @@ function normalizeOrigin(raw) {
|
|
|
17990
18191
|
return `${host}/${pathPart}`;
|
|
17991
18192
|
}
|
|
17992
18193
|
function findRepoRoot(cwd) {
|
|
17993
|
-
let dir =
|
|
18194
|
+
let dir = path39.resolve(cwd);
|
|
17994
18195
|
const seen = /* @__PURE__ */ new Set();
|
|
17995
18196
|
for (let i = 0; i < 256; i++) {
|
|
17996
18197
|
if (seen.has(dir)) return null;
|
|
17997
18198
|
seen.add(dir);
|
|
17998
18199
|
try {
|
|
17999
|
-
const stat3 =
|
|
18200
|
+
const stat3 = fs33.statSync(path39.join(dir, ".git"), { throwIfNoEntry: false });
|
|
18000
18201
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
18001
18202
|
} catch {
|
|
18002
18203
|
}
|
|
18003
|
-
const parent =
|
|
18204
|
+
const parent = path39.dirname(dir);
|
|
18004
18205
|
if (parent === dir) return null;
|
|
18005
18206
|
dir = parent;
|
|
18006
18207
|
}
|
|
@@ -18011,7 +18212,7 @@ var _execSeam2 = {
|
|
|
18011
18212
|
const out2 = (0, import_child_process16.execFileSync)(file, args2, opts);
|
|
18012
18213
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
18013
18214
|
},
|
|
18014
|
-
realpath: (p2) =>
|
|
18215
|
+
realpath: (p2) => fs33.realpathSync(p2)
|
|
18015
18216
|
};
|
|
18016
18217
|
function readOrigin(cwd) {
|
|
18017
18218
|
try {
|
|
@@ -18040,7 +18241,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
18040
18241
|
} catch {
|
|
18041
18242
|
}
|
|
18042
18243
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
18043
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
18244
|
+
return { projectKey: `path:${hash}`, projectLabel: path39.basename(real) || "project" };
|
|
18044
18245
|
}
|
|
18045
18246
|
|
|
18046
18247
|
// src/beads/project-prefix.ts
|
|
@@ -18085,14 +18286,14 @@ var _linkSeam = {
|
|
|
18085
18286
|
homedir: () => os26.homedir(),
|
|
18086
18287
|
isWritableDir: (dir) => {
|
|
18087
18288
|
try {
|
|
18088
|
-
|
|
18289
|
+
fs34.accessSync(dir, fs34.constants.W_OK);
|
|
18089
18290
|
return true;
|
|
18090
18291
|
} catch {
|
|
18091
18292
|
return false;
|
|
18092
18293
|
}
|
|
18093
18294
|
},
|
|
18094
18295
|
ensureDir: (dir) => {
|
|
18095
|
-
|
|
18296
|
+
fs34.mkdirSync(dir, { recursive: true });
|
|
18096
18297
|
},
|
|
18097
18298
|
/**
|
|
18098
18299
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -18113,9 +18314,9 @@ var _linkSeam = {
|
|
|
18113
18314
|
* which `linkBdOntoPath` creates if missing.
|
|
18114
18315
|
*/
|
|
18115
18316
|
cliBinDir: () => {
|
|
18116
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18317
|
+
const pathDirs = (process.env.PATH ?? "").split(path40.delimiter).filter(Boolean);
|
|
18117
18318
|
const home = _linkSeam.homedir();
|
|
18118
|
-
const localBin = home ?
|
|
18319
|
+
const localBin = home ? path40.join(home, ".local", "bin") : null;
|
|
18119
18320
|
if (localBin) {
|
|
18120
18321
|
try {
|
|
18121
18322
|
_linkSeam.ensureDir(localBin);
|
|
@@ -18125,16 +18326,16 @@ var _linkSeam = {
|
|
|
18125
18326
|
const candidates = [];
|
|
18126
18327
|
if (localBin) candidates.push(localBin);
|
|
18127
18328
|
try {
|
|
18128
|
-
candidates.push(
|
|
18329
|
+
candidates.push(path40.dirname(process.execPath));
|
|
18129
18330
|
} catch {
|
|
18130
18331
|
}
|
|
18131
18332
|
candidates.push("/usr/local/bin");
|
|
18132
18333
|
const entry = process.argv[1];
|
|
18133
18334
|
if (entry) {
|
|
18134
18335
|
try {
|
|
18135
|
-
candidates.push(
|
|
18336
|
+
candidates.push(path40.dirname(fs34.realpathSync(entry)));
|
|
18136
18337
|
} catch {
|
|
18137
|
-
candidates.push(
|
|
18338
|
+
candidates.push(path40.dirname(entry));
|
|
18138
18339
|
}
|
|
18139
18340
|
}
|
|
18140
18341
|
const onPathWritable = candidates.find(
|
|
@@ -18146,20 +18347,20 @@ var _linkSeam = {
|
|
|
18146
18347
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
18147
18348
|
readlink: (linkPath) => {
|
|
18148
18349
|
try {
|
|
18149
|
-
return
|
|
18350
|
+
return fs34.readlinkSync(linkPath);
|
|
18150
18351
|
} catch {
|
|
18151
18352
|
return null;
|
|
18152
18353
|
}
|
|
18153
18354
|
},
|
|
18154
|
-
unlink: (linkPath) =>
|
|
18155
|
-
symlink: (target, linkPath) =>
|
|
18355
|
+
unlink: (linkPath) => fs34.unlinkSync(linkPath),
|
|
18356
|
+
symlink: (target, linkPath) => fs34.symlinkSync(target, linkPath)
|
|
18156
18357
|
};
|
|
18157
18358
|
function linkBdOntoPath(binaryPath) {
|
|
18158
18359
|
if (_linkSeam.platform() === "win32") return;
|
|
18159
18360
|
const binDir = _linkSeam.cliBinDir();
|
|
18160
18361
|
if (!binDir) return;
|
|
18161
18362
|
_linkSeam.ensureDir(binDir);
|
|
18162
|
-
const linkPath =
|
|
18363
|
+
const linkPath = path40.join(binDir, "bd");
|
|
18163
18364
|
if (linkPath === binaryPath) return;
|
|
18164
18365
|
const current = _linkSeam.readlink(linkPath);
|
|
18165
18366
|
if (current === binaryPath) return;
|
|
@@ -18300,7 +18501,7 @@ function dedupeRecipes(agents) {
|
|
|
18300
18501
|
|
|
18301
18502
|
// src/beads/watcher.ts
|
|
18302
18503
|
var crypto4 = __toESM(require("crypto"));
|
|
18303
|
-
var
|
|
18504
|
+
var path41 = __toESM(require("path"));
|
|
18304
18505
|
|
|
18305
18506
|
// src/services/file-watcher/transport.ts
|
|
18306
18507
|
var http5 = __toESM(require("http"));
|
|
@@ -18375,7 +18576,7 @@ var BeadsWatcher = class {
|
|
|
18375
18576
|
constructor(opts) {
|
|
18376
18577
|
this.opts = opts;
|
|
18377
18578
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18378
|
-
this.feedPath = opts.feedPath ??
|
|
18579
|
+
this.feedPath = opts.feedPath ?? path41.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
18379
18580
|
this.apiBase = opts.apiBaseUrl ?? API_BASE4;
|
|
18380
18581
|
}
|
|
18381
18582
|
opts;
|
|
@@ -18699,7 +18900,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18699
18900
|
function cleanupAttachmentTempFiles() {
|
|
18700
18901
|
for (const p2 of pendingAttachmentFiles) {
|
|
18701
18902
|
try {
|
|
18702
|
-
|
|
18903
|
+
fs35.unlinkSync(p2);
|
|
18703
18904
|
} catch {
|
|
18704
18905
|
}
|
|
18705
18906
|
}
|
|
@@ -18708,8 +18909,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18708
18909
|
function saveFilesTemp(files) {
|
|
18709
18910
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18710
18911
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18711
|
-
const tmpPath =
|
|
18712
|
-
|
|
18912
|
+
const tmpPath = path42.join(os27.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18913
|
+
fs35.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18713
18914
|
pendingAttachmentFiles.add(tmpPath);
|
|
18714
18915
|
return tmpPath;
|
|
18715
18916
|
});
|
|
@@ -18729,7 +18930,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18729
18930
|
setTimeout(() => {
|
|
18730
18931
|
for (const p2 of paths) {
|
|
18731
18932
|
try {
|
|
18732
|
-
|
|
18933
|
+
fs35.unlinkSync(p2);
|
|
18733
18934
|
} catch {
|
|
18734
18935
|
}
|
|
18735
18936
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -19256,6 +19457,9 @@ var requestPreviewDetectH = (ctx) => {
|
|
|
19256
19457
|
return;
|
|
19257
19458
|
}
|
|
19258
19459
|
log.info("preview", `detect: ${detection.framework} on :${detection.port} (took ${tookMs}ms)`);
|
|
19460
|
+
void writePreviewConfig(process.cwd(), detection).catch((err) => {
|
|
19461
|
+
log.info("preview", `detect: writePreviewConfig failed (non-fatal): ${String(err)}`);
|
|
19462
|
+
});
|
|
19259
19463
|
void postPreviewEvent({
|
|
19260
19464
|
sessionId: ctx.sessionId,
|
|
19261
19465
|
pluginId: ctx.pluginId,
|
|
@@ -19334,8 +19538,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19334
19538
|
if (args2.length === 0) return detection;
|
|
19335
19539
|
const binName = args2[0];
|
|
19336
19540
|
if (binName.startsWith("-")) return detection;
|
|
19337
|
-
const binPath =
|
|
19338
|
-
if (!
|
|
19541
|
+
const binPath = path42.join(cwd, "node_modules", ".bin", binName);
|
|
19542
|
+
if (!fs35.existsSync(binPath)) return detection;
|
|
19339
19543
|
return {
|
|
19340
19544
|
...detection,
|
|
19341
19545
|
command: binPath,
|
|
@@ -19772,9 +19976,9 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
19772
19976
|
|
|
19773
19977
|
// src/services/file-watcher.service.ts
|
|
19774
19978
|
var import_child_process19 = require("child_process");
|
|
19775
|
-
var
|
|
19979
|
+
var fs36 = __toESM(require("fs"));
|
|
19776
19980
|
var os28 = __toESM(require("os"));
|
|
19777
|
-
var
|
|
19981
|
+
var path43 = __toESM(require("path"));
|
|
19778
19982
|
var import_ignore = __toESM(require("ignore"));
|
|
19779
19983
|
|
|
19780
19984
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -19884,10 +20088,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
19884
20088
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
19885
20089
|
/[\\/]Templates([\\/]|$)/i
|
|
19886
20090
|
];
|
|
19887
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
20091
|
+
function isUnsafeWindowsWatchRoot(dir, homedir26) {
|
|
19888
20092
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
19889
20093
|
const cwd = norm(dir);
|
|
19890
|
-
const home = norm(
|
|
20094
|
+
const home = norm(homedir26);
|
|
19891
20095
|
if (cwd === home) return true;
|
|
19892
20096
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
19893
20097
|
const sysRoots = [
|
|
@@ -19917,18 +20121,18 @@ var _findGitRootSeam = {
|
|
|
19917
20121
|
resolve: _defaultFindGitRoot
|
|
19918
20122
|
};
|
|
19919
20123
|
function _defaultFindGitRoot(startDir) {
|
|
19920
|
-
let dir =
|
|
20124
|
+
let dir = path43.resolve(startDir);
|
|
19921
20125
|
const seen = /* @__PURE__ */ new Set();
|
|
19922
20126
|
for (let i = 0; i < 256; i++) {
|
|
19923
20127
|
if (seen.has(dir)) return null;
|
|
19924
20128
|
seen.add(dir);
|
|
19925
20129
|
try {
|
|
19926
|
-
const gitPath =
|
|
19927
|
-
const stat3 =
|
|
20130
|
+
const gitPath = path43.join(dir, ".git");
|
|
20131
|
+
const stat3 = fs36.statSync(gitPath, { throwIfNoEntry: false });
|
|
19928
20132
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
19929
20133
|
} catch {
|
|
19930
20134
|
}
|
|
19931
|
-
const parent =
|
|
20135
|
+
const parent = path43.dirname(dir);
|
|
19932
20136
|
if (parent === dir) return null;
|
|
19933
20137
|
dir = parent;
|
|
19934
20138
|
}
|
|
@@ -20173,7 +20377,7 @@ var FileWatcherService = class {
|
|
|
20173
20377
|
}
|
|
20174
20378
|
async emitForFile(absPath, changeType) {
|
|
20175
20379
|
if (this.stopped) return;
|
|
20176
|
-
const fileDir =
|
|
20380
|
+
const fileDir = path43.dirname(absPath);
|
|
20177
20381
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
20178
20382
|
if (gitRoot === void 0) {
|
|
20179
20383
|
gitRoot = findGitRoot2(fileDir);
|
|
@@ -20186,19 +20390,19 @@ var FileWatcherService = class {
|
|
|
20186
20390
|
);
|
|
20187
20391
|
return;
|
|
20188
20392
|
}
|
|
20189
|
-
const relPathInRepo =
|
|
20393
|
+
const relPathInRepo = path43.relative(gitRoot, absPath);
|
|
20190
20394
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
20191
20395
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
20192
20396
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
20193
20397
|
log.trace(
|
|
20194
20398
|
"fileWatcher",
|
|
20195
|
-
`${relPathInRepo} ignored by ${
|
|
20399
|
+
`${relPathInRepo} ignored by ${path43.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
20196
20400
|
);
|
|
20197
20401
|
return;
|
|
20198
20402
|
}
|
|
20199
20403
|
this.opts.onRepoDirty?.(gitRoot);
|
|
20200
|
-
const repoPath =
|
|
20201
|
-
const repoName =
|
|
20404
|
+
const repoPath = path43.relative(this.opts.workingDir, gitRoot);
|
|
20405
|
+
const repoName = path43.basename(gitRoot);
|
|
20202
20406
|
let diffText = "";
|
|
20203
20407
|
let fileStatus = "modified";
|
|
20204
20408
|
if (changeType === "unlink") {
|
|
@@ -20373,7 +20577,7 @@ var FileWatcherService = class {
|
|
|
20373
20577
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
20374
20578
|
let entries;
|
|
20375
20579
|
try {
|
|
20376
|
-
entries =
|
|
20580
|
+
entries = fs36.readdirSync(dir, { withFileTypes: true });
|
|
20377
20581
|
} catch {
|
|
20378
20582
|
return;
|
|
20379
20583
|
}
|
|
@@ -20382,16 +20586,16 @@ var FileWatcherService = class {
|
|
|
20382
20586
|
);
|
|
20383
20587
|
if (gitignoreEntry) {
|
|
20384
20588
|
try {
|
|
20385
|
-
const body =
|
|
20386
|
-
const rel =
|
|
20589
|
+
const body = fs36.readFileSync(path43.join(dir, ".gitignore"), "utf8");
|
|
20590
|
+
const rel = path43.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
20387
20591
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
20388
20592
|
const trimmed = line.trim();
|
|
20389
20593
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
20390
20594
|
if (!rel) return line;
|
|
20391
20595
|
if (trimmed.startsWith("!")) {
|
|
20392
|
-
return "!" +
|
|
20596
|
+
return "!" + path43.posix.join(rel, trimmed.slice(1));
|
|
20393
20597
|
}
|
|
20394
|
-
return
|
|
20598
|
+
return path43.posix.join(rel, trimmed);
|
|
20395
20599
|
}).join("\n");
|
|
20396
20600
|
matcher.add(prefixed);
|
|
20397
20601
|
} catch {
|
|
@@ -20400,7 +20604,7 @@ var FileWatcherService = class {
|
|
|
20400
20604
|
for (const entry of entries) {
|
|
20401
20605
|
if (!entry.isDirectory()) continue;
|
|
20402
20606
|
if (entry.name === ".git") continue;
|
|
20403
|
-
const childAbs =
|
|
20607
|
+
const childAbs = path43.join(dir, entry.name);
|
|
20404
20608
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
20405
20609
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
20406
20610
|
}
|
|
@@ -20570,7 +20774,7 @@ var import_crypto4 = require("crypto");
|
|
|
20570
20774
|
|
|
20571
20775
|
// src/services/turn-files/git-changeset.ts
|
|
20572
20776
|
var import_child_process20 = require("child_process");
|
|
20573
|
-
var
|
|
20777
|
+
var path44 = __toESM(require("path"));
|
|
20574
20778
|
async function collectRepoChangeset(opts) {
|
|
20575
20779
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
20576
20780
|
if (status2 === null) return null;
|
|
@@ -20681,7 +20885,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
20681
20885
|
});
|
|
20682
20886
|
}
|
|
20683
20887
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
20684
|
-
const
|
|
20888
|
+
const fs43 = await import("fs/promises");
|
|
20685
20889
|
const out2 = [];
|
|
20686
20890
|
await walk(workingDir, 0);
|
|
20687
20891
|
return out2;
|
|
@@ -20689,7 +20893,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20689
20893
|
if (depth > maxDepth) return;
|
|
20690
20894
|
let entries = [];
|
|
20691
20895
|
try {
|
|
20692
|
-
const dirents = await
|
|
20896
|
+
const dirents = await fs43.readdir(dir, { withFileTypes: true });
|
|
20693
20897
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
20694
20898
|
} catch {
|
|
20695
20899
|
return;
|
|
@@ -20700,8 +20904,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20700
20904
|
if (hasGit) {
|
|
20701
20905
|
out2.push({
|
|
20702
20906
|
repoRoot: dir,
|
|
20703
|
-
repoPath:
|
|
20704
|
-
repoName:
|
|
20907
|
+
repoPath: path44.relative(workingDir, dir),
|
|
20908
|
+
repoName: path44.basename(dir)
|
|
20705
20909
|
});
|
|
20706
20910
|
return;
|
|
20707
20911
|
}
|
|
@@ -20709,14 +20913,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
20709
20913
|
if (!entry.isDirectory) continue;
|
|
20710
20914
|
if (entry.name === "node_modules") continue;
|
|
20711
20915
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
20712
|
-
await walk(
|
|
20916
|
+
await walk(path44.join(dir, entry.name), depth + 1);
|
|
20713
20917
|
}
|
|
20714
20918
|
}
|
|
20715
20919
|
}
|
|
20716
20920
|
|
|
20717
20921
|
// src/services/turn-files/files-outbox.ts
|
|
20718
|
-
var
|
|
20719
|
-
var
|
|
20922
|
+
var fs37 = __toESM(require("fs/promises"));
|
|
20923
|
+
var path45 = __toESM(require("path"));
|
|
20720
20924
|
var import_os7 = require("os");
|
|
20721
20925
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
20722
20926
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -20749,16 +20953,16 @@ var FilesOutbox = class {
|
|
|
20749
20953
|
backoffIndex = 0;
|
|
20750
20954
|
stopped = false;
|
|
20751
20955
|
constructor(opts) {
|
|
20752
|
-
const base = opts.baseDir ??
|
|
20753
|
-
this.filePath =
|
|
20956
|
+
const base = opts.baseDir ?? path45.join(homeDir(), HOME_OUTBOX_DIR);
|
|
20957
|
+
this.filePath = path45.join(base, `${opts.sessionId}.jsonl`);
|
|
20754
20958
|
this.post = opts.post;
|
|
20755
20959
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
20756
20960
|
}
|
|
20757
20961
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
20758
20962
|
* line is durable on disk (not once the POST succeeds). */
|
|
20759
20963
|
async enqueue(entry) {
|
|
20760
|
-
await
|
|
20761
|
-
await
|
|
20964
|
+
await fs37.mkdir(path45.dirname(this.filePath), { recursive: true });
|
|
20965
|
+
await fs37.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20762
20966
|
this.backoffIndex = 0;
|
|
20763
20967
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
20764
20968
|
}
|
|
@@ -20847,7 +21051,7 @@ var FilesOutbox = class {
|
|
|
20847
21051
|
async readAll() {
|
|
20848
21052
|
let raw = "";
|
|
20849
21053
|
try {
|
|
20850
|
-
raw = await
|
|
21054
|
+
raw = await fs37.readFile(this.filePath, "utf8");
|
|
20851
21055
|
} catch {
|
|
20852
21056
|
return [];
|
|
20853
21057
|
}
|
|
@@ -20871,12 +21075,12 @@ var FilesOutbox = class {
|
|
|
20871
21075
|
async rewrite(entries) {
|
|
20872
21076
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
20873
21077
|
if (entries.length === 0) {
|
|
20874
|
-
await
|
|
21078
|
+
await fs37.unlink(this.filePath).catch(() => void 0);
|
|
20875
21079
|
return;
|
|
20876
21080
|
}
|
|
20877
21081
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
20878
|
-
await
|
|
20879
|
-
await
|
|
21082
|
+
await fs37.writeFile(tmpPath, payload, "utf8");
|
|
21083
|
+
await fs37.rename(tmpPath, this.filePath);
|
|
20880
21084
|
}
|
|
20881
21085
|
};
|
|
20882
21086
|
function applyJitter(ms) {
|
|
@@ -21974,10 +22178,10 @@ var ChromeStepTracker = class {
|
|
|
21974
22178
|
const visible = lines.map((l) => parseLine2(l)).filter((s) => s !== null);
|
|
21975
22179
|
if (visible.length === 0) return;
|
|
21976
22180
|
for (const step of visible) {
|
|
21977
|
-
const
|
|
22181
|
+
const exists2 = this.history.some(
|
|
21978
22182
|
(s) => s.tool === step.tool && s.label === step.label
|
|
21979
22183
|
);
|
|
21980
|
-
if (!
|
|
22184
|
+
if (!exists2) this.history.push(step);
|
|
21981
22185
|
}
|
|
21982
22186
|
}
|
|
21983
22187
|
/**
|
|
@@ -22722,8 +22926,8 @@ var OutputService = class _OutputService {
|
|
|
22722
22926
|
};
|
|
22723
22927
|
|
|
22724
22928
|
// src/services/history.service.ts
|
|
22725
|
-
var
|
|
22726
|
-
var
|
|
22929
|
+
var fs38 = __toESM(require("fs"));
|
|
22930
|
+
var path46 = __toESM(require("path"));
|
|
22727
22931
|
var os29 = __toESM(require("os"));
|
|
22728
22932
|
var https7 = __toESM(require("https"));
|
|
22729
22933
|
var http7 = __toESM(require("http"));
|
|
@@ -22751,7 +22955,7 @@ function parseJsonl(filePath) {
|
|
|
22751
22955
|
const messages = [];
|
|
22752
22956
|
let raw;
|
|
22753
22957
|
try {
|
|
22754
|
-
raw =
|
|
22958
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
22755
22959
|
} catch (err) {
|
|
22756
22960
|
if (err.code !== "ENOENT") {
|
|
22757
22961
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -22886,7 +23090,7 @@ var HistoryService = class _HistoryService {
|
|
|
22886
23090
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
22887
23091
|
}
|
|
22888
23092
|
get projectDir() {
|
|
22889
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
23093
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path46.join(os29.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
22890
23094
|
}
|
|
22891
23095
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
22892
23096
|
setCurrentConversationId(id) {
|
|
@@ -22898,7 +23102,7 @@ var HistoryService = class _HistoryService {
|
|
|
22898
23102
|
/** Return the current message count in the active conversation. */
|
|
22899
23103
|
getCurrentMessageCount() {
|
|
22900
23104
|
if (!this.currentConversationId) return 0;
|
|
22901
|
-
const filePath =
|
|
23105
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22902
23106
|
return parseJsonl(filePath).length;
|
|
22903
23107
|
}
|
|
22904
23108
|
/**
|
|
@@ -22909,7 +23113,7 @@ var HistoryService = class _HistoryService {
|
|
|
22909
23113
|
const deadline = Date.now() + timeoutMs;
|
|
22910
23114
|
while (Date.now() < deadline) {
|
|
22911
23115
|
if (!this.currentConversationId) return null;
|
|
22912
|
-
const filePath =
|
|
23116
|
+
const filePath = path46.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
22913
23117
|
const messages = parseJsonl(filePath);
|
|
22914
23118
|
if (messages.length > previousCount) {
|
|
22915
23119
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -22935,16 +23139,16 @@ var HistoryService = class _HistoryService {
|
|
|
22935
23139
|
const dir = this.projectDir;
|
|
22936
23140
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22937
23141
|
try {
|
|
22938
|
-
const files =
|
|
23142
|
+
const files = fs38.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22939
23143
|
try {
|
|
22940
|
-
const stat3 =
|
|
23144
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22941
23145
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22942
23146
|
} catch {
|
|
22943
23147
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
22944
23148
|
}
|
|
22945
23149
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
22946
23150
|
if (files.length > 0) {
|
|
22947
|
-
this.currentConversationId =
|
|
23151
|
+
this.currentConversationId = path46.basename(files[0].name, ".jsonl");
|
|
22948
23152
|
}
|
|
22949
23153
|
} catch {
|
|
22950
23154
|
}
|
|
@@ -22978,13 +23182,13 @@ var HistoryService = class _HistoryService {
|
|
|
22978
23182
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
22979
23183
|
let entries;
|
|
22980
23184
|
try {
|
|
22981
|
-
entries =
|
|
23185
|
+
entries = fs38.readdirSync(dir, { withFileTypes: true });
|
|
22982
23186
|
} catch {
|
|
22983
23187
|
return null;
|
|
22984
23188
|
}
|
|
22985
23189
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
22986
23190
|
try {
|
|
22987
|
-
const stat3 =
|
|
23191
|
+
const stat3 = fs38.statSync(path46.join(dir, e.name));
|
|
22988
23192
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
22989
23193
|
} catch {
|
|
22990
23194
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -22993,12 +23197,12 @@ var HistoryService = class _HistoryService {
|
|
|
22993
23197
|
if (files.length === 0) return null;
|
|
22994
23198
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
22995
23199
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
22996
|
-
return this.extractUsageFromFile(
|
|
23200
|
+
return this.extractUsageFromFile(path46.join(dir, targetFile));
|
|
22997
23201
|
}
|
|
22998
23202
|
extractUsageFromFile(filePath) {
|
|
22999
23203
|
let raw;
|
|
23000
23204
|
try {
|
|
23001
|
-
raw =
|
|
23205
|
+
raw = fs38.readFileSync(filePath, "utf8");
|
|
23002
23206
|
} catch {
|
|
23003
23207
|
return null;
|
|
23004
23208
|
}
|
|
@@ -23043,9 +23247,9 @@ var HistoryService = class _HistoryService {
|
|
|
23043
23247
|
let totalCost = 0;
|
|
23044
23248
|
let files;
|
|
23045
23249
|
try {
|
|
23046
|
-
files =
|
|
23250
|
+
files = fs38.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
23047
23251
|
try {
|
|
23048
|
-
return
|
|
23252
|
+
return fs38.statSync(path46.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
23049
23253
|
} catch {
|
|
23050
23254
|
return false;
|
|
23051
23255
|
}
|
|
@@ -23056,7 +23260,7 @@ var HistoryService = class _HistoryService {
|
|
|
23056
23260
|
for (const file of files) {
|
|
23057
23261
|
let raw;
|
|
23058
23262
|
try {
|
|
23059
|
-
raw =
|
|
23263
|
+
raw = fs38.readFileSync(path46.join(projectDir, file), "utf8");
|
|
23060
23264
|
} catch {
|
|
23061
23265
|
continue;
|
|
23062
23266
|
}
|
|
@@ -23120,7 +23324,7 @@ var HistoryService = class _HistoryService {
|
|
|
23120
23324
|
* showing an empty conversation.
|
|
23121
23325
|
*/
|
|
23122
23326
|
async loadConversation(sessionId) {
|
|
23123
|
-
const filePath =
|
|
23327
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23124
23328
|
const messages = parseJsonl(filePath);
|
|
23125
23329
|
if (messages.length === 0) return;
|
|
23126
23330
|
const totalBatches = Math.ceil(messages.length / CONVERSATION_BATCH_SIZE);
|
|
@@ -23174,7 +23378,7 @@ var HistoryService = class _HistoryService {
|
|
|
23174
23378
|
if (!this.currentConversationId) return 0;
|
|
23175
23379
|
}
|
|
23176
23380
|
const sessionId = this.currentConversationId;
|
|
23177
|
-
const filePath =
|
|
23381
|
+
const filePath = path46.join(this.projectDir, `${sessionId}.jsonl`);
|
|
23178
23382
|
const messages = parseJsonl(filePath);
|
|
23179
23383
|
if (messages.length === 0) return 0;
|
|
23180
23384
|
const marker = this.lastUploadedUuid.get(sessionId);
|
|
@@ -23642,6 +23846,34 @@ function buildKeepAlive(ctx) {
|
|
|
23642
23846
|
};
|
|
23643
23847
|
}
|
|
23644
23848
|
|
|
23849
|
+
// src/agents/claude/onboarding.ts
|
|
23850
|
+
var fs39 = __toESM(require("fs"));
|
|
23851
|
+
var os30 = __toESM(require("os"));
|
|
23852
|
+
var path47 = __toESM(require("path"));
|
|
23853
|
+
function ensureClaudeOnboarded() {
|
|
23854
|
+
try {
|
|
23855
|
+
const file = path47.join(os30.homedir(), ".claude.json");
|
|
23856
|
+
let config = {};
|
|
23857
|
+
try {
|
|
23858
|
+
config = JSON.parse(fs39.readFileSync(file, "utf8"));
|
|
23859
|
+
} catch {
|
|
23860
|
+
}
|
|
23861
|
+
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
23862
|
+
return;
|
|
23863
|
+
}
|
|
23864
|
+
config.hasCompletedOnboarding = true;
|
|
23865
|
+
config.theme = typeof config.theme === "string" ? config.theme : "dark";
|
|
23866
|
+
if (typeof config.lastOnboardingVersion !== "string") {
|
|
23867
|
+
config.lastOnboardingVersion = "2.1.177";
|
|
23868
|
+
}
|
|
23869
|
+
fs39.mkdirSync(path47.dirname(file), { recursive: true });
|
|
23870
|
+
fs39.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
23871
|
+
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
23872
|
+
} catch (err) {
|
|
23873
|
+
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
23874
|
+
}
|
|
23875
|
+
}
|
|
23876
|
+
|
|
23645
23877
|
// src/commands/start.ts
|
|
23646
23878
|
async function start(requestedAgent) {
|
|
23647
23879
|
showIntro();
|
|
@@ -23696,6 +23928,7 @@ async function start(requestedAgent) {
|
|
|
23696
23928
|
"pluginAuth",
|
|
23697
23929
|
`boot triple sessionId=${session.id} pluginId=${pluginId} tokenLen=${tokenForLog.length} tokenHead=${tokenForLog.slice(0, 12)} tokenTail=${tokenForLog.slice(-8)} mintedEqualsCached=${refreshed === session.pluginAuthToken}`
|
|
23698
23930
|
);
|
|
23931
|
+
if (process.env.CODESPACES === "true") ensureClaudeOnboarded();
|
|
23699
23932
|
let beads = null;
|
|
23700
23933
|
const getBeads = () => beads;
|
|
23701
23934
|
const beadsReady = provisionBeadsForStart({
|
|
@@ -23710,17 +23943,21 @@ async function start(requestedAgent) {
|
|
|
23710
23943
|
beads = started;
|
|
23711
23944
|
return started;
|
|
23712
23945
|
});
|
|
23946
|
+
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
23713
23947
|
if (process.env.CODESPACES === "true") {
|
|
23714
|
-
const
|
|
23948
|
+
const GATE_TIMEOUT_MS = 24e4;
|
|
23715
23949
|
let gateTimer;
|
|
23716
23950
|
await Promise.race([
|
|
23717
|
-
beadsReady.catch(() => null),
|
|
23951
|
+
Promise.all([beadsReady.catch(() => null), depsReady]),
|
|
23718
23952
|
new Promise((resolve7) => {
|
|
23719
|
-
gateTimer = setTimeout(resolve7,
|
|
23953
|
+
gateTimer = setTimeout(resolve7, GATE_TIMEOUT_MS);
|
|
23720
23954
|
})
|
|
23721
23955
|
]);
|
|
23722
23956
|
if (gateTimer) clearTimeout(gateTimer);
|
|
23723
|
-
log.info(
|
|
23957
|
+
log.info(
|
|
23958
|
+
"beads",
|
|
23959
|
+
`agent-spawn gate released \u2014 beads ${beads ? "ready" : "pending"}; project deps provisioned`
|
|
23960
|
+
);
|
|
23724
23961
|
}
|
|
23725
23962
|
const acpDisabled = process.env.CODEAM_ACP_DISABLED === "1";
|
|
23726
23963
|
if (!acpDisabled && session.pluginAuthToken) {
|
|
@@ -24107,9 +24344,9 @@ async function autoLinkAfterPair(opts) {
|
|
|
24107
24344
|
}
|
|
24108
24345
|
|
|
24109
24346
|
// src/commands/pair-auto.ts
|
|
24110
|
-
var
|
|
24111
|
-
var
|
|
24112
|
-
var
|
|
24347
|
+
var fs40 = __toESM(require("fs"));
|
|
24348
|
+
var os31 = __toESM(require("os"));
|
|
24349
|
+
var path48 = __toESM(require("path"));
|
|
24113
24350
|
var import_crypto7 = require("crypto");
|
|
24114
24351
|
|
|
24115
24352
|
// src/commands/start-infra-only.ts
|
|
@@ -24304,12 +24541,12 @@ function readTokenFromArgs(args2) {
|
|
|
24304
24541
|
}
|
|
24305
24542
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
24306
24543
|
if (fileFlag) {
|
|
24307
|
-
const
|
|
24544
|
+
const path55 = fileFlag.slice("--token-file=".length);
|
|
24308
24545
|
try {
|
|
24309
|
-
const content =
|
|
24310
|
-
if (content.length === 0) fail(`--token-file ${
|
|
24546
|
+
const content = fs40.readFileSync(path55, "utf8").trim();
|
|
24547
|
+
if (content.length === 0) fail(`--token-file ${path55} is empty`);
|
|
24311
24548
|
try {
|
|
24312
|
-
|
|
24549
|
+
fs40.unlinkSync(path55);
|
|
24313
24550
|
} catch {
|
|
24314
24551
|
}
|
|
24315
24552
|
return content;
|
|
@@ -24335,7 +24572,7 @@ async function claimOnce(token, pluginId) {
|
|
|
24335
24572
|
pluginId,
|
|
24336
24573
|
ideName: "codeam-cli (codespace)",
|
|
24337
24574
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
24338
|
-
hostname:
|
|
24575
|
+
hostname: os31.hostname(),
|
|
24339
24576
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
24340
24577
|
// Current git branch of the codespace's working directory, so the
|
|
24341
24578
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -24392,7 +24629,7 @@ async function claim(token, pluginId) {
|
|
|
24392
24629
|
}
|
|
24393
24630
|
}
|
|
24394
24631
|
function pairAutoLockPath() {
|
|
24395
|
-
return
|
|
24632
|
+
return path48.join(os31.homedir(), ".codeam", "pair-auto.lock");
|
|
24396
24633
|
}
|
|
24397
24634
|
function isLivePairAuto(pid) {
|
|
24398
24635
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -24402,7 +24639,7 @@ function isLivePairAuto(pid) {
|
|
|
24402
24639
|
if (e.code !== "EPERM") return false;
|
|
24403
24640
|
}
|
|
24404
24641
|
try {
|
|
24405
|
-
return
|
|
24642
|
+
return fs40.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
24406
24643
|
} catch {
|
|
24407
24644
|
return true;
|
|
24408
24645
|
}
|
|
@@ -24410,19 +24647,19 @@ function isLivePairAuto(pid) {
|
|
|
24410
24647
|
function acquireSingletonLock() {
|
|
24411
24648
|
const lockPath = pairAutoLockPath();
|
|
24412
24649
|
try {
|
|
24413
|
-
|
|
24650
|
+
fs40.mkdirSync(path48.dirname(lockPath), { recursive: true });
|
|
24414
24651
|
try {
|
|
24415
|
-
|
|
24652
|
+
fs40.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
24416
24653
|
} catch (e) {
|
|
24417
24654
|
if (e.code !== "EEXIST") throw e;
|
|
24418
|
-
const holder = Number(
|
|
24655
|
+
const holder = Number(fs40.readFileSync(lockPath, "utf8").trim());
|
|
24419
24656
|
if (isLivePairAuto(holder)) return false;
|
|
24420
|
-
|
|
24657
|
+
fs40.writeFileSync(lockPath, String(process.pid));
|
|
24421
24658
|
}
|
|
24422
24659
|
process.once("exit", () => {
|
|
24423
24660
|
try {
|
|
24424
|
-
if (
|
|
24425
|
-
|
|
24661
|
+
if (fs40.existsSync(lockPath) && Number(fs40.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24662
|
+
fs40.unlinkSync(lockPath);
|
|
24426
24663
|
}
|
|
24427
24664
|
} catch {
|
|
24428
24665
|
}
|
|
@@ -24621,7 +24858,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
24621
24858
|
var import_child_process22 = require("child_process");
|
|
24622
24859
|
var import_util4 = require("util");
|
|
24623
24860
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
24624
|
-
var
|
|
24861
|
+
var path49 = __toESM(require("path"));
|
|
24625
24862
|
var execFileP5 = (0, import_util4.promisify)(import_child_process22.execFile);
|
|
24626
24863
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
24627
24864
|
function resetStdinForChild() {
|
|
@@ -25110,7 +25347,7 @@ var GitHubCodespacesProvider = class {
|
|
|
25110
25347
|
});
|
|
25111
25348
|
}
|
|
25112
25349
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25113
|
-
const remoteDir =
|
|
25350
|
+
const remoteDir = path49.posix.dirname(remotePath);
|
|
25114
25351
|
const parts = [
|
|
25115
25352
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
25116
25353
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -25180,7 +25417,7 @@ function shellQuote(s) {
|
|
|
25180
25417
|
// src/services/providers/gitpod.ts
|
|
25181
25418
|
var import_child_process23 = require("child_process");
|
|
25182
25419
|
var import_util5 = require("util");
|
|
25183
|
-
var
|
|
25420
|
+
var path50 = __toESM(require("path"));
|
|
25184
25421
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
25185
25422
|
var execFileP6 = (0, import_util5.promisify)(import_child_process23.execFile);
|
|
25186
25423
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -25420,7 +25657,7 @@ var GitpodProvider = class {
|
|
|
25420
25657
|
});
|
|
25421
25658
|
}
|
|
25422
25659
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25423
|
-
const remoteDir =
|
|
25660
|
+
const remoteDir = path50.posix.dirname(remotePath);
|
|
25424
25661
|
const parts = [
|
|
25425
25662
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
25426
25663
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -25456,7 +25693,7 @@ function shellQuote2(s) {
|
|
|
25456
25693
|
// src/services/providers/gitlab-workspaces.ts
|
|
25457
25694
|
var import_child_process24 = require("child_process");
|
|
25458
25695
|
var import_util6 = require("util");
|
|
25459
|
-
var
|
|
25696
|
+
var path51 = __toESM(require("path"));
|
|
25460
25697
|
var execFileP7 = (0, import_util6.promisify)(import_child_process24.execFile);
|
|
25461
25698
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
25462
25699
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -25716,7 +25953,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
25716
25953
|
}
|
|
25717
25954
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
25718
25955
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
25719
|
-
const remoteDir =
|
|
25956
|
+
const remoteDir = path51.posix.dirname(remotePath);
|
|
25720
25957
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
25721
25958
|
if (options.mode != null) {
|
|
25722
25959
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -25784,7 +26021,7 @@ function shellQuote3(s) {
|
|
|
25784
26021
|
// src/services/providers/railway.ts
|
|
25785
26022
|
var import_child_process25 = require("child_process");
|
|
25786
26023
|
var import_util7 = require("util");
|
|
25787
|
-
var
|
|
26024
|
+
var path52 = __toESM(require("path"));
|
|
25788
26025
|
var execFileP8 = (0, import_util7.promisify)(import_child_process25.execFile);
|
|
25789
26026
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
25790
26027
|
function resetStdinForChild4() {
|
|
@@ -26020,7 +26257,7 @@ var RailwayProvider = class {
|
|
|
26020
26257
|
if (!projectId || !serviceId) {
|
|
26021
26258
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
26022
26259
|
}
|
|
26023
|
-
const remoteDir =
|
|
26260
|
+
const remoteDir = path52.posix.dirname(remotePath);
|
|
26024
26261
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
26025
26262
|
if (options.mode != null) {
|
|
26026
26263
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -26563,8 +26800,8 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
26563
26800
|
var import_node_dns = require("dns");
|
|
26564
26801
|
var import_node_util4 = require("util");
|
|
26565
26802
|
var import_node_crypto8 = require("crypto");
|
|
26566
|
-
var
|
|
26567
|
-
var
|
|
26803
|
+
var fs41 = __toESM(require("fs"));
|
|
26804
|
+
var path53 = __toESM(require("path"));
|
|
26568
26805
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
26569
26806
|
var dnsResolveP = (0, import_node_util4.promisify)(import_node_dns.resolve);
|
|
26570
26807
|
async function checkDns(apiBase) {
|
|
@@ -26620,13 +26857,13 @@ async function checkHealth(apiBase) {
|
|
|
26620
26857
|
}
|
|
26621
26858
|
}
|
|
26622
26859
|
function checkConfigDir() {
|
|
26623
|
-
const dir =
|
|
26860
|
+
const dir = path53.join(require("os").homedir(), ".codeam");
|
|
26624
26861
|
try {
|
|
26625
|
-
|
|
26626
|
-
const probe =
|
|
26627
|
-
|
|
26628
|
-
const read =
|
|
26629
|
-
|
|
26862
|
+
fs41.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
26863
|
+
const probe = path53.join(dir, ".doctor-probe");
|
|
26864
|
+
fs41.writeFileSync(probe, "ok", { mode: 384 });
|
|
26865
|
+
const read = fs41.readFileSync(probe, "utf8");
|
|
26866
|
+
fs41.unlinkSync(probe);
|
|
26630
26867
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
26631
26868
|
return {
|
|
26632
26869
|
id: "config-dir",
|
|
@@ -26666,9 +26903,9 @@ function checkSessions() {
|
|
|
26666
26903
|
}
|
|
26667
26904
|
}
|
|
26668
26905
|
function checkAgentBinaries() {
|
|
26669
|
-
const
|
|
26906
|
+
const os33 = createOsStrategy();
|
|
26670
26907
|
return getEnabledAgents().map((meta) => {
|
|
26671
|
-
const found =
|
|
26908
|
+
const found = os33.findInPath(meta.binaryName);
|
|
26672
26909
|
return {
|
|
26673
26910
|
id: `agent-${meta.id}`,
|
|
26674
26911
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -26690,7 +26927,7 @@ function checkNodePty() {
|
|
|
26690
26927
|
detail: "not required on this platform"
|
|
26691
26928
|
};
|
|
26692
26929
|
}
|
|
26693
|
-
const vendoredPath =
|
|
26930
|
+
const vendoredPath = path53.join(__dirname, "vendor", "node-pty");
|
|
26694
26931
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
26695
26932
|
try {
|
|
26696
26933
|
require(target);
|
|
@@ -26732,7 +26969,7 @@ function checkChokidar() {
|
|
|
26732
26969
|
}
|
|
26733
26970
|
async function doctor(args2 = []) {
|
|
26734
26971
|
const json = args2.includes("--json");
|
|
26735
|
-
const cliVersion = true ? "2.39.
|
|
26972
|
+
const cliVersion = true ? "2.39.10" : "0.0.0-dev";
|
|
26736
26973
|
const apiBase = resolveApiBaseUrl();
|
|
26737
26974
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
26738
26975
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -26931,7 +27168,7 @@ async function completion(args2) {
|
|
|
26931
27168
|
// src/commands/version.ts
|
|
26932
27169
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
26933
27170
|
function version2() {
|
|
26934
|
-
const v = true ? "2.39.
|
|
27171
|
+
const v = true ? "2.39.10" : "unknown";
|
|
26935
27172
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
26936
27173
|
}
|
|
26937
27174
|
|
|
@@ -27059,9 +27296,9 @@ function tryShowSubcommandHelp(cmd, args2) {
|
|
|
27059
27296
|
var _subcommandHelpKeys = Object.keys(HELPS);
|
|
27060
27297
|
|
|
27061
27298
|
// src/lib/updateNotifier.ts
|
|
27062
|
-
var
|
|
27063
|
-
var
|
|
27064
|
-
var
|
|
27299
|
+
var fs42 = __toESM(require("fs"));
|
|
27300
|
+
var os32 = __toESM(require("os"));
|
|
27301
|
+
var path54 = __toESM(require("path"));
|
|
27065
27302
|
var https8 = __toESM(require("https"));
|
|
27066
27303
|
var import_node_child_process12 = require("child_process");
|
|
27067
27304
|
var import_picocolors16 = __toESM(require("picocolors"));
|
|
@@ -27070,12 +27307,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
27070
27307
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
27071
27308
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
27072
27309
|
function cachePath() {
|
|
27073
|
-
const dir =
|
|
27074
|
-
return
|
|
27310
|
+
const dir = path54.join(os32.homedir(), ".codeam");
|
|
27311
|
+
return path54.join(dir, "update-check.json");
|
|
27075
27312
|
}
|
|
27076
27313
|
function readCache() {
|
|
27077
27314
|
try {
|
|
27078
|
-
const raw =
|
|
27315
|
+
const raw = fs42.readFileSync(cachePath(), "utf8");
|
|
27079
27316
|
const parsed = JSON.parse(raw);
|
|
27080
27317
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
27081
27318
|
return parsed;
|
|
@@ -27086,10 +27323,10 @@ function readCache() {
|
|
|
27086
27323
|
function writeCache(cache) {
|
|
27087
27324
|
try {
|
|
27088
27325
|
const file = cachePath();
|
|
27089
|
-
|
|
27326
|
+
fs42.mkdirSync(path54.dirname(file), { recursive: true });
|
|
27090
27327
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
27091
|
-
|
|
27092
|
-
|
|
27328
|
+
fs42.writeFileSync(tmp, JSON.stringify(cache));
|
|
27329
|
+
fs42.renameSync(tmp, file);
|
|
27093
27330
|
} catch {
|
|
27094
27331
|
}
|
|
27095
27332
|
}
|
|
@@ -27163,8 +27400,8 @@ function isLinkedInstall() {
|
|
|
27163
27400
|
timeout: 2e3
|
|
27164
27401
|
}).trim();
|
|
27165
27402
|
if (!root) return false;
|
|
27166
|
-
const pkgPath =
|
|
27167
|
-
return
|
|
27403
|
+
const pkgPath = path54.join(root, PKG_NAME);
|
|
27404
|
+
return fs42.lstatSync(pkgPath).isSymbolicLink();
|
|
27168
27405
|
} catch {
|
|
27169
27406
|
return false;
|
|
27170
27407
|
}
|
|
@@ -27200,7 +27437,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
27200
27437
|
return;
|
|
27201
27438
|
}
|
|
27202
27439
|
try {
|
|
27203
|
-
|
|
27440
|
+
fs42.unlinkSync(cachePath());
|
|
27204
27441
|
} catch {
|
|
27205
27442
|
}
|
|
27206
27443
|
process.stderr.write(` ${import_picocolors16.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -27217,7 +27454,7 @@ function checkForUpdates() {
|
|
|
27217
27454
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
27218
27455
|
if (process.env.CI) return;
|
|
27219
27456
|
if (!process.stdout.isTTY) return;
|
|
27220
|
-
const current = true ? "2.39.
|
|
27457
|
+
const current = true ? "2.39.10" : null;
|
|
27221
27458
|
if (!current) return;
|
|
27222
27459
|
const cache = readCache();
|
|
27223
27460
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|