codeam-cli 2.52.11 → 2.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +796 -659
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -522,9 +522,9 @@ var _default = makeConfig();
|
|
|
522
522
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
523
523
|
|
|
524
524
|
// src/commands/pair-auto.ts
|
|
525
|
-
var
|
|
526
|
-
var
|
|
527
|
-
var
|
|
525
|
+
var fs45 = __toESM(require("fs"));
|
|
526
|
+
var os38 = __toESM(require("os"));
|
|
527
|
+
var path50 = __toESM(require("path"));
|
|
528
528
|
var import_crypto4 = require("crypto");
|
|
529
529
|
|
|
530
530
|
// src/services/telemetry.service.ts
|
|
@@ -560,8 +560,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
560
560
|
return decodedFile;
|
|
561
561
|
};
|
|
562
562
|
}
|
|
563
|
-
function normalizeWindowsPath(
|
|
564
|
-
return
|
|
563
|
+
function normalizeWindowsPath(path64) {
|
|
564
|
+
return path64.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
565
565
|
}
|
|
566
566
|
|
|
567
567
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3041,9 +3041,9 @@ async function addSourceContext(frames) {
|
|
|
3041
3041
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3042
3042
|
return frames;
|
|
3043
3043
|
}
|
|
3044
|
-
function getContextLinesFromFile(
|
|
3044
|
+
function getContextLinesFromFile(path64, ranges, output) {
|
|
3045
3045
|
return new Promise((resolve7) => {
|
|
3046
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3046
|
+
const stream = (0, import_node_fs.createReadStream)(path64);
|
|
3047
3047
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3048
3048
|
input: stream
|
|
3049
3049
|
});
|
|
@@ -3058,7 +3058,7 @@ function getContextLinesFromFile(path63, ranges, output) {
|
|
|
3058
3058
|
let rangeStart = range[0];
|
|
3059
3059
|
let rangeEnd = range[1];
|
|
3060
3060
|
function onStreamError() {
|
|
3061
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3061
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path64, 1);
|
|
3062
3062
|
lineReaded.close();
|
|
3063
3063
|
lineReaded.removeAllListeners();
|
|
3064
3064
|
destroyStreamAndResolve();
|
|
@@ -3119,8 +3119,8 @@ function clearLineContext(frame) {
|
|
|
3119
3119
|
delete frame.context_line;
|
|
3120
3120
|
delete frame.post_context;
|
|
3121
3121
|
}
|
|
3122
|
-
function shouldSkipContextLinesForFile(
|
|
3123
|
-
return
|
|
3122
|
+
function shouldSkipContextLinesForFile(path64) {
|
|
3123
|
+
return path64.startsWith("node:") || path64.endsWith(".min.js") || path64.endsWith(".min.cjs") || path64.endsWith(".min.mjs") || path64.startsWith("data:");
|
|
3124
3124
|
}
|
|
3125
3125
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3126
3126
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -5397,7 +5397,7 @@ function readAnonId() {
|
|
|
5397
5397
|
}
|
|
5398
5398
|
function superProperties() {
|
|
5399
5399
|
return {
|
|
5400
|
-
cliVersion: true ? "2.
|
|
5400
|
+
cliVersion: true ? "2.53.0" : "0.0.0-dev",
|
|
5401
5401
|
nodeVersion: process.version,
|
|
5402
5402
|
platform: process.platform,
|
|
5403
5403
|
arch: process.arch,
|
|
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
|
|
|
5578
5578
|
// package.json
|
|
5579
5579
|
var package_default = {
|
|
5580
5580
|
name: "codeam-cli",
|
|
5581
|
-
version: "2.
|
|
5581
|
+
version: "2.53.0",
|
|
5582
5582
|
description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
|
|
5583
5583
|
type: "commonjs",
|
|
5584
5584
|
main: "dist/index.js",
|
|
@@ -6104,6 +6104,93 @@ function computePollDelay({ baseMs, failures }) {
|
|
|
6104
6104
|
return Math.round(jitter);
|
|
6105
6105
|
}
|
|
6106
6106
|
|
|
6107
|
+
// src/services/headroom/proxy-supervisor.ts
|
|
6108
|
+
var import_child_process2 = require("child_process");
|
|
6109
|
+
var fs4 = __toESM(require("fs"));
|
|
6110
|
+
var os5 = __toESM(require("os"));
|
|
6111
|
+
var path4 = __toESM(require("path"));
|
|
6112
|
+
|
|
6113
|
+
// src/services/headroom/budget-args.ts
|
|
6114
|
+
function buildBudgetProxyArgs(env) {
|
|
6115
|
+
const budget = env["HEADROOM_BUDGET"];
|
|
6116
|
+
if (!budget) return [];
|
|
6117
|
+
const period = env["HEADROOM_BUDGET_PERIOD"] ?? "daily";
|
|
6118
|
+
return ["--budget", budget, "--budget-period", period];
|
|
6119
|
+
}
|
|
6120
|
+
|
|
6121
|
+
// src/services/headroom/proxy-supervisor.ts
|
|
6122
|
+
async function ensureHeadroomProxy(deps) {
|
|
6123
|
+
if (!deps.isConfigured()) return "skip";
|
|
6124
|
+
let alive = false;
|
|
6125
|
+
try {
|
|
6126
|
+
alive = await deps.probeAlive();
|
|
6127
|
+
} catch {
|
|
6128
|
+
alive = false;
|
|
6129
|
+
}
|
|
6130
|
+
if (alive) return "alive";
|
|
6131
|
+
log.warn("headroom-supervisor", "proxy :8787 is down \u2014 respawning");
|
|
6132
|
+
deps.spawnProxy();
|
|
6133
|
+
return "respawned";
|
|
6134
|
+
}
|
|
6135
|
+
function isHeadroomConfiguredReal(homeDir2 = os5.homedir()) {
|
|
6136
|
+
if (process.env.HEADROOM_ENABLED === "1") return true;
|
|
6137
|
+
const csEnv = path4.join(homeDir2, ".codeam", "codespace-env.json");
|
|
6138
|
+
try {
|
|
6139
|
+
const j2 = JSON.parse(fs4.readFileSync(csEnv, "utf8"));
|
|
6140
|
+
if (j2.HEADROOM_ENABLED === "1" || j2.HEADROOM_ENABLED === 1) return true;
|
|
6141
|
+
} catch {
|
|
6142
|
+
}
|
|
6143
|
+
const settings = path4.join(homeDir2, ".claude", "settings.json");
|
|
6144
|
+
try {
|
|
6145
|
+
if (fs4.readFileSync(settings, "utf8").includes("127.0.0.1:8787")) return true;
|
|
6146
|
+
} catch {
|
|
6147
|
+
}
|
|
6148
|
+
return false;
|
|
6149
|
+
}
|
|
6150
|
+
async function probeProxyAliveReal() {
|
|
6151
|
+
const controller = new AbortController();
|
|
6152
|
+
const timer = setTimeout(() => controller.abort(), 2e3);
|
|
6153
|
+
try {
|
|
6154
|
+
const res = await fetch("http://127.0.0.1:8787/livez", {
|
|
6155
|
+
signal: controller.signal
|
|
6156
|
+
});
|
|
6157
|
+
return res.ok;
|
|
6158
|
+
} catch {
|
|
6159
|
+
return false;
|
|
6160
|
+
} finally {
|
|
6161
|
+
clearTimeout(timer);
|
|
6162
|
+
}
|
|
6163
|
+
}
|
|
6164
|
+
function spawnProxyReal() {
|
|
6165
|
+
try {
|
|
6166
|
+
const proxyEnv = {
|
|
6167
|
+
...process.env,
|
|
6168
|
+
HEADROOM_KOMPRESS_BACKEND: "onnx_cpu"
|
|
6169
|
+
};
|
|
6170
|
+
const proxy = (0, import_child_process2.spawn)(
|
|
6171
|
+
"headroom",
|
|
6172
|
+
["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
|
|
6173
|
+
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
6174
|
+
);
|
|
6175
|
+
proxy.once("error", (e) => {
|
|
6176
|
+
log.warn("headroom-supervisor", `respawn error (best-effort): ${e.message}`);
|
|
6177
|
+
});
|
|
6178
|
+
proxy.unref();
|
|
6179
|
+
} catch (e) {
|
|
6180
|
+
log.warn(
|
|
6181
|
+
"headroom-supervisor",
|
|
6182
|
+
`respawn failed (best-effort): ${e instanceof Error ? e.message : String(e)}`
|
|
6183
|
+
);
|
|
6184
|
+
}
|
|
6185
|
+
}
|
|
6186
|
+
function makeRealProxySupervisorDeps() {
|
|
6187
|
+
return {
|
|
6188
|
+
isConfigured: () => isHeadroomConfiguredReal(),
|
|
6189
|
+
probeAlive: probeProxyAliveReal,
|
|
6190
|
+
spawnProxy: spawnProxyReal
|
|
6191
|
+
};
|
|
6192
|
+
}
|
|
6193
|
+
|
|
6107
6194
|
// src/services/command-relay.service.ts
|
|
6108
6195
|
function httpStatusOf(err) {
|
|
6109
6196
|
if (typeof err === "object" && err !== null && "statusCode" in err) {
|
|
@@ -6130,6 +6217,9 @@ var CommandRelayService = class {
|
|
|
6130
6217
|
pairingInvalid = false;
|
|
6131
6218
|
heartbeatTimer = null;
|
|
6132
6219
|
agentsTimer = null;
|
|
6220
|
+
headroomSupervisorTimer = null;
|
|
6221
|
+
/** Injectable for tests; defaults to real fs/fetch/spawn wiring. */
|
|
6222
|
+
headroomSupervisorDeps = makeRealProxySupervisorDeps();
|
|
6133
6223
|
/** True once `/api/plugin/agents` has accepted at least one report. */
|
|
6134
6224
|
agentsRegistered = false;
|
|
6135
6225
|
/** SSE connection (null when on the polling fallback or stopped). */
|
|
@@ -6190,6 +6280,10 @@ var CommandRelayService = class {
|
|
|
6190
6280
|
if (this._running && !this.agentsRegistered) this.reportAgents();
|
|
6191
6281
|
}, 5e3);
|
|
6192
6282
|
this.reportAgents();
|
|
6283
|
+
void ensureHeadroomProxy(this.headroomSupervisorDeps).catch(() => void 0);
|
|
6284
|
+
this.headroomSupervisorTimer = setInterval(() => {
|
|
6285
|
+
void ensureHeadroomProxy(this.headroomSupervisorDeps).catch(() => void 0);
|
|
6286
|
+
}, 3e4);
|
|
6193
6287
|
if (process.env.NODE_ENV === "test" || process.env.CODEAM_DISABLE_SSE_PULL === "1") {
|
|
6194
6288
|
log.info("relay", "SSE disabled \u2014 using polling fallback");
|
|
6195
6289
|
this.startPollingFallback();
|
|
@@ -6444,7 +6538,12 @@ var CommandRelayService = class {
|
|
|
6444
6538
|
pluginId: this.pluginId,
|
|
6445
6539
|
online,
|
|
6446
6540
|
agentId: this.agentMeta.id,
|
|
6447
|
-
branch: this.cachedBranch
|
|
6541
|
+
branch: this.cachedBranch,
|
|
6542
|
+
// Report our own version so the backend can keep PairedSession.ideVersion
|
|
6543
|
+
// fresh + clear the "CLI update available" banner after a self-update
|
|
6544
|
+
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
6545
|
+
// pair/reconnect). Older backends ignore the extra field.
|
|
6546
|
+
..."2.53.0" ? { ideVersion: "2.53.0" } : {}
|
|
6448
6547
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
6449
6548
|
}
|
|
6450
6549
|
/**
|
|
@@ -6489,6 +6588,10 @@ var CommandRelayService = class {
|
|
|
6489
6588
|
clearInterval(this.agentsTimer);
|
|
6490
6589
|
this.agentsTimer = null;
|
|
6491
6590
|
}
|
|
6591
|
+
if (this.headroomSupervisorTimer) {
|
|
6592
|
+
clearInterval(this.headroomSupervisorTimer);
|
|
6593
|
+
this.headroomSupervisorTimer = null;
|
|
6594
|
+
}
|
|
6492
6595
|
if (this.sseReconnectTimer) {
|
|
6493
6596
|
clearTimeout(this.sseReconnectTimer);
|
|
6494
6597
|
this.sseReconnectTimer = null;
|
|
@@ -6505,10 +6608,10 @@ var CommandRelayService = class {
|
|
|
6505
6608
|
};
|
|
6506
6609
|
|
|
6507
6610
|
// src/services/file-watcher.service.ts
|
|
6508
|
-
var
|
|
6509
|
-
var
|
|
6510
|
-
var
|
|
6511
|
-
var
|
|
6611
|
+
var import_child_process3 = require("child_process");
|
|
6612
|
+
var fs5 = __toESM(require("fs"));
|
|
6613
|
+
var os6 = __toESM(require("os"));
|
|
6614
|
+
var path5 = __toESM(require("path"));
|
|
6512
6615
|
var import_ignore = __toESM(require("ignore"));
|
|
6513
6616
|
|
|
6514
6617
|
// src/services/file-watcher/diff-parser.ts
|
|
@@ -6667,10 +6770,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
|
|
|
6667
6770
|
/[\\/]Start Menu([\\/]|$)/i,
|
|
6668
6771
|
/[\\/]Templates([\\/]|$)/i
|
|
6669
6772
|
];
|
|
6670
|
-
function isUnsafeWindowsWatchRoot(dir,
|
|
6773
|
+
function isUnsafeWindowsWatchRoot(dir, homedir35) {
|
|
6671
6774
|
const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
|
|
6672
6775
|
const cwd = norm(dir);
|
|
6673
|
-
const home = norm(
|
|
6776
|
+
const home = norm(homedir35);
|
|
6674
6777
|
if (cwd === home) return true;
|
|
6675
6778
|
if (/^[a-z]:$/.test(cwd)) return true;
|
|
6676
6779
|
const sysRoots = [
|
|
@@ -6700,18 +6803,18 @@ var _findGitRootSeam = {
|
|
|
6700
6803
|
resolve: _defaultFindGitRoot
|
|
6701
6804
|
};
|
|
6702
6805
|
function _defaultFindGitRoot(startDir) {
|
|
6703
|
-
let dir =
|
|
6806
|
+
let dir = path5.resolve(startDir);
|
|
6704
6807
|
const seen = /* @__PURE__ */ new Set();
|
|
6705
6808
|
for (let i = 0; i < 256; i++) {
|
|
6706
6809
|
if (seen.has(dir)) return null;
|
|
6707
6810
|
seen.add(dir);
|
|
6708
6811
|
try {
|
|
6709
|
-
const gitPath =
|
|
6710
|
-
const stat3 =
|
|
6812
|
+
const gitPath = path5.join(dir, ".git");
|
|
6813
|
+
const stat3 = fs5.statSync(gitPath, { throwIfNoEntry: false });
|
|
6711
6814
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
6712
6815
|
} catch {
|
|
6713
6816
|
}
|
|
6714
|
-
const parent =
|
|
6817
|
+
const parent = path5.dirname(dir);
|
|
6715
6818
|
if (parent === dir) return null;
|
|
6716
6819
|
dir = parent;
|
|
6717
6820
|
}
|
|
@@ -6769,7 +6872,7 @@ var FileWatcherService = class {
|
|
|
6769
6872
|
throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
|
|
6770
6873
|
}
|
|
6771
6874
|
const isWin = process.platform === "win32";
|
|
6772
|
-
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir,
|
|
6875
|
+
if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os6.homedir())) {
|
|
6773
6876
|
log.warn(
|
|
6774
6877
|
"fileWatcher",
|
|
6775
6878
|
`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.`
|
|
@@ -6956,7 +7059,7 @@ var FileWatcherService = class {
|
|
|
6956
7059
|
}
|
|
6957
7060
|
async emitForFile(absPath, changeType) {
|
|
6958
7061
|
if (this.stopped) return;
|
|
6959
|
-
const fileDir =
|
|
7062
|
+
const fileDir = path5.dirname(absPath);
|
|
6960
7063
|
let gitRoot = this.gitRootByDir.get(fileDir);
|
|
6961
7064
|
if (gitRoot === void 0) {
|
|
6962
7065
|
gitRoot = findGitRoot(fileDir);
|
|
@@ -6969,19 +7072,19 @@ var FileWatcherService = class {
|
|
|
6969
7072
|
);
|
|
6970
7073
|
return;
|
|
6971
7074
|
}
|
|
6972
|
-
const relPathInRepo =
|
|
7075
|
+
const relPathInRepo = path5.relative(gitRoot, absPath);
|
|
6973
7076
|
if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
|
|
6974
7077
|
const matcher = this.getGitIgnoreMatcher(gitRoot);
|
|
6975
7078
|
if (matcher && matcher.ignores(relPathInRepo)) {
|
|
6976
7079
|
log.trace(
|
|
6977
7080
|
"fileWatcher",
|
|
6978
|
-
`${relPathInRepo} ignored by ${
|
|
7081
|
+
`${relPathInRepo} ignored by ${path5.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
|
|
6979
7082
|
);
|
|
6980
7083
|
return;
|
|
6981
7084
|
}
|
|
6982
7085
|
this.opts.onRepoDirty?.(gitRoot);
|
|
6983
|
-
const repoPath =
|
|
6984
|
-
const repoName =
|
|
7086
|
+
const repoPath = path5.relative(this.opts.workingDir, gitRoot);
|
|
7087
|
+
const repoName = path5.basename(gitRoot);
|
|
6985
7088
|
let diffText = "";
|
|
6986
7089
|
let fileStatus = "modified";
|
|
6987
7090
|
if (changeType === "unlink") {
|
|
@@ -7156,7 +7259,7 @@ var FileWatcherService = class {
|
|
|
7156
7259
|
collectGitignoreFiles(repoRoot, dir, matcher) {
|
|
7157
7260
|
let entries;
|
|
7158
7261
|
try {
|
|
7159
|
-
entries =
|
|
7262
|
+
entries = fs5.readdirSync(dir, { withFileTypes: true });
|
|
7160
7263
|
} catch {
|
|
7161
7264
|
return;
|
|
7162
7265
|
}
|
|
@@ -7165,16 +7268,16 @@ var FileWatcherService = class {
|
|
|
7165
7268
|
);
|
|
7166
7269
|
if (gitignoreEntry) {
|
|
7167
7270
|
try {
|
|
7168
|
-
const body =
|
|
7169
|
-
const rel =
|
|
7271
|
+
const body = fs5.readFileSync(path5.join(dir, ".gitignore"), "utf8");
|
|
7272
|
+
const rel = path5.relative(repoRoot, dir).replace(/\\/g, "/");
|
|
7170
7273
|
const prefixed = body.split(/\r?\n/).map((line) => {
|
|
7171
7274
|
const trimmed = line.trim();
|
|
7172
7275
|
if (!trimmed || trimmed.startsWith("#")) return line;
|
|
7173
7276
|
if (!rel) return line;
|
|
7174
7277
|
if (trimmed.startsWith("!")) {
|
|
7175
|
-
return "!" +
|
|
7278
|
+
return "!" + path5.posix.join(rel, trimmed.slice(1));
|
|
7176
7279
|
}
|
|
7177
|
-
return
|
|
7280
|
+
return path5.posix.join(rel, trimmed);
|
|
7178
7281
|
}).join("\n");
|
|
7179
7282
|
matcher.add(prefixed);
|
|
7180
7283
|
} catch {
|
|
@@ -7183,7 +7286,7 @@ var FileWatcherService = class {
|
|
|
7183
7286
|
for (const entry of entries) {
|
|
7184
7287
|
if (!entry.isDirectory()) continue;
|
|
7185
7288
|
if (entry.name === ".git") continue;
|
|
7186
|
-
const childAbs =
|
|
7289
|
+
const childAbs = path5.join(dir, entry.name);
|
|
7187
7290
|
if (isIgnoredFilePath(childAbs)) continue;
|
|
7188
7291
|
this.collectGitignoreFiles(repoRoot, childAbs, matcher);
|
|
7189
7292
|
}
|
|
@@ -7320,7 +7423,7 @@ async function _runGitImpl(cwd, args2, opts = {}) {
|
|
|
7320
7423
|
return new Promise((resolve7) => {
|
|
7321
7424
|
let proc;
|
|
7322
7425
|
try {
|
|
7323
|
-
proc = (0,
|
|
7426
|
+
proc = (0, import_child_process3.spawn)("git", args2, { cwd, env: process.env });
|
|
7324
7427
|
} catch {
|
|
7325
7428
|
resolve7(null);
|
|
7326
7429
|
return;
|
|
@@ -7545,7 +7648,7 @@ function _post2(url, headers, payload) {
|
|
|
7545
7648
|
}
|
|
7546
7649
|
|
|
7547
7650
|
// src/services/terminal-ops.service.ts
|
|
7548
|
-
var
|
|
7651
|
+
var import_child_process4 = require("child_process");
|
|
7549
7652
|
var import_crypto2 = require("crypto");
|
|
7550
7653
|
var import_path3 = __toESM(require("path"));
|
|
7551
7654
|
var MAX_CONCURRENT_SESSIONS = 4;
|
|
@@ -7668,7 +7771,7 @@ function createPythonSession(id, shell, cwd, env, cols, rows) {
|
|
|
7668
7771
|
log.trace("terminal", `python helper spawn python=${python} shell=${shell} cwd=${cwd}`);
|
|
7669
7772
|
let child;
|
|
7670
7773
|
try {
|
|
7671
|
-
child = (0,
|
|
7774
|
+
child = (0, import_child_process4.spawn)(python, ["-c", PYTHON_TERMINAL_HELPER, shell], {
|
|
7672
7775
|
cwd,
|
|
7673
7776
|
env: { ...env, COLUMNS: String(cols), LINES: String(rows) },
|
|
7674
7777
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -7814,11 +7917,11 @@ function closeAllTerminals() {
|
|
|
7814
7917
|
}
|
|
7815
7918
|
|
|
7816
7919
|
// src/commands/start/handlers.ts
|
|
7817
|
-
var
|
|
7818
|
-
var
|
|
7819
|
-
var
|
|
7920
|
+
var fs44 = __toESM(require("fs"));
|
|
7921
|
+
var os37 = __toESM(require("os"));
|
|
7922
|
+
var path49 = __toESM(require("path"));
|
|
7820
7923
|
var import_crypto3 = require("crypto");
|
|
7821
|
-
var
|
|
7924
|
+
var import_child_process22 = require("child_process");
|
|
7822
7925
|
var import_which2 = __toESM(require("which"));
|
|
7823
7926
|
|
|
7824
7927
|
// src/lib/payload.ts
|
|
@@ -7969,8 +8072,8 @@ function parsePayload2(schema, raw) {
|
|
|
7969
8072
|
}
|
|
7970
8073
|
|
|
7971
8074
|
// src/services/file-ops.service.ts
|
|
7972
|
-
var
|
|
7973
|
-
var
|
|
8075
|
+
var fs6 = __toESM(require("fs/promises"));
|
|
8076
|
+
var path7 = __toESM(require("path"));
|
|
7974
8077
|
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
7975
8078
|
var MAX_WALK_DEPTH = 6;
|
|
7976
8079
|
var MAX_VISITED_DIRS = 5e3;
|
|
@@ -8005,12 +8108,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
|
|
|
8005
8108
|
"__pycache__"
|
|
8006
8109
|
]);
|
|
8007
8110
|
function isUnder(parent, candidate) {
|
|
8008
|
-
const rel =
|
|
8009
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
8111
|
+
const rel = path7.relative(parent, candidate);
|
|
8112
|
+
return rel === "" || !rel.startsWith("..") && !path7.isAbsolute(rel);
|
|
8010
8113
|
}
|
|
8011
8114
|
async function isExistingFile(absPath) {
|
|
8012
8115
|
try {
|
|
8013
|
-
const stat3 = await
|
|
8116
|
+
const stat3 = await fs6.stat(absPath);
|
|
8014
8117
|
return stat3.isFile();
|
|
8015
8118
|
} catch {
|
|
8016
8119
|
return false;
|
|
@@ -8023,13 +8126,13 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
8023
8126
|
ctx.visited++;
|
|
8024
8127
|
let entries = [];
|
|
8025
8128
|
try {
|
|
8026
|
-
entries = await
|
|
8129
|
+
entries = await fs6.readdir(dir, { withFileTypes: true });
|
|
8027
8130
|
} catch {
|
|
8028
8131
|
return;
|
|
8029
8132
|
}
|
|
8030
8133
|
for (const e of entries) {
|
|
8031
8134
|
if (!e.isFile()) continue;
|
|
8032
|
-
const full =
|
|
8135
|
+
const full = path7.join(dir, e.name);
|
|
8033
8136
|
if (needleVariants.some((needle) => full.endsWith(needle))) {
|
|
8034
8137
|
ctx.matches.push(full);
|
|
8035
8138
|
if (ctx.matches.length >= ctx.cap) return;
|
|
@@ -8039,21 +8142,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
|
|
|
8039
8142
|
if (!e.isDirectory()) continue;
|
|
8040
8143
|
if (SUBDIR_IGNORE.has(e.name)) continue;
|
|
8041
8144
|
if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
|
|
8042
|
-
await walkForSuffix(
|
|
8145
|
+
await walkForSuffix(path7.join(dir, e.name), needleVariants, depth + 1, ctx);
|
|
8043
8146
|
if (ctx.matches.length >= ctx.cap) return;
|
|
8044
8147
|
}
|
|
8045
8148
|
}
|
|
8046
8149
|
async function findFile(rawPath) {
|
|
8047
8150
|
const cwd = process.cwd();
|
|
8048
|
-
if (
|
|
8049
|
-
const abs =
|
|
8151
|
+
if (path7.isAbsolute(rawPath)) {
|
|
8152
|
+
const abs = path7.normalize(rawPath);
|
|
8050
8153
|
if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
|
|
8051
8154
|
}
|
|
8052
|
-
const direct =
|
|
8155
|
+
const direct = path7.resolve(cwd, rawPath);
|
|
8053
8156
|
if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
|
|
8054
|
-
const normalized =
|
|
8157
|
+
const normalized = path7.normalize(rawPath).replace(/^[./\\]+/, "");
|
|
8055
8158
|
const needles = [
|
|
8056
|
-
`${
|
|
8159
|
+
`${path7.sep}${normalized}`,
|
|
8057
8160
|
`/${normalized}`
|
|
8058
8161
|
].filter((v, i, a) => a.indexOf(v) === i);
|
|
8059
8162
|
const ctx = { visited: 0, matches: [], cap: 16 };
|
|
@@ -8067,7 +8170,7 @@ async function findWriteTarget(rawPath) {
|
|
|
8067
8170
|
const found = await findFile(rawPath);
|
|
8068
8171
|
if (found) return found;
|
|
8069
8172
|
const cwd = process.cwd();
|
|
8070
|
-
const fallback =
|
|
8173
|
+
const fallback = path7.isAbsolute(rawPath) ? path7.normalize(rawPath) : path7.resolve(cwd, rawPath);
|
|
8071
8174
|
if (!isUnder(cwd, fallback)) return null;
|
|
8072
8175
|
return fallback;
|
|
8073
8176
|
}
|
|
@@ -8084,11 +8187,11 @@ async function readProjectFile(rawPath) {
|
|
|
8084
8187
|
if (!abs) {
|
|
8085
8188
|
return { error: `File not found in the project tree: ${rawPath}` };
|
|
8086
8189
|
}
|
|
8087
|
-
const stat3 = await
|
|
8190
|
+
const stat3 = await fs6.stat(abs);
|
|
8088
8191
|
if (stat3.size > MAX_FILE_BYTES) {
|
|
8089
8192
|
return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
|
|
8090
8193
|
}
|
|
8091
|
-
const buf = await
|
|
8194
|
+
const buf = await fs6.readFile(abs);
|
|
8092
8195
|
if (looksBinary(buf)) {
|
|
8093
8196
|
return { error: "Binary file \u2014 refusing to open in a code editor." };
|
|
8094
8197
|
}
|
|
@@ -8107,8 +8210,8 @@ async function writeProjectFile(rawPath, content) {
|
|
|
8107
8210
|
if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
|
|
8108
8211
|
return { error: "Content too large." };
|
|
8109
8212
|
}
|
|
8110
|
-
await
|
|
8111
|
-
await
|
|
8213
|
+
await fs6.mkdir(path7.dirname(abs), { recursive: true });
|
|
8214
|
+
await fs6.writeFile(abs, content, "utf-8");
|
|
8112
8215
|
return { ok: true };
|
|
8113
8216
|
} catch (e) {
|
|
8114
8217
|
const msg = e instanceof Error ? e.message : "Write failed";
|
|
@@ -8117,11 +8220,11 @@ async function writeProjectFile(rawPath, content) {
|
|
|
8117
8220
|
}
|
|
8118
8221
|
|
|
8119
8222
|
// src/services/project-ops.service.ts
|
|
8120
|
-
var
|
|
8223
|
+
var import_child_process5 = require("child_process");
|
|
8121
8224
|
var import_util = require("util");
|
|
8122
|
-
var
|
|
8123
|
-
var
|
|
8124
|
-
var execFileP = (0, import_util.promisify)(
|
|
8225
|
+
var fs7 = __toESM(require("fs/promises"));
|
|
8226
|
+
var path8 = __toESM(require("path"));
|
|
8227
|
+
var execFileP = (0, import_util.promisify)(import_child_process5.execFile);
|
|
8125
8228
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
8126
8229
|
"node_modules",
|
|
8127
8230
|
".git",
|
|
@@ -8168,7 +8271,7 @@ async function listProjectFiles(opts = {}) {
|
|
|
8168
8271
|
}
|
|
8169
8272
|
let entries = [];
|
|
8170
8273
|
try {
|
|
8171
|
-
entries = await
|
|
8274
|
+
entries = await fs7.readdir(dir, { withFileTypes: true });
|
|
8172
8275
|
} catch {
|
|
8173
8276
|
return;
|
|
8174
8277
|
}
|
|
@@ -8178,18 +8281,18 @@ async function listProjectFiles(opts = {}) {
|
|
|
8178
8281
|
return;
|
|
8179
8282
|
}
|
|
8180
8283
|
if (PROJECT_IGNORE.has(e.name)) continue;
|
|
8181
|
-
const full =
|
|
8284
|
+
const full = path8.join(dir, e.name);
|
|
8182
8285
|
if (e.isDirectory()) {
|
|
8183
8286
|
if (depth >= 12) continue;
|
|
8184
8287
|
await walk(full, depth + 1);
|
|
8185
8288
|
} else if (e.isFile()) {
|
|
8186
|
-
const rel =
|
|
8289
|
+
const rel = path8.relative(root, full);
|
|
8187
8290
|
if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
|
|
8188
8291
|
continue;
|
|
8189
8292
|
}
|
|
8190
8293
|
let size = 0;
|
|
8191
8294
|
try {
|
|
8192
|
-
const st3 = await
|
|
8295
|
+
const st3 = await fs7.stat(full);
|
|
8193
8296
|
size = st3.size;
|
|
8194
8297
|
} catch {
|
|
8195
8298
|
}
|
|
@@ -8291,8 +8394,8 @@ async function gitStatus(cwd) {
|
|
|
8291
8394
|
let hasMergeInProgress = false;
|
|
8292
8395
|
try {
|
|
8293
8396
|
const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
|
|
8294
|
-
const mergeHead =
|
|
8295
|
-
await
|
|
8397
|
+
const mergeHead = path8.isAbsolute(gitDir) ? path8.join(gitDir, "MERGE_HEAD") : path8.join(root, gitDir, "MERGE_HEAD");
|
|
8398
|
+
await fs7.access(mergeHead);
|
|
8296
8399
|
hasMergeInProgress = true;
|
|
8297
8400
|
} catch {
|
|
8298
8401
|
}
|
|
@@ -8438,7 +8541,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
8438
8541
|
}
|
|
8439
8542
|
let content = "";
|
|
8440
8543
|
try {
|
|
8441
|
-
content = await
|
|
8544
|
+
content = await fs7.readFile(path8.join(cwd, f.path), "utf8");
|
|
8442
8545
|
} catch {
|
|
8443
8546
|
continue;
|
|
8444
8547
|
}
|
|
@@ -8514,15 +8617,15 @@ function formatRemaining(expiresAt) {
|
|
|
8514
8617
|
}
|
|
8515
8618
|
|
|
8516
8619
|
// src/services/apply-file-review.service.ts
|
|
8517
|
-
var
|
|
8518
|
-
var
|
|
8519
|
-
var
|
|
8620
|
+
var import_child_process6 = require("child_process");
|
|
8621
|
+
var fs8 = __toESM(require("fs"));
|
|
8622
|
+
var path9 = __toESM(require("path"));
|
|
8520
8623
|
async function applyFileReview(workingDir, filePath, action) {
|
|
8521
|
-
if (filePath.includes("..") ||
|
|
8624
|
+
if (filePath.includes("..") || path9.isAbsolute(filePath)) {
|
|
8522
8625
|
return { ok: false, action, filePath, error: "invalid file path" };
|
|
8523
8626
|
}
|
|
8524
|
-
const absFile =
|
|
8525
|
-
const repoRoot = findGitRoot2(
|
|
8627
|
+
const absFile = path9.resolve(workingDir, filePath);
|
|
8628
|
+
const repoRoot = findGitRoot2(path9.dirname(absFile));
|
|
8526
8629
|
if (!repoRoot) {
|
|
8527
8630
|
return {
|
|
8528
8631
|
ok: false,
|
|
@@ -8531,7 +8634,7 @@ async function applyFileReview(workingDir, filePath, action) {
|
|
|
8531
8634
|
error: `no enclosing git repo for ${filePath}`
|
|
8532
8635
|
};
|
|
8533
8636
|
}
|
|
8534
|
-
const relInRepo =
|
|
8637
|
+
const relInRepo = path9.relative(repoRoot, absFile);
|
|
8535
8638
|
if (!relInRepo || relInRepo.startsWith("..")) {
|
|
8536
8639
|
return { ok: false, action, filePath, error: "path escapes repo root" };
|
|
8537
8640
|
}
|
|
@@ -8556,7 +8659,7 @@ function runGit2(cwd, args2) {
|
|
|
8556
8659
|
return new Promise((resolve7) => {
|
|
8557
8660
|
let proc;
|
|
8558
8661
|
try {
|
|
8559
|
-
proc = (0,
|
|
8662
|
+
proc = (0, import_child_process6.spawn)("git", args2, { cwd, env: process.env });
|
|
8560
8663
|
} catch (err) {
|
|
8561
8664
|
resolve7({ ok: false, code: -1, stdout: "", stderr: err.message });
|
|
8562
8665
|
return;
|
|
@@ -8580,17 +8683,17 @@ function runGit2(cwd, args2) {
|
|
|
8580
8683
|
});
|
|
8581
8684
|
}
|
|
8582
8685
|
function findGitRoot2(startDir) {
|
|
8583
|
-
let dir =
|
|
8686
|
+
let dir = path9.resolve(startDir);
|
|
8584
8687
|
const seen = /* @__PURE__ */ new Set();
|
|
8585
8688
|
for (let i = 0; i < 256; i++) {
|
|
8586
8689
|
if (seen.has(dir)) return null;
|
|
8587
8690
|
seen.add(dir);
|
|
8588
8691
|
try {
|
|
8589
|
-
const stat3 =
|
|
8692
|
+
const stat3 = fs8.statSync(path9.join(dir, ".git"), { throwIfNoEntry: false });
|
|
8590
8693
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
8591
8694
|
} catch {
|
|
8592
8695
|
}
|
|
8593
|
-
const parent =
|
|
8696
|
+
const parent = path9.dirname(dir);
|
|
8594
8697
|
if (parent === dir) return null;
|
|
8595
8698
|
dir = parent;
|
|
8596
8699
|
}
|
|
@@ -8599,8 +8702,8 @@ function findGitRoot2(startDir) {
|
|
|
8599
8702
|
|
|
8600
8703
|
// src/commands/link.ts
|
|
8601
8704
|
var import_node_crypto5 = require("crypto");
|
|
8602
|
-
var
|
|
8603
|
-
var
|
|
8705
|
+
var fs26 = __toESM(require("fs"));
|
|
8706
|
+
var path31 = __toESM(require("path"));
|
|
8604
8707
|
var import_chokidar = __toESM(require("chokidar"));
|
|
8605
8708
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
8606
8709
|
|
|
@@ -10655,19 +10758,19 @@ function parseFrame(frame, dispatch) {
|
|
|
10655
10758
|
}
|
|
10656
10759
|
|
|
10657
10760
|
// src/os/posix.ts
|
|
10658
|
-
var
|
|
10659
|
-
var
|
|
10660
|
-
var
|
|
10761
|
+
var fs10 = __toESM(require("fs"));
|
|
10762
|
+
var os8 = __toESM(require("os"));
|
|
10763
|
+
var path12 = __toESM(require("path"));
|
|
10661
10764
|
var import_node_crypto2 = require("crypto");
|
|
10662
10765
|
|
|
10663
10766
|
// src/os/strategy.ts
|
|
10664
|
-
var
|
|
10767
|
+
var path10 = __toESM(require("path"));
|
|
10665
10768
|
function findInPathFor(name, opts) {
|
|
10666
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
10769
|
+
const dirs = (process.env.PATH ?? "").split(path10.delimiter).filter(Boolean);
|
|
10667
10770
|
const candidates = opts.candidates(name);
|
|
10668
10771
|
for (const dir of dirs) {
|
|
10669
10772
|
for (const candidate of candidates) {
|
|
10670
|
-
const full =
|
|
10773
|
+
const full = path10.join(dir, candidate);
|
|
10671
10774
|
try {
|
|
10672
10775
|
opts.accessSync(full, opts.accessFlag);
|
|
10673
10776
|
return full;
|
|
@@ -10679,10 +10782,10 @@ function findInPathFor(name, opts) {
|
|
|
10679
10782
|
}
|
|
10680
10783
|
|
|
10681
10784
|
// src/services/pty/unix.strategy.ts
|
|
10682
|
-
var
|
|
10683
|
-
var
|
|
10684
|
-
var
|
|
10685
|
-
var
|
|
10785
|
+
var import_child_process7 = require("child_process");
|
|
10786
|
+
var fs9 = __toESM(require("fs"));
|
|
10787
|
+
var os7 = __toESM(require("os"));
|
|
10788
|
+
var path11 = __toESM(require("path"));
|
|
10686
10789
|
|
|
10687
10790
|
// src/services/pty/types.ts
|
|
10688
10791
|
function findInPath(name) {
|
|
@@ -10764,9 +10867,9 @@ var UnixPtyStrategy = class {
|
|
|
10764
10867
|
}
|
|
10765
10868
|
const cols = process.stdout.columns || 220;
|
|
10766
10869
|
const rows = process.stdout.rows || 50;
|
|
10767
|
-
this.helperPath =
|
|
10768
|
-
|
|
10769
|
-
this.proc = (0,
|
|
10870
|
+
this.helperPath = path11.join(os7.tmpdir(), "codeam-pty-helper.py");
|
|
10871
|
+
fs9.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
|
|
10872
|
+
this.proc = (0, import_child_process7.spawn)(python, [this.helperPath, cmd, ...args2], {
|
|
10770
10873
|
stdio: ["pipe", "pipe", "inherit"],
|
|
10771
10874
|
cwd,
|
|
10772
10875
|
env: {
|
|
@@ -10831,7 +10934,7 @@ var UnixPtyStrategy = class {
|
|
|
10831
10934
|
* are NOT interpreted by /bin/sh.
|
|
10832
10935
|
*/
|
|
10833
10936
|
spawnDirect(cmd, cwd, args2 = []) {
|
|
10834
|
-
this.proc = (0,
|
|
10937
|
+
this.proc = (0, import_child_process7.spawn)(cmd, args2, {
|
|
10835
10938
|
stdio: ["pipe", "inherit", "inherit"],
|
|
10836
10939
|
cwd,
|
|
10837
10940
|
env: process.env,
|
|
@@ -10894,7 +10997,7 @@ var UnixPtyStrategy = class {
|
|
|
10894
10997
|
removeTempFile() {
|
|
10895
10998
|
if (this.helperPath) {
|
|
10896
10999
|
try {
|
|
10897
|
-
|
|
11000
|
+
fs9.unlinkSync(this.helperPath);
|
|
10898
11001
|
} catch {
|
|
10899
11002
|
}
|
|
10900
11003
|
this.helperPath = null;
|
|
@@ -10905,11 +11008,11 @@ var UnixPtyStrategy = class {
|
|
|
10905
11008
|
// src/os/posix.ts
|
|
10906
11009
|
var PosixOsStrategy = class {
|
|
10907
11010
|
homeDir() {
|
|
10908
|
-
return
|
|
11011
|
+
return os8.homedir();
|
|
10909
11012
|
}
|
|
10910
11013
|
scratchPath(prefix) {
|
|
10911
11014
|
const tag = `${process.pid}-${(0, import_node_crypto2.randomBytes)(4).toString("hex")}`;
|
|
10912
|
-
return
|
|
11015
|
+
return path12.join(os8.tmpdir(), `${prefix}-${tag}`);
|
|
10913
11016
|
}
|
|
10914
11017
|
devNull() {
|
|
10915
11018
|
return "/dev/null";
|
|
@@ -10917,8 +11020,8 @@ var PosixOsStrategy = class {
|
|
|
10917
11020
|
findInPath(name) {
|
|
10918
11021
|
return findInPathFor(name, {
|
|
10919
11022
|
candidates: () => [name],
|
|
10920
|
-
accessFlag:
|
|
10921
|
-
accessSync:
|
|
11023
|
+
accessFlag: fs10.constants.X_OK,
|
|
11024
|
+
accessSync: fs10.accessSync
|
|
10922
11025
|
});
|
|
10923
11026
|
}
|
|
10924
11027
|
augmentPath(dirs) {
|
|
@@ -10946,15 +11049,15 @@ var LinuxOsStrategy = class extends PosixOsStrategy {
|
|
|
10946
11049
|
};
|
|
10947
11050
|
|
|
10948
11051
|
// src/os/win32.ts
|
|
10949
|
-
var
|
|
10950
|
-
var
|
|
10951
|
-
var
|
|
11052
|
+
var fs11 = __toESM(require("fs"));
|
|
11053
|
+
var os9 = __toESM(require("os"));
|
|
11054
|
+
var path14 = __toESM(require("path"));
|
|
10952
11055
|
var import_node_crypto3 = require("crypto");
|
|
10953
11056
|
|
|
10954
11057
|
// src/services/pty/windows-conpty.strategy.ts
|
|
10955
|
-
var
|
|
11058
|
+
var path13 = __toESM(require("path"));
|
|
10956
11059
|
function loadNodePty2() {
|
|
10957
|
-
const vendoredPath =
|
|
11060
|
+
const vendoredPath = path13.join(__dirname, "vendor", "node-pty");
|
|
10958
11061
|
try {
|
|
10959
11062
|
return require(vendoredPath);
|
|
10960
11063
|
} catch (vendorErr) {
|
|
@@ -11073,7 +11176,7 @@ var WindowsConPtyStrategy = class _WindowsConPtyStrategy {
|
|
|
11073
11176
|
};
|
|
11074
11177
|
|
|
11075
11178
|
// src/services/pty/windows.strategy.ts
|
|
11076
|
-
var
|
|
11179
|
+
var import_child_process8 = require("child_process");
|
|
11077
11180
|
var WindowsPtyStrategy = class {
|
|
11078
11181
|
constructor(opts) {
|
|
11079
11182
|
this.opts = opts;
|
|
@@ -11081,7 +11184,7 @@ var WindowsPtyStrategy = class {
|
|
|
11081
11184
|
opts;
|
|
11082
11185
|
proc = null;
|
|
11083
11186
|
spawn(cmd, cwd, args2 = []) {
|
|
11084
|
-
this.proc = (0,
|
|
11187
|
+
this.proc = (0, import_child_process8.spawn)(cmd, args2, {
|
|
11085
11188
|
stdio: ["pipe", "pipe", "inherit"],
|
|
11086
11189
|
cwd,
|
|
11087
11190
|
env: {
|
|
@@ -11140,25 +11243,25 @@ var WINDOWS_EXEC_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
|
|
|
11140
11243
|
var Win32OsStrategy = class {
|
|
11141
11244
|
id = "win32";
|
|
11142
11245
|
homeDir() {
|
|
11143
|
-
return
|
|
11246
|
+
return os9.homedir();
|
|
11144
11247
|
}
|
|
11145
11248
|
scratchPath(prefix) {
|
|
11146
11249
|
const tag = `${process.pid}-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
|
|
11147
|
-
return
|
|
11250
|
+
return path14.join(os9.tmpdir(), `${prefix}-${tag}`);
|
|
11148
11251
|
}
|
|
11149
11252
|
devNull() {
|
|
11150
11253
|
return "NUL";
|
|
11151
11254
|
}
|
|
11152
11255
|
findInPath(name) {
|
|
11153
|
-
const hasExt =
|
|
11256
|
+
const hasExt = path14.extname(name).length > 0;
|
|
11154
11257
|
return findInPathFor(name, {
|
|
11155
11258
|
candidates: (n) => hasExt ? [n] : [...WINDOWS_EXEC_EXTS.map((ext) => `${n}${ext}`), n],
|
|
11156
11259
|
// Windows has no Unix execute bit; presence + matching extension
|
|
11157
11260
|
// IS the executability check. X_OK on Windows is a no-op alias
|
|
11158
11261
|
// for F_OK at the libuv layer anyway, but F_OK makes intent
|
|
11159
11262
|
// explicit.
|
|
11160
|
-
accessFlag:
|
|
11161
|
-
accessSync:
|
|
11263
|
+
accessFlag: fs11.constants.F_OK,
|
|
11264
|
+
accessSync: fs11.accessSync
|
|
11162
11265
|
});
|
|
11163
11266
|
}
|
|
11164
11267
|
augmentPath(dirs) {
|
|
@@ -11195,7 +11298,7 @@ var Win32OsStrategy = class {
|
|
|
11195
11298
|
return `"${escaped.replace(/[&|^<>()%!]/g, "^$&")}"`;
|
|
11196
11299
|
}
|
|
11197
11300
|
buildLaunch(binaryPath, extraArgs = []) {
|
|
11198
|
-
const ext =
|
|
11301
|
+
const ext = path14.extname(binaryPath).toLowerCase();
|
|
11199
11302
|
if (ext === ".cmd" || ext === ".bat") {
|
|
11200
11303
|
return { cmd: "cmd.exe", args: ["/c", binaryPath, ...extraArgs] };
|
|
11201
11304
|
}
|
|
@@ -11250,28 +11353,28 @@ function buildForPlatform(platform3) {
|
|
|
11250
11353
|
var import_node_crypto4 = require("crypto");
|
|
11251
11354
|
|
|
11252
11355
|
// src/agents/claude/resolver.ts
|
|
11253
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
11254
|
-
const found =
|
|
11356
|
+
function buildClaudeLaunch(extraArgs = [], os44 = createOsStrategy()) {
|
|
11357
|
+
const found = os44.findInPath("claude") ?? os44.findInPath("claude-code");
|
|
11255
11358
|
if (!found) return null;
|
|
11256
|
-
return
|
|
11359
|
+
return os44.buildLaunch(found, extraArgs);
|
|
11257
11360
|
}
|
|
11258
11361
|
|
|
11259
11362
|
// src/agents/claude/installer.ts
|
|
11260
|
-
var
|
|
11261
|
-
var
|
|
11262
|
-
var
|
|
11363
|
+
var import_child_process9 = require("child_process");
|
|
11364
|
+
var path15 = __toESM(require("path"));
|
|
11365
|
+
var os10 = __toESM(require("os"));
|
|
11263
11366
|
function probeInstallDirs() {
|
|
11264
|
-
const home =
|
|
11367
|
+
const home = os10.homedir();
|
|
11265
11368
|
if (process.platform === "win32") {
|
|
11266
11369
|
return [
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11370
|
+
path15.join(home, ".claude", "local"),
|
|
11371
|
+
path15.join(home, "AppData", "Local", "AnthropicClaude"),
|
|
11372
|
+
path15.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
|
|
11270
11373
|
];
|
|
11271
11374
|
}
|
|
11272
11375
|
return [
|
|
11273
|
-
|
|
11274
|
-
|
|
11376
|
+
path15.join(home, ".local", "bin"),
|
|
11377
|
+
path15.join(home, ".claude", "local"),
|
|
11275
11378
|
"/usr/local/bin"
|
|
11276
11379
|
];
|
|
11277
11380
|
}
|
|
@@ -11280,7 +11383,7 @@ function isAvailable() {
|
|
|
11280
11383
|
}
|
|
11281
11384
|
function augmentPath() {
|
|
11282
11385
|
const dirs = probeInstallDirs();
|
|
11283
|
-
const sep7 =
|
|
11386
|
+
const sep7 = path15.delimiter;
|
|
11284
11387
|
const current = process.env.PATH ?? "";
|
|
11285
11388
|
const existing = new Set(current.split(sep7).filter(Boolean));
|
|
11286
11389
|
const additions = dirs.filter((d3) => !existing.has(d3));
|
|
@@ -11298,7 +11401,7 @@ function runInstaller() {
|
|
|
11298
11401
|
"irm https://claude.ai/install.ps1 | iex"
|
|
11299
11402
|
] : ["-c", "curl -fsSL https://claude.ai/install.sh | bash"];
|
|
11300
11403
|
return new Promise((resolve7) => {
|
|
11301
|
-
const proc = (0,
|
|
11404
|
+
const proc = (0, import_child_process9.spawn)(cmd, args2, { stdio: "inherit" });
|
|
11302
11405
|
proc.on("error", (err) => {
|
|
11303
11406
|
console.error(`
|
|
11304
11407
|
\u2717 Installer failed to launch: ${err.message}`);
|
|
@@ -11342,9 +11445,9 @@ var import_node_child_process2 = require("child_process");
|
|
|
11342
11445
|
|
|
11343
11446
|
// src/agents/claude/local-token.ts
|
|
11344
11447
|
var import_node_child_process = require("child_process");
|
|
11345
|
-
var
|
|
11346
|
-
var
|
|
11347
|
-
var
|
|
11448
|
+
var fs12 = __toESM(require("fs"));
|
|
11449
|
+
var os11 = __toESM(require("os"));
|
|
11450
|
+
var path16 = __toESM(require("path"));
|
|
11348
11451
|
var import_node_util3 = require("util");
|
|
11349
11452
|
var execFileP2 = (0, import_node_util3.promisify)(import_node_child_process.execFile);
|
|
11350
11453
|
var KEYCHAIN_SERVICE_NAMES = [
|
|
@@ -11354,17 +11457,17 @@ var KEYCHAIN_SERVICE_NAMES = [
|
|
|
11354
11457
|
"Anthropic Claude"
|
|
11355
11458
|
];
|
|
11356
11459
|
function claudeCredentialsPaths() {
|
|
11357
|
-
const home =
|
|
11460
|
+
const home = os11.homedir();
|
|
11358
11461
|
return [
|
|
11359
|
-
|
|
11360
|
-
|
|
11462
|
+
path16.join(home, ".claude", ".credentials.json"),
|
|
11463
|
+
path16.join(home, ".config", "claude", ".credentials.json")
|
|
11361
11464
|
];
|
|
11362
11465
|
}
|
|
11363
11466
|
async function extractLocalClaudeToken() {
|
|
11364
11467
|
const agentState = readClaudeAgentState();
|
|
11365
11468
|
for (const flat of claudeCredentialsPaths()) {
|
|
11366
|
-
if (!
|
|
11367
|
-
const credential =
|
|
11469
|
+
if (!fs12.existsSync(flat)) continue;
|
|
11470
|
+
const credential = fs12.readFileSync(flat, "utf8").trim();
|
|
11368
11471
|
if (credential.length > 0) {
|
|
11369
11472
|
return { method: "oauth", credential, source: "flat-file", agentState };
|
|
11370
11473
|
}
|
|
@@ -11389,10 +11492,10 @@ async function extractLocalClaudeToken() {
|
|
|
11389
11492
|
}
|
|
11390
11493
|
function readClaudeAgentState() {
|
|
11391
11494
|
const STATE_MAX_BYTES = 256 * 1024;
|
|
11392
|
-
const candidate =
|
|
11495
|
+
const candidate = path16.join(os11.homedir(), ".claude.json");
|
|
11393
11496
|
try {
|
|
11394
|
-
if (!
|
|
11395
|
-
const buf =
|
|
11497
|
+
if (!fs12.existsSync(candidate)) return void 0;
|
|
11498
|
+
const buf = fs12.readFileSync(candidate);
|
|
11396
11499
|
if (buf.length === 0 || buf.length > STATE_MAX_BYTES) return void 0;
|
|
11397
11500
|
const text = buf.toString("utf8").trim();
|
|
11398
11501
|
return text.length > 0 ? text : void 0;
|
|
@@ -11479,10 +11582,10 @@ function claudeLoginLauncher() {
|
|
|
11479
11582
|
}
|
|
11480
11583
|
|
|
11481
11584
|
// src/agents/claude/quota.ts
|
|
11482
|
-
var
|
|
11483
|
-
var
|
|
11484
|
-
var
|
|
11485
|
-
var
|
|
11585
|
+
var fs13 = __toESM(require("fs"));
|
|
11586
|
+
var os12 = __toESM(require("os"));
|
|
11587
|
+
var path17 = __toESM(require("path"));
|
|
11588
|
+
var import_child_process10 = require("child_process");
|
|
11486
11589
|
var HELPER_SCRIPT = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
|
|
11487
11590
|
m,s=pty.openpty()
|
|
11488
11591
|
try:
|
|
@@ -11544,14 +11647,14 @@ async function fetchClaudeQuota() {
|
|
|
11544
11647
|
resolve7(null);
|
|
11545
11648
|
return;
|
|
11546
11649
|
}
|
|
11547
|
-
const helperPath =
|
|
11548
|
-
|
|
11650
|
+
const helperPath = path17.join(os12.tmpdir(), "codeam-quota-helper.py");
|
|
11651
|
+
fs13.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
|
|
11549
11652
|
const python = findInPath("python3") ?? findInPath("python");
|
|
11550
11653
|
if (!python) {
|
|
11551
11654
|
resolve7(null);
|
|
11552
11655
|
return;
|
|
11553
11656
|
}
|
|
11554
|
-
const proc = (0,
|
|
11657
|
+
const proc = (0, import_child_process10.spawn)(python, [helperPath, claudeCmd, "--tools", ""], {
|
|
11555
11658
|
stdio: ["pipe", "pipe", "ignore"],
|
|
11556
11659
|
cwd: process.cwd(),
|
|
11557
11660
|
env: { ...process.env, TERM: "dumb", COLUMNS: "120", LINES: "30" }
|
|
@@ -11572,7 +11675,7 @@ async function fetchClaudeQuota() {
|
|
|
11572
11675
|
} catch {
|
|
11573
11676
|
}
|
|
11574
11677
|
try {
|
|
11575
|
-
|
|
11678
|
+
fs13.unlinkSync(helperPath);
|
|
11576
11679
|
} catch {
|
|
11577
11680
|
}
|
|
11578
11681
|
resolve7(result);
|
|
@@ -11592,7 +11695,7 @@ async function fetchClaudeQuota() {
|
|
|
11592
11695
|
}
|
|
11593
11696
|
|
|
11594
11697
|
// src/services/spawn-and-capture.ts
|
|
11595
|
-
var
|
|
11698
|
+
var import_child_process11 = require("child_process");
|
|
11596
11699
|
var activeChildren = /* @__PURE__ */ new Set();
|
|
11597
11700
|
function killActiveSpawnAndCaptureChildren() {
|
|
11598
11701
|
for (const child of activeChildren) {
|
|
@@ -11621,7 +11724,7 @@ async function spawnAndCapture(cmd, args2, opts = {}) {
|
|
|
11621
11724
|
};
|
|
11622
11725
|
let child;
|
|
11623
11726
|
try {
|
|
11624
|
-
child = (0,
|
|
11727
|
+
child = (0, import_child_process11.spawn)(cmd, [...args2], {
|
|
11625
11728
|
cwd: opts.cwd,
|
|
11626
11729
|
env: opts.env ?? process.env,
|
|
11627
11730
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -11665,24 +11768,24 @@ async function spawnAndCapture(cmd, args2, opts = {}) {
|
|
|
11665
11768
|
}
|
|
11666
11769
|
|
|
11667
11770
|
// src/agents/claude/history.ts
|
|
11668
|
-
var
|
|
11669
|
-
var
|
|
11670
|
-
var
|
|
11771
|
+
var fs14 = __toESM(require("fs"));
|
|
11772
|
+
var path18 = __toESM(require("path"));
|
|
11773
|
+
var os13 = __toESM(require("os"));
|
|
11671
11774
|
function encodeCwd(cwd) {
|
|
11672
11775
|
return cwd.replace(/[\\/:]/g, "-");
|
|
11673
11776
|
}
|
|
11674
11777
|
function resolveHistoryDir(cwd, projectsRoot) {
|
|
11675
|
-
const root = projectsRoot ??
|
|
11676
|
-
const primary =
|
|
11677
|
-
if (
|
|
11778
|
+
const root = projectsRoot ?? path18.join(os13.homedir(), ".claude", "projects");
|
|
11779
|
+
const primary = path18.join(root, encodeCwd(cwd));
|
|
11780
|
+
if (fs14.existsSync(primary)) return primary;
|
|
11678
11781
|
try {
|
|
11679
|
-
const entries =
|
|
11782
|
+
const entries = fs14.readdirSync(root, { withFileTypes: true });
|
|
11680
11783
|
const wanted = encodeCwd(cwd);
|
|
11681
11784
|
for (const e of entries) {
|
|
11682
11785
|
if (!e.isDirectory()) continue;
|
|
11683
11786
|
const candidate = e.name.replace(/-+/g, "-");
|
|
11684
11787
|
if (candidate === wanted.replace(/-+/g, "-")) {
|
|
11685
|
-
return
|
|
11788
|
+
return path18.join(root, e.name);
|
|
11686
11789
|
}
|
|
11687
11790
|
}
|
|
11688
11791
|
} catch {
|
|
@@ -11694,23 +11797,23 @@ function getCurrentUsage(historyDir, bootTimeMs = 0) {
|
|
|
11694
11797
|
const cutoff = bootTimeMs > 0 ? bootTimeMs - GRACE_MS : 0;
|
|
11695
11798
|
let entries;
|
|
11696
11799
|
try {
|
|
11697
|
-
entries =
|
|
11800
|
+
entries = fs14.readdirSync(historyDir, { withFileTypes: true });
|
|
11698
11801
|
} catch {
|
|
11699
11802
|
return null;
|
|
11700
11803
|
}
|
|
11701
11804
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
11702
11805
|
try {
|
|
11703
|
-
const stat3 =
|
|
11806
|
+
const stat3 = fs14.statSync(path18.join(historyDir, e.name));
|
|
11704
11807
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
11705
11808
|
} catch {
|
|
11706
11809
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
11707
11810
|
}
|
|
11708
11811
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11709
11812
|
if (files.length === 0) return null;
|
|
11710
|
-
const filePath =
|
|
11813
|
+
const filePath = path18.join(historyDir, files[0].name);
|
|
11711
11814
|
let raw;
|
|
11712
11815
|
try {
|
|
11713
|
-
raw =
|
|
11816
|
+
raw = fs14.readFileSync(filePath, "utf8");
|
|
11714
11817
|
} catch {
|
|
11715
11818
|
return null;
|
|
11716
11819
|
}
|
|
@@ -11755,7 +11858,7 @@ function parseHistoryFile(filePath) {
|
|
|
11755
11858
|
const out2 = [];
|
|
11756
11859
|
let raw;
|
|
11757
11860
|
try {
|
|
11758
|
-
raw =
|
|
11861
|
+
raw = fs14.readFileSync(filePath, "utf8");
|
|
11759
11862
|
} catch {
|
|
11760
11863
|
return out2;
|
|
11761
11864
|
}
|
|
@@ -11800,7 +11903,7 @@ function listResumableSessions(cwd) {
|
|
|
11800
11903
|
if (!dir) return [];
|
|
11801
11904
|
let entries;
|
|
11802
11905
|
try {
|
|
11803
|
-
entries =
|
|
11906
|
+
entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
11804
11907
|
} catch {
|
|
11805
11908
|
return [];
|
|
11806
11909
|
}
|
|
@@ -11808,15 +11911,15 @@ function listResumableSessions(cwd) {
|
|
|
11808
11911
|
for (const entry of entries) {
|
|
11809
11912
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
|
|
11810
11913
|
const id = entry.name.slice(0, -".jsonl".length);
|
|
11811
|
-
const filePath =
|
|
11914
|
+
const filePath = path18.join(dir, entry.name);
|
|
11812
11915
|
let timestamp = Date.now();
|
|
11813
11916
|
try {
|
|
11814
|
-
timestamp =
|
|
11917
|
+
timestamp = fs14.statSync(filePath).mtimeMs;
|
|
11815
11918
|
} catch {
|
|
11816
11919
|
}
|
|
11817
11920
|
let summary = "";
|
|
11818
11921
|
try {
|
|
11819
|
-
const raw =
|
|
11922
|
+
const raw = fs14.readFileSync(filePath, "utf8");
|
|
11820
11923
|
for (const line of raw.split("\n")) {
|
|
11821
11924
|
if (!line.trim()) continue;
|
|
11822
11925
|
try {
|
|
@@ -11846,8 +11949,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
11846
11949
|
meta = getAgent("claude");
|
|
11847
11950
|
mode = "interactive";
|
|
11848
11951
|
os;
|
|
11849
|
-
constructor(
|
|
11850
|
-
this.os =
|
|
11952
|
+
constructor(os44) {
|
|
11953
|
+
this.os = os44;
|
|
11851
11954
|
}
|
|
11852
11955
|
/**
|
|
11853
11956
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -11979,24 +12082,24 @@ var ClaudeRuntimeStrategy = class {
|
|
|
11979
12082
|
};
|
|
11980
12083
|
|
|
11981
12084
|
// src/agents/claude/deploy.ts
|
|
12085
|
+
var fs16 = __toESM(require("fs"));
|
|
12086
|
+
var os15 = __toESM(require("os"));
|
|
12087
|
+
var path20 = __toESM(require("path"));
|
|
12088
|
+
|
|
12089
|
+
// src/agents/claude/credentials.ts
|
|
12090
|
+
var import_child_process12 = require("child_process");
|
|
11982
12091
|
var fs15 = __toESM(require("fs"));
|
|
11983
12092
|
var os14 = __toESM(require("os"));
|
|
11984
12093
|
var path19 = __toESM(require("path"));
|
|
11985
|
-
|
|
11986
|
-
// src/agents/claude/credentials.ts
|
|
11987
|
-
var import_child_process11 = require("child_process");
|
|
11988
|
-
var fs14 = __toESM(require("fs"));
|
|
11989
|
-
var os13 = __toESM(require("os"));
|
|
11990
|
-
var path18 = __toESM(require("path"));
|
|
11991
12094
|
var import_util2 = require("util");
|
|
11992
|
-
var execFileP3 = (0, import_util2.promisify)(
|
|
12095
|
+
var execFileP3 = (0, import_util2.promisify)(import_child_process12.execFile);
|
|
11993
12096
|
async function detectLocalClaudeCredentials() {
|
|
11994
|
-
const localClaudeDir =
|
|
11995
|
-
const flat =
|
|
11996
|
-
if (
|
|
12097
|
+
const localClaudeDir = path19.join(os14.homedir(), ".claude");
|
|
12098
|
+
const flat = path19.join(localClaudeDir, ".credentials.json");
|
|
12099
|
+
if (fs15.existsSync(flat)) {
|
|
11997
12100
|
return { source: "flat-file", description: "~/.claude/.credentials.json" };
|
|
11998
12101
|
}
|
|
11999
|
-
if (
|
|
12102
|
+
if (os14.platform() === "darwin") {
|
|
12000
12103
|
try {
|
|
12001
12104
|
await execFileP3(
|
|
12002
12105
|
"security",
|
|
@@ -12011,9 +12114,9 @@ async function detectLocalClaudeCredentials() {
|
|
|
12011
12114
|
return { source: "none", description: "" };
|
|
12012
12115
|
}
|
|
12013
12116
|
async function bridgeClaudeCredentials(provider, workspaceId) {
|
|
12014
|
-
const localClaudeDir =
|
|
12015
|
-
const fileBased =
|
|
12016
|
-
if (
|
|
12117
|
+
const localClaudeDir = path19.join(os14.homedir(), ".claude");
|
|
12118
|
+
const fileBased = path19.join(localClaudeDir, ".credentials.json");
|
|
12119
|
+
if (fs15.existsSync(fileBased)) {
|
|
12017
12120
|
return { source: "flat-file", description: "~/.claude/.credentials.json" };
|
|
12018
12121
|
}
|
|
12019
12122
|
if (process.platform === "darwin") {
|
|
@@ -12105,8 +12208,8 @@ var ClaudeDeployStrategy = class {
|
|
|
12105
12208
|
process.exit(1);
|
|
12106
12209
|
}
|
|
12107
12210
|
claudeStep.stop("\u2713 Claude CLI installed");
|
|
12108
|
-
const localClaudeDir =
|
|
12109
|
-
const haveLocalClaude =
|
|
12211
|
+
const localClaudeDir = path20.join(os15.homedir(), ".claude");
|
|
12212
|
+
const haveLocalClaude = fs16.existsSync(localClaudeDir) && fs16.statSync(localClaudeDir).isDirectory();
|
|
12110
12213
|
if (haveLocalClaude) {
|
|
12111
12214
|
const copyStep = fe();
|
|
12112
12215
|
copyStep.start("Copying local Claude config to workspace\u2026");
|
|
@@ -12160,10 +12263,10 @@ var ClaudeDeployStrategy = class {
|
|
|
12160
12263
|
}
|
|
12161
12264
|
}
|
|
12162
12265
|
if (opts.bridged !== "none") {
|
|
12163
|
-
const localClaudeJson =
|
|
12164
|
-
if (
|
|
12266
|
+
const localClaudeJson = path20.join(os15.homedir(), ".claude.json");
|
|
12267
|
+
if (fs16.existsSync(localClaudeJson)) {
|
|
12165
12268
|
try {
|
|
12166
|
-
const contents =
|
|
12269
|
+
const contents = fs16.readFileSync(localClaudeJson);
|
|
12167
12270
|
await provider.uploadFile(
|
|
12168
12271
|
workspaceId,
|
|
12169
12272
|
"/home/codespace/.claude.json",
|
|
@@ -12196,7 +12299,7 @@ var ClaudeDeployStrategy = class {
|
|
|
12196
12299
|
|
|
12197
12300
|
// src/agents/codex/runtime.ts
|
|
12198
12301
|
var import_node_child_process4 = require("child_process");
|
|
12199
|
-
var
|
|
12302
|
+
var path23 = __toESM(require("path"));
|
|
12200
12303
|
|
|
12201
12304
|
// src/agents/codex/history.ts
|
|
12202
12305
|
var import_node_fs3 = __toESM(require("fs"));
|
|
@@ -12456,16 +12559,16 @@ function getCurrentUsage2(historyDir) {
|
|
|
12456
12559
|
var import_node_child_process3 = require("child_process");
|
|
12457
12560
|
|
|
12458
12561
|
// src/agents/codex/local-token.ts
|
|
12459
|
-
var
|
|
12460
|
-
var
|
|
12461
|
-
var
|
|
12562
|
+
var fs18 = __toESM(require("fs"));
|
|
12563
|
+
var os17 = __toESM(require("os"));
|
|
12564
|
+
var path22 = __toESM(require("path"));
|
|
12462
12565
|
function codexCredentialsPath() {
|
|
12463
|
-
return
|
|
12566
|
+
return path22.join(os17.homedir(), ".codex", "auth.json");
|
|
12464
12567
|
}
|
|
12465
12568
|
async function extractLocalCodexToken() {
|
|
12466
12569
|
const file = codexCredentialsPath();
|
|
12467
|
-
if (!
|
|
12468
|
-
const credential =
|
|
12570
|
+
if (!fs18.existsSync(file)) return null;
|
|
12571
|
+
const credential = fs18.readFileSync(file, "utf8").trim();
|
|
12469
12572
|
if (credential.length === 0) return null;
|
|
12470
12573
|
return { method: "oauth", credential, source: "flat-file" };
|
|
12471
12574
|
}
|
|
@@ -12524,8 +12627,8 @@ function codexCredentialLocator() {
|
|
|
12524
12627
|
function codexLoginLauncher() {
|
|
12525
12628
|
return {
|
|
12526
12629
|
async ensureInstalled() {
|
|
12527
|
-
const
|
|
12528
|
-
return
|
|
12630
|
+
const os44 = createOsStrategy();
|
|
12631
|
+
return os44.findInPath("codex") !== null;
|
|
12529
12632
|
},
|
|
12530
12633
|
launch() {
|
|
12531
12634
|
return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -12548,8 +12651,8 @@ var CodexRuntimeStrategy = class {
|
|
|
12548
12651
|
meta = getAgent("codex");
|
|
12549
12652
|
mode = "interactive";
|
|
12550
12653
|
os;
|
|
12551
|
-
constructor(
|
|
12552
|
-
this.os =
|
|
12654
|
+
constructor(os44) {
|
|
12655
|
+
this.os = os44;
|
|
12553
12656
|
}
|
|
12554
12657
|
async prepareLaunch() {
|
|
12555
12658
|
let binary = this.os.findInPath("codex");
|
|
@@ -12648,12 +12751,12 @@ var CodexRuntimeStrategy = class {
|
|
|
12648
12751
|
});
|
|
12649
12752
|
}
|
|
12650
12753
|
};
|
|
12651
|
-
function resolveNpm(
|
|
12652
|
-
return
|
|
12754
|
+
function resolveNpm(os44) {
|
|
12755
|
+
return os44.id === "win32" ? "npm.cmd" : "npm";
|
|
12653
12756
|
}
|
|
12654
|
-
async function installCodexViaNpm(
|
|
12757
|
+
async function installCodexViaNpm(os44) {
|
|
12655
12758
|
return new Promise((resolve7, reject) => {
|
|
12656
|
-
const proc = (0, import_node_child_process4.spawn)(resolveNpm(
|
|
12759
|
+
const proc = (0, import_node_child_process4.spawn)(resolveNpm(os44), ["install", "-g", "@openai/codex"], {
|
|
12657
12760
|
stdio: "inherit"
|
|
12658
12761
|
});
|
|
12659
12762
|
proc.on("close", (code) => {
|
|
@@ -12670,16 +12773,16 @@ async function installCodexViaNpm(os43) {
|
|
|
12670
12773
|
});
|
|
12671
12774
|
});
|
|
12672
12775
|
}
|
|
12673
|
-
function augmentNpmGlobalBin(
|
|
12776
|
+
function augmentNpmGlobalBin(os44) {
|
|
12674
12777
|
try {
|
|
12675
|
-
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(
|
|
12778
|
+
const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os44), ["prefix", "-g"], {
|
|
12676
12779
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12677
12780
|
});
|
|
12678
12781
|
if (result.status !== 0) return;
|
|
12679
12782
|
const prefix = result.stdout.toString().trim();
|
|
12680
12783
|
if (!prefix) return;
|
|
12681
|
-
const binDir =
|
|
12682
|
-
|
|
12784
|
+
const binDir = os44.id === "win32" ? prefix : path23.join(prefix, "bin");
|
|
12785
|
+
os44.augmentPath([binDir]);
|
|
12683
12786
|
} catch {
|
|
12684
12787
|
}
|
|
12685
12788
|
}
|
|
@@ -12763,9 +12866,9 @@ var import_node_child_process7 = require("child_process");
|
|
|
12763
12866
|
// src/agents/coderabbit/installer.ts
|
|
12764
12867
|
var import_node_child_process5 = require("child_process");
|
|
12765
12868
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
12766
|
-
async function ensureCoderabbitInstalled(
|
|
12767
|
-
if (
|
|
12768
|
-
if (
|
|
12869
|
+
async function ensureCoderabbitInstalled(os44) {
|
|
12870
|
+
if (os44.findInPath("coderabbit")) return true;
|
|
12871
|
+
if (os44.id === "win32") {
|
|
12769
12872
|
console.error(
|
|
12770
12873
|
"\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"
|
|
12771
12874
|
);
|
|
@@ -12780,15 +12883,15 @@ async function ensureCoderabbitInstalled(os43) {
|
|
|
12780
12883
|
proc.on("error", () => resolve7(false));
|
|
12781
12884
|
});
|
|
12782
12885
|
if (!ok) return false;
|
|
12783
|
-
|
|
12784
|
-
return
|
|
12886
|
+
os44.augmentPath([`${os44.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
12887
|
+
return os44.findInPath("coderabbit") !== null;
|
|
12785
12888
|
}
|
|
12786
12889
|
|
|
12787
12890
|
// src/agents/coderabbit/link.ts
|
|
12788
12891
|
var import_node_child_process6 = require("child_process");
|
|
12789
|
-
var
|
|
12790
|
-
var
|
|
12791
|
-
var
|
|
12892
|
+
var fs20 = __toESM(require("fs"));
|
|
12893
|
+
var os19 = __toESM(require("os"));
|
|
12894
|
+
var path25 = __toESM(require("path"));
|
|
12792
12895
|
|
|
12793
12896
|
// src/agents/strategy.ts
|
|
12794
12897
|
function validateNonEmptyCredential(token) {
|
|
@@ -12797,12 +12900,12 @@ function validateNonEmptyCredential(token) {
|
|
|
12797
12900
|
|
|
12798
12901
|
// src/agents/coderabbit/link.ts
|
|
12799
12902
|
function authPath() {
|
|
12800
|
-
return
|
|
12903
|
+
return path25.join(os19.homedir(), ".coderabbit", "auth.json");
|
|
12801
12904
|
}
|
|
12802
12905
|
async function extractLocalCoderabbitToken() {
|
|
12803
12906
|
const file = authPath();
|
|
12804
|
-
if (!
|
|
12805
|
-
const credential =
|
|
12907
|
+
if (!fs20.existsSync(file)) return null;
|
|
12908
|
+
const credential = fs20.readFileSync(file, "utf8").trim();
|
|
12806
12909
|
if (credential.length === 0) return null;
|
|
12807
12910
|
return { method: "oauth", credential, source: "flat-file" };
|
|
12808
12911
|
}
|
|
@@ -12816,10 +12919,10 @@ function coderabbitCredentialLocator() {
|
|
|
12816
12919
|
validate: validateNonEmptyCredential
|
|
12817
12920
|
};
|
|
12818
12921
|
}
|
|
12819
|
-
function coderabbitLoginLauncher(
|
|
12922
|
+
function coderabbitLoginLauncher(os44) {
|
|
12820
12923
|
return {
|
|
12821
12924
|
async ensureInstalled() {
|
|
12822
|
-
return ensureCoderabbitInstalled(
|
|
12925
|
+
return ensureCoderabbitInstalled(os44);
|
|
12823
12926
|
},
|
|
12824
12927
|
launch() {
|
|
12825
12928
|
return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
|
|
@@ -12842,11 +12945,11 @@ function parseReview(stdout) {
|
|
|
12842
12945
|
for (const line of lines) {
|
|
12843
12946
|
const m = line.match(HUNK_LINE_RE);
|
|
12844
12947
|
if (!m) continue;
|
|
12845
|
-
const [,
|
|
12846
|
-
if (!
|
|
12948
|
+
const [, path64, lineNo, sevToken, message] = m;
|
|
12949
|
+
if (!path64 || !lineNo || !message) continue;
|
|
12847
12950
|
const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
|
|
12848
12951
|
hunks.push({
|
|
12849
|
-
path:
|
|
12952
|
+
path: path64.trim(),
|
|
12850
12953
|
line: Number(lineNo),
|
|
12851
12954
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
12852
12955
|
message: cleanedMessage
|
|
@@ -12865,8 +12968,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
12865
12968
|
meta = getAgent("coderabbit");
|
|
12866
12969
|
mode = "batch";
|
|
12867
12970
|
os;
|
|
12868
|
-
constructor(
|
|
12869
|
-
this.os =
|
|
12971
|
+
constructor(os44) {
|
|
12972
|
+
this.os = os44;
|
|
12870
12973
|
}
|
|
12871
12974
|
getDefaultArgs() {
|
|
12872
12975
|
return ["review"];
|
|
@@ -12934,12 +13037,12 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
12934
13037
|
};
|
|
12935
13038
|
|
|
12936
13039
|
// src/agents/cursor/history.ts
|
|
12937
|
-
var
|
|
12938
|
-
var
|
|
12939
|
-
var
|
|
12940
|
-
var HISTORY_ROOT =
|
|
13040
|
+
var fs21 = __toESM(require("fs"));
|
|
13041
|
+
var os20 = __toESM(require("os"));
|
|
13042
|
+
var path26 = __toESM(require("path"));
|
|
13043
|
+
var HISTORY_ROOT = path26.join(os20.homedir(), ".cursor", "projects");
|
|
12941
13044
|
function resolveHistoryDir3(cwd) {
|
|
12942
|
-
if (!
|
|
13045
|
+
if (!fs21.existsSync(HISTORY_ROOT)) return null;
|
|
12943
13046
|
void cwd;
|
|
12944
13047
|
return HISTORY_ROOT;
|
|
12945
13048
|
}
|
|
@@ -12954,16 +13057,16 @@ function getCurrentUsage3(_historyDir) {
|
|
|
12954
13057
|
var import_node_child_process8 = require("child_process");
|
|
12955
13058
|
|
|
12956
13059
|
// src/agents/cursor/local-token.ts
|
|
12957
|
-
var
|
|
12958
|
-
var
|
|
12959
|
-
var
|
|
13060
|
+
var fs22 = __toESM(require("fs"));
|
|
13061
|
+
var os21 = __toESM(require("os"));
|
|
13062
|
+
var path27 = __toESM(require("path"));
|
|
12960
13063
|
function cursorCredentialsPath() {
|
|
12961
|
-
return
|
|
13064
|
+
return path27.join(os21.homedir(), ".cursor", "auth.json");
|
|
12962
13065
|
}
|
|
12963
13066
|
async function extractLocalCursorToken() {
|
|
12964
13067
|
const file = cursorCredentialsPath();
|
|
12965
|
-
if (!
|
|
12966
|
-
const credential =
|
|
13068
|
+
if (!fs22.existsSync(file)) return null;
|
|
13069
|
+
const credential = fs22.readFileSync(file, "utf8").trim();
|
|
12967
13070
|
if (credential.length === 0) return null;
|
|
12968
13071
|
return { method: "oauth", credential, source: "flat-file" };
|
|
12969
13072
|
}
|
|
@@ -12982,10 +13085,10 @@ function cursorCredentialLocator() {
|
|
|
12982
13085
|
validate: validateNonEmptyCredential
|
|
12983
13086
|
};
|
|
12984
13087
|
}
|
|
12985
|
-
function cursorLoginLauncher(
|
|
13088
|
+
function cursorLoginLauncher(os44) {
|
|
12986
13089
|
return {
|
|
12987
13090
|
async ensureInstalled() {
|
|
12988
|
-
if (
|
|
13091
|
+
if (os44.findInPath("cursor-agent")) return true;
|
|
12989
13092
|
console.error(
|
|
12990
13093
|
"\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"
|
|
12991
13094
|
);
|
|
@@ -13047,8 +13150,8 @@ var CursorRuntimeStrategy = class {
|
|
|
13047
13150
|
meta = getAgent("cursor");
|
|
13048
13151
|
mode = "interactive";
|
|
13049
13152
|
os;
|
|
13050
|
-
constructor(
|
|
13051
|
-
this.os =
|
|
13153
|
+
constructor(os44) {
|
|
13154
|
+
this.os = os44;
|
|
13052
13155
|
}
|
|
13053
13156
|
async prepareLaunch() {
|
|
13054
13157
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -13127,12 +13230,12 @@ var CursorRuntimeStrategy = class {
|
|
|
13127
13230
|
};
|
|
13128
13231
|
|
|
13129
13232
|
// src/agents/aider/history.ts
|
|
13130
|
-
var
|
|
13131
|
-
var
|
|
13233
|
+
var fs23 = __toESM(require("fs"));
|
|
13234
|
+
var path28 = __toESM(require("path"));
|
|
13132
13235
|
var AIDER_HISTORY_FILE = ".aider.chat.history.md";
|
|
13133
13236
|
function resolveHistoryDir4(cwd) {
|
|
13134
|
-
const candidate =
|
|
13135
|
-
return
|
|
13237
|
+
const candidate = path28.join(cwd, AIDER_HISTORY_FILE);
|
|
13238
|
+
return fs23.existsSync(candidate) ? cwd : null;
|
|
13136
13239
|
}
|
|
13137
13240
|
function parseHistoryFile4(_filePath) {
|
|
13138
13241
|
return [];
|
|
@@ -13145,10 +13248,10 @@ function getCurrentUsage4(_historyDir) {
|
|
|
13145
13248
|
var import_node_child_process9 = require("child_process");
|
|
13146
13249
|
|
|
13147
13250
|
// src/agents/aider/local-token.ts
|
|
13148
|
-
var
|
|
13149
|
-
var
|
|
13150
|
-
var
|
|
13151
|
-
var AIDER_CONF_FILE =
|
|
13251
|
+
var fs24 = __toESM(require("fs"));
|
|
13252
|
+
var os22 = __toESM(require("os"));
|
|
13253
|
+
var path29 = __toESM(require("path"));
|
|
13254
|
+
var AIDER_CONF_FILE = path29.join(os22.homedir(), ".aider.conf.yml");
|
|
13152
13255
|
var API_KEY_ENV_VARS = [
|
|
13153
13256
|
"ANTHROPIC_API_KEY",
|
|
13154
13257
|
"OPENAI_API_KEY",
|
|
@@ -13163,8 +13266,8 @@ async function extractLocalAiderToken() {
|
|
|
13163
13266
|
return { method: "api_key", credential: value.trim(), source: "flat-file" };
|
|
13164
13267
|
}
|
|
13165
13268
|
}
|
|
13166
|
-
if (
|
|
13167
|
-
const conf =
|
|
13269
|
+
if (fs24.existsSync(AIDER_CONF_FILE)) {
|
|
13270
|
+
const conf = fs24.readFileSync(AIDER_CONF_FILE, "utf8");
|
|
13168
13271
|
const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
|
|
13169
13272
|
if (match) {
|
|
13170
13273
|
return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
|
|
@@ -13187,10 +13290,10 @@ function aiderCredentialLocator() {
|
|
|
13187
13290
|
validate: validateNonEmptyCredential
|
|
13188
13291
|
};
|
|
13189
13292
|
}
|
|
13190
|
-
function aiderLoginLauncher(
|
|
13293
|
+
function aiderLoginLauncher(os44) {
|
|
13191
13294
|
return {
|
|
13192
13295
|
async ensureInstalled() {
|
|
13193
|
-
if (
|
|
13296
|
+
if (os44.findInPath("aider")) return true;
|
|
13194
13297
|
console.error(
|
|
13195
13298
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
13196
13299
|
);
|
|
@@ -13200,7 +13303,7 @@ function aiderLoginLauncher(os43) {
|
|
|
13200
13303
|
console.error(
|
|
13201
13304
|
"\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"
|
|
13202
13305
|
);
|
|
13203
|
-
return (0, import_node_child_process9.spawn)(
|
|
13306
|
+
return (0, import_node_child_process9.spawn)(os44.id === "win32" ? "cmd.exe" : "sh", os44.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
13204
13307
|
stdio: "ignore"
|
|
13205
13308
|
});
|
|
13206
13309
|
}
|
|
@@ -13272,8 +13375,8 @@ var AiderRuntimeStrategy = class {
|
|
|
13272
13375
|
meta = getAgent("aider");
|
|
13273
13376
|
mode = "interactive";
|
|
13274
13377
|
os;
|
|
13275
|
-
constructor(
|
|
13276
|
-
this.os =
|
|
13378
|
+
constructor(os44) {
|
|
13379
|
+
this.os = os44;
|
|
13277
13380
|
}
|
|
13278
13381
|
async prepareLaunch() {
|
|
13279
13382
|
const binary = this.os.findInPath("aider");
|
|
@@ -13344,19 +13447,19 @@ var AiderRuntimeStrategy = class {
|
|
|
13344
13447
|
var import_node_child_process10 = require("child_process");
|
|
13345
13448
|
|
|
13346
13449
|
// src/agents/gemini/local-token.ts
|
|
13347
|
-
var
|
|
13348
|
-
var
|
|
13349
|
-
var
|
|
13450
|
+
var fs25 = __toESM(require("fs"));
|
|
13451
|
+
var os23 = __toESM(require("os"));
|
|
13452
|
+
var path30 = __toESM(require("path"));
|
|
13350
13453
|
function geminiCredentialsPath() {
|
|
13351
|
-
return
|
|
13454
|
+
return path30.join(os23.homedir(), ".gemini", "oauth_creds.json");
|
|
13352
13455
|
}
|
|
13353
13456
|
function geminiCredentialsPaths() {
|
|
13354
13457
|
return [geminiCredentialsPath()];
|
|
13355
13458
|
}
|
|
13356
13459
|
async function extractLocalGeminiToken() {
|
|
13357
13460
|
const file = geminiCredentialsPath();
|
|
13358
|
-
if (!
|
|
13359
|
-
const credential =
|
|
13461
|
+
if (!fs25.existsSync(file)) return null;
|
|
13462
|
+
const credential = fs25.readFileSync(file, "utf8").trim();
|
|
13360
13463
|
if (credential.length === 0) return null;
|
|
13361
13464
|
return { method: "oauth", credential, source: "flat-file" };
|
|
13362
13465
|
}
|
|
@@ -13402,8 +13505,8 @@ function geminiCredentialLocator() {
|
|
|
13402
13505
|
function geminiLoginLauncher() {
|
|
13403
13506
|
return {
|
|
13404
13507
|
async ensureInstalled() {
|
|
13405
|
-
const
|
|
13406
|
-
return
|
|
13508
|
+
const os44 = createOsStrategy();
|
|
13509
|
+
return os44.findInPath("gemini") !== null;
|
|
13407
13510
|
},
|
|
13408
13511
|
launch() {
|
|
13409
13512
|
return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13436,8 +13539,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
13436
13539
|
meta = getAgent("gemini");
|
|
13437
13540
|
mode = "interactive";
|
|
13438
13541
|
os;
|
|
13439
|
-
constructor(
|
|
13440
|
-
this.os =
|
|
13542
|
+
constructor(os44) {
|
|
13543
|
+
this.os = os44;
|
|
13441
13544
|
}
|
|
13442
13545
|
async prepareLaunch() {
|
|
13443
13546
|
const binary = this.os.findInPath("gemini");
|
|
@@ -13536,18 +13639,18 @@ var GeminiRuntimeStrategy = class {
|
|
|
13536
13639
|
|
|
13537
13640
|
// src/agents/registry.ts
|
|
13538
13641
|
var runtimeBuilders = {
|
|
13539
|
-
claude: (
|
|
13540
|
-
codex: (
|
|
13541
|
-
coderabbit: (
|
|
13542
|
-
cursor: (
|
|
13543
|
-
aider: (
|
|
13544
|
-
gemini: (
|
|
13642
|
+
claude: (os44) => new ClaudeRuntimeStrategy(os44),
|
|
13643
|
+
codex: (os44) => new CodexRuntimeStrategy(os44),
|
|
13644
|
+
coderabbit: (os44) => new CoderabbitRuntimeStrategy(os44),
|
|
13645
|
+
cursor: (os44) => new CursorRuntimeStrategy(os44),
|
|
13646
|
+
aider: (os44) => new AiderRuntimeStrategy(os44),
|
|
13647
|
+
gemini: (os44) => new GeminiRuntimeStrategy(os44)
|
|
13545
13648
|
};
|
|
13546
13649
|
var deployBuilders = {
|
|
13547
13650
|
claude: () => new ClaudeDeployStrategy(),
|
|
13548
13651
|
codex: () => new CodexDeployStrategy()
|
|
13549
13652
|
};
|
|
13550
|
-
function createAgentStrategy(agent,
|
|
13653
|
+
function createAgentStrategy(agent, os44 = createOsStrategy()) {
|
|
13551
13654
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
13552
13655
|
throw new Error(
|
|
13553
13656
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -13557,10 +13660,10 @@ function createAgentStrategy(agent, os43 = createOsStrategy()) {
|
|
|
13557
13660
|
if (!build) {
|
|
13558
13661
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
13559
13662
|
}
|
|
13560
|
-
return build(
|
|
13663
|
+
return build(os44);
|
|
13561
13664
|
}
|
|
13562
|
-
function createInteractiveAgentStrategy(agent,
|
|
13563
|
-
const s = createAgentStrategy(agent,
|
|
13665
|
+
function createInteractiveAgentStrategy(agent, os44 = createOsStrategy()) {
|
|
13666
|
+
const s = createAgentStrategy(agent, os44);
|
|
13564
13667
|
if (s.mode !== "interactive") {
|
|
13565
13668
|
throw new Error(
|
|
13566
13669
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -13616,7 +13719,7 @@ function parseLinkArgs(args2) {
|
|
|
13616
13719
|
if (apiKeyFileArg) {
|
|
13617
13720
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
13618
13721
|
try {
|
|
13619
|
-
apiKey =
|
|
13722
|
+
apiKey = fs26.readFileSync(path31.resolve(filePath), "utf8").trim();
|
|
13620
13723
|
} catch (err) {
|
|
13621
13724
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
13622
13725
|
}
|
|
@@ -13743,7 +13846,7 @@ async function link(args2 = []) {
|
|
|
13743
13846
|
return;
|
|
13744
13847
|
}
|
|
13745
13848
|
if (parsed.tokenFile) {
|
|
13746
|
-
const credential =
|
|
13849
|
+
const credential = fs26.readFileSync(path31.resolve(parsed.tokenFile), "utf8").trim();
|
|
13747
13850
|
if (!credential) {
|
|
13748
13851
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
13749
13852
|
process.exit(1);
|
|
@@ -13964,9 +14067,9 @@ async function linkDryRunPreflight(ctx) {
|
|
|
13964
14067
|
|
|
13965
14068
|
// src/commands/host-agent.ts
|
|
13966
14069
|
var import_node_child_process15 = require("child_process");
|
|
13967
|
-
var
|
|
13968
|
-
var
|
|
13969
|
-
var
|
|
14070
|
+
var os30 = __toESM(require("os"));
|
|
14071
|
+
var fs33 = __toESM(require("fs"));
|
|
14072
|
+
var path37 = __toESM(require("path"));
|
|
13970
14073
|
|
|
13971
14074
|
// src/util/restrict-to-owner.ts
|
|
13972
14075
|
var import_node_fs5 = __toESM(require("fs"));
|
|
@@ -14002,13 +14105,13 @@ function restrictToOwner(filePath) {
|
|
|
14002
14105
|
}
|
|
14003
14106
|
|
|
14004
14107
|
// src/commands/host/host-client.ts
|
|
14005
|
-
var
|
|
14006
|
-
var
|
|
14007
|
-
var
|
|
14108
|
+
var fs28 = __toESM(require("fs"));
|
|
14109
|
+
var os25 = __toESM(require("os"));
|
|
14110
|
+
var path32 = __toESM(require("path"));
|
|
14008
14111
|
function sampleCpuTimes() {
|
|
14009
14112
|
let idle = 0;
|
|
14010
14113
|
let total = 0;
|
|
14011
|
-
for (const cpu of
|
|
14114
|
+
for (const cpu of os25.cpus()) {
|
|
14012
14115
|
const t2 = cpu.times;
|
|
14013
14116
|
idle += t2.idle;
|
|
14014
14117
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -14027,8 +14130,8 @@ var MetricsCollector = class {
|
|
|
14027
14130
|
const prev = this.prevCpu;
|
|
14028
14131
|
this.prevCpu = current;
|
|
14029
14132
|
if (!prev) {
|
|
14030
|
-
const cores =
|
|
14031
|
-
const proxy =
|
|
14133
|
+
const cores = os25.cpus().length || 1;
|
|
14134
|
+
const proxy = os25.loadavg()[0] / cores * 100;
|
|
14032
14135
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
14033
14136
|
}
|
|
14034
14137
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -14041,8 +14144,8 @@ var MetricsCollector = class {
|
|
|
14041
14144
|
collect() {
|
|
14042
14145
|
return {
|
|
14043
14146
|
cpuPct: this.cpuPct(),
|
|
14044
|
-
ramUsedMb: Math.round((
|
|
14045
|
-
ramTotalMb: Math.round(
|
|
14147
|
+
ramUsedMb: Math.round((os25.totalmem() - os25.freemem()) / 1048576),
|
|
14148
|
+
ramTotalMb: Math.round(os25.totalmem() / 1048576),
|
|
14046
14149
|
latencyMs: this.lastLatencyMs
|
|
14047
14150
|
};
|
|
14048
14151
|
}
|
|
@@ -14051,19 +14154,19 @@ function apiBase() {
|
|
|
14051
14154
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
14052
14155
|
}
|
|
14053
14156
|
function hostIdentityPath() {
|
|
14054
|
-
return
|
|
14157
|
+
return path32.join(os25.homedir(), ".codeam", "host-agent.json");
|
|
14055
14158
|
}
|
|
14056
14159
|
function collectOsInfo() {
|
|
14057
14160
|
return {
|
|
14058
|
-
distro:
|
|
14059
|
-
arch:
|
|
14060
|
-
kernel:
|
|
14161
|
+
distro: os25.platform(),
|
|
14162
|
+
arch: os25.arch(),
|
|
14163
|
+
kernel: os25.release(),
|
|
14061
14164
|
nodeVersion: process.versions.node
|
|
14062
14165
|
};
|
|
14063
14166
|
}
|
|
14064
14167
|
function loadHostIdentity() {
|
|
14065
14168
|
try {
|
|
14066
|
-
const raw =
|
|
14169
|
+
const raw = fs28.readFileSync(hostIdentityPath(), "utf8");
|
|
14067
14170
|
const parsed = JSON.parse(raw);
|
|
14068
14171
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
14069
14172
|
const p2 = parsed;
|
|
@@ -14076,8 +14179,8 @@ function loadHostIdentity() {
|
|
|
14076
14179
|
}
|
|
14077
14180
|
function saveHostIdentity(identity) {
|
|
14078
14181
|
const file = hostIdentityPath();
|
|
14079
|
-
|
|
14080
|
-
|
|
14182
|
+
fs28.mkdirSync(path32.dirname(file), { recursive: true, mode: 448 });
|
|
14183
|
+
fs28.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
14081
14184
|
encoding: "utf8",
|
|
14082
14185
|
mode: 384
|
|
14083
14186
|
});
|
|
@@ -14122,7 +14225,7 @@ function isTerminalEnrollError(err) {
|
|
|
14122
14225
|
}
|
|
14123
14226
|
function deleteHostIdentity() {
|
|
14124
14227
|
try {
|
|
14125
|
-
|
|
14228
|
+
fs28.rmSync(hostIdentityPath(), { force: true });
|
|
14126
14229
|
} catch {
|
|
14127
14230
|
}
|
|
14128
14231
|
}
|
|
@@ -14245,17 +14348,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
14245
14348
|
}
|
|
14246
14349
|
|
|
14247
14350
|
// src/commands/host/workspace.ts
|
|
14248
|
-
var
|
|
14249
|
-
var
|
|
14250
|
-
var
|
|
14351
|
+
var fs29 = __toESM(require("fs"));
|
|
14352
|
+
var os26 = __toESM(require("os"));
|
|
14353
|
+
var path33 = __toESM(require("path"));
|
|
14251
14354
|
var import_node_child_process12 = require("child_process");
|
|
14252
14355
|
var import_node_util4 = require("util");
|
|
14253
14356
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
|
|
14254
14357
|
function isAbsolutePathTarget(target) {
|
|
14255
|
-
return
|
|
14358
|
+
return path33.isAbsolute(target);
|
|
14256
14359
|
}
|
|
14257
14360
|
function selfHostedWorkspaceRoot() {
|
|
14258
|
-
return
|
|
14361
|
+
return path33.join(os26.homedir(), ".codeam", "self-hosted");
|
|
14259
14362
|
}
|
|
14260
14363
|
function nonInteractiveGitEnv() {
|
|
14261
14364
|
return {
|
|
@@ -14308,13 +14411,13 @@ async function fetchGithubIdentity(token) {
|
|
|
14308
14411
|
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
14309
14412
|
const gh = githubOwnerRepo(repoRef.trim());
|
|
14310
14413
|
if (!gh || !cloneToken) return;
|
|
14311
|
-
const credFile =
|
|
14312
|
-
|
|
14414
|
+
const credFile = path33.join(dest, ".git", "codeam-credentials");
|
|
14415
|
+
fs29.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
14313
14416
|
`, { mode: 384 });
|
|
14314
14417
|
restrictToOwner(credFile);
|
|
14315
14418
|
const env = nonInteractiveGitEnv();
|
|
14316
14419
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
14317
|
-
const credFilePosix = credFile.split(
|
|
14420
|
+
const credFilePosix = credFile.split(path33.sep).join("/");
|
|
14318
14421
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
14319
14422
|
});
|
|
14320
14423
|
await git2([
|
|
@@ -14350,17 +14453,17 @@ function maskToken(text, cloneToken) {
|
|
|
14350
14453
|
}
|
|
14351
14454
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
14352
14455
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
14353
|
-
if (!
|
|
14456
|
+
if (!fs29.existsSync(repoOrPath)) {
|
|
14354
14457
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
14355
14458
|
}
|
|
14356
14459
|
return repoOrPath;
|
|
14357
14460
|
}
|
|
14358
|
-
const dest =
|
|
14359
|
-
if (
|
|
14461
|
+
const dest = path33.join(selfHostedWorkspaceRoot(), deployId);
|
|
14462
|
+
if (fs29.existsSync(path33.join(dest, ".git"))) {
|
|
14360
14463
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
14361
14464
|
return dest;
|
|
14362
14465
|
}
|
|
14363
|
-
|
|
14466
|
+
fs29.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
14364
14467
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
14365
14468
|
try {
|
|
14366
14469
|
await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -14377,9 +14480,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
14377
14480
|
}
|
|
14378
14481
|
|
|
14379
14482
|
// src/commands/host/agent-provisioning.ts
|
|
14380
|
-
var
|
|
14381
|
-
var
|
|
14382
|
-
var
|
|
14483
|
+
var fs30 = __toESM(require("fs"));
|
|
14484
|
+
var os27 = __toESM(require("os"));
|
|
14485
|
+
var path34 = __toESM(require("path"));
|
|
14383
14486
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
14384
14487
|
claude_code: "claude",
|
|
14385
14488
|
claude: "claude",
|
|
@@ -14394,22 +14497,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
14394
14497
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
14395
14498
|
}
|
|
14396
14499
|
function ensureDir(dir) {
|
|
14397
|
-
|
|
14500
|
+
fs30.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
14398
14501
|
}
|
|
14399
14502
|
function writeFile0600(filePath, contents) {
|
|
14400
|
-
ensureDir(
|
|
14401
|
-
|
|
14503
|
+
ensureDir(path34.dirname(filePath));
|
|
14504
|
+
fs30.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
14402
14505
|
restrictToOwner(filePath);
|
|
14403
14506
|
}
|
|
14404
14507
|
function rmIfExists(filePath) {
|
|
14405
14508
|
try {
|
|
14406
|
-
|
|
14509
|
+
fs30.rmSync(filePath, { force: true });
|
|
14407
14510
|
} catch {
|
|
14408
14511
|
}
|
|
14409
14512
|
}
|
|
14410
14513
|
var claudeProvisioner = {
|
|
14411
14514
|
write(auth, home) {
|
|
14412
|
-
const credentialsJson =
|
|
14515
|
+
const credentialsJson = path34.join(home, ".claude", ".credentials.json");
|
|
14413
14516
|
if (auth.kind === "api_key") {
|
|
14414
14517
|
rmIfExists(credentialsJson);
|
|
14415
14518
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -14421,8 +14524,8 @@ var claudeProvisioner = {
|
|
|
14421
14524
|
} else {
|
|
14422
14525
|
rmIfExists(credentialsJson);
|
|
14423
14526
|
}
|
|
14424
|
-
const claudeJson =
|
|
14425
|
-
if (!
|
|
14527
|
+
const claudeJson = path34.join(home, ".claude.json");
|
|
14528
|
+
if (!fs30.existsSync(claudeJson)) {
|
|
14426
14529
|
writeFile0600(
|
|
14427
14530
|
claudeJson,
|
|
14428
14531
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -14433,7 +14536,7 @@ var claudeProvisioner = {
|
|
|
14433
14536
|
};
|
|
14434
14537
|
var codexProvisioner = {
|
|
14435
14538
|
write(auth, home) {
|
|
14436
|
-
const authJson =
|
|
14539
|
+
const authJson = path34.join(home, ".codex", "auth.json");
|
|
14437
14540
|
if (auth.kind === "api_key") {
|
|
14438
14541
|
rmIfExists(authJson);
|
|
14439
14542
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -14444,8 +14547,8 @@ var codexProvisioner = {
|
|
|
14444
14547
|
};
|
|
14445
14548
|
var geminiProvisioner = {
|
|
14446
14549
|
write(auth, home) {
|
|
14447
|
-
const settingsJson =
|
|
14448
|
-
const oauthCreds =
|
|
14550
|
+
const settingsJson = path34.join(home, ".gemini", "settings.json");
|
|
14551
|
+
const oauthCreds = path34.join(home, ".gemini", "oauth_creds.json");
|
|
14449
14552
|
if (auth.kind === "api_key") {
|
|
14450
14553
|
rmIfExists(oauthCreds);
|
|
14451
14554
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -14458,7 +14561,7 @@ var geminiProvisioner = {
|
|
|
14458
14561
|
};
|
|
14459
14562
|
var cursorProvisioner = {
|
|
14460
14563
|
write(auth, home) {
|
|
14461
|
-
const authJson =
|
|
14564
|
+
const authJson = path34.join(home, ".config", "cursor", "auth.json");
|
|
14462
14565
|
if (auth.kind === "api_key") {
|
|
14463
14566
|
rmIfExists(authJson);
|
|
14464
14567
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -14495,7 +14598,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
14495
14598
|
this.agentId = agentId;
|
|
14496
14599
|
}
|
|
14497
14600
|
};
|
|
14498
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
14601
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os27.homedir()) {
|
|
14499
14602
|
const internal = toInternalAgentId(publicAgentId);
|
|
14500
14603
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
14501
14604
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -14505,11 +14608,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os26.homedir(
|
|
|
14505
14608
|
|
|
14506
14609
|
// src/commands/host/git-tooling.ts
|
|
14507
14610
|
var import_node_child_process13 = require("child_process");
|
|
14508
|
-
var
|
|
14509
|
-
var
|
|
14510
|
-
var
|
|
14611
|
+
var fs31 = __toESM(require("fs"));
|
|
14612
|
+
var os28 = __toESM(require("os"));
|
|
14613
|
+
var path35 = __toESM(require("path"));
|
|
14511
14614
|
function codeamBinDir() {
|
|
14512
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
14615
|
+
return process.env.CODEAM_BIN_DIR ?? path35.join(os28.homedir(), ".codeam", "bin");
|
|
14513
14616
|
}
|
|
14514
14617
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
14515
14618
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -14541,7 +14644,7 @@ async function download(url, dest) {
|
|
|
14541
14644
|
const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
|
|
14542
14645
|
if (!res.ok || !res.body) return false;
|
|
14543
14646
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
14544
|
-
|
|
14647
|
+
fs31.writeFileSync(dest, buf);
|
|
14545
14648
|
return true;
|
|
14546
14649
|
} catch {
|
|
14547
14650
|
return false;
|
|
@@ -14564,8 +14667,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
14564
14667
|
const version3 = await resolveVersionFn(token);
|
|
14565
14668
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
14566
14669
|
const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
14567
|
-
const tmpRoot =
|
|
14568
|
-
const archive =
|
|
14670
|
+
const tmpRoot = fs31.mkdtempSync(path35.join(os28.tmpdir(), "codeam-gh-"));
|
|
14671
|
+
const archive = path35.join(tmpRoot, `${asset}.${ext}`);
|
|
14569
14672
|
if (!await downloadFn(url, archive)) {
|
|
14570
14673
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
14571
14674
|
return null;
|
|
@@ -14575,16 +14678,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
14575
14678
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
14576
14679
|
return null;
|
|
14577
14680
|
}
|
|
14578
|
-
const extractedBin =
|
|
14579
|
-
if (!
|
|
14681
|
+
const extractedBin = path35.join(tmpRoot, asset, "bin", binaryName);
|
|
14682
|
+
if (!fs31.existsSync(extractedBin)) {
|
|
14580
14683
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
14581
14684
|
return null;
|
|
14582
14685
|
}
|
|
14583
14686
|
const binDir = codeamBinDir();
|
|
14584
|
-
|
|
14585
|
-
const target =
|
|
14586
|
-
|
|
14587
|
-
|
|
14687
|
+
fs31.mkdirSync(binDir, { recursive: true });
|
|
14688
|
+
const target = path35.join(binDir, binaryName);
|
|
14689
|
+
fs31.copyFileSync(extractedBin, target);
|
|
14690
|
+
fs31.chmodSync(target, 493);
|
|
14588
14691
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
14589
14692
|
return target;
|
|
14590
14693
|
} catch (e) {
|
|
@@ -14762,18 +14865,10 @@ var HeadroomStatsReporter = class {
|
|
|
14762
14865
|
}
|
|
14763
14866
|
};
|
|
14764
14867
|
|
|
14765
|
-
// src/services/headroom/budget-args.ts
|
|
14766
|
-
function buildBudgetProxyArgs(env) {
|
|
14767
|
-
const budget = env["HEADROOM_BUDGET"];
|
|
14768
|
-
if (!budget) return [];
|
|
14769
|
-
const period = env["HEADROOM_BUDGET_PERIOD"] ?? "daily";
|
|
14770
|
-
return ["--budget", budget, "--budget-period", period];
|
|
14771
|
-
}
|
|
14772
|
-
|
|
14773
14868
|
// src/lib/updateNotifier.ts
|
|
14774
|
-
var
|
|
14775
|
-
var
|
|
14776
|
-
var
|
|
14869
|
+
var fs32 = __toESM(require("fs"));
|
|
14870
|
+
var os29 = __toESM(require("os"));
|
|
14871
|
+
var path36 = __toESM(require("path"));
|
|
14777
14872
|
var https6 = __toESM(require("https"));
|
|
14778
14873
|
var import_node_child_process14 = require("child_process");
|
|
14779
14874
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -14782,12 +14877,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
14782
14877
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
14783
14878
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
14784
14879
|
function cachePath() {
|
|
14785
|
-
const dir =
|
|
14786
|
-
return
|
|
14880
|
+
const dir = path36.join(os29.homedir(), ".codeam");
|
|
14881
|
+
return path36.join(dir, "update-check.json");
|
|
14787
14882
|
}
|
|
14788
14883
|
function readCache() {
|
|
14789
14884
|
try {
|
|
14790
|
-
const raw =
|
|
14885
|
+
const raw = fs32.readFileSync(cachePath(), "utf8");
|
|
14791
14886
|
const parsed = JSON.parse(raw);
|
|
14792
14887
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
14793
14888
|
return parsed;
|
|
@@ -14798,10 +14893,10 @@ function readCache() {
|
|
|
14798
14893
|
function writeCache(cache) {
|
|
14799
14894
|
try {
|
|
14800
14895
|
const file = cachePath();
|
|
14801
|
-
|
|
14896
|
+
fs32.mkdirSync(path36.dirname(file), { recursive: true });
|
|
14802
14897
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
14803
|
-
|
|
14804
|
-
|
|
14898
|
+
fs32.writeFileSync(tmp, JSON.stringify(cache));
|
|
14899
|
+
fs32.renameSync(tmp, file);
|
|
14805
14900
|
} catch {
|
|
14806
14901
|
}
|
|
14807
14902
|
}
|
|
@@ -14875,8 +14970,8 @@ function isLinkedInstall() {
|
|
|
14875
14970
|
timeout: 2e3
|
|
14876
14971
|
}).trim();
|
|
14877
14972
|
if (!root) return false;
|
|
14878
|
-
const pkgPath =
|
|
14879
|
-
return
|
|
14973
|
+
const pkgPath = path36.join(root, PKG_NAME);
|
|
14974
|
+
return fs32.lstatSync(pkgPath).isSymbolicLink();
|
|
14880
14975
|
} catch {
|
|
14881
14976
|
return false;
|
|
14882
14977
|
}
|
|
@@ -14912,7 +15007,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
14912
15007
|
return;
|
|
14913
15008
|
}
|
|
14914
15009
|
try {
|
|
14915
|
-
|
|
15010
|
+
fs32.unlinkSync(cachePath());
|
|
14916
15011
|
} catch {
|
|
14917
15012
|
}
|
|
14918
15013
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -14928,7 +15023,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
14928
15023
|
if (process.env.NODE_ENV === "test") return;
|
|
14929
15024
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
14930
15025
|
if (process.env.CI) return;
|
|
14931
|
-
const current = true ? "2.
|
|
15026
|
+
const current = true ? "2.53.0" : null;
|
|
14932
15027
|
if (!current) return;
|
|
14933
15028
|
const cache = readCache();
|
|
14934
15029
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -14945,7 +15040,7 @@ function checkForUpdates() {
|
|
|
14945
15040
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
14946
15041
|
if (process.env.CI) return;
|
|
14947
15042
|
if (!process.stdout.isTTY) return;
|
|
14948
|
-
const current = true ? "2.
|
|
15043
|
+
const current = true ? "2.53.0" : null;
|
|
14949
15044
|
if (!current) return;
|
|
14950
15045
|
const cache = readCache();
|
|
14951
15046
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -15017,8 +15112,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
15017
15112
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
15018
15113
|
try {
|
|
15019
15114
|
const file = headroomConfigPath();
|
|
15020
|
-
if (!
|
|
15021
|
-
const cfg = JSON.parse(
|
|
15115
|
+
if (!fs33.existsSync(file)) return null;
|
|
15116
|
+
const cfg = JSON.parse(fs33.readFileSync(file, "utf8"));
|
|
15022
15117
|
if (!cfg?.enabled) return null;
|
|
15023
15118
|
const agent = cfg.agent ?? "claude";
|
|
15024
15119
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -15282,15 +15377,15 @@ function isHeadroomSupportedAgent(agentId) {
|
|
|
15282
15377
|
return n.startsWith("claude") || n.startsWith("codex") || n.startsWith("copilot");
|
|
15283
15378
|
}
|
|
15284
15379
|
function headroomConfigPath() {
|
|
15285
|
-
return
|
|
15380
|
+
return path37.join(os30.homedir(), ".codeam", "headroom-config.json");
|
|
15286
15381
|
}
|
|
15287
15382
|
function persistHeadroomConfig(config) {
|
|
15288
15383
|
try {
|
|
15289
15384
|
const file = headroomConfigPath();
|
|
15290
|
-
|
|
15385
|
+
fs33.mkdirSync(path37.dirname(file), { recursive: true, mode: 448 });
|
|
15291
15386
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
15292
|
-
|
|
15293
|
-
|
|
15387
|
+
fs33.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
15388
|
+
fs33.renameSync(tmp, file);
|
|
15294
15389
|
restrictToOwner(file);
|
|
15295
15390
|
} catch (err) {
|
|
15296
15391
|
log.warn(
|
|
@@ -15300,21 +15395,21 @@ function persistHeadroomConfig(config) {
|
|
|
15300
15395
|
}
|
|
15301
15396
|
}
|
|
15302
15397
|
function agentSettingsPath(kind) {
|
|
15303
|
-
const home =
|
|
15304
|
-
if (kind === "claude") return
|
|
15305
|
-
if (kind === "codex") return
|
|
15306
|
-
if (kind === "copilot") return
|
|
15398
|
+
const home = os30.homedir();
|
|
15399
|
+
if (kind === "claude") return path37.join(home, ".claude", "settings.json");
|
|
15400
|
+
if (kind === "codex") return path37.join(home, ".codex", "auth.json");
|
|
15401
|
+
if (kind === "copilot") return path37.join(home, ".config", "github-copilot", "hosts.json");
|
|
15307
15402
|
return null;
|
|
15308
15403
|
}
|
|
15309
15404
|
function backupAgentHeadroomConfig(kind) {
|
|
15310
15405
|
const src = agentSettingsPath(kind);
|
|
15311
15406
|
if (!src) return;
|
|
15312
15407
|
try {
|
|
15313
|
-
if (!
|
|
15314
|
-
const dest =
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15408
|
+
if (!fs33.existsSync(src)) return;
|
|
15409
|
+
const dest = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
15410
|
+
fs33.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
|
|
15411
|
+
fs33.copyFileSync(src, dest);
|
|
15412
|
+
fs33.chmodSync(dest, 384);
|
|
15318
15413
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
15319
15414
|
} catch (err) {
|
|
15320
15415
|
log.warn(
|
|
@@ -15326,12 +15421,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
15326
15421
|
function restoreAgentHeadroomConfig(kind) {
|
|
15327
15422
|
const dest = agentSettingsPath(kind);
|
|
15328
15423
|
if (!dest) return false;
|
|
15329
|
-
const src =
|
|
15330
|
-
if (!
|
|
15424
|
+
const src = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
15425
|
+
if (!fs33.existsSync(src)) return false;
|
|
15331
15426
|
try {
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15427
|
+
fs33.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
|
|
15428
|
+
fs33.copyFileSync(src, dest);
|
|
15429
|
+
fs33.chmodSync(dest, 384);
|
|
15335
15430
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
15336
15431
|
return true;
|
|
15337
15432
|
} catch (err) {
|
|
@@ -15344,7 +15439,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
15344
15439
|
}
|
|
15345
15440
|
function readHeadroomChildEnv() {
|
|
15346
15441
|
try {
|
|
15347
|
-
const raw =
|
|
15442
|
+
const raw = fs33.readFileSync(headroomConfigPath(), "utf8");
|
|
15348
15443
|
const parsed = JSON.parse(raw);
|
|
15349
15444
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
15350
15445
|
const o = parsed;
|
|
@@ -15369,37 +15464,37 @@ function bundledClaudeBinDir() {
|
|
|
15369
15464
|
const roots = /* @__PURE__ */ new Set();
|
|
15370
15465
|
let dir = __dirname;
|
|
15371
15466
|
for (let i = 0; i < 6; i++) {
|
|
15372
|
-
roots.add(
|
|
15373
|
-
const parent =
|
|
15467
|
+
roots.add(path37.join(dir, "node_modules"));
|
|
15468
|
+
const parent = path37.dirname(dir);
|
|
15374
15469
|
if (parent === dir) break;
|
|
15375
15470
|
dir = parent;
|
|
15376
15471
|
}
|
|
15377
15472
|
try {
|
|
15378
15473
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
15379
|
-
const marker = `${
|
|
15474
|
+
const marker = `${path37.sep}@anthropic-ai${path37.sep}`;
|
|
15380
15475
|
const idx = main2.lastIndexOf(marker);
|
|
15381
15476
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
15382
15477
|
} catch {
|
|
15383
15478
|
}
|
|
15384
15479
|
for (const nm of roots) {
|
|
15385
|
-
const atAnthropic =
|
|
15480
|
+
const atAnthropic = path37.join(nm, "@anthropic-ai");
|
|
15386
15481
|
let entries;
|
|
15387
15482
|
try {
|
|
15388
|
-
entries =
|
|
15483
|
+
entries = fs33.readdirSync(atAnthropic);
|
|
15389
15484
|
} catch {
|
|
15390
15485
|
continue;
|
|
15391
15486
|
}
|
|
15392
15487
|
for (const entry of entries) {
|
|
15393
15488
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
15394
|
-
const bin =
|
|
15395
|
-
if (
|
|
15489
|
+
const bin = path37.join(atAnthropic, entry, "claude");
|
|
15490
|
+
if (fs33.existsSync(bin)) return path37.dirname(bin);
|
|
15396
15491
|
}
|
|
15397
15492
|
}
|
|
15398
15493
|
return null;
|
|
15399
15494
|
}
|
|
15400
15495
|
async function getFreeDiskBytes(dir) {
|
|
15401
15496
|
try {
|
|
15402
|
-
const s = await
|
|
15497
|
+
const s = await fs33.promises.statfs(dir);
|
|
15403
15498
|
return s.bsize * s.bavail;
|
|
15404
15499
|
} catch {
|
|
15405
15500
|
return null;
|
|
@@ -15591,7 +15686,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
15591
15686
|
if (initKind === "claude") {
|
|
15592
15687
|
const claudeDir = bundledClaudeBinDir();
|
|
15593
15688
|
if (claudeDir) {
|
|
15594
|
-
initEnv.PATH = `${claudeDir}${
|
|
15689
|
+
initEnv.PATH = `${claudeDir}${path37.delimiter}${process.env["PATH"] ?? ""}`;
|
|
15595
15690
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
15596
15691
|
} else {
|
|
15597
15692
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -15647,7 +15742,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.s
|
|
|
15647
15742
|
detached: false
|
|
15648
15743
|
});
|
|
15649
15744
|
function currentCliVersion() {
|
|
15650
|
-
return true ? "2.
|
|
15745
|
+
return true ? "2.53.0" : null;
|
|
15651
15746
|
}
|
|
15652
15747
|
function runCmd(cmd, args2, timeoutMs) {
|
|
15653
15748
|
return new Promise((resolve7) => {
|
|
@@ -15728,7 +15823,7 @@ var defaultDisableService = () => {
|
|
|
15728
15823
|
};
|
|
15729
15824
|
var defaultTeardownHeadroom = () => {
|
|
15730
15825
|
try {
|
|
15731
|
-
const kind = JSON.parse(
|
|
15826
|
+
const kind = JSON.parse(fs33.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
15732
15827
|
if (kind) {
|
|
15733
15828
|
(0, import_node_child_process15.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
15734
15829
|
}
|
|
@@ -16042,9 +16137,9 @@ var HostAgentSupervisor = class {
|
|
|
16042
16137
|
API_TIMEOUT_MS: "3000000",
|
|
16043
16138
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
16044
16139
|
};
|
|
16045
|
-
const houseConfigDir =
|
|
16140
|
+
const houseConfigDir = path37.join(os30.homedir(), ".codeam", "house-claude");
|
|
16046
16141
|
try {
|
|
16047
|
-
|
|
16142
|
+
fs33.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
16048
16143
|
} catch {
|
|
16049
16144
|
}
|
|
16050
16145
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -16062,14 +16157,14 @@ var HostAgentSupervisor = class {
|
|
|
16062
16157
|
report("installing", "installing agent CLI");
|
|
16063
16158
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
16064
16159
|
}
|
|
16065
|
-
const home = process.env.HOME ||
|
|
16160
|
+
const home = process.env.HOME || os30.homedir();
|
|
16066
16161
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
16067
16162
|
if (payload.cloneToken) {
|
|
16068
16163
|
try {
|
|
16069
16164
|
report("preparing", "configuring git tooling");
|
|
16070
16165
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
16071
16166
|
if (ghCmd) {
|
|
16072
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
16167
|
+
childEnv.PATH = `${codeamBinDir()}${path37.delimiter}${childEnv.PATH}`;
|
|
16073
16168
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
16074
16169
|
}
|
|
16075
16170
|
} catch (e) {
|
|
@@ -16085,7 +16180,7 @@ var HostAgentSupervisor = class {
|
|
|
16085
16180
|
}
|
|
16086
16181
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
16087
16182
|
report("headroom", "setting up Headroom proxy");
|
|
16088
|
-
const freeBytes = await this.getFreeDisk(
|
|
16183
|
+
const freeBytes = await this.getFreeDisk(os30.homedir());
|
|
16089
16184
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
16090
16185
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
16091
16186
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -16207,7 +16302,7 @@ var HostAgentSupervisor = class {
|
|
|
16207
16302
|
*/
|
|
16208
16303
|
runAgentInstall(script) {
|
|
16209
16304
|
return new Promise((resolve7) => {
|
|
16210
|
-
const home = process.env.HOME ||
|
|
16305
|
+
const home = process.env.HOME || os30.homedir();
|
|
16211
16306
|
const child = (0, import_node_child_process15.spawn)("sh", ["-c", script], {
|
|
16212
16307
|
env: { ...process.env, HOME: home },
|
|
16213
16308
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -16383,10 +16478,10 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
16383
16478
|
}
|
|
16384
16479
|
|
|
16385
16480
|
// src/services/headroom/budget-relaunch.ts
|
|
16386
|
-
var
|
|
16387
|
-
var
|
|
16388
|
-
var
|
|
16389
|
-
var
|
|
16481
|
+
var fs34 = __toESM(require("fs"));
|
|
16482
|
+
var os31 = __toESM(require("os"));
|
|
16483
|
+
var path38 = __toESM(require("path"));
|
|
16484
|
+
var import_child_process13 = require("child_process");
|
|
16390
16485
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
16391
16486
|
const rawArgs = manifest.proxy_args ?? [];
|
|
16392
16487
|
const strippedArgs = [];
|
|
@@ -16419,7 +16514,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
16419
16514
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
16420
16515
|
}
|
|
16421
16516
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
16422
|
-
const deployDir =
|
|
16517
|
+
const deployDir = path38.join(homeDir2, ".headroom", "deploy");
|
|
16423
16518
|
let profiles;
|
|
16424
16519
|
try {
|
|
16425
16520
|
profiles = deps.readDir(deployDir);
|
|
@@ -16428,7 +16523,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
16428
16523
|
}
|
|
16429
16524
|
const results = [];
|
|
16430
16525
|
for (const profile of profiles) {
|
|
16431
|
-
const manifestPath =
|
|
16526
|
+
const manifestPath = path38.join(deployDir, profile, "manifest.json");
|
|
16432
16527
|
let raw;
|
|
16433
16528
|
try {
|
|
16434
16529
|
raw = deps.readJson(manifestPath);
|
|
@@ -16460,12 +16555,12 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
16460
16555
|
}
|
|
16461
16556
|
function writeManifestReal(manifestPath, manifest) {
|
|
16462
16557
|
const tmp = manifestPath + ".codeam.tmp";
|
|
16463
|
-
|
|
16464
|
-
|
|
16558
|
+
fs34.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
16559
|
+
fs34.renameSync(tmp, manifestPath);
|
|
16465
16560
|
}
|
|
16466
16561
|
function restartDeploymentReal(profile) {
|
|
16467
16562
|
try {
|
|
16468
|
-
const proc = (0,
|
|
16563
|
+
const proc = (0, import_child_process13.spawn)("headroom", ["install", "restart", "--profile", profile], {
|
|
16469
16564
|
detached: true,
|
|
16470
16565
|
stdio: "ignore"
|
|
16471
16566
|
});
|
|
@@ -16482,7 +16577,7 @@ function restartDeploymentReal(profile) {
|
|
|
16482
16577
|
}
|
|
16483
16578
|
function killProxyReal() {
|
|
16484
16579
|
try {
|
|
16485
|
-
const killer = (0,
|
|
16580
|
+
const killer = (0, import_child_process13.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
16486
16581
|
detached: true,
|
|
16487
16582
|
stdio: "ignore"
|
|
16488
16583
|
});
|
|
@@ -16492,13 +16587,13 @@ function killProxyReal() {
|
|
|
16492
16587
|
} catch {
|
|
16493
16588
|
}
|
|
16494
16589
|
}
|
|
16495
|
-
function
|
|
16590
|
+
function spawnProxyReal2(budget) {
|
|
16496
16591
|
try {
|
|
16497
16592
|
const proxyEnv = {
|
|
16498
16593
|
...process.env,
|
|
16499
16594
|
HEADROOM_KOMPRESS_BACKEND: "onnx_cpu"
|
|
16500
16595
|
};
|
|
16501
|
-
const proxy = (0,
|
|
16596
|
+
const proxy = (0, import_child_process13.spawn)(
|
|
16502
16597
|
"headroom",
|
|
16503
16598
|
["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
|
|
16504
16599
|
{
|
|
@@ -16519,21 +16614,21 @@ function spawnProxyReal(budget) {
|
|
|
16519
16614
|
}
|
|
16520
16615
|
}
|
|
16521
16616
|
function makeRealApplyBudgetDeps() {
|
|
16522
|
-
const homeDir2 =
|
|
16617
|
+
const homeDir2 = os31.homedir();
|
|
16523
16618
|
return {
|
|
16524
16619
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
16525
|
-
readDir: (dir) =>
|
|
16526
|
-
readJson: (filePath) => JSON.parse(
|
|
16620
|
+
readDir: (dir) => fs34.readdirSync(dir),
|
|
16621
|
+
readJson: (filePath) => JSON.parse(fs34.readFileSync(filePath, "utf8"))
|
|
16527
16622
|
}),
|
|
16528
16623
|
writeManifest: writeManifestReal,
|
|
16529
16624
|
restartDeployment: restartDeploymentReal,
|
|
16530
16625
|
killProxy: killProxyReal,
|
|
16531
|
-
spawnProxy:
|
|
16626
|
+
spawnProxy: spawnProxyReal2
|
|
16532
16627
|
};
|
|
16533
16628
|
}
|
|
16534
16629
|
|
|
16535
16630
|
// src/services/preview/cloudflared.ts
|
|
16536
|
-
var
|
|
16631
|
+
var import_child_process14 = require("child_process");
|
|
16537
16632
|
var import_fs = require("fs");
|
|
16538
16633
|
var import_promises = __toESM(require("fs/promises"));
|
|
16539
16634
|
var import_os6 = __toESM(require("os"));
|
|
@@ -16610,7 +16705,7 @@ async function isExecutableBinary(p2) {
|
|
|
16610
16705
|
}
|
|
16611
16706
|
function extractTgz(tgzPath, destDir) {
|
|
16612
16707
|
return new Promise((resolve7, reject) => {
|
|
16613
|
-
const child = (0,
|
|
16708
|
+
const child = (0, import_child_process14.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
|
|
16614
16709
|
child.on("error", (err) => reject(err));
|
|
16615
16710
|
child.on(
|
|
16616
16711
|
"exit",
|
|
@@ -16644,7 +16739,7 @@ async function spawnNamedTunnel(bin, token, port) {
|
|
|
16644
16739
|
await import_promises.default.mkdir(credDir, { recursive: true });
|
|
16645
16740
|
const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
|
|
16646
16741
|
await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
|
|
16647
|
-
return (0,
|
|
16742
|
+
return (0, import_child_process14.spawn)(
|
|
16648
16743
|
bin,
|
|
16649
16744
|
[
|
|
16650
16745
|
"tunnel",
|
|
@@ -16660,9 +16755,9 @@ async function spawnNamedTunnel(bin, token, port) {
|
|
|
16660
16755
|
}
|
|
16661
16756
|
|
|
16662
16757
|
// src/services/preview/codespace.ts
|
|
16663
|
-
var
|
|
16758
|
+
var import_child_process15 = require("child_process");
|
|
16664
16759
|
var import_util3 = require("util");
|
|
16665
|
-
var execFileP5 = (0, import_util3.promisify)(
|
|
16760
|
+
var execFileP5 = (0, import_util3.promisify)(import_child_process15.execFile);
|
|
16666
16761
|
|
|
16667
16762
|
// src/services/preview/config-file.ts
|
|
16668
16763
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
@@ -16857,10 +16952,10 @@ var import_fs2 = require("fs");
|
|
|
16857
16952
|
var import_path6 = __toESM(require("path"));
|
|
16858
16953
|
|
|
16859
16954
|
// src/services/preview/run-setup.ts
|
|
16860
|
-
var
|
|
16955
|
+
var import_child_process16 = require("child_process");
|
|
16861
16956
|
function runSetupCommand(cmd, args2, cwd, env, opts) {
|
|
16862
16957
|
return new Promise((resolve7) => {
|
|
16863
|
-
const child = (0,
|
|
16958
|
+
const child = (0, import_child_process16.spawn)(cmd, args2, {
|
|
16864
16959
|
cwd,
|
|
16865
16960
|
env: { ...process.env, ...env ?? {} },
|
|
16866
16961
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -17166,10 +17261,10 @@ function activePreviewSessionIds() {
|
|
|
17166
17261
|
}
|
|
17167
17262
|
|
|
17168
17263
|
// src/beads/bd-adapter.ts
|
|
17169
|
-
var
|
|
17170
|
-
var
|
|
17171
|
-
var
|
|
17172
|
-
var
|
|
17264
|
+
var import_child_process17 = require("child_process");
|
|
17265
|
+
var fs39 = __toESM(require("fs"));
|
|
17266
|
+
var os33 = __toESM(require("os"));
|
|
17267
|
+
var path43 = __toESM(require("path"));
|
|
17173
17268
|
var BD_PACKAGE = "@beads/bd";
|
|
17174
17269
|
function resolveBundledBdBinary() {
|
|
17175
17270
|
return _resolveSeam.resolveBundled();
|
|
@@ -17181,11 +17276,11 @@ function _defaultResolveBundled() {
|
|
|
17181
17276
|
} catch {
|
|
17182
17277
|
return null;
|
|
17183
17278
|
}
|
|
17184
|
-
const binDir =
|
|
17279
|
+
const binDir = path43.join(path43.dirname(pkgJsonPath), "bin");
|
|
17185
17280
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
17186
|
-
const binaryPath =
|
|
17281
|
+
const binaryPath = path43.join(binDir, binaryName);
|
|
17187
17282
|
try {
|
|
17188
|
-
|
|
17283
|
+
fs39.accessSync(binaryPath, fs39.constants.F_OK);
|
|
17189
17284
|
return binaryPath;
|
|
17190
17285
|
} catch {
|
|
17191
17286
|
return null;
|
|
@@ -17195,13 +17290,13 @@ function resolveBdOnPath() {
|
|
|
17195
17290
|
return _resolveSeam.resolveOnPath();
|
|
17196
17291
|
}
|
|
17197
17292
|
function _defaultResolveOnPath() {
|
|
17198
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
17293
|
+
const dirs = (process.env.PATH ?? "").split(path43.delimiter).filter(Boolean);
|
|
17199
17294
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
17200
17295
|
for (const dir of dirs) {
|
|
17201
17296
|
for (const candidate of candidates) {
|
|
17202
|
-
const full =
|
|
17297
|
+
const full = path43.join(dir, candidate);
|
|
17203
17298
|
try {
|
|
17204
|
-
|
|
17299
|
+
fs39.accessSync(full, fs39.constants.F_OK);
|
|
17205
17300
|
return full;
|
|
17206
17301
|
} catch {
|
|
17207
17302
|
}
|
|
@@ -17220,7 +17315,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
|
|
|
17220
17315
|
return new Promise((resolve7) => {
|
|
17221
17316
|
let proc;
|
|
17222
17317
|
try {
|
|
17223
|
-
proc = (0,
|
|
17318
|
+
proc = (0, import_child_process17.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
|
|
17224
17319
|
} catch (err) {
|
|
17225
17320
|
resolve7({ code: -1, stdout: "", stderr: err.message });
|
|
17226
17321
|
return;
|
|
@@ -17286,7 +17381,7 @@ var BdAdapter = class {
|
|
|
17286
17381
|
const env = { ...process.env };
|
|
17287
17382
|
if (!env.HOME) {
|
|
17288
17383
|
try {
|
|
17289
|
-
const home =
|
|
17384
|
+
const home = os33.homedir();
|
|
17290
17385
|
if (home) env.HOME = home;
|
|
17291
17386
|
} catch {
|
|
17292
17387
|
}
|
|
@@ -17374,13 +17469,13 @@ function coerceIssue(row, projectKey) {
|
|
|
17374
17469
|
}
|
|
17375
17470
|
|
|
17376
17471
|
// src/beads/provisioner.ts
|
|
17377
|
-
var
|
|
17378
|
-
var
|
|
17379
|
-
var
|
|
17380
|
-
var
|
|
17472
|
+
var import_child_process21 = require("child_process");
|
|
17473
|
+
var fs42 = __toESM(require("fs"));
|
|
17474
|
+
var os35 = __toESM(require("os"));
|
|
17475
|
+
var path46 = __toESM(require("path"));
|
|
17381
17476
|
|
|
17382
17477
|
// src/beads/install-bd.ts
|
|
17383
|
-
var
|
|
17478
|
+
var import_child_process18 = require("child_process");
|
|
17384
17479
|
var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
|
|
17385
17480
|
var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
|
|
17386
17481
|
function resolveInstallStrategy(platform3) {
|
|
@@ -17411,7 +17506,7 @@ function _defaultInstallSpawn(strategy) {
|
|
|
17411
17506
|
return new Promise((resolve7) => {
|
|
17412
17507
|
let proc;
|
|
17413
17508
|
try {
|
|
17414
|
-
proc = (0,
|
|
17509
|
+
proc = (0, import_child_process18.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
17415
17510
|
} catch (err) {
|
|
17416
17511
|
resolve7({ ok: false, code: -1, stderr: err.message });
|
|
17417
17512
|
return;
|
|
@@ -17441,10 +17536,10 @@ async function installBd(platform3 = process.platform) {
|
|
|
17441
17536
|
}
|
|
17442
17537
|
|
|
17443
17538
|
// src/beads/install-dolt.ts
|
|
17444
|
-
var
|
|
17445
|
-
var
|
|
17446
|
-
var
|
|
17447
|
-
var
|
|
17539
|
+
var import_child_process19 = require("child_process");
|
|
17540
|
+
var fs40 = __toESM(require("fs"));
|
|
17541
|
+
var os34 = __toESM(require("os"));
|
|
17542
|
+
var path44 = __toESM(require("path"));
|
|
17448
17543
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
17449
17544
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
17450
17545
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -17484,11 +17579,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
17484
17579
|
}
|
|
17485
17580
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
17486
17581
|
function doltPlatformTuple(platform3, arch2) {
|
|
17487
|
-
const
|
|
17582
|
+
const os44 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
17488
17583
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
17489
17584
|
if (!a) return null;
|
|
17490
|
-
if (
|
|
17491
|
-
return `${
|
|
17585
|
+
if (os44 === "windows" && a !== "amd64") return null;
|
|
17586
|
+
return `${os44}-${a}`;
|
|
17492
17587
|
}
|
|
17493
17588
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
17494
17589
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -17533,14 +17628,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
17533
17628
|
return result;
|
|
17534
17629
|
}
|
|
17535
17630
|
var _doltPathSeam = {
|
|
17536
|
-
homedir: () =>
|
|
17631
|
+
homedir: () => os34.homedir(),
|
|
17537
17632
|
getPath: () => process.env.PATH ?? "",
|
|
17538
17633
|
setPath: (p2) => {
|
|
17539
17634
|
process.env.PATH = p2;
|
|
17540
17635
|
},
|
|
17541
17636
|
exists: (p2) => {
|
|
17542
17637
|
try {
|
|
17543
|
-
|
|
17638
|
+
fs40.accessSync(p2, fs40.constants.F_OK);
|
|
17544
17639
|
return true;
|
|
17545
17640
|
} catch {
|
|
17546
17641
|
return false;
|
|
@@ -17551,7 +17646,7 @@ function doltBinaryNames(platform3) {
|
|
|
17551
17646
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
17552
17647
|
}
|
|
17553
17648
|
function knownDoltDirs(platform3) {
|
|
17554
|
-
const P3 = platform3 === "win32" ?
|
|
17649
|
+
const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
|
|
17555
17650
|
const home = _doltPathSeam.homedir();
|
|
17556
17651
|
if (platform3 === "win32") {
|
|
17557
17652
|
return [
|
|
@@ -17567,7 +17662,7 @@ function knownDoltDirs(platform3) {
|
|
|
17567
17662
|
].filter(Boolean);
|
|
17568
17663
|
}
|
|
17569
17664
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
17570
|
-
const P3 = platform3 === "win32" ?
|
|
17665
|
+
const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
|
|
17571
17666
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
17572
17667
|
const names = doltBinaryNames(platform3);
|
|
17573
17668
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -17603,7 +17698,7 @@ function _defaultDoltInstallSpawn(strategy) {
|
|
|
17603
17698
|
};
|
|
17604
17699
|
let proc;
|
|
17605
17700
|
try {
|
|
17606
|
-
proc = (0,
|
|
17701
|
+
proc = (0, import_child_process19.spawn)(strategy.command, strategy.args, {
|
|
17607
17702
|
env: process.env,
|
|
17608
17703
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17609
17704
|
});
|
|
@@ -17701,10 +17796,10 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
17701
17796
|
}
|
|
17702
17797
|
|
|
17703
17798
|
// src/beads/project-key.ts
|
|
17704
|
-
var
|
|
17799
|
+
var import_child_process20 = require("child_process");
|
|
17705
17800
|
var crypto2 = __toESM(require("crypto"));
|
|
17706
|
-
var
|
|
17707
|
-
var
|
|
17801
|
+
var fs41 = __toESM(require("fs"));
|
|
17802
|
+
var path45 = __toESM(require("path"));
|
|
17708
17803
|
function normalizeOrigin(raw) {
|
|
17709
17804
|
const trimmed = raw.trim();
|
|
17710
17805
|
if (!trimmed) return null;
|
|
@@ -17730,17 +17825,17 @@ function normalizeOrigin(raw) {
|
|
|
17730
17825
|
return `${host2}/${pathPart}`;
|
|
17731
17826
|
}
|
|
17732
17827
|
function findRepoRoot(cwd) {
|
|
17733
|
-
let dir =
|
|
17828
|
+
let dir = path45.resolve(cwd);
|
|
17734
17829
|
const seen = /* @__PURE__ */ new Set();
|
|
17735
17830
|
for (let i = 0; i < 256; i++) {
|
|
17736
17831
|
if (seen.has(dir)) return null;
|
|
17737
17832
|
seen.add(dir);
|
|
17738
17833
|
try {
|
|
17739
|
-
const stat3 =
|
|
17834
|
+
const stat3 = fs41.statSync(path45.join(dir, ".git"), { throwIfNoEntry: false });
|
|
17740
17835
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
17741
17836
|
} catch {
|
|
17742
17837
|
}
|
|
17743
|
-
const parent =
|
|
17838
|
+
const parent = path45.dirname(dir);
|
|
17744
17839
|
if (parent === dir) return null;
|
|
17745
17840
|
dir = parent;
|
|
17746
17841
|
}
|
|
@@ -17748,10 +17843,10 @@ function findRepoRoot(cwd) {
|
|
|
17748
17843
|
}
|
|
17749
17844
|
var _execSeam2 = {
|
|
17750
17845
|
exec: (file, args2, opts) => {
|
|
17751
|
-
const out2 = (0,
|
|
17846
|
+
const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
|
|
17752
17847
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
17753
17848
|
},
|
|
17754
|
-
realpath: (p2) =>
|
|
17849
|
+
realpath: (p2) => fs41.realpathSync(p2)
|
|
17755
17850
|
};
|
|
17756
17851
|
function readOrigin(cwd) {
|
|
17757
17852
|
try {
|
|
@@ -17780,7 +17875,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
17780
17875
|
} catch {
|
|
17781
17876
|
}
|
|
17782
17877
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
17783
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
17878
|
+
return { projectKey: `path:${hash}`, projectLabel: path45.basename(real) || "project" };
|
|
17784
17879
|
}
|
|
17785
17880
|
|
|
17786
17881
|
// src/beads/project-prefix.ts
|
|
@@ -17822,17 +17917,17 @@ var _provisionSeam = {
|
|
|
17822
17917
|
};
|
|
17823
17918
|
var _linkSeam = {
|
|
17824
17919
|
platform: () => process.platform,
|
|
17825
|
-
homedir: () =>
|
|
17920
|
+
homedir: () => os35.homedir(),
|
|
17826
17921
|
isWritableDir: (dir) => {
|
|
17827
17922
|
try {
|
|
17828
|
-
|
|
17923
|
+
fs42.accessSync(dir, fs42.constants.W_OK);
|
|
17829
17924
|
return true;
|
|
17830
17925
|
} catch {
|
|
17831
17926
|
return false;
|
|
17832
17927
|
}
|
|
17833
17928
|
},
|
|
17834
17929
|
ensureDir: (dir) => {
|
|
17835
|
-
|
|
17930
|
+
fs42.mkdirSync(dir, { recursive: true });
|
|
17836
17931
|
},
|
|
17837
17932
|
/**
|
|
17838
17933
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -17853,9 +17948,9 @@ var _linkSeam = {
|
|
|
17853
17948
|
* which `linkBdOntoPath` creates if missing.
|
|
17854
17949
|
*/
|
|
17855
17950
|
cliBinDir: () => {
|
|
17856
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
17951
|
+
const pathDirs = (process.env.PATH ?? "").split(path46.delimiter).filter(Boolean);
|
|
17857
17952
|
const home = _linkSeam.homedir();
|
|
17858
|
-
const localBin = home ?
|
|
17953
|
+
const localBin = home ? path46.join(home, ".local", "bin") : null;
|
|
17859
17954
|
if (localBin) {
|
|
17860
17955
|
try {
|
|
17861
17956
|
_linkSeam.ensureDir(localBin);
|
|
@@ -17865,16 +17960,16 @@ var _linkSeam = {
|
|
|
17865
17960
|
const candidates = [];
|
|
17866
17961
|
if (localBin) candidates.push(localBin);
|
|
17867
17962
|
try {
|
|
17868
|
-
candidates.push(
|
|
17963
|
+
candidates.push(path46.dirname(process.execPath));
|
|
17869
17964
|
} catch {
|
|
17870
17965
|
}
|
|
17871
17966
|
candidates.push("/usr/local/bin");
|
|
17872
17967
|
const entry = process.argv[1];
|
|
17873
17968
|
if (entry) {
|
|
17874
17969
|
try {
|
|
17875
|
-
candidates.push(
|
|
17970
|
+
candidates.push(path46.dirname(fs42.realpathSync(entry)));
|
|
17876
17971
|
} catch {
|
|
17877
|
-
candidates.push(
|
|
17972
|
+
candidates.push(path46.dirname(entry));
|
|
17878
17973
|
}
|
|
17879
17974
|
}
|
|
17880
17975
|
const onPathWritable = candidates.find(
|
|
@@ -17886,20 +17981,20 @@ var _linkSeam = {
|
|
|
17886
17981
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
17887
17982
|
readlink: (linkPath) => {
|
|
17888
17983
|
try {
|
|
17889
|
-
return
|
|
17984
|
+
return fs42.readlinkSync(linkPath);
|
|
17890
17985
|
} catch {
|
|
17891
17986
|
return null;
|
|
17892
17987
|
}
|
|
17893
17988
|
},
|
|
17894
|
-
unlink: (linkPath) =>
|
|
17895
|
-
symlink: (target, linkPath) =>
|
|
17989
|
+
unlink: (linkPath) => fs42.unlinkSync(linkPath),
|
|
17990
|
+
symlink: (target, linkPath) => fs42.symlinkSync(target, linkPath)
|
|
17896
17991
|
};
|
|
17897
17992
|
function linkBdOntoPath(binaryPath) {
|
|
17898
17993
|
if (_linkSeam.platform() === "win32") return;
|
|
17899
17994
|
const binDir = _linkSeam.cliBinDir();
|
|
17900
17995
|
if (!binDir) return;
|
|
17901
17996
|
_linkSeam.ensureDir(binDir);
|
|
17902
|
-
const linkPath =
|
|
17997
|
+
const linkPath = path46.join(binDir, "bd");
|
|
17903
17998
|
if (linkPath === binaryPath) return;
|
|
17904
17999
|
const current = _linkSeam.readlink(linkPath);
|
|
17905
18000
|
if (current === binaryPath) return;
|
|
@@ -17908,7 +18003,7 @@ function linkBdOntoPath(binaryPath) {
|
|
|
17908
18003
|
log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
|
|
17909
18004
|
}
|
|
17910
18005
|
function setGitBeadsRole() {
|
|
17911
|
-
(0,
|
|
18006
|
+
(0, import_child_process21.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
|
|
17912
18007
|
stdio: "ignore"
|
|
17913
18008
|
});
|
|
17914
18009
|
}
|
|
@@ -18094,7 +18189,7 @@ function dedupeRecipes(agents) {
|
|
|
18094
18189
|
|
|
18095
18190
|
// src/beads/watcher.ts
|
|
18096
18191
|
var crypto4 = __toESM(require("crypto"));
|
|
18097
|
-
var
|
|
18192
|
+
var path47 = __toESM(require("path"));
|
|
18098
18193
|
var API_BASE6 = resolveApiBaseUrl();
|
|
18099
18194
|
var DEBOUNCE_MS2 = 400;
|
|
18100
18195
|
var ZERO_SUMMARY = {
|
|
@@ -18118,7 +18213,7 @@ var BeadsWatcher = class {
|
|
|
18118
18213
|
constructor(opts) {
|
|
18119
18214
|
this.opts = opts;
|
|
18120
18215
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
18121
|
-
this.feedPath = opts.feedPath ??
|
|
18216
|
+
this.feedPath = opts.feedPath ?? path47.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
18122
18217
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
18123
18218
|
}
|
|
18124
18219
|
opts;
|
|
@@ -18528,7 +18623,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
|
18528
18623
|
function cleanupAttachmentTempFiles() {
|
|
18529
18624
|
for (const p2 of pendingAttachmentFiles) {
|
|
18530
18625
|
try {
|
|
18531
|
-
|
|
18626
|
+
fs44.unlinkSync(p2);
|
|
18532
18627
|
} catch {
|
|
18533
18628
|
}
|
|
18534
18629
|
}
|
|
@@ -18537,8 +18632,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
18537
18632
|
function saveFilesTemp(files) {
|
|
18538
18633
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
18539
18634
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
18540
|
-
const tmpPath =
|
|
18541
|
-
|
|
18635
|
+
const tmpPath = path49.join(os37.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
18636
|
+
fs44.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
18542
18637
|
pendingAttachmentFiles.add(tmpPath);
|
|
18543
18638
|
return tmpPath;
|
|
18544
18639
|
});
|
|
@@ -18558,7 +18653,7 @@ var startTask = (ctx, _cmd, parsed) => {
|
|
|
18558
18653
|
setTimeout(() => {
|
|
18559
18654
|
for (const p2 of paths) {
|
|
18560
18655
|
try {
|
|
18561
|
-
|
|
18656
|
+
fs44.unlinkSync(p2);
|
|
18562
18657
|
} catch {
|
|
18563
18658
|
}
|
|
18564
18659
|
pendingAttachmentFiles.delete(p2);
|
|
@@ -18683,7 +18778,7 @@ var sessionTerminated = async (ctx, cmd) => {
|
|
|
18683
18778
|
} catch {
|
|
18684
18779
|
}
|
|
18685
18780
|
try {
|
|
18686
|
-
const proc = (0,
|
|
18781
|
+
const proc = (0, import_child_process22.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
18687
18782
|
detached: true,
|
|
18688
18783
|
stdio: "ignore"
|
|
18689
18784
|
});
|
|
@@ -18705,7 +18800,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
18705
18800
|
}
|
|
18706
18801
|
if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
|
|
18707
18802
|
try {
|
|
18708
|
-
const stopProc = (0,
|
|
18803
|
+
const stopProc = (0, import_child_process22.spawn)(
|
|
18709
18804
|
"bash",
|
|
18710
18805
|
["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
|
|
18711
18806
|
{ detached: true, stdio: "ignore" }
|
|
@@ -18715,7 +18810,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
18715
18810
|
}
|
|
18716
18811
|
}
|
|
18717
18812
|
try {
|
|
18718
|
-
const proc = (0,
|
|
18813
|
+
const proc = (0, import_child_process22.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
18719
18814
|
detached: true,
|
|
18720
18815
|
stdio: "ignore"
|
|
18721
18816
|
});
|
|
@@ -18759,9 +18854,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
18759
18854
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
18760
18855
|
};
|
|
18761
18856
|
var envReadH = async (ctx, cmd) => {
|
|
18762
|
-
const envPath =
|
|
18857
|
+
const envPath = path49.join(process.cwd(), ".env");
|
|
18763
18858
|
try {
|
|
18764
|
-
const raw = await
|
|
18859
|
+
const raw = await fs44.promises.readFile(envPath, "utf8");
|
|
18765
18860
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
18766
18861
|
exists: true,
|
|
18767
18862
|
vars: parseDotenv(raw)
|
|
@@ -18792,14 +18887,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
18792
18887
|
}
|
|
18793
18888
|
seen.add(v.key);
|
|
18794
18889
|
}
|
|
18795
|
-
const envPath =
|
|
18796
|
-
const tmpPath =
|
|
18890
|
+
const envPath = path49.join(process.cwd(), ".env");
|
|
18891
|
+
const tmpPath = path49.join(process.cwd(), ".env.codeam.tmp");
|
|
18797
18892
|
try {
|
|
18798
|
-
await
|
|
18799
|
-
await
|
|
18893
|
+
await fs44.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
18894
|
+
await fs44.promises.rename(tmpPath, envPath);
|
|
18800
18895
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
18801
18896
|
} catch (err) {
|
|
18802
|
-
await
|
|
18897
|
+
await fs44.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
18803
18898
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
18804
18899
|
}
|
|
18805
18900
|
};
|
|
@@ -18817,7 +18912,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18817
18912
|
let configuredAgent = rawAgentId;
|
|
18818
18913
|
if (!configuredAgent) {
|
|
18819
18914
|
try {
|
|
18820
|
-
const raw = JSON.parse(
|
|
18915
|
+
const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
|
|
18821
18916
|
configuredAgent = raw.agent ?? "";
|
|
18822
18917
|
} catch {
|
|
18823
18918
|
}
|
|
@@ -18851,7 +18946,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18851
18946
|
persist: persistHeadroomConfig,
|
|
18852
18947
|
readEnabled: () => {
|
|
18853
18948
|
try {
|
|
18854
|
-
const raw = JSON.parse(
|
|
18949
|
+
const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
|
|
18855
18950
|
return raw.enabled === true;
|
|
18856
18951
|
} catch {
|
|
18857
18952
|
return false;
|
|
@@ -18903,7 +18998,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
18903
18998
|
restoreAgentHeadroomConfig: (kind) => restoreAgentHeadroomConfig(kind),
|
|
18904
18999
|
stopProxy: () => {
|
|
18905
19000
|
try {
|
|
18906
|
-
const p2 = (0,
|
|
19001
|
+
const p2 = (0, import_child_process22.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
18907
19002
|
detached: true,
|
|
18908
19003
|
stdio: "ignore"
|
|
18909
19004
|
});
|
|
@@ -18945,7 +19040,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
18945
19040
|
}
|
|
18946
19041
|
let headroomActive = false;
|
|
18947
19042
|
try {
|
|
18948
|
-
const raw = JSON.parse(
|
|
19043
|
+
const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
|
|
18949
19044
|
headroomActive = raw.enabled === true;
|
|
18950
19045
|
} catch {
|
|
18951
19046
|
}
|
|
@@ -18955,7 +19050,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
18955
19050
|
}
|
|
18956
19051
|
let existingConfig = { enabled: true };
|
|
18957
19052
|
try {
|
|
18958
|
-
existingConfig = JSON.parse(
|
|
19053
|
+
existingConfig = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
|
|
18959
19054
|
} catch {
|
|
18960
19055
|
}
|
|
18961
19056
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -19060,7 +19155,7 @@ var defaultCliUpdateDeps = {
|
|
|
19060
19155
|
isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
|
|
19061
19156
|
relaunch: (args2) => {
|
|
19062
19157
|
const entry = process.argv[1];
|
|
19063
|
-
const child = (0,
|
|
19158
|
+
const child = (0, import_child_process22.spawn)(process.execPath, [entry, ...args2], {
|
|
19064
19159
|
detached: true,
|
|
19065
19160
|
stdio: "inherit"
|
|
19066
19161
|
});
|
|
@@ -19073,13 +19168,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
19073
19168
|
function buildNpmInstallInvocation(opts) {
|
|
19074
19169
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
19075
19170
|
const execPath = opts?.execPath ?? process.execPath;
|
|
19076
|
-
const exists2 = opts?.existsSync ??
|
|
19077
|
-
const normalized = entryScript.split(
|
|
19171
|
+
const exists2 = opts?.existsSync ?? fs44.existsSync;
|
|
19172
|
+
const normalized = entryScript.split(path49.sep).join("/");
|
|
19078
19173
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
19079
19174
|
const markerIdx = normalized.indexOf(marker);
|
|
19080
19175
|
const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
|
|
19081
|
-
const siblingNpm =
|
|
19082
|
-
|
|
19176
|
+
const siblingNpm = path49.join(
|
|
19177
|
+
path49.dirname(execPath),
|
|
19083
19178
|
process.platform === "win32" ? "npm.cmd" : "npm"
|
|
19084
19179
|
);
|
|
19085
19180
|
const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
|
|
@@ -19091,7 +19186,7 @@ async function runNpmInstallLatest() {
|
|
|
19091
19186
|
const invocation = buildNpmInstallInvocation();
|
|
19092
19187
|
for (let attempt = 1; attempt <= CLI_UPDATE_MAX_ATTEMPTS; attempt++) {
|
|
19093
19188
|
const result = await new Promise((resolve7) => {
|
|
19094
|
-
(0,
|
|
19189
|
+
(0, import_child_process22.execFile)(
|
|
19095
19190
|
invocation.command,
|
|
19096
19191
|
invocation.args,
|
|
19097
19192
|
{ timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS },
|
|
@@ -19586,8 +19681,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
19586
19681
|
if (args2.length === 0) return detection;
|
|
19587
19682
|
const binName = args2[0];
|
|
19588
19683
|
if (binName.startsWith("-")) return detection;
|
|
19589
|
-
const binPath =
|
|
19590
|
-
if (!
|
|
19684
|
+
const binPath = path49.join(cwd, "node_modules", ".bin", binName);
|
|
19685
|
+
if (!fs44.existsSync(binPath)) return detection;
|
|
19591
19686
|
return {
|
|
19592
19687
|
...detection,
|
|
19593
19688
|
command: binPath,
|
|
@@ -19822,7 +19917,7 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
|
|
|
19822
19917
|
"BOOT_SEQUENCE",
|
|
19823
19918
|
`${spawnable.command} ${spawnable.args.join(" ")}`
|
|
19824
19919
|
);
|
|
19825
|
-
const devServer = (0,
|
|
19920
|
+
const devServer = (0, import_child_process22.spawn)(spawnable.command, spawnable.args, {
|
|
19826
19921
|
cwd: process.cwd(),
|
|
19827
19922
|
env: { ...process.env, ...spawnable.env ?? {} },
|
|
19828
19923
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -19972,7 +20067,7 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
|
|
|
19972
20067
|
`cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
|
|
19973
20068
|
);
|
|
19974
20069
|
}
|
|
19975
|
-
const candidate = (0,
|
|
20070
|
+
const candidate = (0, import_child_process22.spawn)(
|
|
19976
20071
|
bin,
|
|
19977
20072
|
["tunnel", "--url", `http://localhost:${detection.port}`],
|
|
19978
20073
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -20169,13 +20264,13 @@ async function dispatchCommand(ctx, cmd) {
|
|
|
20169
20264
|
}
|
|
20170
20265
|
|
|
20171
20266
|
// src/commands/start/keep-alive.ts
|
|
20172
|
-
var
|
|
20267
|
+
var import_child_process23 = require("child_process");
|
|
20173
20268
|
function buildKeepAlive(ctx) {
|
|
20174
20269
|
let timer = null;
|
|
20175
20270
|
async function setIdleTimeout(minutes) {
|
|
20176
20271
|
if (!ctx.inCodespace || !ctx.codespaceName) return;
|
|
20177
20272
|
await new Promise((resolve7) => {
|
|
20178
|
-
const proc = (0,
|
|
20273
|
+
const proc = (0, import_child_process23.spawn)(
|
|
20179
20274
|
"gh",
|
|
20180
20275
|
[
|
|
20181
20276
|
"api",
|
|
@@ -20406,12 +20501,12 @@ function readTokenFromArgs(args2) {
|
|
|
20406
20501
|
}
|
|
20407
20502
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
20408
20503
|
if (fileFlag) {
|
|
20409
|
-
const
|
|
20504
|
+
const path64 = fileFlag.slice("--token-file=".length);
|
|
20410
20505
|
try {
|
|
20411
|
-
const content =
|
|
20412
|
-
if (content.length === 0) fail(`--token-file ${
|
|
20506
|
+
const content = fs45.readFileSync(path64, "utf8").trim();
|
|
20507
|
+
if (content.length === 0) fail(`--token-file ${path64} is empty`);
|
|
20413
20508
|
try {
|
|
20414
|
-
|
|
20509
|
+
fs45.unlinkSync(path64);
|
|
20415
20510
|
} catch {
|
|
20416
20511
|
}
|
|
20417
20512
|
return content;
|
|
@@ -20437,7 +20532,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
20437
20532
|
pluginId,
|
|
20438
20533
|
ideName: "codeam-cli (codespace)",
|
|
20439
20534
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
20440
|
-
hostname:
|
|
20535
|
+
hostname: os38.hostname(),
|
|
20441
20536
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
20442
20537
|
// Current git branch of the codespace's working directory, so the
|
|
20443
20538
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -20498,7 +20593,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
20498
20593
|
}
|
|
20499
20594
|
}
|
|
20500
20595
|
function pairAutoLockPath() {
|
|
20501
|
-
return
|
|
20596
|
+
return path50.join(os38.homedir(), ".codeam", "pair-auto.lock");
|
|
20502
20597
|
}
|
|
20503
20598
|
function isLivePairAuto(pid) {
|
|
20504
20599
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -20508,7 +20603,7 @@ function isLivePairAuto(pid) {
|
|
|
20508
20603
|
if (e.code !== "EPERM") return false;
|
|
20509
20604
|
}
|
|
20510
20605
|
try {
|
|
20511
|
-
return
|
|
20606
|
+
return fs45.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
20512
20607
|
} catch {
|
|
20513
20608
|
return true;
|
|
20514
20609
|
}
|
|
@@ -20518,24 +20613,24 @@ function isLiveCodeam(pid) {
|
|
|
20518
20613
|
}
|
|
20519
20614
|
function daemonLockPath(sessionId) {
|
|
20520
20615
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
20521
|
-
return
|
|
20616
|
+
return path50.join(os38.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
20522
20617
|
}
|
|
20523
20618
|
function acquireDaemonLock(sessionId) {
|
|
20524
20619
|
const lockPath = daemonLockPath(sessionId);
|
|
20525
20620
|
try {
|
|
20526
|
-
|
|
20621
|
+
fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
|
|
20527
20622
|
try {
|
|
20528
|
-
|
|
20623
|
+
fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
20529
20624
|
} catch (e) {
|
|
20530
20625
|
if (e.code !== "EEXIST") throw e;
|
|
20531
|
-
const holder = Number(
|
|
20626
|
+
const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
|
|
20532
20627
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
20533
|
-
|
|
20628
|
+
fs45.writeFileSync(lockPath, String(process.pid));
|
|
20534
20629
|
}
|
|
20535
20630
|
const release3 = () => {
|
|
20536
20631
|
try {
|
|
20537
|
-
if (
|
|
20538
|
-
|
|
20632
|
+
if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20633
|
+
fs45.unlinkSync(lockPath);
|
|
20539
20634
|
}
|
|
20540
20635
|
} catch {
|
|
20541
20636
|
}
|
|
@@ -20557,19 +20652,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
20557
20652
|
function acquireSingletonLock() {
|
|
20558
20653
|
const lockPath = pairAutoLockPath();
|
|
20559
20654
|
try {
|
|
20560
|
-
|
|
20655
|
+
fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
|
|
20561
20656
|
try {
|
|
20562
|
-
|
|
20657
|
+
fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
20563
20658
|
} catch (e) {
|
|
20564
20659
|
if (e.code !== "EEXIST") throw e;
|
|
20565
|
-
const holder = Number(
|
|
20660
|
+
const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
|
|
20566
20661
|
if (isLivePairAuto(holder)) return false;
|
|
20567
|
-
|
|
20662
|
+
fs45.writeFileSync(lockPath, String(process.pid));
|
|
20568
20663
|
}
|
|
20569
20664
|
process.once("exit", () => {
|
|
20570
20665
|
try {
|
|
20571
|
-
if (
|
|
20572
|
-
|
|
20666
|
+
if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
20667
|
+
fs45.unlinkSync(lockPath);
|
|
20573
20668
|
}
|
|
20574
20669
|
} catch {
|
|
20575
20670
|
}
|
|
@@ -21014,12 +21109,12 @@ var AgentService = class _AgentService {
|
|
|
21014
21109
|
};
|
|
21015
21110
|
|
|
21016
21111
|
// src/agents/acp/adapters.ts
|
|
21017
|
-
var
|
|
21112
|
+
var path52 = __toESM(require("path"));
|
|
21018
21113
|
|
|
21019
21114
|
// src/agents/acp/agent-binary.ts
|
|
21020
21115
|
var import_fs4 = __toESM(require("fs"));
|
|
21021
21116
|
var import_path8 = __toESM(require("path"));
|
|
21022
|
-
var
|
|
21117
|
+
var import_child_process24 = require("child_process");
|
|
21023
21118
|
function currentPlatformKey() {
|
|
21024
21119
|
return `${process.platform}-${process.arch}`;
|
|
21025
21120
|
}
|
|
@@ -21082,7 +21177,7 @@ function isCommandOnPath(cmd, probe = defaultWhich) {
|
|
|
21082
21177
|
function defaultWhich(cmd) {
|
|
21083
21178
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
21084
21179
|
try {
|
|
21085
|
-
const res = (0,
|
|
21180
|
+
const res = (0, import_child_process24.spawnSync)(finder, [cmd], { stdio: "ignore" });
|
|
21086
21181
|
return res.status === 0;
|
|
21087
21182
|
} catch {
|
|
21088
21183
|
return false;
|
|
@@ -21113,13 +21208,13 @@ function resolveBin(pkgName, binName) {
|
|
|
21113
21208
|
try {
|
|
21114
21209
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
21115
21210
|
const manifest = require_(`${pkgName}/package.json`);
|
|
21116
|
-
const pkgDir =
|
|
21211
|
+
const pkgDir = path52.dirname(manifestPath);
|
|
21117
21212
|
const bin = manifest.bin;
|
|
21118
21213
|
if (!bin) return null;
|
|
21119
|
-
if (typeof bin === "string") return
|
|
21214
|
+
if (typeof bin === "string") return path52.resolve(pkgDir, bin);
|
|
21120
21215
|
const target = binName ?? Object.keys(bin)[0];
|
|
21121
21216
|
if (!target || !bin[target]) return null;
|
|
21122
|
-
return
|
|
21217
|
+
return path52.resolve(pkgDir, bin[target]);
|
|
21123
21218
|
} catch {
|
|
21124
21219
|
return null;
|
|
21125
21220
|
}
|
|
@@ -21194,9 +21289,9 @@ function requiresAcp(agent) {
|
|
|
21194
21289
|
var import_node_crypto7 = require("crypto");
|
|
21195
21290
|
|
|
21196
21291
|
// src/services/history.service.ts
|
|
21197
|
-
var
|
|
21198
|
-
var
|
|
21199
|
-
var
|
|
21292
|
+
var fs47 = __toESM(require("fs"));
|
|
21293
|
+
var path53 = __toESM(require("path"));
|
|
21294
|
+
var os39 = __toESM(require("os"));
|
|
21200
21295
|
var https7 = __toESM(require("https"));
|
|
21201
21296
|
var http6 = __toESM(require("http"));
|
|
21202
21297
|
var import_zod2 = require("zod");
|
|
@@ -21223,7 +21318,7 @@ function parseJsonl(filePath) {
|
|
|
21223
21318
|
const messages = [];
|
|
21224
21319
|
let raw;
|
|
21225
21320
|
try {
|
|
21226
|
-
raw =
|
|
21321
|
+
raw = fs47.readFileSync(filePath, "utf8");
|
|
21227
21322
|
} catch (err) {
|
|
21228
21323
|
if (err.code !== "ENOENT") {
|
|
21229
21324
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -21364,7 +21459,7 @@ var HistoryService = class _HistoryService {
|
|
|
21364
21459
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
21365
21460
|
}
|
|
21366
21461
|
get projectDir() {
|
|
21367
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
21462
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path53.join(os39.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
21368
21463
|
}
|
|
21369
21464
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
21370
21465
|
setCurrentConversationId(id) {
|
|
@@ -21376,7 +21471,7 @@ var HistoryService = class _HistoryService {
|
|
|
21376
21471
|
/** Return the current message count in the active conversation. */
|
|
21377
21472
|
getCurrentMessageCount() {
|
|
21378
21473
|
if (!this.currentConversationId) return 0;
|
|
21379
|
-
const filePath =
|
|
21474
|
+
const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
21380
21475
|
return parseJsonl(filePath).length;
|
|
21381
21476
|
}
|
|
21382
21477
|
/**
|
|
@@ -21387,7 +21482,7 @@ var HistoryService = class _HistoryService {
|
|
|
21387
21482
|
const deadline = Date.now() + timeoutMs;
|
|
21388
21483
|
while (Date.now() < deadline) {
|
|
21389
21484
|
if (!this.currentConversationId) return null;
|
|
21390
|
-
const filePath =
|
|
21485
|
+
const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
21391
21486
|
const messages = parseJsonl(filePath);
|
|
21392
21487
|
if (messages.length > previousCount) {
|
|
21393
21488
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -21413,16 +21508,16 @@ var HistoryService = class _HistoryService {
|
|
|
21413
21508
|
const dir = this.projectDir;
|
|
21414
21509
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
21415
21510
|
try {
|
|
21416
|
-
const files =
|
|
21511
|
+
const files = fs47.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
21417
21512
|
try {
|
|
21418
|
-
const stat3 =
|
|
21513
|
+
const stat3 = fs47.statSync(path53.join(dir, e.name));
|
|
21419
21514
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
21420
21515
|
} catch {
|
|
21421
21516
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
21422
21517
|
}
|
|
21423
21518
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
21424
21519
|
if (files.length > 0) {
|
|
21425
|
-
this.currentConversationId =
|
|
21520
|
+
this.currentConversationId = path53.basename(files[0].name, ".jsonl");
|
|
21426
21521
|
}
|
|
21427
21522
|
} catch {
|
|
21428
21523
|
}
|
|
@@ -21456,13 +21551,13 @@ var HistoryService = class _HistoryService {
|
|
|
21456
21551
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
21457
21552
|
let entries;
|
|
21458
21553
|
try {
|
|
21459
|
-
entries =
|
|
21554
|
+
entries = fs47.readdirSync(dir, { withFileTypes: true });
|
|
21460
21555
|
} catch {
|
|
21461
21556
|
return null;
|
|
21462
21557
|
}
|
|
21463
21558
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
21464
21559
|
try {
|
|
21465
|
-
const stat3 =
|
|
21560
|
+
const stat3 = fs47.statSync(path53.join(dir, e.name));
|
|
21466
21561
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
21467
21562
|
} catch {
|
|
21468
21563
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -21471,12 +21566,12 @@ var HistoryService = class _HistoryService {
|
|
|
21471
21566
|
if (files.length === 0) return null;
|
|
21472
21567
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
21473
21568
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
21474
|
-
return this.extractUsageFromFile(
|
|
21569
|
+
return this.extractUsageFromFile(path53.join(dir, targetFile));
|
|
21475
21570
|
}
|
|
21476
21571
|
extractUsageFromFile(filePath) {
|
|
21477
21572
|
let raw;
|
|
21478
21573
|
try {
|
|
21479
|
-
raw =
|
|
21574
|
+
raw = fs47.readFileSync(filePath, "utf8");
|
|
21480
21575
|
} catch {
|
|
21481
21576
|
return null;
|
|
21482
21577
|
}
|
|
@@ -21521,9 +21616,9 @@ var HistoryService = class _HistoryService {
|
|
|
21521
21616
|
let totalCost = 0;
|
|
21522
21617
|
let files;
|
|
21523
21618
|
try {
|
|
21524
|
-
files =
|
|
21619
|
+
files = fs47.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
21525
21620
|
try {
|
|
21526
|
-
return
|
|
21621
|
+
return fs47.statSync(path53.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
21527
21622
|
} catch {
|
|
21528
21623
|
return false;
|
|
21529
21624
|
}
|
|
@@ -21534,7 +21629,7 @@ var HistoryService = class _HistoryService {
|
|
|
21534
21629
|
for (const file of files) {
|
|
21535
21630
|
let raw;
|
|
21536
21631
|
try {
|
|
21537
|
-
raw =
|
|
21632
|
+
raw = fs47.readFileSync(path53.join(projectDir, file), "utf8");
|
|
21538
21633
|
} catch {
|
|
21539
21634
|
continue;
|
|
21540
21635
|
}
|
|
@@ -21613,7 +21708,7 @@ var HistoryService = class _HistoryService {
|
|
|
21613
21708
|
if (this.runtime.resolveHistoryFile) {
|
|
21614
21709
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
21615
21710
|
}
|
|
21616
|
-
return
|
|
21711
|
+
return path53.join(this.projectDir, `${sessionId}.jsonl`);
|
|
21617
21712
|
}
|
|
21618
21713
|
/**
|
|
21619
21714
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -21647,7 +21742,7 @@ var HistoryService = class _HistoryService {
|
|
|
21647
21742
|
};
|
|
21648
21743
|
});
|
|
21649
21744
|
}
|
|
21650
|
-
return parseJsonl(
|
|
21745
|
+
return parseJsonl(path53.join(this.projectDir, `${sessionId}.jsonl`));
|
|
21651
21746
|
}
|
|
21652
21747
|
async loadConversation(sessionId) {
|
|
21653
21748
|
const messages = this.readConversation(sessionId);
|
|
@@ -21703,7 +21798,7 @@ var HistoryService = class _HistoryService {
|
|
|
21703
21798
|
if (!filePath) return false;
|
|
21704
21799
|
let mtimeMs;
|
|
21705
21800
|
try {
|
|
21706
|
-
mtimeMs =
|
|
21801
|
+
mtimeMs = fs47.statSync(filePath).mtimeMs;
|
|
21707
21802
|
} catch {
|
|
21708
21803
|
return false;
|
|
21709
21804
|
}
|
|
@@ -21772,10 +21867,10 @@ var HistoryService = class _HistoryService {
|
|
|
21772
21867
|
|
|
21773
21868
|
// src/agents/acp/client.ts
|
|
21774
21869
|
var import_node_child_process17 = require("child_process");
|
|
21775
|
-
var
|
|
21870
|
+
var fs48 = __toESM(require("fs/promises"));
|
|
21776
21871
|
var fsSync = __toESM(require("fs"));
|
|
21777
|
-
var
|
|
21778
|
-
var
|
|
21872
|
+
var os40 = __toESM(require("os"));
|
|
21873
|
+
var path54 = __toESM(require("path"));
|
|
21779
21874
|
var import_node_stream = require("stream");
|
|
21780
21875
|
|
|
21781
21876
|
// ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
@@ -24608,7 +24703,7 @@ var AcpClient = class {
|
|
|
24608
24703
|
},
|
|
24609
24704
|
readTextFile: async (params) => {
|
|
24610
24705
|
try {
|
|
24611
|
-
const content = await
|
|
24706
|
+
const content = await fs48.readFile(params.path, "utf8");
|
|
24612
24707
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
24613
24708
|
} catch (err) {
|
|
24614
24709
|
const code = err.code;
|
|
@@ -24628,7 +24723,7 @@ var AcpClient = class {
|
|
|
24628
24723
|
},
|
|
24629
24724
|
writeTextFile: async (params) => {
|
|
24630
24725
|
try {
|
|
24631
|
-
await
|
|
24726
|
+
await fs48.writeFile(params.path, params.content, "utf8");
|
|
24632
24727
|
return {};
|
|
24633
24728
|
} catch (err) {
|
|
24634
24729
|
const code = err.code;
|
|
@@ -24677,25 +24772,25 @@ function applyLineRange(content, line, limit) {
|
|
|
24677
24772
|
return { content: lines.slice(start2, end).join("\n") };
|
|
24678
24773
|
}
|
|
24679
24774
|
function knownAgentBinaryDirs() {
|
|
24680
|
-
const home =
|
|
24775
|
+
const home = os40.homedir();
|
|
24681
24776
|
const out2 = [];
|
|
24682
24777
|
out2.push("/tmp/codeam-node20/bin");
|
|
24683
24778
|
for (const root of [
|
|
24684
24779
|
"/usr/local/share/nvm/versions/node",
|
|
24685
|
-
|
|
24780
|
+
path54.join(home, ".nvm/versions/node")
|
|
24686
24781
|
]) {
|
|
24687
24782
|
try {
|
|
24688
24783
|
for (const child of fsSync.readdirSync(root)) {
|
|
24689
|
-
out2.push(
|
|
24784
|
+
out2.push(path54.join(root, child, "bin"));
|
|
24690
24785
|
}
|
|
24691
24786
|
} catch {
|
|
24692
24787
|
}
|
|
24693
24788
|
}
|
|
24694
|
-
out2.push(
|
|
24789
|
+
out2.push(path54.join(home, ".volta/bin"));
|
|
24695
24790
|
out2.push("/usr/local/bin");
|
|
24696
24791
|
out2.push("/usr/bin");
|
|
24697
|
-
out2.push(
|
|
24698
|
-
out2.push(
|
|
24792
|
+
out2.push(path54.join(home, ".local/bin"));
|
|
24793
|
+
out2.push(path54.join(home, "bin"));
|
|
24699
24794
|
return out2.filter((p2) => {
|
|
24700
24795
|
try {
|
|
24701
24796
|
return fsSync.statSync(p2).isDirectory();
|
|
@@ -24706,7 +24801,7 @@ function knownAgentBinaryDirs() {
|
|
|
24706
24801
|
}
|
|
24707
24802
|
function expandPathForAgentBinaries(existingPath) {
|
|
24708
24803
|
const existing = new Set(
|
|
24709
|
-
existingPath.split(
|
|
24804
|
+
existingPath.split(path54.delimiter).filter((p2) => p2.length > 0)
|
|
24710
24805
|
);
|
|
24711
24806
|
const additions = [];
|
|
24712
24807
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -24716,7 +24811,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
24716
24811
|
}
|
|
24717
24812
|
}
|
|
24718
24813
|
if (additions.length === 0) return existingPath;
|
|
24719
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
24814
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path54.delimiter);
|
|
24720
24815
|
}
|
|
24721
24816
|
|
|
24722
24817
|
// src/services/streaming/transport.ts
|
|
@@ -25210,6 +25305,37 @@ You have two options:
|
|
|
25210
25305
|
};
|
|
25211
25306
|
}
|
|
25212
25307
|
|
|
25308
|
+
// src/agents/acp/wakeCredentialProbe.ts
|
|
25309
|
+
async function localCredentialExpiryStatus(agent) {
|
|
25310
|
+
if (!/claude/i.test(agent)) return "unknown";
|
|
25311
|
+
const token = await extractLocalClaudeToken();
|
|
25312
|
+
if (!token) return "unknown";
|
|
25313
|
+
return validateClaudeToken(token).status;
|
|
25314
|
+
}
|
|
25315
|
+
function createWakeCredentialProbe(deps) {
|
|
25316
|
+
return {
|
|
25317
|
+
run: async () => {
|
|
25318
|
+
let status2;
|
|
25319
|
+
try {
|
|
25320
|
+
status2 = await deps.getStatus();
|
|
25321
|
+
} catch {
|
|
25322
|
+
return false;
|
|
25323
|
+
}
|
|
25324
|
+
if (status2 !== "expired") return false;
|
|
25325
|
+
deps.log?.("wake credential probe \u2014 local token expired, surfacing re-auth");
|
|
25326
|
+
try {
|
|
25327
|
+
await deps.emitReauthBubble();
|
|
25328
|
+
} catch {
|
|
25329
|
+
}
|
|
25330
|
+
try {
|
|
25331
|
+
await deps.reportCredentialInvalid();
|
|
25332
|
+
} catch {
|
|
25333
|
+
}
|
|
25334
|
+
return true;
|
|
25335
|
+
}
|
|
25336
|
+
};
|
|
25337
|
+
}
|
|
25338
|
+
|
|
25213
25339
|
// src/agents/acp/reconcileDelta.ts
|
|
25214
25340
|
function reconcileCumulative(existing, incoming) {
|
|
25215
25341
|
if (incoming.length === 0) return existing;
|
|
@@ -25229,16 +25355,16 @@ function commonPrefixLength(a, b) {
|
|
|
25229
25355
|
}
|
|
25230
25356
|
|
|
25231
25357
|
// src/agents/acp/onboarding.ts
|
|
25232
|
-
var
|
|
25233
|
-
var
|
|
25234
|
-
var
|
|
25235
|
-
var
|
|
25358
|
+
var import_child_process25 = require("child_process");
|
|
25359
|
+
var fs49 = __toESM(require("fs"));
|
|
25360
|
+
var os41 = __toESM(require("os"));
|
|
25361
|
+
var path55 = __toESM(require("path"));
|
|
25236
25362
|
var _onboardingSeam = {
|
|
25237
|
-
markerPath: (sessionId) =>
|
|
25238
|
-
exists: (p2) =>
|
|
25363
|
+
markerPath: (sessionId) => path55.join(os41.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
25364
|
+
exists: (p2) => fs49.existsSync(p2),
|
|
25239
25365
|
write: (p2) => {
|
|
25240
|
-
|
|
25241
|
-
|
|
25366
|
+
fs49.mkdirSync(path55.dirname(p2), { recursive: true });
|
|
25367
|
+
fs49.writeFileSync(p2, "");
|
|
25242
25368
|
},
|
|
25243
25369
|
disabled: () => {
|
|
25244
25370
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -25250,7 +25376,7 @@ var _onboardingSeam = {
|
|
|
25250
25376
|
*/
|
|
25251
25377
|
gitRemoteUrl: (cwd) => {
|
|
25252
25378
|
try {
|
|
25253
|
-
return (0,
|
|
25379
|
+
return (0, import_child_process25.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
|
|
25254
25380
|
encoding: "utf8",
|
|
25255
25381
|
stdio: ["ignore", "pipe", "ignore"],
|
|
25256
25382
|
timeout: 2e3
|
|
@@ -25275,7 +25401,7 @@ function resolveRepoName(cwd) {
|
|
|
25275
25401
|
if (name) return name;
|
|
25276
25402
|
}
|
|
25277
25403
|
}
|
|
25278
|
-
const base =
|
|
25404
|
+
const base = path55.basename(cwd || "");
|
|
25279
25405
|
if (base && !isUuid(base)) return base;
|
|
25280
25406
|
return "this project";
|
|
25281
25407
|
}
|
|
@@ -25552,9 +25678,9 @@ function extractSelectPrompt(text) {
|
|
|
25552
25678
|
var import_crypto5 = require("crypto");
|
|
25553
25679
|
|
|
25554
25680
|
// src/services/turn-files/git-changeset.ts
|
|
25555
|
-
var
|
|
25556
|
-
var
|
|
25557
|
-
var
|
|
25681
|
+
var import_child_process26 = require("child_process");
|
|
25682
|
+
var fs50 = __toESM(require("fs/promises"));
|
|
25683
|
+
var path56 = __toESM(require("path"));
|
|
25558
25684
|
async function collectRepoChangeset(opts) {
|
|
25559
25685
|
const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
25560
25686
|
if (status2 === null) return null;
|
|
@@ -25572,7 +25698,7 @@ async function collectRepoChangeset(opts) {
|
|
|
25572
25698
|
let stats;
|
|
25573
25699
|
if (row.fileStatus === "added" && numstatEntry === void 0) {
|
|
25574
25700
|
const lineCount = await readUntrackedLineCount(
|
|
25575
|
-
|
|
25701
|
+
path56.join(opts.repoRoot, row.filePath)
|
|
25576
25702
|
);
|
|
25577
25703
|
stats = { added: lineCount, removed: 0 };
|
|
25578
25704
|
} else {
|
|
@@ -25603,7 +25729,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
25603
25729
|
}
|
|
25604
25730
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
25605
25731
|
try {
|
|
25606
|
-
const content = await
|
|
25732
|
+
const content = await fs50.readFile(absPath, "utf8");
|
|
25607
25733
|
let count = 0;
|
|
25608
25734
|
let pos = -1;
|
|
25609
25735
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -25667,7 +25793,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
25667
25793
|
return new Promise((resolve7) => {
|
|
25668
25794
|
let proc;
|
|
25669
25795
|
try {
|
|
25670
|
-
proc = (0,
|
|
25796
|
+
proc = (0, import_child_process26.spawn)("git", args2, { cwd, env: process.env });
|
|
25671
25797
|
} catch {
|
|
25672
25798
|
resolve7(null);
|
|
25673
25799
|
return;
|
|
@@ -25695,7 +25821,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
25695
25821
|
});
|
|
25696
25822
|
}
|
|
25697
25823
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
25698
|
-
const
|
|
25824
|
+
const fs54 = await import("fs/promises");
|
|
25699
25825
|
const out2 = [];
|
|
25700
25826
|
await walk(workingDir, 0);
|
|
25701
25827
|
return out2;
|
|
@@ -25703,7 +25829,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25703
25829
|
if (depth > maxDepth) return;
|
|
25704
25830
|
let entries = [];
|
|
25705
25831
|
try {
|
|
25706
|
-
const dirents = await
|
|
25832
|
+
const dirents = await fs54.readdir(dir, { withFileTypes: true });
|
|
25707
25833
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
25708
25834
|
} catch {
|
|
25709
25835
|
return;
|
|
@@ -25714,8 +25840,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25714
25840
|
if (hasGit) {
|
|
25715
25841
|
out2.push({
|
|
25716
25842
|
repoRoot: dir,
|
|
25717
|
-
repoPath:
|
|
25718
|
-
repoName:
|
|
25843
|
+
repoPath: path56.relative(workingDir, dir),
|
|
25844
|
+
repoName: path56.basename(dir)
|
|
25719
25845
|
});
|
|
25720
25846
|
return;
|
|
25721
25847
|
}
|
|
@@ -25723,14 +25849,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
25723
25849
|
if (!entry.isDirectory) continue;
|
|
25724
25850
|
if (entry.name === "node_modules") continue;
|
|
25725
25851
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
25726
|
-
await walk(
|
|
25852
|
+
await walk(path56.join(dir, entry.name), depth + 1);
|
|
25727
25853
|
}
|
|
25728
25854
|
}
|
|
25729
25855
|
}
|
|
25730
25856
|
|
|
25731
25857
|
// src/services/turn-files/files-outbox.ts
|
|
25732
|
-
var
|
|
25733
|
-
var
|
|
25858
|
+
var fs51 = __toESM(require("fs/promises"));
|
|
25859
|
+
var path57 = __toESM(require("path"));
|
|
25734
25860
|
var import_os7 = require("os");
|
|
25735
25861
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
25736
25862
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -25763,16 +25889,16 @@ var FilesOutbox = class {
|
|
|
25763
25889
|
backoffIndex = 0;
|
|
25764
25890
|
stopped = false;
|
|
25765
25891
|
constructor(opts) {
|
|
25766
|
-
const base = opts.baseDir ??
|
|
25767
|
-
this.filePath =
|
|
25892
|
+
const base = opts.baseDir ?? path57.join(homeDir(), HOME_OUTBOX_DIR);
|
|
25893
|
+
this.filePath = path57.join(base, `${opts.sessionId}.jsonl`);
|
|
25768
25894
|
this.post = opts.post;
|
|
25769
25895
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
25770
25896
|
}
|
|
25771
25897
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
25772
25898
|
* line is durable on disk (not once the POST succeeds). */
|
|
25773
25899
|
async enqueue(entry) {
|
|
25774
|
-
await
|
|
25775
|
-
await
|
|
25900
|
+
await fs51.mkdir(path57.dirname(this.filePath), { recursive: true });
|
|
25901
|
+
await fs51.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
25776
25902
|
this.backoffIndex = 0;
|
|
25777
25903
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
25778
25904
|
}
|
|
@@ -25861,7 +25987,7 @@ var FilesOutbox = class {
|
|
|
25861
25987
|
async readAll() {
|
|
25862
25988
|
let raw = "";
|
|
25863
25989
|
try {
|
|
25864
|
-
raw = await
|
|
25990
|
+
raw = await fs51.readFile(this.filePath, "utf8");
|
|
25865
25991
|
} catch {
|
|
25866
25992
|
return [];
|
|
25867
25993
|
}
|
|
@@ -25885,12 +26011,12 @@ var FilesOutbox = class {
|
|
|
25885
26011
|
async rewrite(entries) {
|
|
25886
26012
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
25887
26013
|
if (entries.length === 0) {
|
|
25888
|
-
await
|
|
26014
|
+
await fs51.unlink(this.filePath).catch(() => void 0);
|
|
25889
26015
|
return;
|
|
25890
26016
|
}
|
|
25891
26017
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
25892
|
-
await
|
|
25893
|
-
await
|
|
26018
|
+
await fs51.writeFile(tmpPath, payload, "utf8");
|
|
26019
|
+
await fs51.rename(tmpPath, this.filePath);
|
|
25894
26020
|
}
|
|
25895
26021
|
};
|
|
25896
26022
|
function applyJitter(ms) {
|
|
@@ -26876,9 +27002,9 @@ async function runAcpSession(opts) {
|
|
|
26876
27002
|
});
|
|
26877
27003
|
let _budgetReachedPosted = false;
|
|
26878
27004
|
const relaunchProxyWithoutBudget = async () => {
|
|
26879
|
-
const { spawn:
|
|
27005
|
+
const { spawn: spawn34 } = await import("child_process");
|
|
26880
27006
|
try {
|
|
26881
|
-
const killer =
|
|
27007
|
+
const killer = spawn34("pkill", ["-TERM", "-f", "headroom.*proxy"], {
|
|
26882
27008
|
detached: true,
|
|
26883
27009
|
stdio: "ignore"
|
|
26884
27010
|
});
|
|
@@ -26890,7 +27016,7 @@ async function runAcpSession(opts) {
|
|
|
26890
27016
|
await new Promise((r) => setTimeout(r, 500));
|
|
26891
27017
|
const proxyEnv = buildRelaunchProxyEnv(process.env);
|
|
26892
27018
|
try {
|
|
26893
|
-
const proxy =
|
|
27019
|
+
const proxy = spawn34(
|
|
26894
27020
|
"headroom",
|
|
26895
27021
|
["proxy", "--port", "8787"],
|
|
26896
27022
|
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
@@ -27046,6 +27172,17 @@ async function runAcpSession(opts) {
|
|
|
27046
27172
|
);
|
|
27047
27173
|
await onboardingWelcomeDone;
|
|
27048
27174
|
relay.start();
|
|
27175
|
+
void createWakeCredentialProbe({
|
|
27176
|
+
getStatus: () => localCredentialExpiryStatus(opts.agent),
|
|
27177
|
+
emitReauthBubble: async () => {
|
|
27178
|
+
await publisher.publishOutput({ type: "new_turn", done: false });
|
|
27179
|
+
await publisher.publishOutput({ type: "text", content: AUTH_FAILURE_MESSAGE, done: true });
|
|
27180
|
+
history.appendAgentInitiatedReply(AUTH_FAILURE_MESSAGE);
|
|
27181
|
+
await history.flush();
|
|
27182
|
+
},
|
|
27183
|
+
reportCredentialInvalid: () => reportCredentialInvalid(opts),
|
|
27184
|
+
log: (msg) => showInfo(msg)
|
|
27185
|
+
}).run();
|
|
27049
27186
|
const prewarmTimer = setTimeout(() => prewarmPreviewDetection(runtime), 2e4);
|
|
27050
27187
|
const shutdown = async (signal) => {
|
|
27051
27188
|
showInfo(`Shutting down ACP session (${signal})\u2026`);
|
|
@@ -28527,15 +28664,15 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
28527
28664
|
}
|
|
28528
28665
|
|
|
28529
28666
|
// src/agents/claude/onboarding.ts
|
|
28530
|
-
var
|
|
28531
|
-
var
|
|
28532
|
-
var
|
|
28667
|
+
var fs52 = __toESM(require("fs"));
|
|
28668
|
+
var os42 = __toESM(require("os"));
|
|
28669
|
+
var path58 = __toESM(require("path"));
|
|
28533
28670
|
function ensureClaudeOnboarded() {
|
|
28534
28671
|
try {
|
|
28535
|
-
const file =
|
|
28672
|
+
const file = path58.join(os42.homedir(), ".claude.json");
|
|
28536
28673
|
let config = {};
|
|
28537
28674
|
try {
|
|
28538
|
-
config = JSON.parse(
|
|
28675
|
+
config = JSON.parse(fs52.readFileSync(file, "utf8"));
|
|
28539
28676
|
} catch {
|
|
28540
28677
|
}
|
|
28541
28678
|
if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
|
|
@@ -28546,8 +28683,8 @@ function ensureClaudeOnboarded() {
|
|
|
28546
28683
|
if (typeof config.lastOnboardingVersion !== "string") {
|
|
28547
28684
|
config.lastOnboardingVersion = "2.1.177";
|
|
28548
28685
|
}
|
|
28549
|
-
|
|
28550
|
-
|
|
28686
|
+
fs52.mkdirSync(path58.dirname(file), { recursive: true });
|
|
28687
|
+
fs52.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
28551
28688
|
log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
|
|
28552
28689
|
} catch (err) {
|
|
28553
28690
|
log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
|
|
@@ -29195,11 +29332,11 @@ async function logout() {
|
|
|
29195
29332
|
var import_picocolors11 = __toESM(require("picocolors"));
|
|
29196
29333
|
|
|
29197
29334
|
// src/services/providers/github-codespaces.ts
|
|
29198
|
-
var
|
|
29335
|
+
var import_child_process27 = require("child_process");
|
|
29199
29336
|
var import_util4 = require("util");
|
|
29200
29337
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
29201
|
-
var
|
|
29202
|
-
var execFileP6 = (0, import_util4.promisify)(
|
|
29338
|
+
var path59 = __toESM(require("path"));
|
|
29339
|
+
var execFileP6 = (0, import_util4.promisify)(import_child_process27.execFile);
|
|
29203
29340
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
29204
29341
|
function resetStdinForChild() {
|
|
29205
29342
|
if (process.stdin.isTTY) {
|
|
@@ -29243,7 +29380,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29243
29380
|
if (!isAuthed) {
|
|
29244
29381
|
resetStdinForChild();
|
|
29245
29382
|
await new Promise((resolve7, reject) => {
|
|
29246
|
-
const proc = (0,
|
|
29383
|
+
const proc = (0, import_child_process27.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
|
|
29247
29384
|
stdio: "inherit"
|
|
29248
29385
|
});
|
|
29249
29386
|
proc.on("exit", (code) => {
|
|
@@ -29277,7 +29414,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29277
29414
|
wt(noteLines.join("\n"), "One more permission needed");
|
|
29278
29415
|
resetStdinForChild();
|
|
29279
29416
|
const refreshCode = await new Promise((resolve7, reject) => {
|
|
29280
|
-
const proc = (0,
|
|
29417
|
+
const proc = (0, import_child_process27.spawn)(
|
|
29281
29418
|
"gh",
|
|
29282
29419
|
["auth", "refresh", "-h", "github.com", "-s", "codespace"],
|
|
29283
29420
|
{ stdio: "inherit" }
|
|
@@ -29427,7 +29564,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29427
29564
|
O2.step(`Installing gh via ${installCmd.describe}\u2026`);
|
|
29428
29565
|
resetStdinForChild();
|
|
29429
29566
|
const ok = await new Promise((resolve7) => {
|
|
29430
|
-
const proc = (0,
|
|
29567
|
+
const proc = (0, import_child_process27.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
|
|
29431
29568
|
proc.on("exit", (code) => resolve7(code === 0));
|
|
29432
29569
|
proc.on("error", () => resolve7(false));
|
|
29433
29570
|
});
|
|
@@ -29454,7 +29591,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29454
29591
|
);
|
|
29455
29592
|
resetStdinForChild();
|
|
29456
29593
|
await new Promise((resolve7, reject) => {
|
|
29457
|
-
const proc = (0,
|
|
29594
|
+
const proc = (0, import_child_process27.spawn)(
|
|
29458
29595
|
"gh",
|
|
29459
29596
|
["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
|
|
29460
29597
|
{ stdio: "inherit" }
|
|
@@ -29632,7 +29769,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29632
29769
|
async streamCommand(workspaceId, command2) {
|
|
29633
29770
|
resetStdinForChild();
|
|
29634
29771
|
return new Promise((resolve7, reject) => {
|
|
29635
|
-
const proc = (0,
|
|
29772
|
+
const proc = (0, import_child_process27.spawn)(
|
|
29636
29773
|
"gh",
|
|
29637
29774
|
["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
|
|
29638
29775
|
{ stdio: "inherit" }
|
|
@@ -29659,11 +29796,11 @@ var GitHubCodespacesProvider = class {
|
|
|
29659
29796
|
`mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
|
|
29660
29797
|
];
|
|
29661
29798
|
await new Promise((resolve7, reject) => {
|
|
29662
|
-
const tar = (0,
|
|
29799
|
+
const tar = (0, import_child_process27.spawn)("tar", tarArgs, {
|
|
29663
29800
|
stdio: ["ignore", "pipe", "pipe"],
|
|
29664
29801
|
env: tarEnv
|
|
29665
29802
|
});
|
|
29666
|
-
const ssh = (0,
|
|
29803
|
+
const ssh = (0, import_child_process27.spawn)("gh", sshArgs, {
|
|
29667
29804
|
stdio: [tar.stdout, "pipe", "pipe"]
|
|
29668
29805
|
});
|
|
29669
29806
|
let tarErr = "";
|
|
@@ -29687,7 +29824,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29687
29824
|
});
|
|
29688
29825
|
}
|
|
29689
29826
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
29690
|
-
const remoteDir =
|
|
29827
|
+
const remoteDir = path59.posix.dirname(remotePath);
|
|
29691
29828
|
const parts = [
|
|
29692
29829
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
29693
29830
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -29697,7 +29834,7 @@ var GitHubCodespacesProvider = class {
|
|
|
29697
29834
|
}
|
|
29698
29835
|
const cmd = parts.join(" && ");
|
|
29699
29836
|
await new Promise((resolve7, reject) => {
|
|
29700
|
-
const proc = (0,
|
|
29837
|
+
const proc = (0, import_child_process27.spawn)(
|
|
29701
29838
|
"gh",
|
|
29702
29839
|
["codespace", "ssh", "-c", workspaceId, "--", cmd],
|
|
29703
29840
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -29755,11 +29892,11 @@ function shellQuote(s) {
|
|
|
29755
29892
|
}
|
|
29756
29893
|
|
|
29757
29894
|
// src/services/providers/gitpod.ts
|
|
29758
|
-
var
|
|
29895
|
+
var import_child_process28 = require("child_process");
|
|
29759
29896
|
var import_util5 = require("util");
|
|
29760
|
-
var
|
|
29897
|
+
var path60 = __toESM(require("path"));
|
|
29761
29898
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
29762
|
-
var execFileP7 = (0, import_util5.promisify)(
|
|
29899
|
+
var execFileP7 = (0, import_util5.promisify)(import_child_process28.execFile);
|
|
29763
29900
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
29764
29901
|
function resetStdinForChild2() {
|
|
29765
29902
|
if (process.stdin.isTTY) {
|
|
@@ -29799,7 +29936,7 @@ var GitpodProvider = class {
|
|
|
29799
29936
|
);
|
|
29800
29937
|
resetStdinForChild2();
|
|
29801
29938
|
await new Promise((resolve7, reject) => {
|
|
29802
|
-
const proc = (0,
|
|
29939
|
+
const proc = (0, import_child_process28.spawn)("gitpod", ["login"], { stdio: "inherit" });
|
|
29803
29940
|
proc.on("exit", (code) => {
|
|
29804
29941
|
if (code === 0) resolve7();
|
|
29805
29942
|
else reject(new Error("gitpod login failed."));
|
|
@@ -29951,7 +30088,7 @@ var GitpodProvider = class {
|
|
|
29951
30088
|
async streamCommand(workspaceId, command2) {
|
|
29952
30089
|
resetStdinForChild2();
|
|
29953
30090
|
return new Promise((resolve7, reject) => {
|
|
29954
|
-
const proc = (0,
|
|
30091
|
+
const proc = (0, import_child_process28.spawn)(
|
|
29955
30092
|
"gitpod",
|
|
29956
30093
|
["workspace", "ssh", workspaceId, "--", "-tt", command2],
|
|
29957
30094
|
{ stdio: "inherit" }
|
|
@@ -29971,11 +30108,11 @@ var GitpodProvider = class {
|
|
|
29971
30108
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
29972
30109
|
const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
|
|
29973
30110
|
await new Promise((resolve7, reject) => {
|
|
29974
|
-
const tar = (0,
|
|
30111
|
+
const tar = (0, import_child_process28.spawn)("tar", tarArgs, {
|
|
29975
30112
|
stdio: ["ignore", "pipe", "pipe"],
|
|
29976
30113
|
env: tarEnv
|
|
29977
30114
|
});
|
|
29978
|
-
const ssh = (0,
|
|
30115
|
+
const ssh = (0, import_child_process28.spawn)(
|
|
29979
30116
|
"gitpod",
|
|
29980
30117
|
["workspace", "ssh", workspaceId, "--", remoteCmd],
|
|
29981
30118
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -29997,7 +30134,7 @@ var GitpodProvider = class {
|
|
|
29997
30134
|
});
|
|
29998
30135
|
}
|
|
29999
30136
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
30000
|
-
const remoteDir =
|
|
30137
|
+
const remoteDir = path60.posix.dirname(remotePath);
|
|
30001
30138
|
const parts = [
|
|
30002
30139
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
30003
30140
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -30007,7 +30144,7 @@ var GitpodProvider = class {
|
|
|
30007
30144
|
}
|
|
30008
30145
|
const cmd = parts.join(" && ");
|
|
30009
30146
|
await new Promise((resolve7, reject) => {
|
|
30010
|
-
const proc = (0,
|
|
30147
|
+
const proc = (0, import_child_process28.spawn)(
|
|
30011
30148
|
"gitpod",
|
|
30012
30149
|
["workspace", "ssh", workspaceId, "--", cmd],
|
|
30013
30150
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -30031,10 +30168,10 @@ function shellQuote2(s) {
|
|
|
30031
30168
|
}
|
|
30032
30169
|
|
|
30033
30170
|
// src/services/providers/gitlab-workspaces.ts
|
|
30034
|
-
var
|
|
30171
|
+
var import_child_process29 = require("child_process");
|
|
30035
30172
|
var import_util6 = require("util");
|
|
30036
|
-
var
|
|
30037
|
-
var execFileP8 = (0, import_util6.promisify)(
|
|
30173
|
+
var path61 = __toESM(require("path"));
|
|
30174
|
+
var execFileP8 = (0, import_util6.promisify)(import_child_process29.execFile);
|
|
30038
30175
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
30039
30176
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
30040
30177
|
function resetStdinForChild3() {
|
|
@@ -30076,7 +30213,7 @@ var GitLabWorkspacesProvider = class {
|
|
|
30076
30213
|
);
|
|
30077
30214
|
resetStdinForChild3();
|
|
30078
30215
|
await new Promise((resolve7, reject) => {
|
|
30079
|
-
const proc = (0,
|
|
30216
|
+
const proc = (0, import_child_process29.spawn)(
|
|
30080
30217
|
"glab",
|
|
30081
30218
|
["auth", "login", "--scopes", "api,read_user,read_repository"],
|
|
30082
30219
|
{ stdio: "inherit" }
|
|
@@ -30248,7 +30385,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
30248
30385
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
30249
30386
|
resetStdinForChild3();
|
|
30250
30387
|
return new Promise((resolve7, reject) => {
|
|
30251
|
-
const proc = (0,
|
|
30388
|
+
const proc = (0, import_child_process29.spawn)(
|
|
30252
30389
|
"ssh",
|
|
30253
30390
|
["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
|
|
30254
30391
|
{ stdio: "inherit" }
|
|
@@ -30269,8 +30406,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
30269
30406
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
30270
30407
|
const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
|
|
30271
30408
|
await new Promise((resolve7, reject) => {
|
|
30272
|
-
const tar = (0,
|
|
30273
|
-
const ssh = (0,
|
|
30409
|
+
const tar = (0, import_child_process29.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
30410
|
+
const ssh = (0, import_child_process29.spawn)(
|
|
30274
30411
|
"ssh",
|
|
30275
30412
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
|
|
30276
30413
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -30293,14 +30430,14 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
30293
30430
|
}
|
|
30294
30431
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
30295
30432
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
30296
|
-
const remoteDir =
|
|
30433
|
+
const remoteDir = path61.posix.dirname(remotePath);
|
|
30297
30434
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
30298
30435
|
if (options.mode != null) {
|
|
30299
30436
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
30300
30437
|
}
|
|
30301
30438
|
const cmd = parts.join(" && ");
|
|
30302
30439
|
await new Promise((resolve7, reject) => {
|
|
30303
|
-
const proc = (0,
|
|
30440
|
+
const proc = (0, import_child_process29.spawn)(
|
|
30304
30441
|
"ssh",
|
|
30305
30442
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
|
|
30306
30443
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -30359,10 +30496,10 @@ function shellQuote3(s) {
|
|
|
30359
30496
|
}
|
|
30360
30497
|
|
|
30361
30498
|
// src/services/providers/railway.ts
|
|
30362
|
-
var
|
|
30499
|
+
var import_child_process30 = require("child_process");
|
|
30363
30500
|
var import_util7 = require("util");
|
|
30364
|
-
var
|
|
30365
|
-
var execFileP9 = (0, import_util7.promisify)(
|
|
30501
|
+
var path62 = __toESM(require("path"));
|
|
30502
|
+
var execFileP9 = (0, import_util7.promisify)(import_child_process30.execFile);
|
|
30366
30503
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
30367
30504
|
function resetStdinForChild4() {
|
|
30368
30505
|
if (process.stdin.isTTY) {
|
|
@@ -30403,7 +30540,7 @@ var RailwayProvider = class {
|
|
|
30403
30540
|
);
|
|
30404
30541
|
resetStdinForChild4();
|
|
30405
30542
|
await new Promise((resolve7, reject) => {
|
|
30406
|
-
const proc = (0,
|
|
30543
|
+
const proc = (0, import_child_process30.spawn)("railway", ["login"], { stdio: "inherit" });
|
|
30407
30544
|
proc.on("exit", (code) => {
|
|
30408
30545
|
if (code === 0) resolve7();
|
|
30409
30546
|
else reject(new Error("railway login failed."));
|
|
@@ -30546,7 +30683,7 @@ var RailwayProvider = class {
|
|
|
30546
30683
|
}
|
|
30547
30684
|
resetStdinForChild4();
|
|
30548
30685
|
return new Promise((resolve7, reject) => {
|
|
30549
|
-
const proc = (0,
|
|
30686
|
+
const proc = (0, import_child_process30.spawn)(
|
|
30550
30687
|
"railway",
|
|
30551
30688
|
["shell", "--project", projectId, "--service", serviceId, "--command", command2],
|
|
30552
30689
|
{ stdio: "inherit" }
|
|
@@ -30570,8 +30707,8 @@ var RailwayProvider = class {
|
|
|
30570
30707
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
30571
30708
|
const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
|
|
30572
30709
|
await new Promise((resolve7, reject) => {
|
|
30573
|
-
const tar = (0,
|
|
30574
|
-
const sh = (0,
|
|
30710
|
+
const tar = (0, import_child_process30.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
30711
|
+
const sh = (0, import_child_process30.spawn)(
|
|
30575
30712
|
"railway",
|
|
30576
30713
|
["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
|
|
30577
30714
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -30597,14 +30734,14 @@ var RailwayProvider = class {
|
|
|
30597
30734
|
if (!projectId || !serviceId) {
|
|
30598
30735
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
30599
30736
|
}
|
|
30600
|
-
const remoteDir =
|
|
30737
|
+
const remoteDir = path62.posix.dirname(remotePath);
|
|
30601
30738
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
30602
30739
|
if (options.mode != null) {
|
|
30603
30740
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
30604
30741
|
}
|
|
30605
30742
|
const cmd = parts.join(" && ");
|
|
30606
30743
|
await new Promise((resolve7, reject) => {
|
|
30607
|
-
const proc = (0,
|
|
30744
|
+
const proc = (0, import_child_process30.spawn)(
|
|
30608
30745
|
"railway",
|
|
30609
30746
|
["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
|
|
30610
30747
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -31243,8 +31380,8 @@ async function invite() {
|
|
|
31243
31380
|
var import_node_dns = require("dns");
|
|
31244
31381
|
var import_node_util5 = require("util");
|
|
31245
31382
|
var import_node_crypto8 = require("crypto");
|
|
31246
|
-
var
|
|
31247
|
-
var
|
|
31383
|
+
var fs53 = __toESM(require("fs"));
|
|
31384
|
+
var path63 = __toESM(require("path"));
|
|
31248
31385
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
31249
31386
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
31250
31387
|
async function checkDns(apiBase2) {
|
|
@@ -31300,13 +31437,13 @@ async function checkHealth(apiBase2) {
|
|
|
31300
31437
|
}
|
|
31301
31438
|
}
|
|
31302
31439
|
function checkConfigDir() {
|
|
31303
|
-
const dir =
|
|
31440
|
+
const dir = path63.join(require("os").homedir(), ".codeam");
|
|
31304
31441
|
try {
|
|
31305
|
-
|
|
31306
|
-
const probe =
|
|
31307
|
-
|
|
31308
|
-
const read2 =
|
|
31309
|
-
|
|
31442
|
+
fs53.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
31443
|
+
const probe = path63.join(dir, ".doctor-probe");
|
|
31444
|
+
fs53.writeFileSync(probe, "ok", { mode: 384 });
|
|
31445
|
+
const read2 = fs53.readFileSync(probe, "utf8");
|
|
31446
|
+
fs53.unlinkSync(probe);
|
|
31310
31447
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
31311
31448
|
return {
|
|
31312
31449
|
id: "config-dir",
|
|
@@ -31346,9 +31483,9 @@ function checkSessions() {
|
|
|
31346
31483
|
}
|
|
31347
31484
|
}
|
|
31348
31485
|
function checkAgentBinaries() {
|
|
31349
|
-
const
|
|
31486
|
+
const os44 = createOsStrategy();
|
|
31350
31487
|
return getEnabledAgents().map((meta) => {
|
|
31351
|
-
const found =
|
|
31488
|
+
const found = os44.findInPath(meta.binaryName);
|
|
31352
31489
|
return {
|
|
31353
31490
|
id: `agent-${meta.id}`,
|
|
31354
31491
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -31370,7 +31507,7 @@ function checkNodePty() {
|
|
|
31370
31507
|
detail: "not required on this platform"
|
|
31371
31508
|
};
|
|
31372
31509
|
}
|
|
31373
|
-
const vendoredPath =
|
|
31510
|
+
const vendoredPath = path63.join(__dirname, "vendor", "node-pty");
|
|
31374
31511
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
31375
31512
|
try {
|
|
31376
31513
|
require(target);
|
|
@@ -31412,7 +31549,7 @@ function checkChokidar() {
|
|
|
31412
31549
|
}
|
|
31413
31550
|
async function doctor(args2 = []) {
|
|
31414
31551
|
const json = args2.includes("--json");
|
|
31415
|
-
const cliVersion = true ? "2.
|
|
31552
|
+
const cliVersion = true ? "2.53.0" : "0.0.0-dev";
|
|
31416
31553
|
const apiBase2 = resolveApiBaseUrl();
|
|
31417
31554
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
31418
31555
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -31611,7 +31748,7 @@ async function completion(args2) {
|
|
|
31611
31748
|
// src/commands/version.ts
|
|
31612
31749
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
31613
31750
|
function version2() {
|
|
31614
|
-
const v = true ? "2.
|
|
31751
|
+
const v = true ? "2.53.0" : "unknown";
|
|
31615
31752
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
31616
31753
|
}
|
|
31617
31754
|
|
|
@@ -31760,10 +31897,10 @@ var EXIT_CODE_NAMES = {
|
|
|
31760
31897
|
};
|
|
31761
31898
|
|
|
31762
31899
|
// src/index.ts
|
|
31763
|
-
var
|
|
31900
|
+
var os43 = __toESM(require("os"));
|
|
31764
31901
|
if (!process.env.HOME) {
|
|
31765
31902
|
try {
|
|
31766
|
-
const home =
|
|
31903
|
+
const home = os43.homedir();
|
|
31767
31904
|
if (home) process.env.HOME = home;
|
|
31768
31905
|
} catch {
|
|
31769
31906
|
}
|