codeam-cli 2.53.2 → 2.53.3
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 +7 -0
- package/dist/index.js +764 -669
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -202,6 +202,18 @@ function renderToLines(raw) {
|
|
|
202
202
|
// ../../packages/shared/src/models/pricing.ts
|
|
203
203
|
var MODEL_PRICING = {
|
|
204
204
|
// ── Anthropic / Claude ────────────────────────────────────
|
|
205
|
+
// The 4.x rows below cover the model ids actually emitted by the CLI
|
|
206
|
+
// (apps/cli/src/agents/claude/runtime.ts listModels) and the JetBrains
|
|
207
|
+
// fallback catalog (RemoteCommandRouter.kt). Prices are copied from the
|
|
208
|
+
// same-family base rows (claude-opus-4 / claude-sonnet-4 /
|
|
209
|
+
// claude-3-5-haiku) until distinct published rates land.
|
|
210
|
+
"claude-opus-4-7": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
211
|
+
"claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
212
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
213
|
+
// Haiku-tier prices copied from claude-3-5-haiku (closest same-tier
|
|
214
|
+
// sibling in this table) — previously this id matched NO row and was
|
|
215
|
+
// silently billed at sonnet rates via the unknown-model fallback.
|
|
216
|
+
"claude-haiku-4-5": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
205
217
|
"claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
206
218
|
"claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
207
219
|
"claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
@@ -220,6 +232,10 @@ var MODEL_PRICING = {
|
|
|
220
232
|
};
|
|
221
233
|
var MODEL_CONTEXT_WINDOW = {
|
|
222
234
|
// ── Anthropic / Claude ────────────────────────────────────
|
|
235
|
+
"claude-opus-4-7": 1e6,
|
|
236
|
+
"claude-opus-4-6": 1e6,
|
|
237
|
+
"claude-sonnet-4-6": 1e6,
|
|
238
|
+
"claude-haiku-4-5": 2e5,
|
|
223
239
|
"claude-opus-4": 1e6,
|
|
224
240
|
"claude-sonnet-4": 1e6,
|
|
225
241
|
"claude-3-5-sonnet": 2e5,
|
|
@@ -234,18 +250,23 @@ var MODEL_CONTEXT_WINDOW = {
|
|
|
234
250
|
"codex-auto-review": 272e3
|
|
235
251
|
};
|
|
236
252
|
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
237
|
-
function
|
|
238
|
-
|
|
239
|
-
|
|
253
|
+
function longestPrefixMatch(table, model) {
|
|
254
|
+
let best;
|
|
255
|
+
let bestLen = -1;
|
|
256
|
+
for (const [prefix, value] of Object.entries(table)) {
|
|
257
|
+
if (prefix.length > bestLen && model.startsWith(prefix)) {
|
|
258
|
+
best = value;
|
|
259
|
+
bestLen = prefix.length;
|
|
260
|
+
}
|
|
240
261
|
}
|
|
241
|
-
return
|
|
262
|
+
return best;
|
|
263
|
+
}
|
|
264
|
+
function getPricing(model) {
|
|
265
|
+
return longestPrefixMatch(MODEL_PRICING, model) ?? MODEL_PRICING["claude-sonnet-4"];
|
|
242
266
|
}
|
|
243
267
|
function getContextWindow(model) {
|
|
244
268
|
if (!model) return DEFAULT_CONTEXT_WINDOW;
|
|
245
|
-
|
|
246
|
-
if (model.startsWith(prefix)) return size;
|
|
247
|
-
}
|
|
248
|
-
return DEFAULT_CONTEXT_WINDOW;
|
|
269
|
+
return longestPrefixMatch(MODEL_CONTEXT_WINDOW, model) ?? DEFAULT_CONTEXT_WINDOW;
|
|
249
270
|
}
|
|
250
271
|
|
|
251
272
|
// ../../packages/shared/src/agents/registry.ts
|
|
@@ -522,9 +543,9 @@ var _default = makeConfig();
|
|
|
522
543
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
523
544
|
|
|
524
545
|
// src/commands/pair-auto.ts
|
|
525
|
-
var
|
|
526
|
-
var
|
|
527
|
-
var
|
|
546
|
+
var fs46 = __toESM(require("fs"));
|
|
547
|
+
var os39 = __toESM(require("os"));
|
|
548
|
+
var path51 = __toESM(require("path"));
|
|
528
549
|
var import_crypto4 = require("crypto");
|
|
529
550
|
|
|
530
551
|
// src/services/telemetry.service.ts
|
|
@@ -560,8 +581,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
560
581
|
return decodedFile;
|
|
561
582
|
};
|
|
562
583
|
}
|
|
563
|
-
function normalizeWindowsPath(
|
|
564
|
-
return
|
|
584
|
+
function normalizeWindowsPath(path65) {
|
|
585
|
+
return path65.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
565
586
|
}
|
|
566
587
|
|
|
567
588
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3041,9 +3062,9 @@ async function addSourceContext(frames) {
|
|
|
3041
3062
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3042
3063
|
return frames;
|
|
3043
3064
|
}
|
|
3044
|
-
function getContextLinesFromFile(
|
|
3065
|
+
function getContextLinesFromFile(path65, ranges, output) {
|
|
3045
3066
|
return new Promise((resolve7) => {
|
|
3046
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3067
|
+
const stream = (0, import_node_fs.createReadStream)(path65);
|
|
3047
3068
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3048
3069
|
input: stream
|
|
3049
3070
|
});
|
|
@@ -3058,7 +3079,7 @@ function getContextLinesFromFile(path64, ranges, output) {
|
|
|
3058
3079
|
let rangeStart = range[0];
|
|
3059
3080
|
let rangeEnd = range[1];
|
|
3060
3081
|
function onStreamError() {
|
|
3061
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3082
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path65, 1);
|
|
3062
3083
|
lineReaded.close();
|
|
3063
3084
|
lineReaded.removeAllListeners();
|
|
3064
3085
|
destroyStreamAndResolve();
|
|
@@ -3119,8 +3140,8 @@ function clearLineContext(frame) {
|
|
|
3119
3140
|
delete frame.context_line;
|
|
3120
3141
|
delete frame.post_context;
|
|
3121
3142
|
}
|
|
3122
|
-
function shouldSkipContextLinesForFile(
|
|
3123
|
-
return
|
|
3143
|
+
function shouldSkipContextLinesForFile(path65) {
|
|
3144
|
+
return path65.startsWith("node:") || path65.endsWith(".min.js") || path65.endsWith(".min.cjs") || path65.endsWith(".min.mjs") || path65.startsWith("data:");
|
|
3124
3145
|
}
|
|
3125
3146
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3126
3147
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5397,7 +5418,7 @@ function readAnonId() {
|
|
|
5397
5418
|
}
|
|
5398
5419
|
function superProperties() {
|
|
5399
5420
|
return {
|
|
5400
|
-
cliVersion: true ? "2.53.
|
|
5421
|
+
cliVersion: true ? "2.53.3" : "0.0.0-dev",
|
|
5401
5422
|
nodeVersion: process.version,
|
|
5402
5423
|
platform: process.platform,
|
|
5403
5424
|
arch: process.arch,
|
|
@@ -5578,7 +5599,7 @@ var os4 = __toESM(require("os"));
|
|
|
5578
5599
|
// package.json
|
|
5579
5600
|
var package_default = {
|
|
5580
5601
|
name: "codeam-cli",
|
|
5581
|
-
version: "2.53.
|
|
5602
|
+
version: "2.53.3",
|
|
5582
5603
|
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
5604
|
type: "commonjs",
|
|
5584
5605
|
main: "dist/index.js",
|
|
@@ -6106,9 +6127,9 @@ function computePollDelay({ baseMs, failures }) {
|
|
|
6106
6127
|
|
|
6107
6128
|
// src/services/headroom/proxy-supervisor.ts
|
|
6108
6129
|
var import_child_process2 = require("child_process");
|
|
6109
|
-
var
|
|
6110
|
-
var
|
|
6111
|
-
var
|
|
6130
|
+
var fs5 = __toESM(require("fs"));
|
|
6131
|
+
var os6 = __toESM(require("os"));
|
|
6132
|
+
var path5 = __toESM(require("path"));
|
|
6112
6133
|
|
|
6113
6134
|
// src/services/headroom/budget-args.ts
|
|
6114
6135
|
function buildBudgetProxyArgs(env) {
|
|
@@ -6118,6 +6139,74 @@ function buildBudgetProxyArgs(env) {
|
|
|
6118
6139
|
return ["--budget", budget, "--budget-period", period];
|
|
6119
6140
|
}
|
|
6120
6141
|
|
|
6142
|
+
// src/services/headroom/proxy-pid.ts
|
|
6143
|
+
var import_node_child_process = require("child_process");
|
|
6144
|
+
var fs4 = __toESM(require("fs"));
|
|
6145
|
+
var os5 = __toESM(require("os"));
|
|
6146
|
+
var path4 = __toESM(require("path"));
|
|
6147
|
+
function headroomProxyPidfilePath() {
|
|
6148
|
+
return path4.join(os5.homedir(), ".codeam", "headroom-proxy.pid");
|
|
6149
|
+
}
|
|
6150
|
+
function writeHeadroomProxyPidfile(pid) {
|
|
6151
|
+
if (!pid) return;
|
|
6152
|
+
try {
|
|
6153
|
+
const file = headroomProxyPidfilePath();
|
|
6154
|
+
fs4.mkdirSync(path4.dirname(file), { recursive: true, mode: 448 });
|
|
6155
|
+
fs4.writeFileSync(file, `${pid}
|
|
6156
|
+
`, { encoding: "utf8", mode: 384 });
|
|
6157
|
+
} catch {
|
|
6158
|
+
}
|
|
6159
|
+
}
|
|
6160
|
+
function readHeadroomProxyPidfile() {
|
|
6161
|
+
try {
|
|
6162
|
+
const pid = Number(fs4.readFileSync(headroomProxyPidfilePath(), "utf8").trim());
|
|
6163
|
+
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
6164
|
+
} catch {
|
|
6165
|
+
return null;
|
|
6166
|
+
}
|
|
6167
|
+
}
|
|
6168
|
+
function isPidAlive(pid) {
|
|
6169
|
+
try {
|
|
6170
|
+
process.kill(pid, 0);
|
|
6171
|
+
return true;
|
|
6172
|
+
} catch {
|
|
6173
|
+
return false;
|
|
6174
|
+
}
|
|
6175
|
+
}
|
|
6176
|
+
function pkillFallback() {
|
|
6177
|
+
try {
|
|
6178
|
+
const killer = (0, import_node_child_process.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
6179
|
+
detached: true,
|
|
6180
|
+
stdio: "ignore"
|
|
6181
|
+
});
|
|
6182
|
+
killer.once("error", () => {
|
|
6183
|
+
});
|
|
6184
|
+
killer.unref();
|
|
6185
|
+
} catch {
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
function killHeadroomProxy() {
|
|
6189
|
+
const pid = readHeadroomProxyPidfile();
|
|
6190
|
+
if (pid !== null && isPidAlive(pid)) {
|
|
6191
|
+
try {
|
|
6192
|
+
process.kill(pid, "SIGTERM");
|
|
6193
|
+
try {
|
|
6194
|
+
fs4.rmSync(headroomProxyPidfilePath(), { force: true });
|
|
6195
|
+
} catch {
|
|
6196
|
+
}
|
|
6197
|
+
return;
|
|
6198
|
+
} catch {
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
if (pid !== null) {
|
|
6202
|
+
try {
|
|
6203
|
+
fs4.rmSync(headroomProxyPidfilePath(), { force: true });
|
|
6204
|
+
} catch {
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
pkillFallback();
|
|
6208
|
+
}
|
|
6209
|
+
|
|
6121
6210
|
// src/services/headroom/proxy-supervisor.ts
|
|
6122
6211
|
async function ensureHeadroomProxy(deps) {
|
|
6123
6212
|
if (!deps.isConfigured()) return "skip";
|
|
@@ -6132,17 +6221,17 @@ async function ensureHeadroomProxy(deps) {
|
|
|
6132
6221
|
deps.spawnProxy();
|
|
6133
6222
|
return "respawned";
|
|
6134
6223
|
}
|
|
6135
|
-
function isHeadroomConfiguredReal(homeDir2 =
|
|
6224
|
+
function isHeadroomConfiguredReal(homeDir2 = os6.homedir()) {
|
|
6136
6225
|
if (process.env.HEADROOM_ENABLED === "1") return true;
|
|
6137
|
-
const csEnv =
|
|
6226
|
+
const csEnv = path5.join(homeDir2, ".codeam", "codespace-env.json");
|
|
6138
6227
|
try {
|
|
6139
|
-
const j2 = JSON.parse(
|
|
6228
|
+
const j2 = JSON.parse(fs5.readFileSync(csEnv, "utf8"));
|
|
6140
6229
|
if (j2.HEADROOM_ENABLED === "1" || j2.HEADROOM_ENABLED === 1) return true;
|
|
6141
6230
|
} catch {
|
|
6142
6231
|
}
|
|
6143
|
-
const settings =
|
|
6232
|
+
const settings = path5.join(homeDir2, ".claude", "settings.json");
|
|
6144
6233
|
try {
|
|
6145
|
-
if (
|
|
6234
|
+
if (fs5.readFileSync(settings, "utf8").includes("127.0.0.1:8787")) return true;
|
|
6146
6235
|
} catch {
|
|
6147
6236
|
}
|
|
6148
6237
|
return false;
|
|
@@ -6176,6 +6265,7 @@ function spawnProxyReal() {
|
|
|
6176
6265
|
log.warn("headroom-supervisor", `respawn error (best-effort): ${e.message}`);
|
|
6177
6266
|
});
|
|
6178
6267
|
proxy.unref();
|
|
6268
|
+
writeHeadroomProxyPidfile(proxy.pid);
|
|
6179
6269
|
} catch (e) {
|
|
6180
6270
|
log.warn(
|
|
6181
6271
|
"headroom-supervisor",
|
|
@@ -6543,7 +6633,7 @@ var CommandRelayService = class {
|
|
|
6543
6633
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
6544
6634
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6545
6635
|
// pair/reconnect). Older backends ignore the extra field.
|
|
6546
|
-
..."2.53.
|
|
6636
|
+
..."2.53.3" ? { ideVersion: "2.53.3" } : {}
|
|
6547
6637
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6548
6638
|
}
|
|
6549
6639
|
/**
|
|
@@ -6609,9 +6699,9 @@ var CommandRelayService = class {
|
|
|
6609
6699
|
|
|
6610
6700
|
// src/services/file-watcher.service.ts
|
|
6611
6701
|
var import_child_process3 = require("child_process");
|
|
6612
|
-
var
|
|
6613
|
-
var
|
|
6614
|
-
var
|
|
6702
|
+
var fs6 = __toESM(require("fs"));
|
|
6703
|
+
var os7 = __toESM(require("os"));
|
|
6704
|
+
var path6 = __toESM(require("path"));
|
|
6615
6705
|
var import_ignore = __toESM(require("ignore"));
|
|
6616
6706
|
|
|
6617
6707
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -6770,10 +6860,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
6770
6860
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
6771
6861
|
/[\\/]Templates([\\/]|$)/i
|
|
6772
6862
|
];
|
|
6773
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
6863
|
+
function isUnsafeWindowsWatchRoot(dir, homedir36) {
|
|
6774
6864
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
6775
6865
|
const cwd = norm(dir);
|
|
6776
|
-
const home = norm(
|
|
6866
|
+
const home = norm(homedir36);
|
|
6777
6867
|
if (cwd === home) return true;
|
|
6778
6868
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
6779
6869
|
const sysRoots = [
|
|
@@ -6803,18 +6893,18 @@ var _findGitRootSeam = {
|
|
|
6803
6893
|
resolve: _defaultFindGitRoot
|
|
6804
6894
|
};
|
|
6805
6895
|
function _defaultFindGitRoot(startDir) {
|
|
6806
|
-
let dir =
|
|
6896
|
+
let dir = path6.resolve(startDir);
|
|
6807
6897
|
const seen = /* @__PURE__ */ new Set();
|
|
6808
6898
|
for (let i = 0; i < 256; i++) {
|
|
6809
6899
|
if (seen.has(dir)) return null;
|
|
6810
6900
|
seen.add(dir);
|
|
6811
6901
|
try {
|
|
6812
|
-
const gitPath =
|
|
6813
|
-
const stat3 =
|
|
6902
|
+
const gitPath = path6.join(dir, ".git");
|
|
6903
|
+
const stat3 = fs6.statSync(gitPath, { throwIfNoEntry: false });
|
|
6814
6904
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
6815
6905
|
} catch {
|
|
6816
6906
|
}
|
|
6817
|
-
const parent =
|
|
6907
|
+
const parent = path6.dirname(dir);
|
|
6818
6908
|
if (parent === dir) return null;
|
|
6819
6909
|
dir = parent;
|
|
6820
6910
|
}
|
|
@@ -6872,7 +6962,7 @@ var FileWatcherService = class {
|
|
|
6872
6962
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
6873
6963
|
}
|
|
6874
6964
|
const isWin = process.platform === "win32";
|
|
6875
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
6965
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os7.homedir())) {
|
|
6876
6966
|
log.warn(
|
|
6877
6967
|
"fileWatcher",
|
|
6878
6968
|
`refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
|
|
@@ -7059,7 +7149,7 @@ var FileWatcherService = class {
|
|
|
7059
7149
|
}
|
|
7060
7150
|
async emitForFile(absPath, changeType) {
|
|
7061
7151
|
if (this.stopped) return;
|
|
7062
|
-
const fileDir =
|
|
7152
|
+
const fileDir = path6.dirname(absPath);
|
|
7063
7153
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
7064
7154
|
if (gitRoot === void 0) {
|
|
7065
7155
|
gitRoot = findGitRoot(fileDir);
|
|
@@ -7072,19 +7162,19 @@ var FileWatcherService = class {
|
|
|
7072
7162
|
);
|
|
7073
7163
|
return;
|
|
7074
7164
|
}
|
|
7075
|
-
const relPathInRepo =
|
|
7165
|
+
const relPathInRepo = path6.relative(gitRoot, absPath);
|
|
7076
7166
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
7077
7167
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
7078
7168
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
7079
7169
|
log.trace(
|
|
7080
7170
|
"fileWatcher",
|
|
7081
|
-
`${relPathInRepo} ignored by ${
|
|
7171
|
+
`${relPathInRepo} ignored by ${path6.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
7082
7172
|
);
|
|
7083
7173
|
return;
|
|
7084
7174
|
}
|
|
7085
7175
|
this.opts.onRepoDirty?.(gitRoot);
|
|
7086
|
-
const repoPath =
|
|
7087
|
-
const repoName =
|
|
7176
|
+
const repoPath = path6.relative(this.opts.workingDir, gitRoot);
|
|
7177
|
+
const repoName = path6.basename(gitRoot);
|
|
7088
7178
|
let diffText = "";
|
|
7089
7179
|
let fileStatus = "modified";
|
|
7090
7180
|
if (changeType === "unlink") {
|
|
@@ -7259,7 +7349,7 @@ var FileWatcherService = class {
|
|
|
7259
7349
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
7260
7350
|
let entries;
|
|
7261
7351
|
try {
|
|
7262
|
-
entries =
|
|
7352
|
+
entries = fs6.readdirSync(dir, { withFileTypes: true });
|
|
7263
7353
|
} catch {
|
|
7264
7354
|
return;
|
|
7265
7355
|
}
|
|
@@ -7268,16 +7358,16 @@ var FileWatcherService = class {
|
|
|
7268
7358
|
);
|
|
7269
7359
|
if (gitignoreEntry) {
|
|
7270
7360
|
try {
|
|
7271
|
-
const body =
|
|
7272
|
-
const rel =
|
|
7361
|
+
const body = fs6.readFileSync(path6.join(dir, ".gitignore"), "utf8");
|
|
7362
|
+
const rel = path6.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
7273
7363
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
7274
7364
|
const trimmed = line.trim();
|
|
7275
7365
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
7276
7366
|
if (!rel) return line;
|
|
7277
7367
|
if (trimmed.startsWith("!")) {
|
|
7278
|
-
return "!" +
|
|
7368
|
+
return "!" + path6.posix.join(rel, trimmed.slice(1));
|
|
7279
7369
|
}
|
|
7280
|
-
return
|
|
7370
|
+
return path6.posix.join(rel, trimmed);
|
|
7281
7371
|
}).join("\n");
|
|
7282
7372
|
matcher.add(prefixed);
|
|
7283
7373
|
} catch {
|
|
@@ -7286,7 +7376,7 @@ var FileWatcherService = class {
|
|
|
7286
7376
|
for (const entry of entries) {
|
|
7287
7377
|
if (!entry.isDirectory()) continue;
|
|
7288
7378
|
if (entry.name === ".git") continue;
|
|
7289
|
-
const childAbs =
|
|
7379
|
+
const childAbs = path6.join(dir, entry.name);
|
|
7290
7380
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
7291
7381
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
7292
7382
|
}
|
|
@@ -7917,9 +8007,9 @@ function closeAllTerminals() {
|
|
|
7917
8007
|
}
|
|
7918
8008
|
|
|
7919
8009
|
// src/commands/start/handlers.ts
|
|
7920
|
-
var
|
|
7921
|
-
var
|
|
7922
|
-
var
|
|
8010
|
+
var fs45 = __toESM(require("fs"));
|
|
8011
|
+
var os38 = __toESM(require("os"));
|
|
8012
|
+
var path50 = __toESM(require("path"));
|
|
7923
8013
|
var import_crypto3 = require("crypto");
|
|
7924
8014
|
var import_child_process22 = require("child_process");
|
|
7925
8015
|
var import_which2 = __toESM(require("which"));
|
|
@@ -8072,8 +8162,8 @@ function parsePayload2(schema, raw) {
|
|
|
8072
8162
|
}
|
|
8073
8163
|
|
|
8074
8164
|
// src/services/file-ops.service.ts
|
|
8075
|
-
var
|
|
8076
|
-
var
|
|
8165
|
+
var fs7 = __toESM(require("fs/promises"));
|
|
8166
|
+
var path8 = __toESM(require("path"));
|
|
8077
8167
|
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
8078
8168
|
var MAX_WALK_DEPTH = 6;
|
|
8079
8169
|
var MAX_VISITED_DIRS = 5e3;
|
|
@@ -8108,12 +8198,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
|
|
|
8108
8198
|
"__pycache__"
|
|
8109
8199
|
]);
|
|
8110
8200
|
function isUnder(parent, candidate) {
|
|
8111
|
-
const rel =
|
|
8112
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
8201
|
+
const rel = path8.relative(parent, candidate);
|
|
8202
|
+
return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
|
|
8113
8203
|
}
|
|
8114
8204
|
async function isExistingFile(absPath) {
|
|
8115
8205
|
try {
|
|
8116
|
-
const stat3 = await
|
|
8206
|
+
const stat3 = await fs7.stat(absPath);
|
|
8117
8207
|
return stat3.isFile();
|
|
8118
8208
|
} catch {
|
|
8119
8209
|
return false;
|
|
@@ -8126,13 +8216,13 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
8126
8216
|
ctx.visited++;
|
|
8127
8217
|
let entries = [];
|
|
8128
8218
|
try {
|
|
8129
|
-
entries = await
|
|
8219
|
+
entries = await fs7.readdir(dir, { withFileTypes: true });
|
|
8130
8220
|
} catch {
|
|
8131
8221
|
return;
|
|
8132
8222
|
}
|
|
8133
8223
|
for (const e of entries) {
|
|
8134
8224
|
if (!e.isFile()) continue;
|
|
8135
|
-
const full =
|
|
8225
|
+
const full = path8.join(dir, e.name);
|
|
8136
8226
|
if (needleVariants.some((needle) => full.endsWith(needle))) {
|
|
8137
8227
|
ctx.matches.push(full);
|
|
8138
8228
|
if (ctx.matches.length >= ctx.cap) return;
|
|
@@ -8142,21 +8232,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
8142
8232
|
if (!e.isDirectory()) continue;
|
|
8143
8233
|
if (SUBDIR_IGNORE.has(e.name)) continue;
|
|
8144
8234
|
if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
|
|
8145
|
-
await walkForSuffix(
|
|
8235
|
+
await walkForSuffix(path8.join(dir, e.name), needleVariants, depth + 1, ctx);
|
|
8146
8236
|
if (ctx.matches.length >= ctx.cap) return;
|
|
8147
8237
|
}
|
|
8148
8238
|
}
|
|
8149
8239
|
async function findFile(rawPath) {
|
|
8150
8240
|
const cwd = process.cwd();
|
|
8151
|
-
if (
|
|
8152
|
-
const abs =
|
|
8241
|
+
if (path8.isAbsolute(rawPath)) {
|
|
8242
|
+
const abs = path8.normalize(rawPath);
|
|
8153
8243
|
if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
|
|
8154
8244
|
}
|
|
8155
|
-
const direct =
|
|
8245
|
+
const direct = path8.resolve(cwd, rawPath);
|
|
8156
8246
|
if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
|
|
8157
|
-
const normalized =
|
|
8247
|
+
const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
|
|
8158
8248
|
const needles = [
|
|
8159
|
-
`${
|
|
8249
|
+
`${path8.sep}${normalized}`,
|
|
8160
8250
|
`/${normalized}`
|
|
8161
8251
|
].filter((v, i, a) => a.indexOf(v) === i);
|
|
8162
8252
|
const ctx = { visited: 0, matches: [], cap: 16 };
|
|
@@ -8170,7 +8260,7 @@ async function findWriteTarget(rawPath) {
|
|
|
8170
8260
|
const found = await findFile(rawPath);
|
|
8171
8261
|
if (found) return found;
|
|
8172
8262
|
const cwd = process.cwd();
|
|
8173
|
-
const fallback =
|
|
8263
|
+
const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
|
|
8174
8264
|
if (!isUnder(cwd, fallback)) return null;
|
|
8175
8265
|
return fallback;
|
|
8176
8266
|
}
|
|
@@ -8187,11 +8277,11 @@ async function readProjectFile(rawPath) {
|
|
|
8187
8277
|
if (!abs) {
|
|
8188
8278
|
return { error: `File not found in the project tree: ${rawPath}` };
|
|
8189
8279
|
}
|
|
8190
|
-
const stat3 = await
|
|
8280
|
+
const stat3 = await fs7.stat(abs);
|
|
8191
8281
|
if (stat3.size > MAX_FILE_BYTES) {
|
|
8192
8282
|
return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
|
|
8193
8283
|
}
|
|
8194
|
-
const buf = await
|
|
8284
|
+
const buf = await fs7.readFile(abs);
|
|
8195
8285
|
if (looksBinary(buf)) {
|
|
8196
8286
|
return { error: "Binary file \u2014 refusing to open in a code editor." };
|
|
8197
8287
|
}
|
|
@@ -8210,8 +8300,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
8210
8300
|
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
|
|
8211
8301
|
return { error: "Content too large." };
|
|
8212
8302
|
}
|
|
8213
|
-
await
|
|
8214
|
-
await
|
|
8303
|
+
await fs7.mkdir(path8.dirname(abs), { recursive: true });
|
|
8304
|
+
await fs7.writeFile(abs, content, "utf-8");
|
|
8215
8305
|
return { ok: true };
|
|
8216
8306
|
} catch (e) {
|
|
8217
8307
|
const msg = e instanceof Error ? e.message : "Write failed";
|
|
@@ -8222,8 +8312,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
8222
8312
|
// src/services/project-ops.service.ts
|
|
8223
8313
|
var import_child_process5 = require("child_process");
|
|
8224
8314
|
var import_util = require("util");
|
|
8225
|
-
var
|
|
8226
|
-
var
|
|
8315
|
+
var fs8 = __toESM(require("fs/promises"));
|
|
8316
|
+
var path9 = __toESM(require("path"));
|
|
8227
8317
|
var execFileP = (0, import_util.promisify)(import_child_process5.execFile);
|
|
8228
8318
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
8229
8319
|
"node_modules",
|
|
@@ -8271,7 +8361,7 @@ async function listProjectFiles(opts = {}) {
|
|
|
8271
8361
|
}
|
|
8272
8362
|
let entries = [];
|
|
8273
8363
|
try {
|
|
8274
|
-
entries = await
|
|
8364
|
+
entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
8275
8365
|
} catch {
|
|
8276
8366
|
return;
|
|
8277
8367
|
}
|
|
@@ -8281,18 +8371,18 @@ async function listProjectFiles(opts = {}) {
|
|
|
8281
8371
|
return;
|
|
8282
8372
|
}
|
|
8283
8373
|
if (PROJECT_IGNORE.has(e.name)) continue;
|
|
8284
|
-
const full =
|
|
8374
|
+
const full = path9.join(dir, e.name);
|
|
8285
8375
|
if (e.isDirectory()) {
|
|
8286
8376
|
if (depth >= 12) continue;
|
|
8287
8377
|
await walk(full, depth + 1);
|
|
8288
8378
|
} else if (e.isFile()) {
|
|
8289
|
-
const rel =
|
|
8379
|
+
const rel = path9.relative(root, full);
|
|
8290
8380
|
if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
|
|
8291
8381
|
continue;
|
|
8292
8382
|
}
|
|
8293
8383
|
let size = 0;
|
|
8294
8384
|
try {
|
|
8295
|
-
const st3 = await
|
|
8385
|
+
const st3 = await fs8.stat(full);
|
|
8296
8386
|
size = st3.size;
|
|
8297
8387
|
} catch {
|
|
8298
8388
|
}
|
|
@@ -8394,8 +8484,8 @@ async function gitStatus(cwd) {
|
|
|
8394
8484
|
let hasMergeInProgress = false;
|
|
8395
8485
|
try {
|
|
8396
8486
|
const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
|
|
8397
|
-
const mergeHead =
|
|
8398
|
-
await
|
|
8487
|
+
const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
|
|
8488
|
+
await fs8.access(mergeHead);
|
|
8399
8489
|
hasMergeInProgress = true;
|
|
8400
8490
|
} catch {
|
|
8401
8491
|
}
|
|
@@ -8541,7 +8631,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
8541
8631
|
}
|
|
8542
8632
|
let content = "";
|
|
8543
8633
|
try {
|
|
8544
|
-
content = await
|
|
8634
|
+
content = await fs8.readFile(path9.join(cwd, f.path), "utf8");
|
|
8545
8635
|
} catch {
|
|
8546
8636
|
continue;
|
|
8547
8637
|
}
|
|
@@ -8618,14 +8708,14 @@ function formatRemaining(expiresAt) {
|
|
|
8618
8708
|
|
|
8619
8709
|
// src/services/apply-file-review.service.ts
|
|
8620
8710
|
var import_child_process6 = require("child_process");
|
|
8621
|
-
var
|
|
8622
|
-
var
|
|
8711
|
+
var fs9 = __toESM(require("fs"));
|
|
8712
|
+
var path10 = __toESM(require("path"));
|
|
8623
8713
|
async function applyFileReview(workingDir, filePath, action) {
|
|
8624
|
-
if (filePath.includes("..") ||
|
|
8714
|
+
if (filePath.includes("..") || path10.isAbsolute(filePath)) {
|
|
8625
8715
|
return { ok: false, action, filePath, error: "invalid file path" };
|
|
8626
8716
|
}
|
|
8627
|
-
const absFile =
|
|
8628
|
-
const repoRoot = findGitRoot2(
|
|
8717
|
+
const absFile = path10.resolve(workingDir, filePath);
|
|
8718
|
+
const repoRoot = findGitRoot2(path10.dirname(absFile));
|
|
8629
8719
|
if (!repoRoot) {
|
|
8630
8720
|
return {
|
|
8631
8721
|
ok: false,
|
|
@@ -8634,7 +8724,7 @@ async function applyFileReview(workingDir, filePath, action) {
|
|
|
8634
8724
|
error: `no enclosing git repo for ${filePath}`
|
|
8635
8725
|
};
|
|
8636
8726
|
}
|
|
8637
|
-
const relInRepo =
|
|
8727
|
+
const relInRepo = path10.relative(repoRoot, absFile);
|
|
8638
8728
|
if (!relInRepo || relInRepo.startsWith("..")) {
|
|
8639
8729
|
return { ok: false, action, filePath, error: "path escapes repo root" };
|
|
8640
8730
|
}
|
|
@@ -8683,17 +8773,17 @@ function runGit2(cwd, args2) {
|
|
|
8683
8773
|
});
|
|
8684
8774
|
}
|
|
8685
8775
|
function findGitRoot2(startDir) {
|
|
8686
|
-
let dir =
|
|
8776
|
+
let dir = path10.resolve(startDir);
|
|
8687
8777
|
const seen = /* @__PURE__ */ new Set();
|
|
8688
8778
|
for (let i = 0; i < 256; i++) {
|
|
8689
8779
|
if (seen.has(dir)) return null;
|
|
8690
8780
|
seen.add(dir);
|
|
8691
8781
|
try {
|
|
8692
|
-
const stat3 =
|
|
8782
|
+
const stat3 = fs9.statSync(path10.join(dir, ".git"), { throwIfNoEntry: false });
|
|
8693
8783
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
8694
8784
|
} catch {
|
|
8695
8785
|
}
|
|
8696
|
-
const parent =
|
|
8786
|
+
const parent = path10.dirname(dir);
|
|
8697
8787
|
if (parent === dir) return null;
|
|
8698
8788
|
dir = parent;
|
|
8699
8789
|
}
|
|
@@ -8702,8 +8792,8 @@ function findGitRoot2(startDir) {
|
|
|
8702
8792
|
|
|
8703
8793
|
// src/commands/link.ts
|
|
8704
8794
|
var import_node_crypto5 = require("crypto");
|
|
8705
|
-
var
|
|
8706
|
-
var
|
|
8795
|
+
var fs27 = __toESM(require("fs"));
|
|
8796
|
+
var path32 = __toESM(require("path"));
|
|
8707
8797
|
var import_chokidar = __toESM(require("chokidar"));
|
|
8708
8798
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
8709
8799
|
|
|
@@ -10758,19 +10848,19 @@ function parseFrame(frame, dispatch) {
|
|
|
10758
10848
|
}
|
|
10759
10849
|
|
|
10760
10850
|
// src/os/posix.ts
|
|
10761
|
-
var
|
|
10762
|
-
var
|
|
10763
|
-
var
|
|
10851
|
+
var fs11 = __toESM(require("fs"));
|
|
10852
|
+
var os9 = __toESM(require("os"));
|
|
10853
|
+
var path13 = __toESM(require("path"));
|
|
10764
10854
|
var import_node_crypto2 = require("crypto");
|
|
10765
10855
|
|
|
10766
10856
|
// src/os/strategy.ts
|
|
10767
|
-
var
|
|
10857
|
+
var path11 = __toESM(require("path"));
|
|
10768
10858
|
function findInPathFor(name, opts) {
|
|
10769
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
10859
|
+
const dirs = (process.env.PATH ?? "").split(path11.delimiter).filter(Boolean);
|
|
10770
10860
|
const candidates = opts.candidates(name);
|
|
10771
10861
|
for (const dir of dirs) {
|
|
10772
10862
|
for (const candidate of candidates) {
|
|
10773
|
-
const full =
|
|
10863
|
+
const full = path11.join(dir, candidate);
|
|
10774
10864
|
try {
|
|
10775
10865
|
opts.accessSync(full, opts.accessFlag);
|
|
10776
10866
|
return full;
|
|
@@ -10783,9 +10873,9 @@ function findInPathFor(name, opts) {
|
|
|
10783
10873
|
|
|
10784
10874
|
// src/services/pty/unix.strategy.ts
|
|
10785
10875
|
var import_child_process7 = require("child_process");
|
|
10786
|
-
var
|
|
10787
|
-
var
|
|
10788
|
-
var
|
|
10876
|
+
var fs10 = __toESM(require("fs"));
|
|
10877
|
+
var os8 = __toESM(require("os"));
|
|
10878
|
+
var path12 = __toESM(require("path"));
|
|
10789
10879
|
|
|
10790
10880
|
// src/services/pty/types.ts
|
|
10791
10881
|
function findInPath(name) {
|
|
@@ -10867,8 +10957,8 @@ var UnixPtyStrategy = class {
|
|
|
10867
10957
|
}
|
|
10868
10958
|
const cols = process.stdout.columns || 220;
|
|
10869
10959
|
const rows = process.stdout.rows || 50;
|
|
10870
|
-
this.helperPath =
|
|
10871
|
-
|
|
10960
|
+
this.helperPath = path12.join(os8.tmpdir(), "codeam-pty-helper.py");
|
|
10961
|
+
fs10.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
|
|
10872
10962
|
this.proc = (0, import_child_process7.spawn)(python, [this.helperPath, cmd, ...args2], {
|
|
10873
10963
|
stdio: ["pipe", "pipe", "inherit"],
|
|
10874
10964
|
cwd,
|
|
@@ -10997,7 +11087,7 @@ var UnixPtyStrategy = class {
|
|
|
10997
11087
|
removeTempFile() {
|
|
10998
11088
|
if (this.helperPath) {
|
|
10999
11089
|
try {
|
|
11000
|
-
|
|
11090
|
+
fs10.unlinkSync(this.helperPath);
|
|
11001
11091
|
} catch {
|
|
11002
11092
|
}
|
|
11003
11093
|
this.helperPath = null;
|
|
@@ -11008,11 +11098,11 @@ var UnixPtyStrategy = class {
|
|
|
11008
11098
|
// src/os/posix.ts
|
|
11009
11099
|
var PosixOsStrategy = class {
|
|
11010
11100
|
homeDir() {
|
|
11011
|
-
return
|
|
11101
|
+
return os9.homedir();
|
|
11012
11102
|
}
|
|
11013
11103
|
scratchPath(prefix) {
|
|
11014
11104
|
const tag = `${process.pid}-${(0, import_node_crypto2.randomBytes)(4).toString("hex")}`;
|
|
11015
|
-
return
|
|
11105
|
+
return path13.join(os9.tmpdir(), `${prefix}-${tag}`);
|
|
11016
11106
|
}
|
|
11017
11107
|
devNull() {
|
|
11018
11108
|
return "/dev/null";
|
|
@@ -11020,8 +11110,8 @@ var PosixOsStrategy = class {
|
|
|
11020
11110
|
findInPath(name) {
|
|
11021
11111
|
return findInPathFor(name, {
|
|
11022
11112
|
candidates: () => [name],
|
|
11023
|
-
accessFlag:
|
|
11024
|
-
accessSync:
|
|
11113
|
+
accessFlag: fs11.constants.X_OK,
|
|
11114
|
+
accessSync: fs11.accessSync
|
|
11025
11115
|
});
|
|
11026
11116
|
}
|
|
11027
11117
|
augmentPath(dirs) {
|
|
@@ -11049,15 +11139,15 @@ var LinuxOsStrategy = class extends PosixOsStrategy {
|
|
|
11049
11139
|
};
|
|
11050
11140
|
|
|
11051
11141
|
// src/os/win32.ts
|
|
11052
|
-
var
|
|
11053
|
-
var
|
|
11054
|
-
var
|
|
11142
|
+
var fs12 = __toESM(require("fs"));
|
|
11143
|
+
var os10 = __toESM(require("os"));
|
|
11144
|
+
var path15 = __toESM(require("path"));
|
|
11055
11145
|
var import_node_crypto3 = require("crypto");
|
|
11056
11146
|
|
|
11057
11147
|
// src/services/pty/windows-conpty.strategy.ts
|
|
11058
|
-
var
|
|
11148
|
+
var path14 = __toESM(require("path"));
|
|
11059
11149
|
function loadNodePty2() {
|
|
11060
|
-
const vendoredPath =
|
|
11150
|
+
const vendoredPath = path14.join(__dirname, "vendor", "node-pty");
|
|
11061
11151
|
try {
|
|
11062
11152
|
return require(vendoredPath);
|
|
11063
11153
|
} catch (vendorErr) {
|
|
@@ -11243,25 +11333,25 @@ var WINDOWS_EXEC_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
|
|
|
11243
11333
|
var Win32OsStrategy = class {
|
|
11244
11334
|
id = "win32";
|
|
11245
11335
|
homeDir() {
|
|
11246
|
-
return
|
|
11336
|
+
return os10.homedir();
|
|
11247
11337
|
}
|
|
11248
11338
|
scratchPath(prefix) {
|
|
11249
11339
|
const tag = `${process.pid}-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
|
|
11250
|
-
return
|
|
11340
|
+
return path15.join(os10.tmpdir(), `${prefix}-${tag}`);
|
|
11251
11341
|
}
|
|
11252
11342
|
devNull() {
|
|
11253
11343
|
return "NUL";
|
|
11254
11344
|
}
|
|
11255
11345
|
findInPath(name) {
|
|
11256
|
-
const hasExt =
|
|
11346
|
+
const hasExt = path15.extname(name).length > 0;
|
|
11257
11347
|
return findInPathFor(name, {
|
|
11258
11348
|
candidates: (n) => hasExt ? [n] : [...WINDOWS_EXEC_EXTS.map((ext) => `${n}${ext}`), n],
|
|
11259
11349
|
// Windows has no Unix execute bit; presence + matching extension
|
|
11260
11350
|
// IS the executability check. X_OK on Windows is a no-op alias
|
|
11261
11351
|
// for F_OK at the libuv layer anyway, but F_OK makes intent
|
|
11262
11352
|
// explicit.
|
|
11263
|
-
accessFlag:
|
|
11264
|
-
accessSync:
|
|
11353
|
+
accessFlag: fs12.constants.F_OK,
|
|
11354
|
+
accessSync: fs12.accessSync
|
|
11265
11355
|
});
|
|
11266
11356
|
}
|
|
11267
11357
|
augmentPath(dirs) {
|
|
@@ -11298,7 +11388,7 @@ var Win32OsStrategy = class {
|
|
|
11298
11388
|
return `"${escaped.replace(/[&|^<>()%!]/g, "^$&")}"`;
|
|
11299
11389
|
}
|
|
11300
11390
|
buildLaunch(binaryPath, extraArgs = []) {
|
|
11301
|
-
const ext =
|
|
11391
|
+
const ext = path15.extname(binaryPath).toLowerCase();
|
|
11302
11392
|
if (ext === ".cmd" || ext === ".bat") {
|
|
11303
11393
|
return { cmd: "cmd.exe", args: ["/c", binaryPath, ...extraArgs] };
|
|
11304
11394
|
}
|
|
@@ -11353,28 +11443,28 @@ function buildForPlatform(platform3) {
|
|
|
11353
11443
|
var import_node_crypto4 = require("crypto");
|
|
11354
11444
|
|
|
11355
11445
|
// src/agents/claude/resolver.ts
|
|
11356
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11357
|
-
const found =
|
|
11446
|
+
function buildClaudeLaunch(extraArgs = [], os45 = createOsStrategy()) {
|
|
11447
|
+
const found = os45.findInPath("claude") ?? os45.findInPath("claude-code");
|
|
11358
11448
|
if (!found) return null;
|
|
11359
|
-
return
|
|
11449
|
+
return os45.buildLaunch(found, extraArgs);
|
|
11360
11450
|
}
|
|
11361
11451
|
|
|
11362
11452
|
// src/agents/claude/installer.ts
|
|
11363
11453
|
var import_child_process9 = require("child_process");
|
|
11364
|
-
var
|
|
11365
|
-
var
|
|
11454
|
+
var path16 = __toESM(require("path"));
|
|
11455
|
+
var os11 = __toESM(require("os"));
|
|
11366
11456
|
function probeInstallDirs() {
|
|
11367
|
-
const home =
|
|
11457
|
+
const home = os11.homedir();
|
|
11368
11458
|
if (process.platform === "win32") {
|
|
11369
11459
|
return [
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11460
|
+
path16.join(home, ".claude", "local"),
|
|
11461
|
+
path16.join(home, "AppData", "Local", "AnthropicClaude"),
|
|
11462
|
+
path16.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
|
|
11373
11463
|
];
|
|
11374
11464
|
}
|
|
11375
11465
|
return [
|
|
11376
|
-
|
|
11377
|
-
|
|
11466
|
+
path16.join(home, ".local", "bin"),
|
|
11467
|
+
path16.join(home, ".claude", "local"),
|
|
11378
11468
|
"/usr/local/bin"
|
|
11379
11469
|
];
|
|
11380
11470
|
}
|
|
@@ -11383,7 +11473,7 @@ function isAvailable() {
|
|
|
11383
11473
|
}
|
|
11384
11474
|
function augmentPath() {
|
|
11385
11475
|
const dirs = probeInstallDirs();
|
|
11386
|
-
const sep7 =
|
|
11476
|
+
const sep7 = path16.delimiter;
|
|
11387
11477
|
const current = process.env.PATH ?? "";
|
|
11388
11478
|
const existing = new Set(current.split(sep7).filter(Boolean));
|
|
11389
11479
|
const additions = dirs.filter((d3) => !existing.has(d3));
|
|
@@ -11441,15 +11531,15 @@ async function ensureClaudeInstalled() {
|
|
|
11441
11531
|
}
|
|
11442
11532
|
|
|
11443
11533
|
// src/agents/claude/link.ts
|
|
11444
|
-
var
|
|
11534
|
+
var import_node_child_process3 = require("child_process");
|
|
11445
11535
|
|
|
11446
11536
|
// src/agents/claude/local-token.ts
|
|
11447
|
-
var
|
|
11448
|
-
var
|
|
11449
|
-
var
|
|
11450
|
-
var
|
|
11537
|
+
var import_node_child_process2 = require("child_process");
|
|
11538
|
+
var fs13 = __toESM(require("fs"));
|
|
11539
|
+
var os12 = __toESM(require("os"));
|
|
11540
|
+
var path17 = __toESM(require("path"));
|
|
11451
11541
|
var import_node_util3 = require("util");
|
|
11452
|
-
var execFileP2 = (0, import_node_util3.promisify)(
|
|
11542
|
+
var execFileP2 = (0, import_node_util3.promisify)(import_node_child_process2.execFile);
|
|
11453
11543
|
var KEYCHAIN_SERVICE_NAMES = [
|
|
11454
11544
|
"Claude Code-credentials",
|
|
11455
11545
|
"claude-code-credentials",
|
|
@@ -11457,17 +11547,17 @@ var KEYCHAIN_SERVICE_NAMES = [
|
|
|
11457
11547
|
"Anthropic Claude"
|
|
11458
11548
|
];
|
|
11459
11549
|
function claudeCredentialsPaths() {
|
|
11460
|
-
const home =
|
|
11550
|
+
const home = os12.homedir();
|
|
11461
11551
|
return [
|
|
11462
|
-
|
|
11463
|
-
|
|
11552
|
+
path17.join(home, ".claude", ".credentials.json"),
|
|
11553
|
+
path17.join(home, ".config", "claude", ".credentials.json")
|
|
11464
11554
|
];
|
|
11465
11555
|
}
|
|
11466
11556
|
async function extractLocalClaudeToken() {
|
|
11467
11557
|
const agentState = readClaudeAgentState();
|
|
11468
11558
|
for (const flat of claudeCredentialsPaths()) {
|
|
11469
|
-
if (!
|
|
11470
|
-
const credential =
|
|
11559
|
+
if (!fs13.existsSync(flat)) continue;
|
|
11560
|
+
const credential = fs13.readFileSync(flat, "utf8").trim();
|
|
11471
11561
|
if (credential.length > 0) {
|
|
11472
11562
|
return { method: "oauth", credential, source: "flat-file", agentState };
|
|
11473
11563
|
}
|
|
@@ -11492,10 +11582,10 @@ async function extractLocalClaudeToken() {
|
|
|
11492
11582
|
}
|
|
11493
11583
|
function readClaudeAgentState() {
|
|
11494
11584
|
const STATE_MAX_BYTES = 256 * 1024;
|
|
11495
|
-
const candidate =
|
|
11585
|
+
const candidate = path17.join(os12.homedir(), ".claude.json");
|
|
11496
11586
|
try {
|
|
11497
|
-
if (!
|
|
11498
|
-
const buf =
|
|
11587
|
+
if (!fs13.existsSync(candidate)) return void 0;
|
|
11588
|
+
const buf = fs13.readFileSync(candidate);
|
|
11499
11589
|
if (buf.length === 0 || buf.length > STATE_MAX_BYTES) return void 0;
|
|
11500
11590
|
const text = buf.toString("utf8").trim();
|
|
11501
11591
|
return text.length > 0 ? text : void 0;
|
|
@@ -11542,7 +11632,7 @@ function extractSetupTokenFromOutput(output) {
|
|
|
11542
11632
|
}
|
|
11543
11633
|
function captureClaudeSetupToken() {
|
|
11544
11634
|
return new Promise((resolve7, reject) => {
|
|
11545
|
-
const child = (0,
|
|
11635
|
+
const child = (0, import_node_child_process3.spawn)("claude", ["setup-token"], {
|
|
11546
11636
|
stdio: ["inherit", "pipe", "inherit"]
|
|
11547
11637
|
});
|
|
11548
11638
|
let out2 = "";
|
|
@@ -11570,7 +11660,7 @@ function claudeLoginLauncher() {
|
|
|
11570
11660
|
return {
|
|
11571
11661
|
ensureInstalled: ensureClaudeInstalled,
|
|
11572
11662
|
launch() {
|
|
11573
|
-
const child = (0,
|
|
11663
|
+
const child = (0, import_node_child_process3.spawn)("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
|
|
11574
11664
|
child.stdin?.write("/login\n");
|
|
11575
11665
|
return child;
|
|
11576
11666
|
},
|
|
@@ -11582,9 +11672,9 @@ function claudeLoginLauncher() {
|
|
|
11582
11672
|
}
|
|
11583
11673
|
|
|
11584
11674
|
// src/agents/claude/quota.ts
|
|
11585
|
-
var
|
|
11586
|
-
var
|
|
11587
|
-
var
|
|
11675
|
+
var fs14 = __toESM(require("fs"));
|
|
11676
|
+
var os13 = __toESM(require("os"));
|
|
11677
|
+
var path18 = __toESM(require("path"));
|
|
11588
11678
|
var import_child_process10 = require("child_process");
|
|
11589
11679
|
var HELPER_SCRIPT = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
|
|
11590
11680
|
m,s=pty.openpty()
|
|
@@ -11647,8 +11737,8 @@ async function fetchClaudeQuota() {
|
|
|
11647
11737
|
resolve7(null);
|
|
11648
11738
|
return;
|
|
11649
11739
|
}
|
|
11650
|
-
const helperPath =
|
|
11651
|
-
|
|
11740
|
+
const helperPath = path18.join(os13.tmpdir(), "codeam-quota-helper.py");
|
|
11741
|
+
fs14.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
|
|
11652
11742
|
const python = findInPath("python3") ?? findInPath("python");
|
|
11653
11743
|
if (!python) {
|
|
11654
11744
|
resolve7(null);
|
|
@@ -11675,7 +11765,7 @@ async function fetchClaudeQuota() {
|
|
|
11675
11765
|
} catch {
|
|
11676
11766
|
}
|
|
11677
11767
|
try {
|
|
11678
|
-
|
|
11768
|
+
fs14.unlinkSync(helperPath);
|
|
11679
11769
|
} catch {
|
|
11680
11770
|
}
|
|
11681
11771
|
resolve7(result);
|
|
@@ -11768,24 +11858,24 @@ async function spawnAndCapture(cmd, args2, opts = {}) {
|
|
|
11768
11858
|
}
|
|
11769
11859
|
|
|
11770
11860
|
// src/agents/claude/history.ts
|
|
11771
|
-
var
|
|
11772
|
-
var
|
|
11773
|
-
var
|
|
11861
|
+
var fs15 = __toESM(require("fs"));
|
|
11862
|
+
var path19 = __toESM(require("path"));
|
|
11863
|
+
var os14 = __toESM(require("os"));
|
|
11774
11864
|
function encodeCwd(cwd) {
|
|
11775
11865
|
return cwd.replace(/[\\/:]/g, "-");
|
|
11776
11866
|
}
|
|
11777
11867
|
function resolveHistoryDir(cwd, projectsRoot) {
|
|
11778
|
-
const root = projectsRoot ??
|
|
11779
|
-
const primary =
|
|
11780
|
-
if (
|
|
11868
|
+
const root = projectsRoot ?? path19.join(os14.homedir(), ".claude", "projects");
|
|
11869
|
+
const primary = path19.join(root, encodeCwd(cwd));
|
|
11870
|
+
if (fs15.existsSync(primary)) return primary;
|
|
11781
11871
|
try {
|
|
11782
|
-
const entries =
|
|
11872
|
+
const entries = fs15.readdirSync(root, { withFileTypes: true });
|
|
11783
11873
|
const wanted = encodeCwd(cwd);
|
|
11784
11874
|
for (const e of entries) {
|
|
11785
11875
|
if (!e.isDirectory()) continue;
|
|
11786
11876
|
const candidate = e.name.replace(/-+/g, "-");
|
|
11787
11877
|
if (candidate === wanted.replace(/-+/g, "-")) {
|
|
11788
|
-
return
|
|
11878
|
+
return path19.join(root, e.name);
|
|
11789
11879
|
}
|
|
11790
11880
|
}
|
|
11791
11881
|
} catch {
|
|
@@ -11797,23 +11887,23 @@ function getCurrentUsage(historyDir, bootTimeMs = 0) {
|
|
|
11797
11887
|
const cutoff = bootTimeMs > 0 ? bootTimeMs - GRACE_MS : 0;
|
|
11798
11888
|
let entries;
|
|
11799
11889
|
try {
|
|
11800
|
-
entries =
|
|
11890
|
+
entries = fs15.readdirSync(historyDir, { withFileTypes: true });
|
|
11801
11891
|
} catch {
|
|
11802
11892
|
return null;
|
|
11803
11893
|
}
|
|
11804
11894
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
11805
11895
|
try {
|
|
11806
|
-
const stat3 =
|
|
11896
|
+
const stat3 = fs15.statSync(path19.join(historyDir, e.name));
|
|
11807
11897
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
11808
11898
|
} catch {
|
|
11809
11899
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
11810
11900
|
}
|
|
11811
11901
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11812
11902
|
if (files.length === 0) return null;
|
|
11813
|
-
const filePath =
|
|
11903
|
+
const filePath = path19.join(historyDir, files[0].name);
|
|
11814
11904
|
let raw;
|
|
11815
11905
|
try {
|
|
11816
|
-
raw =
|
|
11906
|
+
raw = fs15.readFileSync(filePath, "utf8");
|
|
11817
11907
|
} catch {
|
|
11818
11908
|
return null;
|
|
11819
11909
|
}
|
|
@@ -11858,7 +11948,7 @@ function parseHistoryFile(filePath) {
|
|
|
11858
11948
|
const out2 = [];
|
|
11859
11949
|
let raw;
|
|
11860
11950
|
try {
|
|
11861
|
-
raw =
|
|
11951
|
+
raw = fs15.readFileSync(filePath, "utf8");
|
|
11862
11952
|
} catch {
|
|
11863
11953
|
return out2;
|
|
11864
11954
|
}
|
|
@@ -11903,7 +11993,7 @@ function listResumableSessions(cwd) {
|
|
|
11903
11993
|
if (!dir) return [];
|
|
11904
11994
|
let entries;
|
|
11905
11995
|
try {
|
|
11906
|
-
entries =
|
|
11996
|
+
entries = fs15.readdirSync(dir, { withFileTypes: true });
|
|
11907
11997
|
} catch {
|
|
11908
11998
|
return [];
|
|
11909
11999
|
}
|
|
@@ -11911,15 +12001,15 @@ function listResumableSessions(cwd) {
|
|
|
11911
12001
|
for (const entry of entries) {
|
|
11912
12002
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
|
|
11913
12003
|
const id = entry.name.slice(0, -".jsonl".length);
|
|
11914
|
-
const filePath =
|
|
12004
|
+
const filePath = path19.join(dir, entry.name);
|
|
11915
12005
|
let timestamp = Date.now();
|
|
11916
12006
|
try {
|
|
11917
|
-
timestamp =
|
|
12007
|
+
timestamp = fs15.statSync(filePath).mtimeMs;
|
|
11918
12008
|
} catch {
|
|
11919
12009
|
}
|
|
11920
12010
|
let summary = "";
|
|
11921
12011
|
try {
|
|
11922
|
-
const raw =
|
|
12012
|
+
const raw = fs15.readFileSync(filePath, "utf8");
|
|
11923
12013
|
for (const line of raw.split("\n")) {
|
|
11924
12014
|
if (!line.trim()) continue;
|
|
11925
12015
|
try {
|
|
@@ -11949,8 +12039,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
11949
12039
|
meta = getAgent("claude");
|
|
11950
12040
|
mode = "interactive";
|
|
11951
12041
|
os;
|
|
11952
|
-
constructor(
|
|
11953
|
-
this.os =
|
|
12042
|
+
constructor(os45) {
|
|
12043
|
+
this.os = os45;
|
|
11954
12044
|
}
|
|
11955
12045
|
/**
|
|
11956
12046
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -12082,24 +12172,24 @@ var ClaudeRuntimeStrategy = class {
|
|
|
12082
12172
|
};
|
|
12083
12173
|
|
|
12084
12174
|
// src/agents/claude/deploy.ts
|
|
12085
|
-
var
|
|
12086
|
-
var
|
|
12087
|
-
var
|
|
12175
|
+
var fs17 = __toESM(require("fs"));
|
|
12176
|
+
var os16 = __toESM(require("os"));
|
|
12177
|
+
var path21 = __toESM(require("path"));
|
|
12088
12178
|
|
|
12089
12179
|
// src/agents/claude/credentials.ts
|
|
12090
12180
|
var import_child_process12 = require("child_process");
|
|
12091
|
-
var
|
|
12092
|
-
var
|
|
12093
|
-
var
|
|
12181
|
+
var fs16 = __toESM(require("fs"));
|
|
12182
|
+
var os15 = __toESM(require("os"));
|
|
12183
|
+
var path20 = __toESM(require("path"));
|
|
12094
12184
|
var import_util2 = require("util");
|
|
12095
12185
|
var execFileP3 = (0, import_util2.promisify)(import_child_process12.execFile);
|
|
12096
12186
|
async function detectLocalClaudeCredentials() {
|
|
12097
|
-
const localClaudeDir =
|
|
12098
|
-
const flat =
|
|
12099
|
-
if (
|
|
12187
|
+
const localClaudeDir = path20.join(os15.homedir(), ".claude");
|
|
12188
|
+
const flat = path20.join(localClaudeDir, ".credentials.json");
|
|
12189
|
+
if (fs16.existsSync(flat)) {
|
|
12100
12190
|
return { source: "flat-file", description: "~/.claude/.credentials.json" };
|
|
12101
12191
|
}
|
|
12102
|
-
if (
|
|
12192
|
+
if (os15.platform() === "darwin") {
|
|
12103
12193
|
try {
|
|
12104
12194
|
await execFileP3(
|
|
12105
12195
|
"security",
|
|
@@ -12114,9 +12204,9 @@ async function detectLocalClaudeCredentials() {
|
|
|
12114
12204
|
return { source: "none", description: "" };
|
|
12115
12205
|
}
|
|
12116
12206
|
async function bridgeClaudeCredentials(provider, workspaceId) {
|
|
12117
|
-
const localClaudeDir =
|
|
12118
|
-
const fileBased =
|
|
12119
|
-
if (
|
|
12207
|
+
const localClaudeDir = path20.join(os15.homedir(), ".claude");
|
|
12208
|
+
const fileBased = path20.join(localClaudeDir, ".credentials.json");
|
|
12209
|
+
if (fs16.existsSync(fileBased)) {
|
|
12120
12210
|
return { source: "flat-file", description: "~/.claude/.credentials.json" };
|
|
12121
12211
|
}
|
|
12122
12212
|
if (process.platform === "darwin") {
|
|
@@ -12208,8 +12298,8 @@ var ClaudeDeployStrategy = class {
|
|
|
12208
12298
|
process.exit(1);
|
|
12209
12299
|
}
|
|
12210
12300
|
claudeStep.stop("\u2713 Claude CLI installed");
|
|
12211
|
-
const localClaudeDir =
|
|
12212
|
-
const haveLocalClaude =
|
|
12301
|
+
const localClaudeDir = path21.join(os16.homedir(), ".claude");
|
|
12302
|
+
const haveLocalClaude = fs17.existsSync(localClaudeDir) && fs17.statSync(localClaudeDir).isDirectory();
|
|
12213
12303
|
if (haveLocalClaude) {
|
|
12214
12304
|
const copyStep = fe();
|
|
12215
12305
|
copyStep.start("Copying local Claude config to workspace\u2026");
|
|
@@ -12263,10 +12353,10 @@ var ClaudeDeployStrategy = class {
|
|
|
12263
12353
|
}
|
|
12264
12354
|
}
|
|
12265
12355
|
if (opts.bridged !== "none") {
|
|
12266
|
-
const localClaudeJson =
|
|
12267
|
-
if (
|
|
12356
|
+
const localClaudeJson = path21.join(os16.homedir(), ".claude.json");
|
|
12357
|
+
if (fs17.existsSync(localClaudeJson)) {
|
|
12268
12358
|
try {
|
|
12269
|
-
const contents =
|
|
12359
|
+
const contents = fs17.readFileSync(localClaudeJson);
|
|
12270
12360
|
await provider.uploadFile(
|
|
12271
12361
|
workspaceId,
|
|
12272
12362
|
"/home/codespace/.claude.json",
|
|
@@ -12298,8 +12388,8 @@ var ClaudeDeployStrategy = class {
|
|
|
12298
12388
|
};
|
|
12299
12389
|
|
|
12300
12390
|
// src/agents/codex/runtime.ts
|
|
12301
|
-
var
|
|
12302
|
-
var
|
|
12391
|
+
var import_node_child_process5 = require("child_process");
|
|
12392
|
+
var path24 = __toESM(require("path"));
|
|
12303
12393
|
|
|
12304
12394
|
// src/agents/codex/history.ts
|
|
12305
12395
|
var import_node_fs3 = __toESM(require("fs"));
|
|
@@ -12556,19 +12646,19 @@ function getCurrentUsage2(historyDir) {
|
|
|
12556
12646
|
}
|
|
12557
12647
|
|
|
12558
12648
|
// src/agents/codex/link.ts
|
|
12559
|
-
var
|
|
12649
|
+
var import_node_child_process4 = require("child_process");
|
|
12560
12650
|
|
|
12561
12651
|
// src/agents/codex/local-token.ts
|
|
12562
|
-
var
|
|
12563
|
-
var
|
|
12564
|
-
var
|
|
12652
|
+
var fs19 = __toESM(require("fs"));
|
|
12653
|
+
var os18 = __toESM(require("os"));
|
|
12654
|
+
var path23 = __toESM(require("path"));
|
|
12565
12655
|
function codexCredentialsPath() {
|
|
12566
|
-
return
|
|
12656
|
+
return path23.join(os18.homedir(), ".codex", "auth.json");
|
|
12567
12657
|
}
|
|
12568
12658
|
async function extractLocalCodexToken() {
|
|
12569
12659
|
const file = codexCredentialsPath();
|
|
12570
|
-
if (!
|
|
12571
|
-
const credential =
|
|
12660
|
+
if (!fs19.existsSync(file)) return null;
|
|
12661
|
+
const credential = fs19.readFileSync(file, "utf8").trim();
|
|
12572
12662
|
if (credential.length === 0) return null;
|
|
12573
12663
|
return { method: "oauth", credential, source: "flat-file" };
|
|
12574
12664
|
}
|
|
@@ -12627,11 +12717,11 @@ function codexCredentialLocator() {
|
|
|
12627
12717
|
function codexLoginLauncher() {
|
|
12628
12718
|
return {
|
|
12629
12719
|
async ensureInstalled() {
|
|
12630
|
-
const
|
|
12631
|
-
return
|
|
12720
|
+
const os45 = createOsStrategy();
|
|
12721
|
+
return os45.findInPath("codex") !== null;
|
|
12632
12722
|
},
|
|
12633
12723
|
launch() {
|
|
12634
|
-
return (0,
|
|
12724
|
+
return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
12635
12725
|
}
|
|
12636
12726
|
};
|
|
12637
12727
|
}
|
|
@@ -12651,8 +12741,8 @@ var CodexRuntimeStrategy = class {
|
|
|
12651
12741
|
meta = getAgent("codex");
|
|
12652
12742
|
mode = "interactive";
|
|
12653
12743
|
os;
|
|
12654
|
-
constructor(
|
|
12655
|
-
this.os =
|
|
12744
|
+
constructor(os45) {
|
|
12745
|
+
this.os = os45;
|
|
12656
12746
|
}
|
|
12657
12747
|
async prepareLaunch() {
|
|
12658
12748
|
let binary = this.os.findInPath("codex");
|
|
@@ -12751,12 +12841,12 @@ var CodexRuntimeStrategy = class {
|
|
|
12751
12841
|
});
|
|
12752
12842
|
}
|
|
12753
12843
|
};
|
|
12754
|
-
function resolveNpm(
|
|
12755
|
-
return
|
|
12844
|
+
function resolveNpm(os45) {
|
|
12845
|
+
return os45.id === "win32" ? "npm.cmd" : "npm";
|
|
12756
12846
|
}
|
|
12757
|
-
async function installCodexViaNpm(
|
|
12847
|
+
async function installCodexViaNpm(os45) {
|
|
12758
12848
|
return new Promise((resolve7, reject) => {
|
|
12759
|
-
const proc = (0,
|
|
12849
|
+
const proc = (0, import_node_child_process5.spawn)(resolveNpm(os45), ["install", "-g", "@openai/codex"], {
|
|
12760
12850
|
stdio: "inherit"
|
|
12761
12851
|
});
|
|
12762
12852
|
proc.on("close", (code) => {
|
|
@@ -12773,16 +12863,16 @@ async function installCodexViaNpm(os44) {
|
|
|
12773
12863
|
});
|
|
12774
12864
|
});
|
|
12775
12865
|
}
|
|
12776
|
-
function augmentNpmGlobalBin(
|
|
12866
|
+
function augmentNpmGlobalBin(os45) {
|
|
12777
12867
|
try {
|
|
12778
|
-
const result = (0,
|
|
12868
|
+
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os45), ["prefix", "-g"], {
|
|
12779
12869
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12780
12870
|
});
|
|
12781
12871
|
if (result.status !== 0) return;
|
|
12782
12872
|
const prefix = result.stdout.toString().trim();
|
|
12783
12873
|
if (!prefix) return;
|
|
12784
|
-
const binDir =
|
|
12785
|
-
|
|
12874
|
+
const binDir = os45.id === "win32" ? prefix : path24.join(prefix, "bin");
|
|
12875
|
+
os45.augmentPath([binDir]);
|
|
12786
12876
|
} catch {
|
|
12787
12877
|
}
|
|
12788
12878
|
}
|
|
@@ -12861,14 +12951,14 @@ var CodexDeployStrategy = class {
|
|
|
12861
12951
|
};
|
|
12862
12952
|
|
|
12863
12953
|
// src/agents/coderabbit/runtime.ts
|
|
12864
|
-
var
|
|
12954
|
+
var import_node_child_process8 = require("child_process");
|
|
12865
12955
|
|
|
12866
12956
|
// src/agents/coderabbit/installer.ts
|
|
12867
|
-
var
|
|
12957
|
+
var import_node_child_process6 = require("child_process");
|
|
12868
12958
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
12869
|
-
async function ensureCoderabbitInstalled(
|
|
12870
|
-
if (
|
|
12871
|
-
if (
|
|
12959
|
+
async function ensureCoderabbitInstalled(os45) {
|
|
12960
|
+
if (os45.findInPath("coderabbit")) return true;
|
|
12961
|
+
if (os45.id === "win32") {
|
|
12872
12962
|
console.error(
|
|
12873
12963
|
"\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"
|
|
12874
12964
|
);
|
|
@@ -12876,22 +12966,22 @@ async function ensureCoderabbitInstalled(os44) {
|
|
|
12876
12966
|
}
|
|
12877
12967
|
console.log("\n CodeRabbit CLI not found \u2014 installing via the official script\u2026\n");
|
|
12878
12968
|
const ok = await new Promise((resolve7) => {
|
|
12879
|
-
const proc = (0,
|
|
12969
|
+
const proc = (0, import_node_child_process6.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL} | sh`], {
|
|
12880
12970
|
stdio: "inherit"
|
|
12881
12971
|
});
|
|
12882
12972
|
proc.on("close", (code) => resolve7(code === 0));
|
|
12883
12973
|
proc.on("error", () => resolve7(false));
|
|
12884
12974
|
});
|
|
12885
12975
|
if (!ok) return false;
|
|
12886
|
-
|
|
12887
|
-
return
|
|
12976
|
+
os45.augmentPath([`${os45.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
12977
|
+
return os45.findInPath("coderabbit") !== null;
|
|
12888
12978
|
}
|
|
12889
12979
|
|
|
12890
12980
|
// src/agents/coderabbit/link.ts
|
|
12891
|
-
var
|
|
12892
|
-
var
|
|
12893
|
-
var
|
|
12894
|
-
var
|
|
12981
|
+
var import_node_child_process7 = require("child_process");
|
|
12982
|
+
var fs21 = __toESM(require("fs"));
|
|
12983
|
+
var os20 = __toESM(require("os"));
|
|
12984
|
+
var path26 = __toESM(require("path"));
|
|
12895
12985
|
|
|
12896
12986
|
// src/agents/strategy.ts
|
|
12897
12987
|
function validateNonEmptyCredential(token) {
|
|
@@ -12900,12 +12990,12 @@ function validateNonEmptyCredential(token) {
|
|
|
12900
12990
|
|
|
12901
12991
|
// src/agents/coderabbit/link.ts
|
|
12902
12992
|
function authPath() {
|
|
12903
|
-
return
|
|
12993
|
+
return path26.join(os20.homedir(), ".coderabbit", "auth.json");
|
|
12904
12994
|
}
|
|
12905
12995
|
async function extractLocalCoderabbitToken() {
|
|
12906
12996
|
const file = authPath();
|
|
12907
|
-
if (!
|
|
12908
|
-
const credential =
|
|
12997
|
+
if (!fs21.existsSync(file)) return null;
|
|
12998
|
+
const credential = fs21.readFileSync(file, "utf8").trim();
|
|
12909
12999
|
if (credential.length === 0) return null;
|
|
12910
13000
|
return { method: "oauth", credential, source: "flat-file" };
|
|
12911
13001
|
}
|
|
@@ -12919,13 +13009,13 @@ function coderabbitCredentialLocator() {
|
|
|
12919
13009
|
validate: validateNonEmptyCredential
|
|
12920
13010
|
};
|
|
12921
13011
|
}
|
|
12922
|
-
function coderabbitLoginLauncher(
|
|
13012
|
+
function coderabbitLoginLauncher(os45) {
|
|
12923
13013
|
return {
|
|
12924
13014
|
async ensureInstalled() {
|
|
12925
|
-
return ensureCoderabbitInstalled(
|
|
13015
|
+
return ensureCoderabbitInstalled(os45);
|
|
12926
13016
|
},
|
|
12927
13017
|
launch() {
|
|
12928
|
-
return (0,
|
|
13018
|
+
return (0, import_node_child_process7.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
12929
13019
|
}
|
|
12930
13020
|
};
|
|
12931
13021
|
}
|
|
@@ -12945,11 +13035,11 @@ function parseReview(stdout) {
|
|
|
12945
13035
|
for (const line of lines) {
|
|
12946
13036
|
const m = line.match(HUNK_LINE_RE);
|
|
12947
13037
|
if (!m) continue;
|
|
12948
|
-
const [,
|
|
12949
|
-
if (!
|
|
13038
|
+
const [, path65, lineNo, sevToken, message] = m;
|
|
13039
|
+
if (!path65 || !lineNo || !message) continue;
|
|
12950
13040
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
12951
13041
|
hunks.push({
|
|
12952
|
-
path:
|
|
13042
|
+
path: path65.trim(),
|
|
12953
13043
|
line: Number(lineNo),
|
|
12954
13044
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
12955
13045
|
message: cleanedMessage
|
|
@@ -12968,8 +13058,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
12968
13058
|
meta = getAgent("coderabbit");
|
|
12969
13059
|
mode = "batch";
|
|
12970
13060
|
os;
|
|
12971
|
-
constructor(
|
|
12972
|
-
this.os =
|
|
13061
|
+
constructor(os45) {
|
|
13062
|
+
this.os = os45;
|
|
12973
13063
|
}
|
|
12974
13064
|
getDefaultArgs() {
|
|
12975
13065
|
return ["review"];
|
|
@@ -13010,7 +13100,7 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13010
13100
|
return new Promise((resolve7, reject) => {
|
|
13011
13101
|
const stdoutBuf = [];
|
|
13012
13102
|
const stderrBuf = [];
|
|
13013
|
-
const proc = (0,
|
|
13103
|
+
const proc = (0, import_node_child_process8.spawn)(launch.cmd, launch.args, {
|
|
13014
13104
|
env: { ...process.env, ...launch.env ?? {} },
|
|
13015
13105
|
stdio: ["ignore", "pipe", "pipe"]
|
|
13016
13106
|
});
|
|
@@ -13037,12 +13127,12 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
13037
13127
|
};
|
|
13038
13128
|
|
|
13039
13129
|
// src/agents/cursor/history.ts
|
|
13040
|
-
var
|
|
13041
|
-
var
|
|
13042
|
-
var
|
|
13043
|
-
var HISTORY_ROOT =
|
|
13130
|
+
var fs22 = __toESM(require("fs"));
|
|
13131
|
+
var os21 = __toESM(require("os"));
|
|
13132
|
+
var path27 = __toESM(require("path"));
|
|
13133
|
+
var HISTORY_ROOT = path27.join(os21.homedir(), ".cursor", "projects");
|
|
13044
13134
|
function resolveHistoryDir3(cwd) {
|
|
13045
|
-
if (!
|
|
13135
|
+
if (!fs22.existsSync(HISTORY_ROOT)) return null;
|
|
13046
13136
|
void cwd;
|
|
13047
13137
|
return HISTORY_ROOT;
|
|
13048
13138
|
}
|
|
@@ -13054,19 +13144,19 @@ function getCurrentUsage3(_historyDir) {
|
|
|
13054
13144
|
}
|
|
13055
13145
|
|
|
13056
13146
|
// src/agents/cursor/link.ts
|
|
13057
|
-
var
|
|
13147
|
+
var import_node_child_process9 = require("child_process");
|
|
13058
13148
|
|
|
13059
13149
|
// src/agents/cursor/local-token.ts
|
|
13060
|
-
var
|
|
13061
|
-
var
|
|
13062
|
-
var
|
|
13150
|
+
var fs23 = __toESM(require("fs"));
|
|
13151
|
+
var os22 = __toESM(require("os"));
|
|
13152
|
+
var path28 = __toESM(require("path"));
|
|
13063
13153
|
function cursorCredentialsPath() {
|
|
13064
|
-
return
|
|
13154
|
+
return path28.join(os22.homedir(), ".cursor", "auth.json");
|
|
13065
13155
|
}
|
|
13066
13156
|
async function extractLocalCursorToken() {
|
|
13067
13157
|
const file = cursorCredentialsPath();
|
|
13068
|
-
if (!
|
|
13069
|
-
const credential =
|
|
13158
|
+
if (!fs23.existsSync(file)) return null;
|
|
13159
|
+
const credential = fs23.readFileSync(file, "utf8").trim();
|
|
13070
13160
|
if (credential.length === 0) return null;
|
|
13071
13161
|
return { method: "oauth", credential, source: "flat-file" };
|
|
13072
13162
|
}
|
|
@@ -13085,17 +13175,17 @@ function cursorCredentialLocator() {
|
|
|
13085
13175
|
validate: validateNonEmptyCredential
|
|
13086
13176
|
};
|
|
13087
13177
|
}
|
|
13088
|
-
function cursorLoginLauncher(
|
|
13178
|
+
function cursorLoginLauncher(os45) {
|
|
13089
13179
|
return {
|
|
13090
13180
|
async ensureInstalled() {
|
|
13091
|
-
if (
|
|
13181
|
+
if (os45.findInPath("cursor-agent")) return true;
|
|
13092
13182
|
console.error(
|
|
13093
13183
|
"\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"
|
|
13094
13184
|
);
|
|
13095
13185
|
return false;
|
|
13096
13186
|
},
|
|
13097
13187
|
launch() {
|
|
13098
|
-
return (0,
|
|
13188
|
+
return (0, import_node_child_process9.spawn)("cursor-agent", ["login"], { stdio: "inherit" });
|
|
13099
13189
|
}
|
|
13100
13190
|
};
|
|
13101
13191
|
}
|
|
@@ -13150,8 +13240,8 @@ var CursorRuntimeStrategy = class {
|
|
|
13150
13240
|
meta = getAgent("cursor");
|
|
13151
13241
|
mode = "interactive";
|
|
13152
13242
|
os;
|
|
13153
|
-
constructor(
|
|
13154
|
-
this.os =
|
|
13243
|
+
constructor(os45) {
|
|
13244
|
+
this.os = os45;
|
|
13155
13245
|
}
|
|
13156
13246
|
async prepareLaunch() {
|
|
13157
13247
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -13230,12 +13320,12 @@ var CursorRuntimeStrategy = class {
|
|
|
13230
13320
|
};
|
|
13231
13321
|
|
|
13232
13322
|
// src/agents/aider/history.ts
|
|
13233
|
-
var
|
|
13234
|
-
var
|
|
13323
|
+
var fs24 = __toESM(require("fs"));
|
|
13324
|
+
var path29 = __toESM(require("path"));
|
|
13235
13325
|
var AIDER_HISTORY_FILE = ".aider.chat.history.md";
|
|
13236
13326
|
function resolveHistoryDir4(cwd) {
|
|
13237
|
-
const candidate =
|
|
13238
|
-
return
|
|
13327
|
+
const candidate = path29.join(cwd, AIDER_HISTORY_FILE);
|
|
13328
|
+
return fs24.existsSync(candidate) ? cwd : null;
|
|
13239
13329
|
}
|
|
13240
13330
|
function parseHistoryFile4(_filePath) {
|
|
13241
13331
|
return [];
|
|
@@ -13245,13 +13335,13 @@ function getCurrentUsage4(_historyDir) {
|
|
|
13245
13335
|
}
|
|
13246
13336
|
|
|
13247
13337
|
// src/agents/aider/link.ts
|
|
13248
|
-
var
|
|
13338
|
+
var import_node_child_process10 = require("child_process");
|
|
13249
13339
|
|
|
13250
13340
|
// src/agents/aider/local-token.ts
|
|
13251
|
-
var
|
|
13252
|
-
var
|
|
13253
|
-
var
|
|
13254
|
-
var AIDER_CONF_FILE =
|
|
13341
|
+
var fs25 = __toESM(require("fs"));
|
|
13342
|
+
var os23 = __toESM(require("os"));
|
|
13343
|
+
var path30 = __toESM(require("path"));
|
|
13344
|
+
var AIDER_CONF_FILE = path30.join(os23.homedir(), ".aider.conf.yml");
|
|
13255
13345
|
var API_KEY_ENV_VARS = [
|
|
13256
13346
|
"ANTHROPIC_API_KEY",
|
|
13257
13347
|
"OPENAI_API_KEY",
|
|
@@ -13266,8 +13356,8 @@ async function extractLocalAiderToken() {
|
|
|
13266
13356
|
return { method: "api_key", credential: value.trim(), source: "flat-file" };
|
|
13267
13357
|
}
|
|
13268
13358
|
}
|
|
13269
|
-
if (
|
|
13270
|
-
const conf =
|
|
13359
|
+
if (fs25.existsSync(AIDER_CONF_FILE)) {
|
|
13360
|
+
const conf = fs25.readFileSync(AIDER_CONF_FILE, "utf8");
|
|
13271
13361
|
const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
|
|
13272
13362
|
if (match) {
|
|
13273
13363
|
return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
|
|
@@ -13290,10 +13380,10 @@ function aiderCredentialLocator() {
|
|
|
13290
13380
|
validate: validateNonEmptyCredential
|
|
13291
13381
|
};
|
|
13292
13382
|
}
|
|
13293
|
-
function aiderLoginLauncher(
|
|
13383
|
+
function aiderLoginLauncher(os45) {
|
|
13294
13384
|
return {
|
|
13295
13385
|
async ensureInstalled() {
|
|
13296
|
-
if (
|
|
13386
|
+
if (os45.findInPath("aider")) return true;
|
|
13297
13387
|
console.error(
|
|
13298
13388
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
13299
13389
|
);
|
|
@@ -13303,7 +13393,7 @@ function aiderLoginLauncher(os44) {
|
|
|
13303
13393
|
console.error(
|
|
13304
13394
|
"\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"
|
|
13305
13395
|
);
|
|
13306
|
-
return (0,
|
|
13396
|
+
return (0, import_node_child_process10.spawn)(os45.id === "win32" ? "cmd.exe" : "sh", os45.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
13307
13397
|
stdio: "ignore"
|
|
13308
13398
|
});
|
|
13309
13399
|
}
|
|
@@ -13375,8 +13465,8 @@ var AiderRuntimeStrategy = class {
|
|
|
13375
13465
|
meta = getAgent("aider");
|
|
13376
13466
|
mode = "interactive";
|
|
13377
13467
|
os;
|
|
13378
|
-
constructor(
|
|
13379
|
-
this.os =
|
|
13468
|
+
constructor(os45) {
|
|
13469
|
+
this.os = os45;
|
|
13380
13470
|
}
|
|
13381
13471
|
async prepareLaunch() {
|
|
13382
13472
|
const binary = this.os.findInPath("aider");
|
|
@@ -13444,22 +13534,22 @@ var AiderRuntimeStrategy = class {
|
|
|
13444
13534
|
};
|
|
13445
13535
|
|
|
13446
13536
|
// src/agents/gemini/link.ts
|
|
13447
|
-
var
|
|
13537
|
+
var import_node_child_process11 = require("child_process");
|
|
13448
13538
|
|
|
13449
13539
|
// src/agents/gemini/local-token.ts
|
|
13450
|
-
var
|
|
13451
|
-
var
|
|
13452
|
-
var
|
|
13540
|
+
var fs26 = __toESM(require("fs"));
|
|
13541
|
+
var os24 = __toESM(require("os"));
|
|
13542
|
+
var path31 = __toESM(require("path"));
|
|
13453
13543
|
function geminiCredentialsPath() {
|
|
13454
|
-
return
|
|
13544
|
+
return path31.join(os24.homedir(), ".gemini", "oauth_creds.json");
|
|
13455
13545
|
}
|
|
13456
13546
|
function geminiCredentialsPaths() {
|
|
13457
13547
|
return [geminiCredentialsPath()];
|
|
13458
13548
|
}
|
|
13459
13549
|
async function extractLocalGeminiToken() {
|
|
13460
13550
|
const file = geminiCredentialsPath();
|
|
13461
|
-
if (!
|
|
13462
|
-
const credential =
|
|
13551
|
+
if (!fs26.existsSync(file)) return null;
|
|
13552
|
+
const credential = fs26.readFileSync(file, "utf8").trim();
|
|
13463
13553
|
if (credential.length === 0) return null;
|
|
13464
13554
|
return { method: "oauth", credential, source: "flat-file" };
|
|
13465
13555
|
}
|
|
@@ -13505,11 +13595,11 @@ function geminiCredentialLocator() {
|
|
|
13505
13595
|
function geminiLoginLauncher() {
|
|
13506
13596
|
return {
|
|
13507
13597
|
async ensureInstalled() {
|
|
13508
|
-
const
|
|
13509
|
-
return
|
|
13598
|
+
const os45 = createOsStrategy();
|
|
13599
|
+
return os45.findInPath("gemini") !== null;
|
|
13510
13600
|
},
|
|
13511
13601
|
launch() {
|
|
13512
|
-
return (0,
|
|
13602
|
+
return (0, import_node_child_process11.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
13513
13603
|
}
|
|
13514
13604
|
};
|
|
13515
13605
|
}
|
|
@@ -13539,8 +13629,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
13539
13629
|
meta = getAgent("gemini");
|
|
13540
13630
|
mode = "interactive";
|
|
13541
13631
|
os;
|
|
13542
|
-
constructor(
|
|
13543
|
-
this.os =
|
|
13632
|
+
constructor(os45) {
|
|
13633
|
+
this.os = os45;
|
|
13544
13634
|
}
|
|
13545
13635
|
async prepareLaunch() {
|
|
13546
13636
|
const binary = this.os.findInPath("gemini");
|
|
@@ -13639,18 +13729,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
13639
13729
|
|
|
13640
13730
|
// src/agents/registry.ts
|
|
13641
13731
|
var runtimeBuilders = {
|
|
13642
|
-
claude: (
|
|
13643
|
-
codex: (
|
|
13644
|
-
coderabbit: (
|
|
13645
|
-
cursor: (
|
|
13646
|
-
aider: (
|
|
13647
|
-
gemini: (
|
|
13732
|
+
claude: (os45) => new ClaudeRuntimeStrategy(os45),
|
|
13733
|
+
codex: (os45) => new CodexRuntimeStrategy(os45),
|
|
13734
|
+
coderabbit: (os45) => new CoderabbitRuntimeStrategy(os45),
|
|
13735
|
+
cursor: (os45) => new CursorRuntimeStrategy(os45),
|
|
13736
|
+
aider: (os45) => new AiderRuntimeStrategy(os45),
|
|
13737
|
+
gemini: (os45) => new GeminiRuntimeStrategy(os45)
|
|
13648
13738
|
};
|
|
13649
13739
|
var deployBuilders = {
|
|
13650
13740
|
claude: () => new ClaudeDeployStrategy(),
|
|
13651
13741
|
codex: () => new CodexDeployStrategy()
|
|
13652
13742
|
};
|
|
13653
|
-
function createAgentStrategy(agent,
|
|
13743
|
+
function createAgentStrategy(agent, os45 = createOsStrategy()) {
|
|
13654
13744
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
13655
13745
|
throw new Error(
|
|
13656
13746
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -13660,10 +13750,10 @@ function createAgentStrategy(agent, os44 = createOsStrategy()) {
|
|
|
13660
13750
|
if (!build) {
|
|
13661
13751
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
13662
13752
|
}
|
|
13663
|
-
return build(
|
|
13753
|
+
return build(os45);
|
|
13664
13754
|
}
|
|
13665
|
-
function createInteractiveAgentStrategy(agent,
|
|
13666
|
-
const s = createAgentStrategy(agent,
|
|
13755
|
+
function createInteractiveAgentStrategy(agent, os45 = createOsStrategy()) {
|
|
13756
|
+
const s = createAgentStrategy(agent, os45);
|
|
13667
13757
|
if (s.mode !== "interactive") {
|
|
13668
13758
|
throw new Error(
|
|
13669
13759
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -13719,7 +13809,7 @@ function parseLinkArgs(args2) {
|
|
|
13719
13809
|
if (apiKeyFileArg) {
|
|
13720
13810
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
13721
13811
|
try {
|
|
13722
|
-
apiKey =
|
|
13812
|
+
apiKey = fs27.readFileSync(path32.resolve(filePath), "utf8").trim();
|
|
13723
13813
|
} catch (err) {
|
|
13724
13814
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
13725
13815
|
}
|
|
@@ -13846,7 +13936,7 @@ async function link(args2 = []) {
|
|
|
13846
13936
|
return;
|
|
13847
13937
|
}
|
|
13848
13938
|
if (parsed.tokenFile) {
|
|
13849
|
-
const credential =
|
|
13939
|
+
const credential = fs27.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
|
|
13850
13940
|
if (!credential) {
|
|
13851
13941
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
13852
13942
|
process.exit(1);
|
|
@@ -14066,15 +14156,15 @@ async function linkDryRunPreflight(ctx) {
|
|
|
14066
14156
|
}
|
|
14067
14157
|
|
|
14068
14158
|
// src/commands/host-agent.ts
|
|
14069
|
-
var
|
|
14070
|
-
var
|
|
14071
|
-
var
|
|
14072
|
-
var
|
|
14159
|
+
var import_node_child_process16 = require("child_process");
|
|
14160
|
+
var os31 = __toESM(require("os"));
|
|
14161
|
+
var fs34 = __toESM(require("fs"));
|
|
14162
|
+
var path38 = __toESM(require("path"));
|
|
14073
14163
|
|
|
14074
14164
|
// src/util/restrict-to-owner.ts
|
|
14075
14165
|
var import_node_fs5 = __toESM(require("fs"));
|
|
14076
14166
|
var import_node_os3 = __toESM(require("os"));
|
|
14077
|
-
var
|
|
14167
|
+
var import_node_child_process12 = require("child_process");
|
|
14078
14168
|
var BROAD_WINDOWS_SIDS = [
|
|
14079
14169
|
"*S-1-1-0",
|
|
14080
14170
|
"*S-1-5-11",
|
|
@@ -14086,7 +14176,7 @@ function restrictToOwner(filePath) {
|
|
|
14086
14176
|
try {
|
|
14087
14177
|
if (process.platform === "win32") {
|
|
14088
14178
|
const username = import_node_os3.default.userInfo().username;
|
|
14089
|
-
(0,
|
|
14179
|
+
(0, import_node_child_process12.execFileSync)(
|
|
14090
14180
|
"icacls",
|
|
14091
14181
|
[
|
|
14092
14182
|
filePath,
|
|
@@ -14105,13 +14195,13 @@ function restrictToOwner(filePath) {
|
|
|
14105
14195
|
}
|
|
14106
14196
|
|
|
14107
14197
|
// src/commands/host/host-client.ts
|
|
14108
|
-
var
|
|
14109
|
-
var
|
|
14110
|
-
var
|
|
14198
|
+
var fs29 = __toESM(require("fs"));
|
|
14199
|
+
var os26 = __toESM(require("os"));
|
|
14200
|
+
var path33 = __toESM(require("path"));
|
|
14111
14201
|
function sampleCpuTimes() {
|
|
14112
14202
|
let idle = 0;
|
|
14113
14203
|
let total = 0;
|
|
14114
|
-
for (const cpu of
|
|
14204
|
+
for (const cpu of os26.cpus()) {
|
|
14115
14205
|
const t2 = cpu.times;
|
|
14116
14206
|
idle += t2.idle;
|
|
14117
14207
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -14130,8 +14220,8 @@ var MetricsCollector = class {
|
|
|
14130
14220
|
const prev = this.prevCpu;
|
|
14131
14221
|
this.prevCpu = current;
|
|
14132
14222
|
if (!prev) {
|
|
14133
|
-
const cores =
|
|
14134
|
-
const proxy =
|
|
14223
|
+
const cores = os26.cpus().length || 1;
|
|
14224
|
+
const proxy = os26.loadavg()[0] / cores * 100;
|
|
14135
14225
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
14136
14226
|
}
|
|
14137
14227
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -14144,8 +14234,8 @@ var MetricsCollector = class {
|
|
|
14144
14234
|
collect() {
|
|
14145
14235
|
return {
|
|
14146
14236
|
cpuPct: this.cpuPct(),
|
|
14147
|
-
ramUsedMb: Math.round((
|
|
14148
|
-
ramTotalMb: Math.round(
|
|
14237
|
+
ramUsedMb: Math.round((os26.totalmem() - os26.freemem()) / 1048576),
|
|
14238
|
+
ramTotalMb: Math.round(os26.totalmem() / 1048576),
|
|
14149
14239
|
latencyMs: this.lastLatencyMs
|
|
14150
14240
|
};
|
|
14151
14241
|
}
|
|
@@ -14154,19 +14244,19 @@ function apiBase() {
|
|
|
14154
14244
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
14155
14245
|
}
|
|
14156
14246
|
function hostIdentityPath() {
|
|
14157
|
-
return
|
|
14247
|
+
return path33.join(os26.homedir(), ".codeam", "host-agent.json");
|
|
14158
14248
|
}
|
|
14159
14249
|
function collectOsInfo() {
|
|
14160
14250
|
return {
|
|
14161
|
-
distro:
|
|
14162
|
-
arch:
|
|
14163
|
-
kernel:
|
|
14251
|
+
distro: os26.platform(),
|
|
14252
|
+
arch: os26.arch(),
|
|
14253
|
+
kernel: os26.release(),
|
|
14164
14254
|
nodeVersion: process.versions.node
|
|
14165
14255
|
};
|
|
14166
14256
|
}
|
|
14167
14257
|
function loadHostIdentity() {
|
|
14168
14258
|
try {
|
|
14169
|
-
const raw =
|
|
14259
|
+
const raw = fs29.readFileSync(hostIdentityPath(), "utf8");
|
|
14170
14260
|
const parsed = JSON.parse(raw);
|
|
14171
14261
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
14172
14262
|
const p2 = parsed;
|
|
@@ -14179,8 +14269,8 @@ function loadHostIdentity() {
|
|
|
14179
14269
|
}
|
|
14180
14270
|
function saveHostIdentity(identity) {
|
|
14181
14271
|
const file = hostIdentityPath();
|
|
14182
|
-
|
|
14183
|
-
|
|
14272
|
+
fs29.mkdirSync(path33.dirname(file), { recursive: true, mode: 448 });
|
|
14273
|
+
fs29.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
14184
14274
|
encoding: "utf8",
|
|
14185
14275
|
mode: 384
|
|
14186
14276
|
});
|
|
@@ -14225,7 +14315,7 @@ function isTerminalEnrollError(err) {
|
|
|
14225
14315
|
}
|
|
14226
14316
|
function deleteHostIdentity() {
|
|
14227
14317
|
try {
|
|
14228
|
-
|
|
14318
|
+
fs29.rmSync(hostIdentityPath(), { force: true });
|
|
14229
14319
|
} catch {
|
|
14230
14320
|
}
|
|
14231
14321
|
}
|
|
@@ -14348,17 +14438,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
14348
14438
|
}
|
|
14349
14439
|
|
|
14350
14440
|
// src/commands/host/workspace.ts
|
|
14351
|
-
var
|
|
14352
|
-
var
|
|
14353
|
-
var
|
|
14354
|
-
var
|
|
14441
|
+
var fs30 = __toESM(require("fs"));
|
|
14442
|
+
var os27 = __toESM(require("os"));
|
|
14443
|
+
var path34 = __toESM(require("path"));
|
|
14444
|
+
var import_node_child_process13 = require("child_process");
|
|
14355
14445
|
var import_node_util4 = require("util");
|
|
14356
|
-
var execFileP4 = (0, import_node_util4.promisify)(
|
|
14446
|
+
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
|
|
14357
14447
|
function isAbsolutePathTarget(target) {
|
|
14358
|
-
return
|
|
14448
|
+
return path34.isAbsolute(target);
|
|
14359
14449
|
}
|
|
14360
14450
|
function selfHostedWorkspaceRoot() {
|
|
14361
|
-
return
|
|
14451
|
+
return path34.join(os27.homedir(), ".codeam", "self-hosted");
|
|
14362
14452
|
}
|
|
14363
14453
|
function nonInteractiveGitEnv() {
|
|
14364
14454
|
return {
|
|
@@ -14411,13 +14501,13 @@ async function fetchGithubIdentity(token) {
|
|
|
14411
14501
|
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
14412
14502
|
const gh = githubOwnerRepo(repoRef.trim());
|
|
14413
14503
|
if (!gh || !cloneToken) return;
|
|
14414
|
-
const credFile =
|
|
14415
|
-
|
|
14504
|
+
const credFile = path34.join(dest, ".git", "codeam-credentials");
|
|
14505
|
+
fs30.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
14416
14506
|
`, { mode: 384 });
|
|
14417
14507
|
restrictToOwner(credFile);
|
|
14418
14508
|
const env = nonInteractiveGitEnv();
|
|
14419
14509
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
14420
|
-
const credFilePosix = credFile.split(
|
|
14510
|
+
const credFilePosix = credFile.split(path34.sep).join("/");
|
|
14421
14511
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
14422
14512
|
});
|
|
14423
14513
|
await git2([
|
|
@@ -14453,17 +14543,17 @@ function maskToken(text, cloneToken) {
|
|
|
14453
14543
|
}
|
|
14454
14544
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
14455
14545
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
14456
|
-
if (!
|
|
14546
|
+
if (!fs30.existsSync(repoOrPath)) {
|
|
14457
14547
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
14458
14548
|
}
|
|
14459
14549
|
return repoOrPath;
|
|
14460
14550
|
}
|
|
14461
|
-
const dest =
|
|
14462
|
-
if (
|
|
14551
|
+
const dest = path34.join(selfHostedWorkspaceRoot(), deployId);
|
|
14552
|
+
if (fs30.existsSync(path34.join(dest, ".git"))) {
|
|
14463
14553
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
14464
14554
|
return dest;
|
|
14465
14555
|
}
|
|
14466
|
-
|
|
14556
|
+
fs30.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
14467
14557
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
14468
14558
|
try {
|
|
14469
14559
|
await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -14480,9 +14570,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
14480
14570
|
}
|
|
14481
14571
|
|
|
14482
14572
|
// src/commands/host/agent-provisioning.ts
|
|
14483
|
-
var
|
|
14484
|
-
var
|
|
14485
|
-
var
|
|
14573
|
+
var fs31 = __toESM(require("fs"));
|
|
14574
|
+
var os28 = __toESM(require("os"));
|
|
14575
|
+
var path35 = __toESM(require("path"));
|
|
14486
14576
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
14487
14577
|
claude_code: "claude",
|
|
14488
14578
|
claude: "claude",
|
|
@@ -14497,22 +14587,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
14497
14587
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
14498
14588
|
}
|
|
14499
14589
|
function ensureDir(dir) {
|
|
14500
|
-
|
|
14590
|
+
fs31.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
14501
14591
|
}
|
|
14502
14592
|
function writeFile0600(filePath, contents) {
|
|
14503
|
-
ensureDir(
|
|
14504
|
-
|
|
14593
|
+
ensureDir(path35.dirname(filePath));
|
|
14594
|
+
fs31.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
14505
14595
|
restrictToOwner(filePath);
|
|
14506
14596
|
}
|
|
14507
14597
|
function rmIfExists(filePath) {
|
|
14508
14598
|
try {
|
|
14509
|
-
|
|
14599
|
+
fs31.rmSync(filePath, { force: true });
|
|
14510
14600
|
} catch {
|
|
14511
14601
|
}
|
|
14512
14602
|
}
|
|
14513
14603
|
var claudeProvisioner = {
|
|
14514
14604
|
write(auth, home) {
|
|
14515
|
-
const credentialsJson =
|
|
14605
|
+
const credentialsJson = path35.join(home, ".claude", ".credentials.json");
|
|
14516
14606
|
if (auth.kind === "api_key") {
|
|
14517
14607
|
rmIfExists(credentialsJson);
|
|
14518
14608
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -14524,8 +14614,8 @@ var claudeProvisioner = {
|
|
|
14524
14614
|
} else {
|
|
14525
14615
|
rmIfExists(credentialsJson);
|
|
14526
14616
|
}
|
|
14527
|
-
const claudeJson =
|
|
14528
|
-
if (!
|
|
14617
|
+
const claudeJson = path35.join(home, ".claude.json");
|
|
14618
|
+
if (!fs31.existsSync(claudeJson)) {
|
|
14529
14619
|
writeFile0600(
|
|
14530
14620
|
claudeJson,
|
|
14531
14621
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -14536,7 +14626,7 @@ var claudeProvisioner = {
|
|
|
14536
14626
|
};
|
|
14537
14627
|
var codexProvisioner = {
|
|
14538
14628
|
write(auth, home) {
|
|
14539
|
-
const authJson =
|
|
14629
|
+
const authJson = path35.join(home, ".codex", "auth.json");
|
|
14540
14630
|
if (auth.kind === "api_key") {
|
|
14541
14631
|
rmIfExists(authJson);
|
|
14542
14632
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -14547,8 +14637,8 @@ var codexProvisioner = {
|
|
|
14547
14637
|
};
|
|
14548
14638
|
var geminiProvisioner = {
|
|
14549
14639
|
write(auth, home) {
|
|
14550
|
-
const settingsJson =
|
|
14551
|
-
const oauthCreds =
|
|
14640
|
+
const settingsJson = path35.join(home, ".gemini", "settings.json");
|
|
14641
|
+
const oauthCreds = path35.join(home, ".gemini", "oauth_creds.json");
|
|
14552
14642
|
if (auth.kind === "api_key") {
|
|
14553
14643
|
rmIfExists(oauthCreds);
|
|
14554
14644
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -14561,7 +14651,7 @@ var geminiProvisioner = {
|
|
|
14561
14651
|
};
|
|
14562
14652
|
var cursorProvisioner = {
|
|
14563
14653
|
write(auth, home) {
|
|
14564
|
-
const authJson =
|
|
14654
|
+
const authJson = path35.join(home, ".config", "cursor", "auth.json");
|
|
14565
14655
|
if (auth.kind === "api_key") {
|
|
14566
14656
|
rmIfExists(authJson);
|
|
14567
14657
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -14598,7 +14688,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
14598
14688
|
this.agentId = agentId;
|
|
14599
14689
|
}
|
|
14600
14690
|
};
|
|
14601
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
14691
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir()) {
|
|
14602
14692
|
const internal = toInternalAgentId(publicAgentId);
|
|
14603
14693
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
14604
14694
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -14607,12 +14697,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os27.homedir(
|
|
|
14607
14697
|
}
|
|
14608
14698
|
|
|
14609
14699
|
// src/commands/host/git-tooling.ts
|
|
14610
|
-
var
|
|
14611
|
-
var
|
|
14612
|
-
var
|
|
14613
|
-
var
|
|
14700
|
+
var import_node_child_process14 = require("child_process");
|
|
14701
|
+
var fs32 = __toESM(require("fs"));
|
|
14702
|
+
var os29 = __toESM(require("os"));
|
|
14703
|
+
var path36 = __toESM(require("path"));
|
|
14614
14704
|
function codeamBinDir() {
|
|
14615
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
14705
|
+
return process.env.CODEAM_BIN_DIR ?? path36.join(os29.homedir(), ".codeam", "bin");
|
|
14616
14706
|
}
|
|
14617
14707
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
14618
14708
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -14644,7 +14734,7 @@ async function download(url, dest) {
|
|
|
14644
14734
|
const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
|
|
14645
14735
|
if (!res.ok || !res.body) return false;
|
|
14646
14736
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
14647
|
-
|
|
14737
|
+
fs32.writeFileSync(dest, buf);
|
|
14648
14738
|
return true;
|
|
14649
14739
|
} catch {
|
|
14650
14740
|
return false;
|
|
@@ -14667,8 +14757,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
14667
14757
|
const version3 = await resolveVersionFn(token);
|
|
14668
14758
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
14669
14759
|
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
14670
|
-
const tmpRoot =
|
|
14671
|
-
const archive =
|
|
14760
|
+
const tmpRoot = fs32.mkdtempSync(path36.join(os29.tmpdir(), "codeam-gh-"));
|
|
14761
|
+
const archive = path36.join(tmpRoot, `${asset}.${ext}`);
|
|
14672
14762
|
if (!await downloadFn(url, archive)) {
|
|
14673
14763
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
14674
14764
|
return null;
|
|
@@ -14678,16 +14768,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
14678
14768
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
14679
14769
|
return null;
|
|
14680
14770
|
}
|
|
14681
|
-
const extractedBin =
|
|
14682
|
-
if (!
|
|
14771
|
+
const extractedBin = path36.join(tmpRoot, asset, "bin", binaryName);
|
|
14772
|
+
if (!fs32.existsSync(extractedBin)) {
|
|
14683
14773
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
14684
14774
|
return null;
|
|
14685
14775
|
}
|
|
14686
14776
|
const binDir = codeamBinDir();
|
|
14687
|
-
|
|
14688
|
-
const target =
|
|
14689
|
-
|
|
14690
|
-
|
|
14777
|
+
fs32.mkdirSync(binDir, { recursive: true });
|
|
14778
|
+
const target = path36.join(binDir, binaryName);
|
|
14779
|
+
fs32.copyFileSync(extractedBin, target);
|
|
14780
|
+
fs32.chmodSync(target, 493);
|
|
14691
14781
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
14692
14782
|
return target;
|
|
14693
14783
|
} catch (e) {
|
|
@@ -14721,7 +14811,7 @@ var defaultGitToolingRunner = {
|
|
|
14721
14811
|
which(cmd) {
|
|
14722
14812
|
try {
|
|
14723
14813
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
14724
|
-
(0,
|
|
14814
|
+
(0, import_node_child_process14.execFileSync)(probe, [cmd], { stdio: "ignore" });
|
|
14725
14815
|
return true;
|
|
14726
14816
|
} catch {
|
|
14727
14817
|
return false;
|
|
@@ -14729,7 +14819,7 @@ var defaultGitToolingRunner = {
|
|
|
14729
14819
|
},
|
|
14730
14820
|
run(cmd, args2, opts = {}) {
|
|
14731
14821
|
return new Promise((resolve7) => {
|
|
14732
|
-
const child = (0,
|
|
14822
|
+
const child = (0, import_node_child_process14.spawn)(cmd, args2, {
|
|
14733
14823
|
stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
|
|
14734
14824
|
});
|
|
14735
14825
|
let stderr = "";
|
|
@@ -14769,6 +14859,16 @@ var defaultGitToolingRunner = {
|
|
|
14769
14859
|
|
|
14770
14860
|
// src/services/headroom/stats-reporter.ts
|
|
14771
14861
|
var DEFAULT_INPUT_PRICE_PER_MILLION = 3;
|
|
14862
|
+
var HEADROOM_FETCH_TIMEOUT_MS = 1e4;
|
|
14863
|
+
async function fetchWithTimeout(url, init, timeoutMs = HEADROOM_FETCH_TIMEOUT_MS) {
|
|
14864
|
+
const controller = new AbortController();
|
|
14865
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
14866
|
+
try {
|
|
14867
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
14868
|
+
} finally {
|
|
14869
|
+
clearTimeout(timer);
|
|
14870
|
+
}
|
|
14871
|
+
}
|
|
14772
14872
|
var ZERO = {
|
|
14773
14873
|
rawTokensEst: 0,
|
|
14774
14874
|
sentTokensEst: 0,
|
|
@@ -14831,6 +14931,9 @@ var HeadroomStatsReporter = class {
|
|
|
14831
14931
|
deps;
|
|
14832
14932
|
timer = null;
|
|
14833
14933
|
prev = ZERO;
|
|
14934
|
+
/** Period spend observed on the previous budgeted post — lets `budgetReached`
|
|
14935
|
+
* fire once per crossing instead of on every post while over the cap. */
|
|
14936
|
+
prevPeriodSpendUsd = null;
|
|
14834
14937
|
start() {
|
|
14835
14938
|
const ms = this.deps.intervalMs ?? (Number(process.env.HEADROOM_STATS_POLL_INTERVAL_MS ?? "30000") || 3e4);
|
|
14836
14939
|
this.timer = setInterval(() => void this.tick(), ms);
|
|
@@ -14847,11 +14950,18 @@ var HeadroomStatsReporter = class {
|
|
|
14847
14950
|
if (delta.compressionTokens > 0 || delta.compressionSavingsUsd > 0 || delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0) {
|
|
14848
14951
|
const getBudgetEnv = this.deps.getBudgetEnv ?? defaultGetBudgetEnv;
|
|
14849
14952
|
const budgetEnv = getBudgetEnv();
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14953
|
+
let budget;
|
|
14954
|
+
if (budgetEnv) {
|
|
14955
|
+
const periodSpendUsd = stats.cost?.cost_with_headroom_usd ?? 0;
|
|
14956
|
+
const crossed = periodSpendUsd >= budgetEnv.budgetUsd && (this.prevPeriodSpendUsd === null || this.prevPeriodSpendUsd < budgetEnv.budgetUsd);
|
|
14957
|
+
this.prevPeriodSpendUsd = periodSpendUsd;
|
|
14958
|
+
budget = {
|
|
14959
|
+
periodSpendUsd,
|
|
14960
|
+
budgetUsd: budgetEnv.budgetUsd,
|
|
14961
|
+
budgetPeriod: budgetEnv.budgetPeriod,
|
|
14962
|
+
...crossed ? { budgetReached: true } : {}
|
|
14963
|
+
};
|
|
14964
|
+
}
|
|
14855
14965
|
await this.deps.postSavings(delta, budget);
|
|
14856
14966
|
}
|
|
14857
14967
|
} catch {
|
|
@@ -14866,23 +14976,23 @@ var HeadroomStatsReporter = class {
|
|
|
14866
14976
|
};
|
|
14867
14977
|
|
|
14868
14978
|
// src/lib/updateNotifier.ts
|
|
14869
|
-
var
|
|
14870
|
-
var
|
|
14871
|
-
var
|
|
14979
|
+
var fs33 = __toESM(require("fs"));
|
|
14980
|
+
var os30 = __toESM(require("os"));
|
|
14981
|
+
var path37 = __toESM(require("path"));
|
|
14872
14982
|
var https6 = __toESM(require("https"));
|
|
14873
|
-
var
|
|
14983
|
+
var import_node_child_process15 = require("child_process");
|
|
14874
14984
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
14875
14985
|
var PKG_NAME = "codeam-cli";
|
|
14876
14986
|
var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
14877
14987
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
14878
14988
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
14879
14989
|
function cachePath() {
|
|
14880
|
-
const dir =
|
|
14881
|
-
return
|
|
14990
|
+
const dir = path37.join(os30.homedir(), ".codeam");
|
|
14991
|
+
return path37.join(dir, "update-check.json");
|
|
14882
14992
|
}
|
|
14883
14993
|
function readCache() {
|
|
14884
14994
|
try {
|
|
14885
|
-
const raw =
|
|
14995
|
+
const raw = fs33.readFileSync(cachePath(), "utf8");
|
|
14886
14996
|
const parsed = JSON.parse(raw);
|
|
14887
14997
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
14888
14998
|
return parsed;
|
|
@@ -14893,10 +15003,10 @@ function readCache() {
|
|
|
14893
15003
|
function writeCache(cache) {
|
|
14894
15004
|
try {
|
|
14895
15005
|
const file = cachePath();
|
|
14896
|
-
|
|
15006
|
+
fs33.mkdirSync(path37.dirname(file), { recursive: true });
|
|
14897
15007
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
14898
|
-
|
|
14899
|
-
|
|
15008
|
+
fs33.writeFileSync(tmp, JSON.stringify(cache));
|
|
15009
|
+
fs33.renameSync(tmp, file);
|
|
14900
15010
|
} catch {
|
|
14901
15011
|
}
|
|
14902
15012
|
}
|
|
@@ -14964,14 +15074,14 @@ function notifyIfStale(currentVersion, latest) {
|
|
|
14964
15074
|
}
|
|
14965
15075
|
function isLinkedInstall() {
|
|
14966
15076
|
try {
|
|
14967
|
-
const root = (0,
|
|
15077
|
+
const root = (0, import_node_child_process15.execSync)("npm root -g", {
|
|
14968
15078
|
encoding: "utf8",
|
|
14969
15079
|
stdio: ["ignore", "pipe", "ignore"],
|
|
14970
15080
|
timeout: 2e3
|
|
14971
15081
|
}).trim();
|
|
14972
15082
|
if (!root) return false;
|
|
14973
|
-
const pkgPath =
|
|
14974
|
-
return
|
|
15083
|
+
const pkgPath = path37.join(root, PKG_NAME);
|
|
15084
|
+
return fs33.lstatSync(pkgPath).isSymbolicLink();
|
|
14975
15085
|
} catch {
|
|
14976
15086
|
return false;
|
|
14977
15087
|
}
|
|
@@ -14992,7 +15102,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
14992
15102
|
|
|
14993
15103
|
`
|
|
14994
15104
|
);
|
|
14995
|
-
const install = (0,
|
|
15105
|
+
const install = (0, import_node_child_process15.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
|
|
14996
15106
|
stdio: "inherit",
|
|
14997
15107
|
env: process.env
|
|
14998
15108
|
});
|
|
@@ -15007,13 +15117,13 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
15007
15117
|
return;
|
|
15008
15118
|
}
|
|
15009
15119
|
try {
|
|
15010
|
-
|
|
15120
|
+
fs33.unlinkSync(cachePath());
|
|
15011
15121
|
} catch {
|
|
15012
15122
|
}
|
|
15013
15123
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
15014
15124
|
|
|
15015
15125
|
`);
|
|
15016
|
-
const child = (0,
|
|
15126
|
+
const child = (0, import_node_child_process15.spawnSync)("codeam", process.argv.slice(2), {
|
|
15017
15127
|
stdio: "inherit",
|
|
15018
15128
|
env: process.env
|
|
15019
15129
|
});
|
|
@@ -15023,7 +15133,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
15023
15133
|
if (process.env.NODE_ENV === "test") return;
|
|
15024
15134
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
15025
15135
|
if (process.env.CI) return;
|
|
15026
|
-
const current = true ? "2.53.
|
|
15136
|
+
const current = true ? "2.53.3" : null;
|
|
15027
15137
|
if (!current) return;
|
|
15028
15138
|
const cache = readCache();
|
|
15029
15139
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15040,7 +15150,7 @@ function checkForUpdates() {
|
|
|
15040
15150
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
15041
15151
|
if (process.env.CI) return;
|
|
15042
15152
|
if (!process.stdout.isTTY) return;
|
|
15043
|
-
const current = true ? "2.53.
|
|
15153
|
+
const current = true ? "2.53.3" : null;
|
|
15044
15154
|
if (!current) return;
|
|
15045
15155
|
const cache = readCache();
|
|
15046
15156
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15074,11 +15184,11 @@ function maybeStartHeadroomReporter(ctx) {
|
|
|
15074
15184
|
process.env["HEADROOM_AGENT"] ?? "claude"
|
|
15075
15185
|
),
|
|
15076
15186
|
fetchStats: async () => {
|
|
15077
|
-
const res = await
|
|
15187
|
+
const res = await fetchWithTimeout("http://localhost:8787/stats");
|
|
15078
15188
|
return res.json();
|
|
15079
15189
|
},
|
|
15080
15190
|
postSavings: async (delta, budget) => {
|
|
15081
|
-
await
|
|
15191
|
+
const res = await fetchWithTimeout(ingestUrl, {
|
|
15082
15192
|
method: "POST",
|
|
15083
15193
|
headers: {
|
|
15084
15194
|
"Content-Type": "application/json",
|
|
@@ -15092,10 +15202,14 @@ function maybeStartHeadroomReporter(ctx) {
|
|
|
15092
15202
|
...budget ? {
|
|
15093
15203
|
periodSpendUsd: budget.periodSpendUsd,
|
|
15094
15204
|
budgetUsd: budget.budgetUsd,
|
|
15095
|
-
budgetPeriod: budget.budgetPeriod
|
|
15205
|
+
budgetPeriod: budget.budgetPeriod,
|
|
15206
|
+
budgetReached: budget.budgetReached
|
|
15096
15207
|
} : {}
|
|
15097
15208
|
})
|
|
15098
15209
|
});
|
|
15210
|
+
if (!res.ok) {
|
|
15211
|
+
log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
|
|
15212
|
+
}
|
|
15099
15213
|
}
|
|
15100
15214
|
});
|
|
15101
15215
|
reporter.start();
|
|
@@ -15112,22 +15226,22 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
15112
15226
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
15113
15227
|
try {
|
|
15114
15228
|
const file = headroomConfigPath();
|
|
15115
|
-
if (!
|
|
15116
|
-
const cfg = JSON.parse(
|
|
15229
|
+
if (!fs34.existsSync(file)) return null;
|
|
15230
|
+
const cfg = JSON.parse(fs34.readFileSync(file, "utf8"));
|
|
15117
15231
|
if (!cfg?.enabled) return null;
|
|
15118
15232
|
const agent = cfg.agent ?? "claude";
|
|
15119
15233
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
15120
15234
|
const reporter = new HeadroomStatsReporter({
|
|
15121
15235
|
inputPricePerMillionUsd: resolveInputPricePerMillion(agent),
|
|
15122
15236
|
fetchStats: async () => {
|
|
15123
|
-
const res = await
|
|
15237
|
+
const res = await fetchWithTimeout("http://localhost:8787/stats");
|
|
15124
15238
|
return res.json();
|
|
15125
15239
|
},
|
|
15126
15240
|
// Body MUST match HeadroomSavingsDto + PluginAuthGuard (sessionId +
|
|
15127
15241
|
// pluginId in the body) — same shape as the codespace reporter above and
|
|
15128
15242
|
// the on-demand `startReporter` in handlers.ts.
|
|
15129
15243
|
postSavings: async (delta, budget) => {
|
|
15130
|
-
await
|
|
15244
|
+
const res = await fetchWithTimeout(ingestUrl, {
|
|
15131
15245
|
method: "POST",
|
|
15132
15246
|
headers: {
|
|
15133
15247
|
"Content-Type": "application/json",
|
|
@@ -15141,10 +15255,14 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
15141
15255
|
...budget ? {
|
|
15142
15256
|
periodSpendUsd: budget.periodSpendUsd,
|
|
15143
15257
|
budgetUsd: budget.budgetUsd,
|
|
15144
|
-
budgetPeriod: budget.budgetPeriod
|
|
15258
|
+
budgetPeriod: budget.budgetPeriod,
|
|
15259
|
+
budgetReached: budget.budgetReached
|
|
15145
15260
|
} : {}
|
|
15146
15261
|
})
|
|
15147
15262
|
});
|
|
15263
|
+
if (!res.ok) {
|
|
15264
|
+
log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
|
|
15265
|
+
}
|
|
15148
15266
|
}
|
|
15149
15267
|
});
|
|
15150
15268
|
reporter.start();
|
|
@@ -15204,7 +15322,7 @@ var HEADROOM_MIN_FREE_DISK_BYTES = 2 * 1024 * 1024 * 1024;
|
|
|
15204
15322
|
var defaultHeadroomRunner = {
|
|
15205
15323
|
which(cmd) {
|
|
15206
15324
|
try {
|
|
15207
|
-
(0,
|
|
15325
|
+
(0, import_node_child_process16.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
15208
15326
|
return true;
|
|
15209
15327
|
} catch {
|
|
15210
15328
|
return false;
|
|
@@ -15213,7 +15331,7 @@ var defaultHeadroomRunner = {
|
|
|
15213
15331
|
run(cmd, args2, opts = {}) {
|
|
15214
15332
|
return new Promise((resolve7) => {
|
|
15215
15333
|
const spawnEnv = opts.env ?? process.env;
|
|
15216
|
-
const child = (0,
|
|
15334
|
+
const child = (0, import_node_child_process16.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
|
|
15217
15335
|
let stderrBuf = "";
|
|
15218
15336
|
let stdoutBuf = "";
|
|
15219
15337
|
let settled = false;
|
|
@@ -15377,15 +15495,15 @@ function isHeadroomSupportedAgent(agentId) {
|
|
|
15377
15495
|
return n.startsWith("claude") || n.startsWith("codex") || n.startsWith("copilot");
|
|
15378
15496
|
}
|
|
15379
15497
|
function headroomConfigPath() {
|
|
15380
|
-
return
|
|
15498
|
+
return path38.join(os31.homedir(), ".codeam", "headroom-config.json");
|
|
15381
15499
|
}
|
|
15382
15500
|
function persistHeadroomConfig(config) {
|
|
15383
15501
|
try {
|
|
15384
15502
|
const file = headroomConfigPath();
|
|
15385
|
-
|
|
15503
|
+
fs34.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
|
|
15386
15504
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
15387
|
-
|
|
15388
|
-
|
|
15505
|
+
fs34.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
15506
|
+
fs34.renameSync(tmp, file);
|
|
15389
15507
|
restrictToOwner(file);
|
|
15390
15508
|
} catch (err) {
|
|
15391
15509
|
log.warn(
|
|
@@ -15395,21 +15513,21 @@ function persistHeadroomConfig(config) {
|
|
|
15395
15513
|
}
|
|
15396
15514
|
}
|
|
15397
15515
|
function agentSettingsPath(kind) {
|
|
15398
|
-
const home =
|
|
15399
|
-
if (kind === "claude") return
|
|
15400
|
-
if (kind === "codex") return
|
|
15401
|
-
if (kind === "copilot") return
|
|
15516
|
+
const home = os31.homedir();
|
|
15517
|
+
if (kind === "claude") return path38.join(home, ".claude", "settings.json");
|
|
15518
|
+
if (kind === "codex") return path38.join(home, ".codex", "auth.json");
|
|
15519
|
+
if (kind === "copilot") return path38.join(home, ".config", "github-copilot", "hosts.json");
|
|
15402
15520
|
return null;
|
|
15403
15521
|
}
|
|
15404
15522
|
function backupAgentHeadroomConfig(kind) {
|
|
15405
15523
|
const src = agentSettingsPath(kind);
|
|
15406
15524
|
if (!src) return;
|
|
15407
15525
|
try {
|
|
15408
|
-
if (!
|
|
15409
|
-
const dest =
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15526
|
+
if (!fs34.existsSync(src)) return;
|
|
15527
|
+
const dest = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
15528
|
+
fs34.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
|
|
15529
|
+
fs34.copyFileSync(src, dest);
|
|
15530
|
+
fs34.chmodSync(dest, 384);
|
|
15413
15531
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
15414
15532
|
} catch (err) {
|
|
15415
15533
|
log.warn(
|
|
@@ -15421,12 +15539,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
15421
15539
|
function restoreAgentHeadroomConfig(kind) {
|
|
15422
15540
|
const dest = agentSettingsPath(kind);
|
|
15423
15541
|
if (!dest) return false;
|
|
15424
|
-
const src =
|
|
15425
|
-
if (!
|
|
15542
|
+
const src = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
15543
|
+
if (!fs34.existsSync(src)) return false;
|
|
15426
15544
|
try {
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15545
|
+
fs34.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
|
|
15546
|
+
fs34.copyFileSync(src, dest);
|
|
15547
|
+
fs34.chmodSync(dest, 384);
|
|
15430
15548
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
15431
15549
|
return true;
|
|
15432
15550
|
} catch (err) {
|
|
@@ -15439,7 +15557,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
15439
15557
|
}
|
|
15440
15558
|
function readHeadroomChildEnv() {
|
|
15441
15559
|
try {
|
|
15442
|
-
const raw =
|
|
15560
|
+
const raw = fs34.readFileSync(headroomConfigPath(), "utf8");
|
|
15443
15561
|
const parsed = JSON.parse(raw);
|
|
15444
15562
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
15445
15563
|
const o = parsed;
|
|
@@ -15464,37 +15582,37 @@ function bundledClaudeBinDir() {
|
|
|
15464
15582
|
const roots = /* @__PURE__ */ new Set();
|
|
15465
15583
|
let dir = __dirname;
|
|
15466
15584
|
for (let i = 0; i < 6; i++) {
|
|
15467
|
-
roots.add(
|
|
15468
|
-
const parent =
|
|
15585
|
+
roots.add(path38.join(dir, "node_modules"));
|
|
15586
|
+
const parent = path38.dirname(dir);
|
|
15469
15587
|
if (parent === dir) break;
|
|
15470
15588
|
dir = parent;
|
|
15471
15589
|
}
|
|
15472
15590
|
try {
|
|
15473
15591
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
15474
|
-
const marker = `${
|
|
15592
|
+
const marker = `${path38.sep}@anthropic-ai${path38.sep}`;
|
|
15475
15593
|
const idx = main2.lastIndexOf(marker);
|
|
15476
15594
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
15477
15595
|
} catch {
|
|
15478
15596
|
}
|
|
15479
15597
|
for (const nm of roots) {
|
|
15480
|
-
const atAnthropic =
|
|
15598
|
+
const atAnthropic = path38.join(nm, "@anthropic-ai");
|
|
15481
15599
|
let entries;
|
|
15482
15600
|
try {
|
|
15483
|
-
entries =
|
|
15601
|
+
entries = fs34.readdirSync(atAnthropic);
|
|
15484
15602
|
} catch {
|
|
15485
15603
|
continue;
|
|
15486
15604
|
}
|
|
15487
15605
|
for (const entry of entries) {
|
|
15488
15606
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
15489
|
-
const bin =
|
|
15490
|
-
if (
|
|
15607
|
+
const bin = path38.join(atAnthropic, entry, "claude");
|
|
15608
|
+
if (fs34.existsSync(bin)) return path38.dirname(bin);
|
|
15491
15609
|
}
|
|
15492
15610
|
}
|
|
15493
15611
|
return null;
|
|
15494
15612
|
}
|
|
15495
15613
|
async function getFreeDiskBytes(dir) {
|
|
15496
15614
|
try {
|
|
15497
|
-
const s = await
|
|
15615
|
+
const s = await fs34.promises.statfs(dir);
|
|
15498
15616
|
return s.bsize * s.bavail;
|
|
15499
15617
|
} catch {
|
|
15500
15618
|
return null;
|
|
@@ -15686,7 +15804,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
15686
15804
|
if (initKind === "claude") {
|
|
15687
15805
|
const claudeDir = bundledClaudeBinDir();
|
|
15688
15806
|
if (claudeDir) {
|
|
15689
|
-
initEnv.PATH = `${claudeDir}${
|
|
15807
|
+
initEnv.PATH = `${claudeDir}${path38.delimiter}${process.env["PATH"] ?? ""}`;
|
|
15690
15808
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
15691
15809
|
} else {
|
|
15692
15810
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -15710,7 +15828,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
15710
15828
|
onProgress("proxy");
|
|
15711
15829
|
try {
|
|
15712
15830
|
const proxyEnv = { ...process.env, HEADROOM_KOMPRESS_BACKEND: "onnx_cpu" };
|
|
15713
|
-
const proxy = (0,
|
|
15831
|
+
const proxy = (0, import_node_child_process16.spawn)(
|
|
15714
15832
|
"headroom",
|
|
15715
15833
|
["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
|
|
15716
15834
|
{
|
|
@@ -15726,6 +15844,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
15726
15844
|
);
|
|
15727
15845
|
});
|
|
15728
15846
|
proxy.unref();
|
|
15847
|
+
writeHeadroomProxyPidfile(proxy.pid);
|
|
15729
15848
|
} catch (e) {
|
|
15730
15849
|
log.warn(
|
|
15731
15850
|
"host-agent",
|
|
@@ -15735,18 +15854,18 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
15735
15854
|
onProgress("ready");
|
|
15736
15855
|
return true;
|
|
15737
15856
|
}
|
|
15738
|
-
var defaultSpawner = (env, cwd, args2 = []) => (0,
|
|
15857
|
+
var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process16.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
|
|
15739
15858
|
cwd,
|
|
15740
15859
|
env: { ...process.env, ...env },
|
|
15741
15860
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15742
15861
|
detached: false
|
|
15743
15862
|
});
|
|
15744
15863
|
function currentCliVersion() {
|
|
15745
|
-
return true ? "2.53.
|
|
15864
|
+
return true ? "2.53.3" : null;
|
|
15746
15865
|
}
|
|
15747
15866
|
function runCmd(cmd, args2, timeoutMs) {
|
|
15748
15867
|
return new Promise((resolve7) => {
|
|
15749
|
-
(0,
|
|
15868
|
+
(0, import_node_child_process16.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
15750
15869
|
const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
|
|
15751
15870
|
resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
15752
15871
|
});
|
|
@@ -15817,22 +15936,19 @@ var defaultOnUpdated = (version3) => {
|
|
|
15817
15936
|
};
|
|
15818
15937
|
var defaultDisableService = () => {
|
|
15819
15938
|
try {
|
|
15820
|
-
(0,
|
|
15939
|
+
(0, import_node_child_process16.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
15821
15940
|
} catch {
|
|
15822
15941
|
}
|
|
15823
15942
|
};
|
|
15824
15943
|
var defaultTeardownHeadroom = () => {
|
|
15825
15944
|
try {
|
|
15826
|
-
const kind = JSON.parse(
|
|
15945
|
+
const kind = JSON.parse(fs34.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
15827
15946
|
if (kind) {
|
|
15828
|
-
(0,
|
|
15947
|
+
(0, import_node_child_process16.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
15829
15948
|
}
|
|
15830
15949
|
} catch {
|
|
15831
15950
|
}
|
|
15832
|
-
|
|
15833
|
-
(0, import_node_child_process15.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
|
|
15834
|
-
} catch {
|
|
15835
|
-
}
|
|
15951
|
+
killHeadroomProxy();
|
|
15836
15952
|
persistHeadroomConfig({ enabled: false });
|
|
15837
15953
|
};
|
|
15838
15954
|
var HostAgentSupervisor = class {
|
|
@@ -16137,9 +16253,9 @@ var HostAgentSupervisor = class {
|
|
|
16137
16253
|
API_TIMEOUT_MS: "3000000",
|
|
16138
16254
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
16139
16255
|
};
|
|
16140
|
-
const houseConfigDir =
|
|
16256
|
+
const houseConfigDir = path38.join(os31.homedir(), ".codeam", "house-claude");
|
|
16141
16257
|
try {
|
|
16142
|
-
|
|
16258
|
+
fs34.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
16143
16259
|
} catch {
|
|
16144
16260
|
}
|
|
16145
16261
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -16157,14 +16273,14 @@ var HostAgentSupervisor = class {
|
|
|
16157
16273
|
report("installing", "installing agent CLI");
|
|
16158
16274
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
16159
16275
|
}
|
|
16160
|
-
const home = process.env.HOME ||
|
|
16276
|
+
const home = process.env.HOME || os31.homedir();
|
|
16161
16277
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
16162
16278
|
if (payload.cloneToken) {
|
|
16163
16279
|
try {
|
|
16164
16280
|
report("preparing", "configuring git tooling");
|
|
16165
16281
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
16166
16282
|
if (ghCmd) {
|
|
16167
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
16283
|
+
childEnv.PATH = `${codeamBinDir()}${path38.delimiter}${childEnv.PATH}`;
|
|
16168
16284
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
16169
16285
|
}
|
|
16170
16286
|
} catch (e) {
|
|
@@ -16180,7 +16296,7 @@ var HostAgentSupervisor = class {
|
|
|
16180
16296
|
}
|
|
16181
16297
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
16182
16298
|
report("headroom", "setting up Headroom proxy");
|
|
16183
|
-
const freeBytes = await this.getFreeDisk(
|
|
16299
|
+
const freeBytes = await this.getFreeDisk(os31.homedir());
|
|
16184
16300
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
16185
16301
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
16186
16302
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -16302,8 +16418,8 @@ var HostAgentSupervisor = class {
|
|
|
16302
16418
|
*/
|
|
16303
16419
|
runAgentInstall(script) {
|
|
16304
16420
|
return new Promise((resolve7) => {
|
|
16305
|
-
const home = process.env.HOME ||
|
|
16306
|
-
const child = (0,
|
|
16421
|
+
const home = process.env.HOME || os31.homedir();
|
|
16422
|
+
const child = (0, import_node_child_process16.spawn)("sh", ["-c", script], {
|
|
16307
16423
|
env: { ...process.env, HOME: home },
|
|
16308
16424
|
stdio: ["ignore", "pipe", "pipe"]
|
|
16309
16425
|
});
|
|
@@ -16484,9 +16600,9 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
16484
16600
|
}
|
|
16485
16601
|
|
|
16486
16602
|
// src/services/headroom/budget-relaunch.ts
|
|
16487
|
-
var
|
|
16488
|
-
var
|
|
16489
|
-
var
|
|
16603
|
+
var fs35 = __toESM(require("fs"));
|
|
16604
|
+
var os32 = __toESM(require("os"));
|
|
16605
|
+
var path39 = __toESM(require("path"));
|
|
16490
16606
|
var import_child_process13 = require("child_process");
|
|
16491
16607
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
16492
16608
|
const rawArgs = manifest.proxy_args ?? [];
|
|
@@ -16520,7 +16636,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
16520
16636
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
16521
16637
|
}
|
|
16522
16638
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
16523
|
-
const deployDir =
|
|
16639
|
+
const deployDir = path39.join(homeDir2, ".headroom", "deploy");
|
|
16524
16640
|
let profiles;
|
|
16525
16641
|
try {
|
|
16526
16642
|
profiles = deps.readDir(deployDir);
|
|
@@ -16529,7 +16645,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
16529
16645
|
}
|
|
16530
16646
|
const results = [];
|
|
16531
16647
|
for (const profile of profiles) {
|
|
16532
|
-
const manifestPath =
|
|
16648
|
+
const manifestPath = path39.join(deployDir, profile, "manifest.json");
|
|
16533
16649
|
let raw;
|
|
16534
16650
|
try {
|
|
16535
16651
|
raw = deps.readJson(manifestPath);
|
|
@@ -16561,8 +16677,8 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
16561
16677
|
}
|
|
16562
16678
|
function writeManifestReal(manifestPath, manifest) {
|
|
16563
16679
|
const tmp = manifestPath + ".codeam.tmp";
|
|
16564
|
-
|
|
16565
|
-
|
|
16680
|
+
fs35.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
16681
|
+
fs35.renameSync(tmp, manifestPath);
|
|
16566
16682
|
}
|
|
16567
16683
|
function restartDeploymentReal(profile) {
|
|
16568
16684
|
try {
|
|
@@ -16582,16 +16698,7 @@ function restartDeploymentReal(profile) {
|
|
|
16582
16698
|
}
|
|
16583
16699
|
}
|
|
16584
16700
|
function killProxyReal() {
|
|
16585
|
-
|
|
16586
|
-
const killer = (0, import_child_process13.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
16587
|
-
detached: true,
|
|
16588
|
-
stdio: "ignore"
|
|
16589
|
-
});
|
|
16590
|
-
killer.once("error", () => {
|
|
16591
|
-
});
|
|
16592
|
-
killer.unref();
|
|
16593
|
-
} catch {
|
|
16594
|
-
}
|
|
16701
|
+
killHeadroomProxy();
|
|
16595
16702
|
}
|
|
16596
16703
|
function spawnProxyReal2(budget) {
|
|
16597
16704
|
try {
|
|
@@ -16612,6 +16719,7 @@ function spawnProxyReal2(budget) {
|
|
|
16612
16719
|
log.warn("headroom-budget", `proxy relaunch error (best-effort): ${e.message}`);
|
|
16613
16720
|
});
|
|
16614
16721
|
proxy.unref();
|
|
16722
|
+
writeHeadroomProxyPidfile(proxy.pid);
|
|
16615
16723
|
} catch (e) {
|
|
16616
16724
|
log.warn(
|
|
16617
16725
|
"headroom-budget",
|
|
@@ -16620,11 +16728,11 @@ function spawnProxyReal2(budget) {
|
|
|
16620
16728
|
}
|
|
16621
16729
|
}
|
|
16622
16730
|
function makeRealApplyBudgetDeps() {
|
|
16623
|
-
const homeDir2 =
|
|
16731
|
+
const homeDir2 = os32.homedir();
|
|
16624
16732
|
return {
|
|
16625
16733
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
16626
|
-
readDir: (dir) =>
|
|
16627
|
-
readJson: (filePath) => JSON.parse(
|
|
16734
|
+
readDir: (dir) => fs35.readdirSync(dir),
|
|
16735
|
+
readJson: (filePath) => JSON.parse(fs35.readFileSync(filePath, "utf8"))
|
|
16628
16736
|
}),
|
|
16629
16737
|
writeManifest: writeManifestReal,
|
|
16630
16738
|
restartDeployment: restartDeploymentReal,
|
|
@@ -17268,9 +17376,9 @@ function activePreviewSessionIds() {
|
|
|
17268
17376
|
|
|
17269
17377
|
// src/beads/bd-adapter.ts
|
|
17270
17378
|
var import_child_process17 = require("child_process");
|
|
17271
|
-
var
|
|
17272
|
-
var
|
|
17273
|
-
var
|
|
17379
|
+
var fs40 = __toESM(require("fs"));
|
|
17380
|
+
var os34 = __toESM(require("os"));
|
|
17381
|
+
var path44 = __toESM(require("path"));
|
|
17274
17382
|
var BD_PACKAGE = "@beads/bd";
|
|
17275
17383
|
function resolveBundledBdBinary() {
|
|
17276
17384
|
return _resolveSeam.resolveBundled();
|
|
@@ -17282,11 +17390,11 @@ function _defaultResolveBundled() {
|
|
|
17282
17390
|
} catch {
|
|
17283
17391
|
return null;
|
|
17284
17392
|
}
|
|
17285
|
-
const binDir =
|
|
17393
|
+
const binDir = path44.join(path44.dirname(pkgJsonPath), "bin");
|
|
17286
17394
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17287
|
-
const binaryPath =
|
|
17395
|
+
const binaryPath = path44.join(binDir, binaryName);
|
|
17288
17396
|
try {
|
|
17289
|
-
|
|
17397
|
+
fs40.accessSync(binaryPath, fs40.constants.F_OK);
|
|
17290
17398
|
return binaryPath;
|
|
17291
17399
|
} catch {
|
|
17292
17400
|
return null;
|
|
@@ -17296,13 +17404,13 @@ function resolveBdOnPath() {
|
|
|
17296
17404
|
return _resolveSeam.resolveOnPath();
|
|
17297
17405
|
}
|
|
17298
17406
|
function _defaultResolveOnPath() {
|
|
17299
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17407
|
+
const dirs = (process.env.PATH ?? "").split(path44.delimiter).filter(Boolean);
|
|
17300
17408
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17301
17409
|
for (const dir of dirs) {
|
|
17302
17410
|
for (const candidate of candidates) {
|
|
17303
|
-
const full =
|
|
17411
|
+
const full = path44.join(dir, candidate);
|
|
17304
17412
|
try {
|
|
17305
|
-
|
|
17413
|
+
fs40.accessSync(full, fs40.constants.F_OK);
|
|
17306
17414
|
return full;
|
|
17307
17415
|
} catch {
|
|
17308
17416
|
}
|
|
@@ -17387,7 +17495,7 @@ var BdAdapter = class {
|
|
|
17387
17495
|
const env = { ...process.env };
|
|
17388
17496
|
if (!env.HOME) {
|
|
17389
17497
|
try {
|
|
17390
|
-
const home =
|
|
17498
|
+
const home = os34.homedir();
|
|
17391
17499
|
if (home) env.HOME = home;
|
|
17392
17500
|
} catch {
|
|
17393
17501
|
}
|
|
@@ -17476,9 +17584,9 @@ function coerceIssue(row, projectKey) {
|
|
|
17476
17584
|
|
|
17477
17585
|
// src/beads/provisioner.ts
|
|
17478
17586
|
var import_child_process21 = require("child_process");
|
|
17479
|
-
var
|
|
17480
|
-
var
|
|
17481
|
-
var
|
|
17587
|
+
var fs43 = __toESM(require("fs"));
|
|
17588
|
+
var os36 = __toESM(require("os"));
|
|
17589
|
+
var path47 = __toESM(require("path"));
|
|
17482
17590
|
|
|
17483
17591
|
// src/beads/install-bd.ts
|
|
17484
17592
|
var import_child_process18 = require("child_process");
|
|
@@ -17543,9 +17651,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
17543
17651
|
|
|
17544
17652
|
// src/beads/install-dolt.ts
|
|
17545
17653
|
var import_child_process19 = require("child_process");
|
|
17546
|
-
var
|
|
17547
|
-
var
|
|
17548
|
-
var
|
|
17654
|
+
var fs41 = __toESM(require("fs"));
|
|
17655
|
+
var os35 = __toESM(require("os"));
|
|
17656
|
+
var path45 = __toESM(require("path"));
|
|
17549
17657
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17550
17658
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17551
17659
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -17585,11 +17693,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
17585
17693
|
}
|
|
17586
17694
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17587
17695
|
function doltPlatformTuple(platform3, arch2) {
|
|
17588
|
-
const
|
|
17696
|
+
const os45 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
17589
17697
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
17590
17698
|
if (!a) return null;
|
|
17591
|
-
if (
|
|
17592
|
-
return `${
|
|
17699
|
+
if (os45 === "windows" && a !== "amd64") return null;
|
|
17700
|
+
return `${os45}-${a}`;
|
|
17593
17701
|
}
|
|
17594
17702
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
17595
17703
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -17634,14 +17742,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
17634
17742
|
return result;
|
|
17635
17743
|
}
|
|
17636
17744
|
var _doltPathSeam = {
|
|
17637
|
-
homedir: () =>
|
|
17745
|
+
homedir: () => os35.homedir(),
|
|
17638
17746
|
getPath: () => process.env.PATH ?? "",
|
|
17639
17747
|
setPath: (p2) => {
|
|
17640
17748
|
process.env.PATH = p2;
|
|
17641
17749
|
},
|
|
17642
17750
|
exists: (p2) => {
|
|
17643
17751
|
try {
|
|
17644
|
-
|
|
17752
|
+
fs41.accessSync(p2, fs41.constants.F_OK);
|
|
17645
17753
|
return true;
|
|
17646
17754
|
} catch {
|
|
17647
17755
|
return false;
|
|
@@ -17652,7 +17760,7 @@ function doltBinaryNames(platform3) {
|
|
|
17652
17760
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17653
17761
|
}
|
|
17654
17762
|
function knownDoltDirs(platform3) {
|
|
17655
|
-
const P3 = platform3 === "win32" ?
|
|
17763
|
+
const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
|
|
17656
17764
|
const home = _doltPathSeam.homedir();
|
|
17657
17765
|
if (platform3 === "win32") {
|
|
17658
17766
|
return [
|
|
@@ -17668,7 +17776,7 @@ function knownDoltDirs(platform3) {
|
|
|
17668
17776
|
].filter(Boolean);
|
|
17669
17777
|
}
|
|
17670
17778
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
17671
|
-
const P3 = platform3 === "win32" ?
|
|
17779
|
+
const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
|
|
17672
17780
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
17673
17781
|
const names = doltBinaryNames(platform3);
|
|
17674
17782
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17804,8 +17912,8 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
17804
17912
|
// src/beads/project-key.ts
|
|
17805
17913
|
var import_child_process20 = require("child_process");
|
|
17806
17914
|
var crypto2 = __toESM(require("crypto"));
|
|
17807
|
-
var
|
|
17808
|
-
var
|
|
17915
|
+
var fs42 = __toESM(require("fs"));
|
|
17916
|
+
var path46 = __toESM(require("path"));
|
|
17809
17917
|
function normalizeOrigin(raw) {
|
|
17810
17918
|
const trimmed = raw.trim();
|
|
17811
17919
|
if (!trimmed) return null;
|
|
@@ -17831,17 +17939,17 @@ function normalizeOrigin(raw) {
|
|
|
17831
17939
|
return `${host2}/${pathPart}`;
|
|
17832
17940
|
}
|
|
17833
17941
|
function findRepoRoot(cwd) {
|
|
17834
|
-
let dir =
|
|
17942
|
+
let dir = path46.resolve(cwd);
|
|
17835
17943
|
const seen = /* @__PURE__ */ new Set();
|
|
17836
17944
|
for (let i = 0; i < 256; i++) {
|
|
17837
17945
|
if (seen.has(dir)) return null;
|
|
17838
17946
|
seen.add(dir);
|
|
17839
17947
|
try {
|
|
17840
|
-
const stat3 =
|
|
17948
|
+
const stat3 = fs42.statSync(path46.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17841
17949
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17842
17950
|
} catch {
|
|
17843
17951
|
}
|
|
17844
|
-
const parent =
|
|
17952
|
+
const parent = path46.dirname(dir);
|
|
17845
17953
|
if (parent === dir) return null;
|
|
17846
17954
|
dir = parent;
|
|
17847
17955
|
}
|
|
@@ -17852,7 +17960,7 @@ var _execSeam2 = {
|
|
|
17852
17960
|
const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
|
|
17853
17961
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17854
17962
|
},
|
|
17855
|
-
realpath: (p2) =>
|
|
17963
|
+
realpath: (p2) => fs42.realpathSync(p2)
|
|
17856
17964
|
};
|
|
17857
17965
|
function readOrigin(cwd) {
|
|
17858
17966
|
try {
|
|
@@ -17881,7 +17989,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
17881
17989
|
} catch {
|
|
17882
17990
|
}
|
|
17883
17991
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17884
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
17992
|
+
return { projectKey: `path:${hash}`, projectLabel: path46.basename(real) || "project" };
|
|
17885
17993
|
}
|
|
17886
17994
|
|
|
17887
17995
|
// src/beads/project-prefix.ts
|
|
@@ -17923,17 +18031,17 @@ var _provisionSeam = {
|
|
|
17923
18031
|
};
|
|
17924
18032
|
var _linkSeam = {
|
|
17925
18033
|
platform: () => process.platform,
|
|
17926
|
-
homedir: () =>
|
|
18034
|
+
homedir: () => os36.homedir(),
|
|
17927
18035
|
isWritableDir: (dir) => {
|
|
17928
18036
|
try {
|
|
17929
|
-
|
|
18037
|
+
fs43.accessSync(dir, fs43.constants.W_OK);
|
|
17930
18038
|
return true;
|
|
17931
18039
|
} catch {
|
|
17932
18040
|
return false;
|
|
17933
18041
|
}
|
|
17934
18042
|
},
|
|
17935
18043
|
ensureDir: (dir) => {
|
|
17936
|
-
|
|
18044
|
+
fs43.mkdirSync(dir, { recursive: true });
|
|
17937
18045
|
},
|
|
17938
18046
|
/**
|
|
17939
18047
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -17954,9 +18062,9 @@ var _linkSeam = {
|
|
|
17954
18062
|
* which `linkBdOntoPath` creates if missing.
|
|
17955
18063
|
*/
|
|
17956
18064
|
cliBinDir: () => {
|
|
17957
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
18065
|
+
const pathDirs = (process.env.PATH ?? "").split(path47.delimiter).filter(Boolean);
|
|
17958
18066
|
const home = _linkSeam.homedir();
|
|
17959
|
-
const localBin = home ?
|
|
18067
|
+
const localBin = home ? path47.join(home, ".local", "bin") : null;
|
|
17960
18068
|
if (localBin) {
|
|
17961
18069
|
try {
|
|
17962
18070
|
_linkSeam.ensureDir(localBin);
|
|
@@ -17966,16 +18074,16 @@ var _linkSeam = {
|
|
|
17966
18074
|
const candidates = [];
|
|
17967
18075
|
if (localBin) candidates.push(localBin);
|
|
17968
18076
|
try {
|
|
17969
|
-
candidates.push(
|
|
18077
|
+
candidates.push(path47.dirname(process.execPath));
|
|
17970
18078
|
} catch {
|
|
17971
18079
|
}
|
|
17972
18080
|
candidates.push("/usr/local/bin");
|
|
17973
18081
|
const entry = process.argv[1];
|
|
17974
18082
|
if (entry) {
|
|
17975
18083
|
try {
|
|
17976
|
-
candidates.push(
|
|
18084
|
+
candidates.push(path47.dirname(fs43.realpathSync(entry)));
|
|
17977
18085
|
} catch {
|
|
17978
|
-
candidates.push(
|
|
18086
|
+
candidates.push(path47.dirname(entry));
|
|
17979
18087
|
}
|
|
17980
18088
|
}
|
|
17981
18089
|
const onPathWritable = candidates.find(
|
|
@@ -17987,20 +18095,20 @@ var _linkSeam = {
|
|
|
17987
18095
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
17988
18096
|
readlink: (linkPath) => {
|
|
17989
18097
|
try {
|
|
17990
|
-
return
|
|
18098
|
+
return fs43.readlinkSync(linkPath);
|
|
17991
18099
|
} catch {
|
|
17992
18100
|
return null;
|
|
17993
18101
|
}
|
|
17994
18102
|
},
|
|
17995
|
-
unlink: (linkPath) =>
|
|
17996
|
-
symlink: (target, linkPath) =>
|
|
18103
|
+
unlink: (linkPath) => fs43.unlinkSync(linkPath),
|
|
18104
|
+
symlink: (target, linkPath) => fs43.symlinkSync(target, linkPath)
|
|
17997
18105
|
};
|
|
17998
18106
|
function linkBdOntoPath(binaryPath) {
|
|
17999
18107
|
if (_linkSeam.platform() === "win32") return;
|
|
18000
18108
|
const binDir = _linkSeam.cliBinDir();
|
|
18001
18109
|
if (!binDir) return;
|
|
18002
18110
|
_linkSeam.ensureDir(binDir);
|
|
18003
|
-
const linkPath =
|
|
18111
|
+
const linkPath = path47.join(binDir, "bd");
|
|
18004
18112
|
if (linkPath === binaryPath) return;
|
|
18005
18113
|
const current = _linkSeam.readlink(linkPath);
|
|
18006
18114
|
if (current === binaryPath) return;
|
|
@@ -18195,7 +18303,7 @@ function dedupeRecipes(agents) {
|
|
|
18195
18303
|
|
|
18196
18304
|
// src/beads/watcher.ts
|
|
18197
18305
|
var crypto4 = __toESM(require("crypto"));
|
|
18198
|
-
var
|
|
18306
|
+
var path48 = __toESM(require("path"));
|
|
18199
18307
|
var API_BASE6 = resolveApiBaseUrl();
|
|
18200
18308
|
var DEBOUNCE_MS2 = 400;
|
|
18201
18309
|
var ZERO_SUMMARY = {
|
|
@@ -18219,7 +18327,7 @@ var BeadsWatcher = class {
|
|
|
18219
18327
|
constructor(opts) {
|
|
18220
18328
|
this.opts = opts;
|
|
18221
18329
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18222
|
-
this.feedPath = opts.feedPath ??
|
|
18330
|
+
this.feedPath = opts.feedPath ?? path48.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
18223
18331
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
18224
18332
|
}
|
|
18225
18333
|
opts;
|
|
@@ -18629,7 +18737,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18629
18737
|
function cleanupAttachmentTempFiles() {
|
|
18630
18738
|
for (const p2 of pendingAttachmentFiles) {
|
|
18631
18739
|
try {
|
|
18632
|
-
|
|
18740
|
+
fs45.unlinkSync(p2);
|
|
18633
18741
|
} catch {
|
|
18634
18742
|
}
|
|
18635
18743
|
}
|
|
@@ -18638,8 +18746,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18638
18746
|
function saveFilesTemp(files) {
|
|
18639
18747
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18640
18748
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18641
|
-
const tmpPath =
|
|
18642
|
-
|
|
18749
|
+
const tmpPath = path50.join(os38.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18750
|
+
fs45.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18643
18751
|
pendingAttachmentFiles.add(tmpPath);
|
|
18644
18752
|
return tmpPath;
|
|
18645
18753
|
});
|
|
@@ -18659,7 +18767,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18659
18767
|
setTimeout(() => {
|
|
18660
18768
|
for (const p2 of paths) {
|
|
18661
18769
|
try {
|
|
18662
|
-
|
|
18770
|
+
fs45.unlinkSync(p2);
|
|
18663
18771
|
} catch {
|
|
18664
18772
|
}
|
|
18665
18773
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -18860,9 +18968,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
18860
18968
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
18861
18969
|
};
|
|
18862
18970
|
var envReadH = async (ctx, cmd) => {
|
|
18863
|
-
const envPath =
|
|
18971
|
+
const envPath = path50.join(process.cwd(), ".env");
|
|
18864
18972
|
try {
|
|
18865
|
-
const raw = await
|
|
18973
|
+
const raw = await fs45.promises.readFile(envPath, "utf8");
|
|
18866
18974
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
18867
18975
|
exists: true,
|
|
18868
18976
|
vars: parseDotenv(raw)
|
|
@@ -18893,14 +19001,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
18893
19001
|
}
|
|
18894
19002
|
seen.add(v.key);
|
|
18895
19003
|
}
|
|
18896
|
-
const envPath =
|
|
18897
|
-
const tmpPath =
|
|
19004
|
+
const envPath = path50.join(process.cwd(), ".env");
|
|
19005
|
+
const tmpPath = path50.join(process.cwd(), ".env.codeam.tmp");
|
|
18898
19006
|
try {
|
|
18899
|
-
await
|
|
18900
|
-
await
|
|
19007
|
+
await fs45.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
19008
|
+
await fs45.promises.rename(tmpPath, envPath);
|
|
18901
19009
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
18902
19010
|
} catch (err) {
|
|
18903
|
-
await
|
|
19011
|
+
await fs45.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
18904
19012
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
18905
19013
|
}
|
|
18906
19014
|
};
|
|
@@ -18918,7 +19026,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18918
19026
|
let configuredAgent = rawAgentId;
|
|
18919
19027
|
if (!configuredAgent) {
|
|
18920
19028
|
try {
|
|
18921
|
-
const raw = JSON.parse(
|
|
19029
|
+
const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
|
|
18922
19030
|
configuredAgent = raw.agent ?? "";
|
|
18923
19031
|
} catch {
|
|
18924
19032
|
}
|
|
@@ -18931,7 +19039,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18931
19039
|
setup: setupHeadroomForSelfHosted,
|
|
18932
19040
|
probeStats: async () => {
|
|
18933
19041
|
try {
|
|
18934
|
-
const res = await
|
|
19042
|
+
const res = await fetchWithTimeout("http://localhost:8787/stats");
|
|
18935
19043
|
if (!res.ok) return null;
|
|
18936
19044
|
const raw = await res.json();
|
|
18937
19045
|
return mapStatsToSavings(raw, {
|
|
@@ -18952,7 +19060,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18952
19060
|
persist: persistHeadroomConfig,
|
|
18953
19061
|
readEnabled: () => {
|
|
18954
19062
|
try {
|
|
18955
|
-
const raw = JSON.parse(
|
|
19063
|
+
const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
|
|
18956
19064
|
return raw.enabled === true;
|
|
18957
19065
|
} catch {
|
|
18958
19066
|
return false;
|
|
@@ -18962,12 +19070,12 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18962
19070
|
_activeReporter?.stop();
|
|
18963
19071
|
const reporter = new HeadroomStatsReporter({
|
|
18964
19072
|
fetchStats: async () => {
|
|
18965
|
-
const res = await
|
|
19073
|
+
const res = await fetchWithTimeout("http://localhost:8787/stats");
|
|
18966
19074
|
return res.json();
|
|
18967
19075
|
},
|
|
18968
19076
|
postSavings: async (delta, budget) => {
|
|
18969
19077
|
if (!opts.ingestUrl) return;
|
|
18970
|
-
await
|
|
19078
|
+
const res = await fetchWithTimeout(opts.ingestUrl, {
|
|
18971
19079
|
method: "POST",
|
|
18972
19080
|
headers: {
|
|
18973
19081
|
"Content-Type": "application/json",
|
|
@@ -18988,10 +19096,14 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18988
19096
|
...budget ? {
|
|
18989
19097
|
periodSpendUsd: budget.periodSpendUsd,
|
|
18990
19098
|
budgetUsd: budget.budgetUsd,
|
|
18991
|
-
budgetPeriod: budget.budgetPeriod
|
|
19099
|
+
budgetPeriod: budget.budgetPeriod,
|
|
19100
|
+
budgetReached: budget.budgetReached
|
|
18992
19101
|
} : {}
|
|
18993
19102
|
})
|
|
18994
19103
|
});
|
|
19104
|
+
if (!res.ok) {
|
|
19105
|
+
log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
|
|
19106
|
+
}
|
|
18995
19107
|
}
|
|
18996
19108
|
});
|
|
18997
19109
|
reporter.start();
|
|
@@ -19002,18 +19114,9 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
19002
19114
|
_activeReporter = null;
|
|
19003
19115
|
},
|
|
19004
19116
|
restoreAgentHeadroomConfig: (kind) => restoreAgentHeadroomConfig(kind),
|
|
19005
|
-
|
|
19006
|
-
|
|
19007
|
-
|
|
19008
|
-
detached: true,
|
|
19009
|
-
stdio: "ignore"
|
|
19010
|
-
});
|
|
19011
|
-
p2.on("error", () => {
|
|
19012
|
-
});
|
|
19013
|
-
p2.unref();
|
|
19014
|
-
} catch {
|
|
19015
|
-
}
|
|
19016
|
-
},
|
|
19117
|
+
// Targeted pidfile kill; falls back to the legacy pkill pattern only when
|
|
19118
|
+
// no live recorded pid exists. Best-effort — never throws.
|
|
19119
|
+
stopProxy: () => killHeadroomProxy(),
|
|
19017
19120
|
emit: (event) => {
|
|
19018
19121
|
const token = ctx.pluginAuthToken;
|
|
19019
19122
|
if (!token) return;
|
|
@@ -19046,7 +19149,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
19046
19149
|
}
|
|
19047
19150
|
let headroomActive = false;
|
|
19048
19151
|
try {
|
|
19049
|
-
const raw = JSON.parse(
|
|
19152
|
+
const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
|
|
19050
19153
|
headroomActive = raw.enabled === true;
|
|
19051
19154
|
} catch {
|
|
19052
19155
|
}
|
|
@@ -19056,7 +19159,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
19056
19159
|
}
|
|
19057
19160
|
let existingConfig = { enabled: true };
|
|
19058
19161
|
try {
|
|
19059
|
-
existingConfig = JSON.parse(
|
|
19162
|
+
existingConfig = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
|
|
19060
19163
|
} catch {
|
|
19061
19164
|
}
|
|
19062
19165
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -19174,13 +19277,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
19174
19277
|
function buildNpmInstallInvocation(opts) {
|
|
19175
19278
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
19176
19279
|
const execPath = opts?.execPath ?? process.execPath;
|
|
19177
|
-
const exists2 = opts?.existsSync ??
|
|
19178
|
-
const normalized = entryScript.split(
|
|
19280
|
+
const exists2 = opts?.existsSync ?? fs45.existsSync;
|
|
19281
|
+
const normalized = entryScript.split(path50.sep).join("/");
|
|
19179
19282
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
19180
19283
|
const markerIdx = normalized.indexOf(marker);
|
|
19181
19284
|
const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
|
|
19182
|
-
const siblingNpm =
|
|
19183
|
-
|
|
19285
|
+
const siblingNpm = path50.join(
|
|
19286
|
+
path50.dirname(execPath),
|
|
19184
19287
|
process.platform === "win32" ? "npm.cmd" : "npm"
|
|
19185
19288
|
);
|
|
19186
19289
|
const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
|
|
@@ -19687,8 +19790,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19687
19790
|
if (args2.length === 0) return detection;
|
|
19688
19791
|
const binName = args2[0];
|
|
19689
19792
|
if (binName.startsWith("-")) return detection;
|
|
19690
|
-
const binPath =
|
|
19691
|
-
if (!
|
|
19793
|
+
const binPath = path50.join(cwd, "node_modules", ".bin", binName);
|
|
19794
|
+
if (!fs45.existsSync(binPath)) return detection;
|
|
19692
19795
|
return {
|
|
19693
19796
|
...detection,
|
|
19694
19797
|
command: binPath,
|
|
@@ -20507,12 +20610,12 @@ function readTokenFromArgs(args2) {
|
|
|
20507
20610
|
}
|
|
20508
20611
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
20509
20612
|
if (fileFlag) {
|
|
20510
|
-
const
|
|
20613
|
+
const path65 = fileFlag.slice("--token-file=".length);
|
|
20511
20614
|
try {
|
|
20512
|
-
const content =
|
|
20513
|
-
if (content.length === 0) fail(`--token-file ${
|
|
20615
|
+
const content = fs46.readFileSync(path65, "utf8").trim();
|
|
20616
|
+
if (content.length === 0) fail(`--token-file ${path65} is empty`);
|
|
20514
20617
|
try {
|
|
20515
|
-
|
|
20618
|
+
fs46.unlinkSync(path65);
|
|
20516
20619
|
} catch {
|
|
20517
20620
|
}
|
|
20518
20621
|
return content;
|
|
@@ -20538,7 +20641,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
20538
20641
|
pluginId,
|
|
20539
20642
|
ideName: "codeam-cli (codespace)",
|
|
20540
20643
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
20541
|
-
hostname:
|
|
20644
|
+
hostname: os39.hostname(),
|
|
20542
20645
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
20543
20646
|
// Current git branch of the codespace's working directory, so the
|
|
20544
20647
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -20599,7 +20702,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
20599
20702
|
}
|
|
20600
20703
|
}
|
|
20601
20704
|
function pairAutoLockPath() {
|
|
20602
|
-
return
|
|
20705
|
+
return path51.join(os39.homedir(), ".codeam", "pair-auto.lock");
|
|
20603
20706
|
}
|
|
20604
20707
|
function isLivePairAuto(pid) {
|
|
20605
20708
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -20609,7 +20712,7 @@ function isLivePairAuto(pid) {
|
|
|
20609
20712
|
if (e.code !== "EPERM") return false;
|
|
20610
20713
|
}
|
|
20611
20714
|
try {
|
|
20612
|
-
return
|
|
20715
|
+
return fs46.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
20613
20716
|
} catch {
|
|
20614
20717
|
return true;
|
|
20615
20718
|
}
|
|
@@ -20619,24 +20722,24 @@ function isLiveCodeam(pid) {
|
|
|
20619
20722
|
}
|
|
20620
20723
|
function daemonLockPath(sessionId) {
|
|
20621
20724
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
20622
|
-
return
|
|
20725
|
+
return path51.join(os39.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
20623
20726
|
}
|
|
20624
20727
|
function acquireDaemonLock(sessionId) {
|
|
20625
20728
|
const lockPath = daemonLockPath(sessionId);
|
|
20626
20729
|
try {
|
|
20627
|
-
|
|
20730
|
+
fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
|
|
20628
20731
|
try {
|
|
20629
|
-
|
|
20732
|
+
fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
20630
20733
|
} catch (e) {
|
|
20631
20734
|
if (e.code !== "EEXIST") throw e;
|
|
20632
|
-
const holder = Number(
|
|
20735
|
+
const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
|
|
20633
20736
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
20634
|
-
|
|
20737
|
+
fs46.writeFileSync(lockPath, String(process.pid));
|
|
20635
20738
|
}
|
|
20636
20739
|
const release3 = () => {
|
|
20637
20740
|
try {
|
|
20638
|
-
if (
|
|
20639
|
-
|
|
20741
|
+
if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20742
|
+
fs46.unlinkSync(lockPath);
|
|
20640
20743
|
}
|
|
20641
20744
|
} catch {
|
|
20642
20745
|
}
|
|
@@ -20658,19 +20761,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
20658
20761
|
function acquireSingletonLock() {
|
|
20659
20762
|
const lockPath = pairAutoLockPath();
|
|
20660
20763
|
try {
|
|
20661
|
-
|
|
20764
|
+
fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
|
|
20662
20765
|
try {
|
|
20663
|
-
|
|
20766
|
+
fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
20664
20767
|
} catch (e) {
|
|
20665
20768
|
if (e.code !== "EEXIST") throw e;
|
|
20666
|
-
const holder = Number(
|
|
20769
|
+
const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
|
|
20667
20770
|
if (isLivePairAuto(holder)) return false;
|
|
20668
|
-
|
|
20771
|
+
fs46.writeFileSync(lockPath, String(process.pid));
|
|
20669
20772
|
}
|
|
20670
20773
|
process.once("exit", () => {
|
|
20671
20774
|
try {
|
|
20672
|
-
if (
|
|
20673
|
-
|
|
20775
|
+
if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20776
|
+
fs46.unlinkSync(lockPath);
|
|
20674
20777
|
}
|
|
20675
20778
|
} catch {
|
|
20676
20779
|
}
|
|
@@ -20752,7 +20855,7 @@ async function pairAuto(args2) {
|
|
|
20752
20855
|
}
|
|
20753
20856
|
|
|
20754
20857
|
// src/services/headroom/wrap-launch.ts
|
|
20755
|
-
var
|
|
20858
|
+
var import_node_child_process17 = require("child_process");
|
|
20756
20859
|
function wrapWithHeadroom(launch, opts) {
|
|
20757
20860
|
if (!opts.enabled || !opts.headroomPresent) return launch;
|
|
20758
20861
|
return {
|
|
@@ -20765,7 +20868,7 @@ var _present;
|
|
|
20765
20868
|
function headroomPresent() {
|
|
20766
20869
|
if (_present !== void 0) return Promise.resolve(_present);
|
|
20767
20870
|
return new Promise((resolve7) => {
|
|
20768
|
-
(0,
|
|
20871
|
+
(0, import_node_child_process17.execFile)("headroom", ["--version"], (err) => {
|
|
20769
20872
|
_present = !err;
|
|
20770
20873
|
resolve7(_present);
|
|
20771
20874
|
});
|
|
@@ -21115,7 +21218,7 @@ var AgentService = class _AgentService {
|
|
|
21115
21218
|
};
|
|
21116
21219
|
|
|
21117
21220
|
// src/agents/acp/adapters.ts
|
|
21118
|
-
var
|
|
21221
|
+
var path53 = __toESM(require("path"));
|
|
21119
21222
|
|
|
21120
21223
|
// src/agents/acp/agent-binary.ts
|
|
21121
21224
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -21268,13 +21371,13 @@ function resolveBin(pkgName, binName) {
|
|
|
21268
21371
|
try {
|
|
21269
21372
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
21270
21373
|
const manifest = require_(`${pkgName}/package.json`);
|
|
21271
|
-
const pkgDir =
|
|
21374
|
+
const pkgDir = path53.dirname(manifestPath);
|
|
21272
21375
|
const bin = manifest.bin;
|
|
21273
21376
|
if (!bin) return null;
|
|
21274
|
-
if (typeof bin === "string") return
|
|
21377
|
+
if (typeof bin === "string") return path53.resolve(pkgDir, bin);
|
|
21275
21378
|
const target = binName ?? Object.keys(bin)[0];
|
|
21276
21379
|
if (!target || !bin[target]) return null;
|
|
21277
|
-
return
|
|
21380
|
+
return path53.resolve(pkgDir, bin[target]);
|
|
21278
21381
|
} catch {
|
|
21279
21382
|
return null;
|
|
21280
21383
|
}
|
|
@@ -21349,9 +21452,9 @@ function requiresAcp(agent) {
|
|
|
21349
21452
|
var import_node_crypto7 = require("crypto");
|
|
21350
21453
|
|
|
21351
21454
|
// src/services/history.service.ts
|
|
21352
|
-
var
|
|
21353
|
-
var
|
|
21354
|
-
var
|
|
21455
|
+
var fs48 = __toESM(require("fs"));
|
|
21456
|
+
var path54 = __toESM(require("path"));
|
|
21457
|
+
var os40 = __toESM(require("os"));
|
|
21355
21458
|
var https7 = __toESM(require("https"));
|
|
21356
21459
|
var http6 = __toESM(require("http"));
|
|
21357
21460
|
var import_zod2 = require("zod");
|
|
@@ -21378,7 +21481,7 @@ function parseJsonl(filePath) {
|
|
|
21378
21481
|
const messages = [];
|
|
21379
21482
|
let raw;
|
|
21380
21483
|
try {
|
|
21381
|
-
raw =
|
|
21484
|
+
raw = fs48.readFileSync(filePath, "utf8");
|
|
21382
21485
|
} catch (err) {
|
|
21383
21486
|
if (err.code !== "ENOENT") {
|
|
21384
21487
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -21519,7 +21622,7 @@ var HistoryService = class _HistoryService {
|
|
|
21519
21622
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
21520
21623
|
}
|
|
21521
21624
|
get projectDir() {
|
|
21522
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
21625
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path54.join(os40.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
21523
21626
|
}
|
|
21524
21627
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
21525
21628
|
setCurrentConversationId(id) {
|
|
@@ -21531,7 +21634,7 @@ var HistoryService = class _HistoryService {
|
|
|
21531
21634
|
/** Return the current message count in the active conversation. */
|
|
21532
21635
|
getCurrentMessageCount() {
|
|
21533
21636
|
if (!this.currentConversationId) return 0;
|
|
21534
|
-
const filePath =
|
|
21637
|
+
const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
21535
21638
|
return parseJsonl(filePath).length;
|
|
21536
21639
|
}
|
|
21537
21640
|
/**
|
|
@@ -21542,7 +21645,7 @@ var HistoryService = class _HistoryService {
|
|
|
21542
21645
|
const deadline = Date.now() + timeoutMs;
|
|
21543
21646
|
while (Date.now() < deadline) {
|
|
21544
21647
|
if (!this.currentConversationId) return null;
|
|
21545
|
-
const filePath =
|
|
21648
|
+
const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
21546
21649
|
const messages = parseJsonl(filePath);
|
|
21547
21650
|
if (messages.length > previousCount) {
|
|
21548
21651
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -21568,16 +21671,16 @@ var HistoryService = class _HistoryService {
|
|
|
21568
21671
|
const dir = this.projectDir;
|
|
21569
21672
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
21570
21673
|
try {
|
|
21571
|
-
const files =
|
|
21674
|
+
const files = fs48.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
21572
21675
|
try {
|
|
21573
|
-
const stat3 =
|
|
21676
|
+
const stat3 = fs48.statSync(path54.join(dir, e.name));
|
|
21574
21677
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
21575
21678
|
} catch {
|
|
21576
21679
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
21577
21680
|
}
|
|
21578
21681
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
21579
21682
|
if (files.length > 0) {
|
|
21580
|
-
this.currentConversationId =
|
|
21683
|
+
this.currentConversationId = path54.basename(files[0].name, ".jsonl");
|
|
21581
21684
|
}
|
|
21582
21685
|
} catch {
|
|
21583
21686
|
}
|
|
@@ -21611,13 +21714,13 @@ var HistoryService = class _HistoryService {
|
|
|
21611
21714
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
21612
21715
|
let entries;
|
|
21613
21716
|
try {
|
|
21614
|
-
entries =
|
|
21717
|
+
entries = fs48.readdirSync(dir, { withFileTypes: true });
|
|
21615
21718
|
} catch {
|
|
21616
21719
|
return null;
|
|
21617
21720
|
}
|
|
21618
21721
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
21619
21722
|
try {
|
|
21620
|
-
const stat3 =
|
|
21723
|
+
const stat3 = fs48.statSync(path54.join(dir, e.name));
|
|
21621
21724
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
21622
21725
|
} catch {
|
|
21623
21726
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -21626,12 +21729,12 @@ var HistoryService = class _HistoryService {
|
|
|
21626
21729
|
if (files.length === 0) return null;
|
|
21627
21730
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
21628
21731
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
21629
|
-
return this.extractUsageFromFile(
|
|
21732
|
+
return this.extractUsageFromFile(path54.join(dir, targetFile));
|
|
21630
21733
|
}
|
|
21631
21734
|
extractUsageFromFile(filePath) {
|
|
21632
21735
|
let raw;
|
|
21633
21736
|
try {
|
|
21634
|
-
raw =
|
|
21737
|
+
raw = fs48.readFileSync(filePath, "utf8");
|
|
21635
21738
|
} catch {
|
|
21636
21739
|
return null;
|
|
21637
21740
|
}
|
|
@@ -21676,9 +21779,9 @@ var HistoryService = class _HistoryService {
|
|
|
21676
21779
|
let totalCost = 0;
|
|
21677
21780
|
let files;
|
|
21678
21781
|
try {
|
|
21679
|
-
files =
|
|
21782
|
+
files = fs48.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
21680
21783
|
try {
|
|
21681
|
-
return
|
|
21784
|
+
return fs48.statSync(path54.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
21682
21785
|
} catch {
|
|
21683
21786
|
return false;
|
|
21684
21787
|
}
|
|
@@ -21689,7 +21792,7 @@ var HistoryService = class _HistoryService {
|
|
|
21689
21792
|
for (const file of files) {
|
|
21690
21793
|
let raw;
|
|
21691
21794
|
try {
|
|
21692
|
-
raw =
|
|
21795
|
+
raw = fs48.readFileSync(path54.join(projectDir, file), "utf8");
|
|
21693
21796
|
} catch {
|
|
21694
21797
|
continue;
|
|
21695
21798
|
}
|
|
@@ -21768,7 +21871,7 @@ var HistoryService = class _HistoryService {
|
|
|
21768
21871
|
if (this.runtime.resolveHistoryFile) {
|
|
21769
21872
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
21770
21873
|
}
|
|
21771
|
-
return
|
|
21874
|
+
return path54.join(this.projectDir, `${sessionId}.jsonl`);
|
|
21772
21875
|
}
|
|
21773
21876
|
/**
|
|
21774
21877
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -21802,7 +21905,7 @@ var HistoryService = class _HistoryService {
|
|
|
21802
21905
|
};
|
|
21803
21906
|
});
|
|
21804
21907
|
}
|
|
21805
|
-
return parseJsonl(
|
|
21908
|
+
return parseJsonl(path54.join(this.projectDir, `${sessionId}.jsonl`));
|
|
21806
21909
|
}
|
|
21807
21910
|
async loadConversation(sessionId) {
|
|
21808
21911
|
const messages = this.readConversation(sessionId);
|
|
@@ -21858,7 +21961,7 @@ var HistoryService = class _HistoryService {
|
|
|
21858
21961
|
if (!filePath) return false;
|
|
21859
21962
|
let mtimeMs;
|
|
21860
21963
|
try {
|
|
21861
|
-
mtimeMs =
|
|
21964
|
+
mtimeMs = fs48.statSync(filePath).mtimeMs;
|
|
21862
21965
|
} catch {
|
|
21863
21966
|
return false;
|
|
21864
21967
|
}
|
|
@@ -21926,11 +22029,11 @@ var HistoryService = class _HistoryService {
|
|
|
21926
22029
|
};
|
|
21927
22030
|
|
|
21928
22031
|
// src/agents/acp/client.ts
|
|
21929
|
-
var
|
|
21930
|
-
var
|
|
22032
|
+
var import_node_child_process18 = require("child_process");
|
|
22033
|
+
var fs49 = __toESM(require("fs/promises"));
|
|
21931
22034
|
var fsSync = __toESM(require("fs"));
|
|
21932
|
-
var
|
|
21933
|
-
var
|
|
22035
|
+
var os41 = __toESM(require("os"));
|
|
22036
|
+
var path55 = __toESM(require("path"));
|
|
21934
22037
|
var import_node_stream = require("stream");
|
|
21935
22038
|
|
|
21936
22039
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -24477,7 +24580,7 @@ var AcpClient = class {
|
|
|
24477
24580
|
"acpClient",
|
|
24478
24581
|
`spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
|
|
24479
24582
|
);
|
|
24480
|
-
const child = (0,
|
|
24583
|
+
const child = (0, import_node_child_process18.spawn)(adapter.command, adapter.args, {
|
|
24481
24584
|
cwd,
|
|
24482
24585
|
// extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
|
|
24483
24586
|
// re-spawn) layers over process.env; PATH stays last so the augmented
|
|
@@ -24763,7 +24866,7 @@ var AcpClient = class {
|
|
|
24763
24866
|
},
|
|
24764
24867
|
readTextFile: async (params) => {
|
|
24765
24868
|
try {
|
|
24766
|
-
const content = await
|
|
24869
|
+
const content = await fs49.readFile(params.path, "utf8");
|
|
24767
24870
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
24768
24871
|
} catch (err) {
|
|
24769
24872
|
const code = err.code;
|
|
@@ -24783,7 +24886,7 @@ var AcpClient = class {
|
|
|
24783
24886
|
},
|
|
24784
24887
|
writeTextFile: async (params) => {
|
|
24785
24888
|
try {
|
|
24786
|
-
await
|
|
24889
|
+
await fs49.writeFile(params.path, params.content, "utf8");
|
|
24787
24890
|
return {};
|
|
24788
24891
|
} catch (err) {
|
|
24789
24892
|
const code = err.code;
|
|
@@ -24832,25 +24935,25 @@ function applyLineRange(content, line, limit) {
|
|
|
24832
24935
|
return { content: lines.slice(start2, end).join("\n") };
|
|
24833
24936
|
}
|
|
24834
24937
|
function knownAgentBinaryDirs() {
|
|
24835
|
-
const home =
|
|
24938
|
+
const home = os41.homedir();
|
|
24836
24939
|
const out2 = [];
|
|
24837
24940
|
out2.push("/tmp/codeam-node20/bin");
|
|
24838
24941
|
for (const root of [
|
|
24839
24942
|
"/usr/local/share/nvm/versions/node",
|
|
24840
|
-
|
|
24943
|
+
path55.join(home, ".nvm/versions/node")
|
|
24841
24944
|
]) {
|
|
24842
24945
|
try {
|
|
24843
24946
|
for (const child of fsSync.readdirSync(root)) {
|
|
24844
|
-
out2.push(
|
|
24947
|
+
out2.push(path55.join(root, child, "bin"));
|
|
24845
24948
|
}
|
|
24846
24949
|
} catch {
|
|
24847
24950
|
}
|
|
24848
24951
|
}
|
|
24849
|
-
out2.push(
|
|
24952
|
+
out2.push(path55.join(home, ".volta/bin"));
|
|
24850
24953
|
out2.push("/usr/local/bin");
|
|
24851
24954
|
out2.push("/usr/bin");
|
|
24852
|
-
out2.push(
|
|
24853
|
-
out2.push(
|
|
24955
|
+
out2.push(path55.join(home, ".local/bin"));
|
|
24956
|
+
out2.push(path55.join(home, "bin"));
|
|
24854
24957
|
return out2.filter((p2) => {
|
|
24855
24958
|
try {
|
|
24856
24959
|
return fsSync.statSync(p2).isDirectory();
|
|
@@ -24861,7 +24964,7 @@ function knownAgentBinaryDirs() {
|
|
|
24861
24964
|
}
|
|
24862
24965
|
function expandPathForAgentBinaries(existingPath) {
|
|
24863
24966
|
const existing = new Set(
|
|
24864
|
-
existingPath.split(
|
|
24967
|
+
existingPath.split(path55.delimiter).filter((p2) => p2.length > 0)
|
|
24865
24968
|
);
|
|
24866
24969
|
const additions = [];
|
|
24867
24970
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -24871,7 +24974,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
24871
24974
|
}
|
|
24872
24975
|
}
|
|
24873
24976
|
if (additions.length === 0) return existingPath;
|
|
24874
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
24977
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path55.delimiter);
|
|
24875
24978
|
}
|
|
24876
24979
|
|
|
24877
24980
|
// src/services/streaming/transport.ts
|
|
@@ -25416,15 +25519,15 @@ function commonPrefixLength(a, b) {
|
|
|
25416
25519
|
|
|
25417
25520
|
// src/agents/acp/onboarding.ts
|
|
25418
25521
|
var import_child_process25 = require("child_process");
|
|
25419
|
-
var
|
|
25420
|
-
var
|
|
25421
|
-
var
|
|
25522
|
+
var fs50 = __toESM(require("fs"));
|
|
25523
|
+
var os42 = __toESM(require("os"));
|
|
25524
|
+
var path56 = __toESM(require("path"));
|
|
25422
25525
|
var _onboardingSeam = {
|
|
25423
|
-
markerPath: (sessionId) =>
|
|
25424
|
-
exists: (p2) =>
|
|
25526
|
+
markerPath: (sessionId) => path56.join(os42.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
25527
|
+
exists: (p2) => fs50.existsSync(p2),
|
|
25425
25528
|
write: (p2) => {
|
|
25426
|
-
|
|
25427
|
-
|
|
25529
|
+
fs50.mkdirSync(path56.dirname(p2), { recursive: true });
|
|
25530
|
+
fs50.writeFileSync(p2, "");
|
|
25428
25531
|
},
|
|
25429
25532
|
disabled: () => {
|
|
25430
25533
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -25461,7 +25564,7 @@ function resolveRepoName(cwd) {
|
|
|
25461
25564
|
if (name) return name;
|
|
25462
25565
|
}
|
|
25463
25566
|
}
|
|
25464
|
-
const base =
|
|
25567
|
+
const base = path56.basename(cwd || "");
|
|
25465
25568
|
if (base && !isUuid(base)) return base;
|
|
25466
25569
|
return "this project";
|
|
25467
25570
|
}
|
|
@@ -25739,8 +25842,8 @@ var import_crypto5 = require("crypto");
|
|
|
25739
25842
|
|
|
25740
25843
|
// src/services/turn-files/git-changeset.ts
|
|
25741
25844
|
var import_child_process26 = require("child_process");
|
|
25742
|
-
var
|
|
25743
|
-
var
|
|
25845
|
+
var fs51 = __toESM(require("fs/promises"));
|
|
25846
|
+
var path57 = __toESM(require("path"));
|
|
25744
25847
|
async function collectRepoChangeset(opts) {
|
|
25745
25848
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
25746
25849
|
if (status2 === null) return null;
|
|
@@ -25758,7 +25861,7 @@ async function collectRepoChangeset(opts) {
|
|
|
25758
25861
|
let stats;
|
|
25759
25862
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
25760
25863
|
const lineCount = await readUntrackedLineCount(
|
|
25761
|
-
|
|
25864
|
+
path57.join(opts.repoRoot, row.filePath)
|
|
25762
25865
|
);
|
|
25763
25866
|
stats = { added: lineCount, removed: 0 };
|
|
25764
25867
|
} else {
|
|
@@ -25789,7 +25892,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
25789
25892
|
}
|
|
25790
25893
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
25791
25894
|
try {
|
|
25792
|
-
const content = await
|
|
25895
|
+
const content = await fs51.readFile(absPath, "utf8");
|
|
25793
25896
|
let count = 0;
|
|
25794
25897
|
let pos = -1;
|
|
25795
25898
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -25881,7 +25984,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
25881
25984
|
});
|
|
25882
25985
|
}
|
|
25883
25986
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
25884
|
-
const
|
|
25987
|
+
const fs55 = await import("fs/promises");
|
|
25885
25988
|
const out2 = [];
|
|
25886
25989
|
await walk(workingDir, 0);
|
|
25887
25990
|
return out2;
|
|
@@ -25889,7 +25992,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25889
25992
|
if (depth > maxDepth) return;
|
|
25890
25993
|
let entries = [];
|
|
25891
25994
|
try {
|
|
25892
|
-
const dirents = await
|
|
25995
|
+
const dirents = await fs55.readdir(dir, { withFileTypes: true });
|
|
25893
25996
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
25894
25997
|
} catch {
|
|
25895
25998
|
return;
|
|
@@ -25900,8 +26003,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25900
26003
|
if (hasGit) {
|
|
25901
26004
|
out2.push({
|
|
25902
26005
|
repoRoot: dir,
|
|
25903
|
-
repoPath:
|
|
25904
|
-
repoName:
|
|
26006
|
+
repoPath: path57.relative(workingDir, dir),
|
|
26007
|
+
repoName: path57.basename(dir)
|
|
25905
26008
|
});
|
|
25906
26009
|
return;
|
|
25907
26010
|
}
|
|
@@ -25909,14 +26012,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25909
26012
|
if (!entry.isDirectory) continue;
|
|
25910
26013
|
if (entry.name === "node_modules") continue;
|
|
25911
26014
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
25912
|
-
await walk(
|
|
26015
|
+
await walk(path57.join(dir, entry.name), depth + 1);
|
|
25913
26016
|
}
|
|
25914
26017
|
}
|
|
25915
26018
|
}
|
|
25916
26019
|
|
|
25917
26020
|
// src/services/turn-files/files-outbox.ts
|
|
25918
|
-
var
|
|
25919
|
-
var
|
|
26021
|
+
var fs52 = __toESM(require("fs/promises"));
|
|
26022
|
+
var path58 = __toESM(require("path"));
|
|
25920
26023
|
var import_os7 = require("os");
|
|
25921
26024
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
25922
26025
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -25949,16 +26052,16 @@ var FilesOutbox = class {
|
|
|
25949
26052
|
backoffIndex = 0;
|
|
25950
26053
|
stopped = false;
|
|
25951
26054
|
constructor(opts) {
|
|
25952
|
-
const base = opts.baseDir ??
|
|
25953
|
-
this.filePath =
|
|
26055
|
+
const base = opts.baseDir ?? path58.join(homeDir(), HOME_OUTBOX_DIR);
|
|
26056
|
+
this.filePath = path58.join(base, `${opts.sessionId}.jsonl`);
|
|
25954
26057
|
this.post = opts.post;
|
|
25955
26058
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
25956
26059
|
}
|
|
25957
26060
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
25958
26061
|
* line is durable on disk (not once the POST succeeds). */
|
|
25959
26062
|
async enqueue(entry) {
|
|
25960
|
-
await
|
|
25961
|
-
await
|
|
26063
|
+
await fs52.mkdir(path58.dirname(this.filePath), { recursive: true });
|
|
26064
|
+
await fs52.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
25962
26065
|
this.backoffIndex = 0;
|
|
25963
26066
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
25964
26067
|
}
|
|
@@ -26047,7 +26150,7 @@ var FilesOutbox = class {
|
|
|
26047
26150
|
async readAll() {
|
|
26048
26151
|
let raw = "";
|
|
26049
26152
|
try {
|
|
26050
|
-
raw = await
|
|
26153
|
+
raw = await fs52.readFile(this.filePath, "utf8");
|
|
26051
26154
|
} catch {
|
|
26052
26155
|
return [];
|
|
26053
26156
|
}
|
|
@@ -26071,12 +26174,12 @@ var FilesOutbox = class {
|
|
|
26071
26174
|
async rewrite(entries) {
|
|
26072
26175
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
26073
26176
|
if (entries.length === 0) {
|
|
26074
|
-
await
|
|
26177
|
+
await fs52.unlink(this.filePath).catch(() => void 0);
|
|
26075
26178
|
return;
|
|
26076
26179
|
}
|
|
26077
26180
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
26078
|
-
await
|
|
26079
|
-
await
|
|
26181
|
+
await fs52.writeFile(tmpPath, payload, "utf8");
|
|
26182
|
+
await fs52.rename(tmpPath, this.filePath);
|
|
26080
26183
|
}
|
|
26081
26184
|
};
|
|
26082
26185
|
function applyJitter(ms) {
|
|
@@ -27066,21 +27169,12 @@ async function runAcpSession(opts) {
|
|
|
27066
27169
|
});
|
|
27067
27170
|
let _budgetReachedPosted = false;
|
|
27068
27171
|
const relaunchProxyWithoutBudget = async () => {
|
|
27069
|
-
const { spawn:
|
|
27070
|
-
|
|
27071
|
-
const killer = spawn35("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
27072
|
-
detached: true,
|
|
27073
|
-
stdio: "ignore"
|
|
27074
|
-
});
|
|
27075
|
-
killer.once("error", () => {
|
|
27076
|
-
});
|
|
27077
|
-
killer.unref();
|
|
27078
|
-
} catch {
|
|
27079
|
-
}
|
|
27172
|
+
const { spawn: spawn36 } = await import("child_process");
|
|
27173
|
+
killHeadroomProxy();
|
|
27080
27174
|
await new Promise((r) => setTimeout(r, 500));
|
|
27081
27175
|
const proxyEnv = buildRelaunchProxyEnv(process.env);
|
|
27082
27176
|
try {
|
|
27083
|
-
const proxy =
|
|
27177
|
+
const proxy = spawn36(
|
|
27084
27178
|
"headroom",
|
|
27085
27179
|
["proxy", "--port", "8787"],
|
|
27086
27180
|
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
@@ -27089,6 +27183,7 @@ async function runAcpSession(opts) {
|
|
|
27089
27183
|
log.warn("acpRunner", `budget recovery proxy relaunch error (best-effort): ${e.message}`);
|
|
27090
27184
|
});
|
|
27091
27185
|
proxy.unref();
|
|
27186
|
+
writeHeadroomProxyPidfile(proxy.pid);
|
|
27092
27187
|
} catch (e) {
|
|
27093
27188
|
log.warn(
|
|
27094
27189
|
"acpRunner",
|
|
@@ -28733,15 +28828,15 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
28733
28828
|
}
|
|
28734
28829
|
|
|
28735
28830
|
// src/agents/claude/onboarding.ts
|
|
28736
|
-
var
|
|
28737
|
-
var
|
|
28738
|
-
var
|
|
28831
|
+
var fs53 = __toESM(require("fs"));
|
|
28832
|
+
var os43 = __toESM(require("os"));
|
|
28833
|
+
var path59 = __toESM(require("path"));
|
|
28739
28834
|
function ensureClaudeOnboarded() {
|
|
28740
28835
|
try {
|
|
28741
|
-
const file =
|
|
28836
|
+
const file = path59.join(os43.homedir(), ".claude.json");
|
|
28742
28837
|
let config = {};
|
|
28743
28838
|
try {
|
|
28744
|
-
config = JSON.parse(
|
|
28839
|
+
config = JSON.parse(fs53.readFileSync(file, "utf8"));
|
|
28745
28840
|
} catch {
|
|
28746
28841
|
}
|
|
28747
28842
|
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
@@ -28752,8 +28847,8 @@ function ensureClaudeOnboarded() {
|
|
|
28752
28847
|
if (typeof config.lastOnboardingVersion !== "string") {
|
|
28753
28848
|
config.lastOnboardingVersion = "2.1.177";
|
|
28754
28849
|
}
|
|
28755
|
-
|
|
28756
|
-
|
|
28850
|
+
fs53.mkdirSync(path59.dirname(file), { recursive: true });
|
|
28851
|
+
fs53.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
28757
28852
|
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
28758
28853
|
} catch (err) {
|
|
28759
28854
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
@@ -29410,7 +29505,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
29410
29505
|
var import_child_process27 = require("child_process");
|
|
29411
29506
|
var import_util4 = require("util");
|
|
29412
29507
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
29413
|
-
var
|
|
29508
|
+
var path60 = __toESM(require("path"));
|
|
29414
29509
|
var execFileP6 = (0, import_util4.promisify)(import_child_process27.execFile);
|
|
29415
29510
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
29416
29511
|
function resetStdinForChild() {
|
|
@@ -29899,7 +29994,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29899
29994
|
});
|
|
29900
29995
|
}
|
|
29901
29996
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
29902
|
-
const remoteDir =
|
|
29997
|
+
const remoteDir = path60.posix.dirname(remotePath);
|
|
29903
29998
|
const parts = [
|
|
29904
29999
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
29905
30000
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -29969,7 +30064,7 @@ function shellQuote(s) {
|
|
|
29969
30064
|
// src/services/providers/gitpod.ts
|
|
29970
30065
|
var import_child_process28 = require("child_process");
|
|
29971
30066
|
var import_util5 = require("util");
|
|
29972
|
-
var
|
|
30067
|
+
var path61 = __toESM(require("path"));
|
|
29973
30068
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
29974
30069
|
var execFileP7 = (0, import_util5.promisify)(import_child_process28.execFile);
|
|
29975
30070
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -30209,7 +30304,7 @@ var GitpodProvider = class {
|
|
|
30209
30304
|
});
|
|
30210
30305
|
}
|
|
30211
30306
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
30212
|
-
const remoteDir =
|
|
30307
|
+
const remoteDir = path61.posix.dirname(remotePath);
|
|
30213
30308
|
const parts = [
|
|
30214
30309
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
30215
30310
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -30245,7 +30340,7 @@ function shellQuote2(s) {
|
|
|
30245
30340
|
// src/services/providers/gitlab-workspaces.ts
|
|
30246
30341
|
var import_child_process29 = require("child_process");
|
|
30247
30342
|
var import_util6 = require("util");
|
|
30248
|
-
var
|
|
30343
|
+
var path62 = __toESM(require("path"));
|
|
30249
30344
|
var execFileP8 = (0, import_util6.promisify)(import_child_process29.execFile);
|
|
30250
30345
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
30251
30346
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -30505,7 +30600,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
30505
30600
|
}
|
|
30506
30601
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
30507
30602
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
30508
|
-
const remoteDir =
|
|
30603
|
+
const remoteDir = path62.posix.dirname(remotePath);
|
|
30509
30604
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
30510
30605
|
if (options.mode != null) {
|
|
30511
30606
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -30573,7 +30668,7 @@ function shellQuote3(s) {
|
|
|
30573
30668
|
// src/services/providers/railway.ts
|
|
30574
30669
|
var import_child_process30 = require("child_process");
|
|
30575
30670
|
var import_util7 = require("util");
|
|
30576
|
-
var
|
|
30671
|
+
var path63 = __toESM(require("path"));
|
|
30577
30672
|
var execFileP9 = (0, import_util7.promisify)(import_child_process30.execFile);
|
|
30578
30673
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
30579
30674
|
function resetStdinForChild4() {
|
|
@@ -30809,7 +30904,7 @@ var RailwayProvider = class {
|
|
|
30809
30904
|
if (!projectId || !serviceId) {
|
|
30810
30905
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
30811
30906
|
}
|
|
30812
|
-
const remoteDir =
|
|
30907
|
+
const remoteDir = path63.posix.dirname(remotePath);
|
|
30813
30908
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
30814
30909
|
if (options.mode != null) {
|
|
30815
30910
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -31455,8 +31550,8 @@ async function invite() {
|
|
|
31455
31550
|
var import_node_dns = require("dns");
|
|
31456
31551
|
var import_node_util5 = require("util");
|
|
31457
31552
|
var import_node_crypto8 = require("crypto");
|
|
31458
|
-
var
|
|
31459
|
-
var
|
|
31553
|
+
var fs54 = __toESM(require("fs"));
|
|
31554
|
+
var path64 = __toESM(require("path"));
|
|
31460
31555
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
31461
31556
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
31462
31557
|
async function checkDns(apiBase2) {
|
|
@@ -31512,13 +31607,13 @@ async function checkHealth(apiBase2) {
|
|
|
31512
31607
|
}
|
|
31513
31608
|
}
|
|
31514
31609
|
function checkConfigDir() {
|
|
31515
|
-
const dir =
|
|
31610
|
+
const dir = path64.join(require("os").homedir(), ".codeam");
|
|
31516
31611
|
try {
|
|
31517
|
-
|
|
31518
|
-
const probe =
|
|
31519
|
-
|
|
31520
|
-
const read2 =
|
|
31521
|
-
|
|
31612
|
+
fs54.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
31613
|
+
const probe = path64.join(dir, ".doctor-probe");
|
|
31614
|
+
fs54.writeFileSync(probe, "ok", { mode: 384 });
|
|
31615
|
+
const read2 = fs54.readFileSync(probe, "utf8");
|
|
31616
|
+
fs54.unlinkSync(probe);
|
|
31522
31617
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
31523
31618
|
return {
|
|
31524
31619
|
id: "config-dir",
|
|
@@ -31558,9 +31653,9 @@ function checkSessions() {
|
|
|
31558
31653
|
}
|
|
31559
31654
|
}
|
|
31560
31655
|
function checkAgentBinaries() {
|
|
31561
|
-
const
|
|
31656
|
+
const os45 = createOsStrategy();
|
|
31562
31657
|
return getEnabledAgents().map((meta) => {
|
|
31563
|
-
const found =
|
|
31658
|
+
const found = os45.findInPath(meta.binaryName);
|
|
31564
31659
|
return {
|
|
31565
31660
|
id: `agent-${meta.id}`,
|
|
31566
31661
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -31582,7 +31677,7 @@ function checkNodePty() {
|
|
|
31582
31677
|
detail: "not required on this platform"
|
|
31583
31678
|
};
|
|
31584
31679
|
}
|
|
31585
|
-
const vendoredPath =
|
|
31680
|
+
const vendoredPath = path64.join(__dirname, "vendor", "node-pty");
|
|
31586
31681
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
31587
31682
|
try {
|
|
31588
31683
|
require(target);
|
|
@@ -31624,7 +31719,7 @@ function checkChokidar() {
|
|
|
31624
31719
|
}
|
|
31625
31720
|
async function doctor(args2 = []) {
|
|
31626
31721
|
const json = args2.includes("--json");
|
|
31627
|
-
const cliVersion = true ? "2.53.
|
|
31722
|
+
const cliVersion = true ? "2.53.3" : "0.0.0-dev";
|
|
31628
31723
|
const apiBase2 = resolveApiBaseUrl();
|
|
31629
31724
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
31630
31725
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -31823,7 +31918,7 @@ async function completion(args2) {
|
|
|
31823
31918
|
// src/commands/version.ts
|
|
31824
31919
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
31825
31920
|
function version2() {
|
|
31826
|
-
const v = true ? "2.53.
|
|
31921
|
+
const v = true ? "2.53.3" : "unknown";
|
|
31827
31922
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
31828
31923
|
}
|
|
31829
31924
|
|
|
@@ -31972,10 +32067,10 @@ var EXIT_CODE_NAMES = {
|
|
|
31972
32067
|
};
|
|
31973
32068
|
|
|
31974
32069
|
// src/index.ts
|
|
31975
|
-
var
|
|
32070
|
+
var os44 = __toESM(require("os"));
|
|
31976
32071
|
if (!process.env.HOME) {
|
|
31977
32072
|
try {
|
|
31978
|
-
const home =
|
|
32073
|
+
const home = os44.homedir();
|
|
31979
32074
|
if (home) process.env.HOME = home;
|
|
31980
32075
|
} catch {
|
|
31981
32076
|
}
|