codeam-cli 2.75.23 → 2.75.26
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 +13 -0
- package/dist/index.js +1232 -507
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -357,8 +357,8 @@ function defaultSpawn(timeoutMs) {
|
|
|
357
357
|
});
|
|
358
358
|
}
|
|
359
359
|
function resolveConvexBin(cwd) {
|
|
360
|
-
const local =
|
|
361
|
-
if (
|
|
360
|
+
const local = path94.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
|
|
361
|
+
if (fs80.existsSync(local)) return { cmd: local, args: [] };
|
|
362
362
|
return { cmd: "npx", args: ["--yes", "convex"] };
|
|
363
363
|
}
|
|
364
364
|
function redact(text, key) {
|
|
@@ -489,13 +489,13 @@ async function runConvexAdminMcp(client3, id) {
|
|
|
489
489
|
});
|
|
490
490
|
await server.connect(new StdioServerTransport());
|
|
491
491
|
}
|
|
492
|
-
var import_node_child_process32,
|
|
492
|
+
var import_node_child_process32, fs80, path94, TOOLS;
|
|
493
493
|
var init_convex_admin_mcp = __esm({
|
|
494
494
|
"src/integrations/convex-admin-mcp.ts"() {
|
|
495
495
|
"use strict";
|
|
496
496
|
import_node_child_process32 = require("child_process");
|
|
497
|
-
|
|
498
|
-
|
|
497
|
+
fs80 = __toESM(require("fs"));
|
|
498
|
+
path94 = __toESM(require("path"));
|
|
499
499
|
TOOLS = [
|
|
500
500
|
{
|
|
501
501
|
name: "tables",
|
|
@@ -3248,6 +3248,9 @@ var USER_EVENTS = {
|
|
|
3248
3248
|
PREVIEW_STOPPED: "preview_stopped",
|
|
3249
3249
|
PREVIEW_ERROR: "preview_error",
|
|
3250
3250
|
PREVIEW_PROGRESS: "preview_progress",
|
|
3251
|
+
/** The agent points at an element of the running preview (`highlight_element`
|
|
3252
|
+
* MCP tool) — the inspector client draws the agent's mark over it. */
|
|
3253
|
+
PREVIEW_AGENT_HIGHLIGHT: "preview_agent_highlight",
|
|
3251
3254
|
BEADS_STATE_CHANGED: "beads_state_changed",
|
|
3252
3255
|
BEADS_PROVISIONING: "beads_provisioning",
|
|
3253
3256
|
BEADS_TEAM_MEMORY_CHANGED: "beads_team_memory_changed",
|
|
@@ -3525,11 +3528,11 @@ function quiet(fn) {
|
|
|
3525
3528
|
log.debug(TAG, "ignored sync error", err);
|
|
3526
3529
|
}
|
|
3527
3530
|
}
|
|
3528
|
-
function rmIfExistsQuiet(
|
|
3531
|
+
function rmIfExistsQuiet(path96) {
|
|
3529
3532
|
try {
|
|
3530
|
-
fs2.rmSync(
|
|
3533
|
+
fs2.rmSync(path96, { force: true });
|
|
3531
3534
|
} catch (err) {
|
|
3532
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
3535
|
+
log.debug(TAG, `rmIfExists failed for ${path96}`, err);
|
|
3533
3536
|
}
|
|
3534
3537
|
}
|
|
3535
3538
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -3695,9 +3698,9 @@ var _default = makeConfig();
|
|
|
3695
3698
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
3696
3699
|
|
|
3697
3700
|
// src/commands/pair-auto.ts
|
|
3698
|
-
var
|
|
3701
|
+
var fs52 = __toESM(require("fs"));
|
|
3699
3702
|
var os40 = __toESM(require("os"));
|
|
3700
|
-
var
|
|
3703
|
+
var path60 = __toESM(require("path"));
|
|
3701
3704
|
var import_crypto3 = require("crypto");
|
|
3702
3705
|
|
|
3703
3706
|
// src/services/telemetry.service.ts
|
|
@@ -3733,8 +3736,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
3733
3736
|
return decodedFile;
|
|
3734
3737
|
};
|
|
3735
3738
|
}
|
|
3736
|
-
function normalizeWindowsPath(
|
|
3737
|
-
return
|
|
3739
|
+
function normalizeWindowsPath(path96) {
|
|
3740
|
+
return path96.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
3738
3741
|
}
|
|
3739
3742
|
|
|
3740
3743
|
// ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
|
|
@@ -6467,13 +6470,13 @@ var PostHogCoreStateless = class {
|
|
|
6467
6470
|
sentFromRoute += batchMessages.length;
|
|
6468
6471
|
}
|
|
6469
6472
|
}
|
|
6470
|
-
async _sendOtlpBatch({ path:
|
|
6473
|
+
async _sendOtlpBatch({ path: path96, payload }) {
|
|
6471
6474
|
if (this.disabled) return {
|
|
6472
6475
|
kind: "fatal",
|
|
6473
6476
|
error: new Error("The client is disabled")
|
|
6474
6477
|
};
|
|
6475
6478
|
const serialized = JSON.stringify(payload);
|
|
6476
|
-
const url2 = `${this.host}/i/v1/${
|
|
6479
|
+
const url2 = `${this.host}/i/v1/${path96}?token=${encodeURIComponent(this.apiKey)}`;
|
|
6477
6480
|
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
|
|
6478
6481
|
const fetchOptions = {
|
|
6479
6482
|
method: "POST",
|
|
@@ -7713,14 +7716,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
|
|
|
7713
7716
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
7714
7717
|
return frames;
|
|
7715
7718
|
}
|
|
7716
|
-
async function openRegularSourceFile(
|
|
7719
|
+
async function openRegularSourceFile(path96, openSourceFile, logger) {
|
|
7717
7720
|
let fileHandle;
|
|
7718
7721
|
let isValid = false;
|
|
7719
7722
|
try {
|
|
7720
|
-
fileHandle = await openSourceFile(
|
|
7723
|
+
fileHandle = await openSourceFile(path96, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
|
|
7721
7724
|
const fileStat = await fileHandle.stat();
|
|
7722
7725
|
if (!fileStat.isFile()) return;
|
|
7723
|
-
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${
|
|
7726
|
+
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path96}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
|
|
7724
7727
|
isValid = true;
|
|
7725
7728
|
return fileHandle;
|
|
7726
7729
|
} catch {
|
|
@@ -7730,8 +7733,8 @@ async function openRegularSourceFile(path95, openSourceFile, logger) {
|
|
|
7730
7733
|
});
|
|
7731
7734
|
}
|
|
7732
7735
|
}
|
|
7733
|
-
async function getContextLinesFromFile(
|
|
7734
|
-
const fileHandle = await openRegularSourceFile(
|
|
7736
|
+
async function getContextLinesFromFile(path96, ranges, output, cacheKey, openSourceFile, logger) {
|
|
7737
|
+
const fileHandle = await openRegularSourceFile(path96, openSourceFile, logger);
|
|
7735
7738
|
if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
7736
7739
|
const openedFileHandle = fileHandle;
|
|
7737
7740
|
return new Promise((resolve12) => {
|
|
@@ -7833,22 +7836,22 @@ function clearLineContext(frame) {
|
|
|
7833
7836
|
delete frame.context_line;
|
|
7834
7837
|
delete frame.post_context;
|
|
7835
7838
|
}
|
|
7836
|
-
function shouldSkipContextLinesForFile(
|
|
7837
|
-
return
|
|
7839
|
+
function shouldSkipContextLinesForFile(path96) {
|
|
7840
|
+
return path96.startsWith("node:") || path96.endsWith(".min.js") || path96.endsWith(".min.cjs") || path96.endsWith(".min.mjs") || path96.startsWith("data:");
|
|
7838
7841
|
}
|
|
7839
7842
|
function shouldSkipContextLinesForFrame(frame) {
|
|
7840
7843
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
7841
7844
|
if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
|
|
7842
7845
|
return false;
|
|
7843
7846
|
}
|
|
7844
|
-
function makeSourceCacheKey(
|
|
7845
|
-
if ((0, import_node_path.isAbsolute)(
|
|
7847
|
+
function makeSourceCacheKey(path96, basePath) {
|
|
7848
|
+
if ((0, import_node_path.isAbsolute)(path96)) return JSON.stringify([
|
|
7846
7849
|
null,
|
|
7847
|
-
|
|
7850
|
+
path96
|
|
7848
7851
|
]);
|
|
7849
7852
|
return void 0 === basePath ? void 0 : JSON.stringify([
|
|
7850
7853
|
basePath,
|
|
7851
|
-
|
|
7854
|
+
path96
|
|
7852
7855
|
]);
|
|
7853
7856
|
}
|
|
7854
7857
|
function rangeExistsInContentCache(cacheKey, range) {
|
|
@@ -10509,7 +10512,7 @@ function readAnonId() {
|
|
|
10509
10512
|
}
|
|
10510
10513
|
function superProperties() {
|
|
10511
10514
|
return {
|
|
10512
|
-
cliVersion: true ? "2.75.
|
|
10515
|
+
cliVersion: true ? "2.75.26" : "0.0.0-dev",
|
|
10513
10516
|
nodeVersion: process.version,
|
|
10514
10517
|
platform: process.platform,
|
|
10515
10518
|
arch: process.arch,
|
|
@@ -10751,7 +10754,7 @@ var http = __toESM(require("http"));
|
|
|
10751
10754
|
// package.json
|
|
10752
10755
|
var package_default = {
|
|
10753
10756
|
name: "codeam-cli",
|
|
10754
|
-
version: "2.75.
|
|
10757
|
+
version: "2.75.26",
|
|
10755
10758
|
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.",
|
|
10756
10759
|
type: "commonjs",
|
|
10757
10760
|
main: "dist/index.js",
|
|
@@ -12081,7 +12084,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12081
12084
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12082
12085
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12083
12086
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12084
|
-
..."2.75.
|
|
12087
|
+
..."2.75.26" ? { ideVersion: "2.75.26" } : {}
|
|
12085
12088
|
};
|
|
12086
12089
|
try {
|
|
12087
12090
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -13534,9 +13537,9 @@ function closeAllTerminals() {
|
|
|
13534
13537
|
}
|
|
13535
13538
|
|
|
13536
13539
|
// src/commands/start/handlers.ts
|
|
13537
|
-
var
|
|
13540
|
+
var fs51 = __toESM(require("fs"));
|
|
13538
13541
|
var os39 = __toESM(require("os"));
|
|
13539
|
-
var
|
|
13542
|
+
var path59 = __toESM(require("path"));
|
|
13540
13543
|
var import_crypto2 = require("crypto");
|
|
13541
13544
|
var import_child_process25 = require("child_process");
|
|
13542
13545
|
|
|
@@ -17150,12 +17153,12 @@ function isAvailable() {
|
|
|
17150
17153
|
}
|
|
17151
17154
|
function augmentPath() {
|
|
17152
17155
|
const dirs = probeInstallDirs();
|
|
17153
|
-
const
|
|
17156
|
+
const sep7 = path15.delimiter;
|
|
17154
17157
|
const current2 = process.env.PATH ?? "";
|
|
17155
|
-
const existing = new Set(current2.split(
|
|
17158
|
+
const existing = new Set(current2.split(sep7).filter(Boolean));
|
|
17156
17159
|
const additions = dirs.filter((d3) => !existing.has(d3));
|
|
17157
17160
|
if (additions.length === 0) return;
|
|
17158
|
-
process.env.PATH = additions.join(
|
|
17161
|
+
process.env.PATH = additions.join(sep7) + sep7 + current2;
|
|
17159
17162
|
}
|
|
17160
17163
|
function runInstaller() {
|
|
17161
17164
|
const isWindows = process.platform === "win32";
|
|
@@ -19603,8 +19606,8 @@ function pickLine(obj) {
|
|
|
19603
19606
|
function toHunk(raw, groupSeverity) {
|
|
19604
19607
|
if (!raw || typeof raw !== "object") return null;
|
|
19605
19608
|
const o = raw;
|
|
19606
|
-
const
|
|
19607
|
-
if (!
|
|
19609
|
+
const path96 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
19610
|
+
if (!path96) return null;
|
|
19608
19611
|
const message = asString(
|
|
19609
19612
|
pick(o, [
|
|
19610
19613
|
"comment",
|
|
@@ -19621,7 +19624,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
19621
19624
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
19622
19625
|
const locObj = pick(o, ["location"]) ?? o;
|
|
19623
19626
|
return {
|
|
19624
|
-
path:
|
|
19627
|
+
path: path96.trim(),
|
|
19625
19628
|
line: pickLine(o) ?? pickLine(locObj),
|
|
19626
19629
|
severity,
|
|
19627
19630
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -19704,10 +19707,10 @@ function parsePlain(stdout) {
|
|
|
19704
19707
|
for (const line of stdout.split(/\r?\n/)) {
|
|
19705
19708
|
const m = line.match(HUNK_LINE_RE);
|
|
19706
19709
|
if (!m) continue;
|
|
19707
|
-
const [,
|
|
19708
|
-
if (!
|
|
19710
|
+
const [, path96, lineNo, sevToken, message] = m;
|
|
19711
|
+
if (!path96 || !lineNo || !message) continue;
|
|
19709
19712
|
hunks.push({
|
|
19710
|
-
path:
|
|
19713
|
+
path: path96.trim(),
|
|
19711
19714
|
line: Number(lineNo),
|
|
19712
19715
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
19713
19716
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -23164,7 +23167,8 @@ async function readPreviewConfig(cwd) {
|
|
|
23164
23167
|
async function writePreviewConfig(cwd, detection) {
|
|
23165
23168
|
const filePath = configPath(cwd);
|
|
23166
23169
|
await import_promises4.default.mkdir(import_path6.default.dirname(filePath), { recursive: true });
|
|
23167
|
-
|
|
23170
|
+
const { candidates: _candidates, ...config } = detection;
|
|
23171
|
+
await import_promises4.default.writeFile(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
23168
23172
|
}
|
|
23169
23173
|
|
|
23170
23174
|
// src/services/preview/dotenv.ts
|
|
@@ -23839,6 +23843,107 @@ function isJsInstallCommand(cmd, args2) {
|
|
|
23839
23843
|
return verb === "install" || verb === "i" || verb === "ci";
|
|
23840
23844
|
}
|
|
23841
23845
|
|
|
23846
|
+
// src/services/preview/script-candidates.ts
|
|
23847
|
+
var fs40 = __toESM(require("fs"));
|
|
23848
|
+
var path48 = __toESM(require("path"));
|
|
23849
|
+
var EXCLUDE_RE = /(^|:)(deploy|publish|release|build|test|e2e|lint|format|typecheck|type-check|clean|prebuild|postinstall|preinstall|prepare|install|migrate|seed|db|prisma|codegen|storybook-build)(:|$)/i;
|
|
23850
|
+
var EXCLUDE_BODY_RE = /\b(run:android|run:ios|gradlew|fastlane|xcodebuild|eas build|eas submit)\b/i;
|
|
23851
|
+
var MAX_APPS = 40;
|
|
23852
|
+
var MAX_CANDIDATES = 120;
|
|
23853
|
+
function frameworkFor(pkg, body) {
|
|
23854
|
+
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
23855
|
+
const has = (d3) => d3 in deps || new RegExp(`\\b${d3}\\b`).test(body);
|
|
23856
|
+
if (has("expo")) return { framework: "Expo", port: 8081, ready_pattern: "Waiting on http|Metro waiting|Logs for your project" };
|
|
23857
|
+
if (has("next")) return { framework: "Next.js", port: 3e3, ready_pattern: "Ready in|Local:.*http" };
|
|
23858
|
+
if (has("vite")) return { framework: "Vite", port: 5173, ready_pattern: "Local:.*http" };
|
|
23859
|
+
if (has("@angular/cli") || /\bng serve\b/.test(body)) return { framework: "Angular", port: 4200, ready_pattern: "Local:.*http|compiled successfully" };
|
|
23860
|
+
if (has("react-scripts")) return { framework: "Create React App", port: 3e3, ready_pattern: "Compiled|Local:.*http" };
|
|
23861
|
+
if (has("nx") || /\bnx\b/.test(body)) return { framework: "Nx", port: 4200, ready_pattern: "Local:.*http|ready|listening" };
|
|
23862
|
+
return { framework: "Node", port: 3e3, ready_pattern: "Local:.*http|ready|listening|started" };
|
|
23863
|
+
}
|
|
23864
|
+
function readPkg(file) {
|
|
23865
|
+
try {
|
|
23866
|
+
return JSON.parse(fs40.readFileSync(file, "utf8"));
|
|
23867
|
+
} catch {
|
|
23868
|
+
return null;
|
|
23869
|
+
}
|
|
23870
|
+
}
|
|
23871
|
+
function expandGlob(root, pattern) {
|
|
23872
|
+
const clean = pattern.replace(/\/+$/, "");
|
|
23873
|
+
if (!clean.endsWith("/*")) return [clean];
|
|
23874
|
+
const base = clean.slice(0, -2);
|
|
23875
|
+
try {
|
|
23876
|
+
return fs40.readdirSync(path48.join(root, base), { withFileTypes: true }).filter((d3) => d3.isDirectory() && !d3.name.startsWith(".") && d3.name !== "node_modules").map((d3) => path48.join(base, d3.name));
|
|
23877
|
+
} catch {
|
|
23878
|
+
return [];
|
|
23879
|
+
}
|
|
23880
|
+
}
|
|
23881
|
+
function workspaceDirs(root, rootPkg) {
|
|
23882
|
+
const ws = rootPkg?.workspaces;
|
|
23883
|
+
const patterns = Array.isArray(ws) ? ws : ws?.packages ?? [];
|
|
23884
|
+
try {
|
|
23885
|
+
const pnpm = fs40.readFileSync(path48.join(root, "pnpm-workspace.yaml"), "utf8");
|
|
23886
|
+
for (const m of pnpm.matchAll(/^\s*-\s*['"]?([^'"\n]+)['"]?\s*$/gm)) patterns.push(m[1]);
|
|
23887
|
+
} catch {
|
|
23888
|
+
}
|
|
23889
|
+
if (patterns.length === 0) patterns.push("apps/*", "packages/*");
|
|
23890
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
23891
|
+
for (const p2 of patterns) for (const d3 of expandGlob(root, p2)) dirs.add(d3);
|
|
23892
|
+
return [...dirs].slice(0, MAX_APPS);
|
|
23893
|
+
}
|
|
23894
|
+
function listScriptCandidates(root) {
|
|
23895
|
+
const out2 = [];
|
|
23896
|
+
const rootPkg = readPkg(path48.join(root, "package.json"));
|
|
23897
|
+
const add = (pkg, appDir) => {
|
|
23898
|
+
for (const [script, body] of Object.entries(pkg.scripts ?? {})) {
|
|
23899
|
+
if (out2.length >= MAX_CANDIDATES) return;
|
|
23900
|
+
if (EXCLUDE_RE.test(script) || EXCLUDE_BODY_RE.test(body)) continue;
|
|
23901
|
+
const fw = frameworkFor(pkg, body);
|
|
23902
|
+
out2.push({
|
|
23903
|
+
app: pkg.name ?? (appDir === "." ? path48.basename(root) : appDir),
|
|
23904
|
+
appDir,
|
|
23905
|
+
script,
|
|
23906
|
+
body,
|
|
23907
|
+
framework: fw.framework,
|
|
23908
|
+
command: "npm",
|
|
23909
|
+
args: appDir === "." ? ["run", script] : ["--prefix", appDir, "run", script],
|
|
23910
|
+
port: fw.port,
|
|
23911
|
+
ready_pattern: fw.ready_pattern
|
|
23912
|
+
});
|
|
23913
|
+
}
|
|
23914
|
+
};
|
|
23915
|
+
if (rootPkg) add(rootPkg, ".");
|
|
23916
|
+
for (const dir of workspaceDirs(root, rootPkg)) {
|
|
23917
|
+
const pkg = readPkg(path48.join(root, dir, "package.json"));
|
|
23918
|
+
if (pkg) add(pkg, dir.split(path48.sep).join("/"));
|
|
23919
|
+
}
|
|
23920
|
+
return out2;
|
|
23921
|
+
}
|
|
23922
|
+
|
|
23923
|
+
// src/services/preview/prewarm-deps.ts
|
|
23924
|
+
var inFlight = null;
|
|
23925
|
+
var PREWARM_INSTALL_TIMEOUT_MS = 5 * 6e4;
|
|
23926
|
+
function prewarmNodeDeps(cwd) {
|
|
23927
|
+
if (inFlight) return inFlight;
|
|
23928
|
+
const missing = detectMissingNodeDeps(cwd);
|
|
23929
|
+
if (!missing || missing.cmd !== "npm") return Promise.resolve();
|
|
23930
|
+
log.info("preview", `prewarm: installing deps (${missing.cmd} ${missing.args.join(" ")})`);
|
|
23931
|
+
const started = Date.now();
|
|
23932
|
+
inFlight = runSetupCommand(missing.cmd, missing.args, cwd, void 0, {
|
|
23933
|
+
timeoutMs: PREWARM_INSTALL_TIMEOUT_MS
|
|
23934
|
+
}).then((r) => {
|
|
23935
|
+
log.info("preview", `prewarm: deps ${r.status} after ${Date.now() - started}ms`);
|
|
23936
|
+
}).catch((err) => {
|
|
23937
|
+
log.info("preview", `prewarm: deps install threw (${String(err)})`);
|
|
23938
|
+
}).finally(() => {
|
|
23939
|
+
inFlight = null;
|
|
23940
|
+
});
|
|
23941
|
+
return inFlight;
|
|
23942
|
+
}
|
|
23943
|
+
function awaitPrewarmInstall() {
|
|
23944
|
+
return inFlight ?? Promise.resolve();
|
|
23945
|
+
}
|
|
23946
|
+
|
|
23842
23947
|
// src/services/preview/tunnel-bringup.ts
|
|
23843
23948
|
var TUNNEL_REGISTERED_RE = /Registered tunnel connection/i;
|
|
23844
23949
|
async function awaitTunnelRegistered(candidate, hostname3, deadlineMs) {
|
|
@@ -23975,19 +24080,19 @@ function activePreviewSessionIds() {
|
|
|
23975
24080
|
|
|
23976
24081
|
// src/services/preview/start-orchestrator.ts
|
|
23977
24082
|
var import_child_process20 = require("child_process");
|
|
23978
|
-
var
|
|
23979
|
-
var
|
|
24083
|
+
var fs43 = __toESM(require("fs"));
|
|
24084
|
+
var path51 = __toESM(require("path"));
|
|
23980
24085
|
var import_which2 = __toESM(require("which"));
|
|
23981
24086
|
|
|
23982
24087
|
// src/services/project-env/index.ts
|
|
23983
24088
|
var import_fs6 = require("fs");
|
|
23984
|
-
var
|
|
24089
|
+
var path50 = __toESM(require("path"));
|
|
23985
24090
|
|
|
23986
24091
|
// src/beads/project-key.ts
|
|
23987
24092
|
var import_child_process19 = require("child_process");
|
|
23988
24093
|
var crypto2 = __toESM(require("crypto"));
|
|
23989
|
-
var
|
|
23990
|
-
var
|
|
24094
|
+
var fs41 = __toESM(require("fs"));
|
|
24095
|
+
var path49 = __toESM(require("path"));
|
|
23991
24096
|
function normalizeOrigin(raw) {
|
|
23992
24097
|
const trimmed = raw.trim();
|
|
23993
24098
|
if (!trimmed) return null;
|
|
@@ -24013,17 +24118,17 @@ function normalizeOrigin(raw) {
|
|
|
24013
24118
|
return `${host2}/${pathPart}`;
|
|
24014
24119
|
}
|
|
24015
24120
|
function findRepoRoot(cwd) {
|
|
24016
|
-
let dir =
|
|
24121
|
+
let dir = path49.resolve(cwd);
|
|
24017
24122
|
const seen2 = /* @__PURE__ */ new Set();
|
|
24018
24123
|
for (let i = 0; i < 256; i++) {
|
|
24019
24124
|
if (seen2.has(dir)) return null;
|
|
24020
24125
|
seen2.add(dir);
|
|
24021
24126
|
try {
|
|
24022
|
-
const stat3 =
|
|
24127
|
+
const stat3 = fs41.statSync(path49.join(dir, ".git"), { throwIfNoEntry: false });
|
|
24023
24128
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
24024
24129
|
} catch {
|
|
24025
24130
|
}
|
|
24026
|
-
const parent =
|
|
24131
|
+
const parent = path49.dirname(dir);
|
|
24027
24132
|
if (parent === dir) return null;
|
|
24028
24133
|
dir = parent;
|
|
24029
24134
|
}
|
|
@@ -24034,7 +24139,7 @@ var _execSeam3 = {
|
|
|
24034
24139
|
const out2 = (0, import_child_process19.execFileSync)(file, args2, opts);
|
|
24035
24140
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
24036
24141
|
},
|
|
24037
|
-
realpath: (p2) =>
|
|
24142
|
+
realpath: (p2) => fs41.realpathSync(p2)
|
|
24038
24143
|
};
|
|
24039
24144
|
function readOrigin(cwd) {
|
|
24040
24145
|
try {
|
|
@@ -24063,7 +24168,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
24063
24168
|
} catch {
|
|
24064
24169
|
}
|
|
24065
24170
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
24066
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
24171
|
+
return { projectKey: `path:${hash}`, projectLabel: path49.basename(real) || "project" };
|
|
24067
24172
|
}
|
|
24068
24173
|
|
|
24069
24174
|
// src/services/project-env/index.ts
|
|
@@ -24076,7 +24181,7 @@ async function readIfExists(p2) {
|
|
|
24076
24181
|
}
|
|
24077
24182
|
async function syncProjectEnvUp(cwd, ctx) {
|
|
24078
24183
|
if (!ctx.pluginAuthToken) return;
|
|
24079
|
-
const content = await readIfExists(
|
|
24184
|
+
const content = await readIfExists(path50.join(cwd, ".env"));
|
|
24080
24185
|
if (content == null) return;
|
|
24081
24186
|
try {
|
|
24082
24187
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -24098,7 +24203,7 @@ async function syncProjectEnvUp(cwd, ctx) {
|
|
|
24098
24203
|
}
|
|
24099
24204
|
async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
24100
24205
|
if (!ctx.pluginAuthToken) return false;
|
|
24101
|
-
const envPath =
|
|
24206
|
+
const envPath = path50.join(cwd, ".env");
|
|
24102
24207
|
if (await readIfExists(envPath) != null) return false;
|
|
24103
24208
|
try {
|
|
24104
24209
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -24109,7 +24214,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
|
24109
24214
|
projectKey
|
|
24110
24215
|
});
|
|
24111
24216
|
if (!stored) return false;
|
|
24112
|
-
const tmp =
|
|
24217
|
+
const tmp = path50.join(cwd, ".env.codeam-restore.tmp");
|
|
24113
24218
|
await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
|
|
24114
24219
|
await import_fs6.promises.rename(tmp, envPath);
|
|
24115
24220
|
log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
|
|
@@ -24526,6 +24631,145 @@ function inspectorClientSource(opts) {
|
|
|
24526
24631
|
redrawMarks();
|
|
24527
24632
|
}
|
|
24528
24633
|
|
|
24634
|
+
/**
|
|
24635
|
+
* Las marcas del AGENTE \u2014 la herramienta highlight_element.
|
|
24636
|
+
*
|
|
24637
|
+
* Van aparte de las del usuario a proposito: no se numeran, no se pueden
|
|
24638
|
+
* borrar desde el composer y no dependen de que el modo inspector este
|
|
24639
|
+
* encendido. Son el agente SE\xD1ALANDO algo, y el usuario las ve aunque no
|
|
24640
|
+
* haya tocado nada: un cursor que viaja hasta el elemento, lo centra en
|
|
24641
|
+
* pantalla y deja una caja con su etiqueta.
|
|
24642
|
+
*
|
|
24643
|
+
* Mismo anclaje que las marcas fijadas (coordenadas de documento), asi que
|
|
24644
|
+
* acompa\xF1an al scroll. Un selector que no encuentra nada no pinta nada: el
|
|
24645
|
+
* agente ya sabe por la herramienta que puede fallar.
|
|
24646
|
+
*/
|
|
24647
|
+
var AGENT = '#22d3ee';
|
|
24648
|
+
var agentMarks = [];
|
|
24649
|
+
var agentHost = null;
|
|
24650
|
+
var agentCursor = null;
|
|
24651
|
+
var agentStyle = null;
|
|
24652
|
+
var agentListening = false;
|
|
24653
|
+
|
|
24654
|
+
function ensureAgentStyle() {
|
|
24655
|
+
if (agentStyle && agentStyle.parentNode) return;
|
|
24656
|
+
agentStyle = document.createElement('style');
|
|
24657
|
+
agentStyle.setAttribute('data-codeam', 'agent-style');
|
|
24658
|
+
agentStyle.textContent =
|
|
24659
|
+
'@keyframes codeam-agent-pulse{0%{box-shadow:0 0 0 0 rgba(34,211,238,.55)}' +
|
|
24660
|
+
'70%{box-shadow:0 0 0 10px rgba(34,211,238,0)}100%{box-shadow:0 0 0 0 rgba(34,211,238,0)}}' +
|
|
24661
|
+
'@keyframes codeam-agent-in{from{opacity:0;transform:scale(1.06)}to{opacity:1;transform:scale(1)}}';
|
|
24662
|
+
(document.head || document.documentElement).appendChild(agentStyle);
|
|
24663
|
+
}
|
|
24664
|
+
|
|
24665
|
+
function ensureAgentCursor() {
|
|
24666
|
+
if (agentCursor && agentCursor.parentNode) return agentCursor;
|
|
24667
|
+
agentCursor = document.createElement('div');
|
|
24668
|
+
agentCursor.setAttribute('data-codeam', 'agent-cursor');
|
|
24669
|
+
agentCursor.style.cssText = [
|
|
24670
|
+
'position:fixed', 'pointer-events:none', 'z-index:2147483647',
|
|
24671
|
+
'left:' + Math.round(window.innerWidth / 2) + 'px', 'top:' + Math.round(window.innerHeight - 40) + 'px',
|
|
24672
|
+
'transition:left .6s cubic-bezier(.22,1,.36,1),top .6s cubic-bezier(.22,1,.36,1),opacity .3s',
|
|
24673
|
+
'opacity:0'
|
|
24674
|
+
].join(';');
|
|
24675
|
+
agentCursor.innerHTML =
|
|
24676
|
+
'<svg width="22" height="22" viewBox="0 0 24 24" style="display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))">' +
|
|
24677
|
+
'<path d="M4 2l15 8.5-6.6 1.6L9 18.5z" fill="' + AGENT + '" stroke="#000" stroke-width="1.2"/></svg>' +
|
|
24678
|
+
'<div style="margin:2px 0 0 14px;background:' + AGENT + ';color:#000;font:700 10px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;' +
|
|
24679
|
+
'padding:1px 6px;border-radius:8px;white-space:nowrap">Agent</div>';
|
|
24680
|
+
document.body.appendChild(agentCursor);
|
|
24681
|
+
return agentCursor;
|
|
24682
|
+
}
|
|
24683
|
+
|
|
24684
|
+
function redrawAgentMarks() {
|
|
24685
|
+
if (agentMarks.length === 0) {
|
|
24686
|
+
if (agentHost && agentHost.parentNode) agentHost.parentNode.removeChild(agentHost);
|
|
24687
|
+
agentHost = null;
|
|
24688
|
+
return;
|
|
24689
|
+
}
|
|
24690
|
+
if (!agentHost || !agentHost.parentNode) {
|
|
24691
|
+
agentHost = document.createElement('div');
|
|
24692
|
+
agentHost.setAttribute('data-codeam', 'agent-marks');
|
|
24693
|
+
agentHost.style.cssText = 'position:absolute;left:0;top:0;width:0;height:0;z-index:2147483646';
|
|
24694
|
+
document.body.appendChild(agentHost);
|
|
24695
|
+
}
|
|
24696
|
+
agentHost.innerHTML = '';
|
|
24697
|
+
var sx = window.scrollX || window.pageXOffset || 0;
|
|
24698
|
+
var sy = window.scrollY || window.pageYOffset || 0;
|
|
24699
|
+
for (var i = 0; i < agentMarks.length; i++) {
|
|
24700
|
+
var m = agentMarks[i];
|
|
24701
|
+
if (!m.el.isConnected) continue;
|
|
24702
|
+
var r = m.el.getBoundingClientRect();
|
|
24703
|
+
var box = document.createElement('div');
|
|
24704
|
+
box.setAttribute('data-codeam', 'agent-mark');
|
|
24705
|
+
box.style.cssText = [
|
|
24706
|
+
'position:absolute', 'pointer-events:none', 'box-sizing:border-box',
|
|
24707
|
+
'border:2px solid ' + AGENT, 'background:rgba(34,211,238,0.10)', 'border-radius:4px',
|
|
24708
|
+
'left:' + (r.left + sx - 3) + 'px', 'top:' + (r.top + sy - 3) + 'px',
|
|
24709
|
+
'width:' + (r.width + 6) + 'px', 'height:' + (r.height + 6) + 'px',
|
|
24710
|
+
'animation:codeam-agent-in .25s ease-out,codeam-agent-pulse 1.6s ease-out 3'
|
|
24711
|
+
].join(';');
|
|
24712
|
+
if (m.label) {
|
|
24713
|
+
var tag = document.createElement('div');
|
|
24714
|
+
tag.setAttribute('data-codeam', 'agent-mark-label');
|
|
24715
|
+
tag.style.cssText = [
|
|
24716
|
+
'position:absolute', 'left:-2px', (r.top >= 22 ? 'top:-22px' : 'bottom:-22px'),
|
|
24717
|
+
'background:' + AGENT, 'color:#000', 'font:700 11px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace',
|
|
24718
|
+
'padding:0 6px', 'border-radius:3px', 'white-space:nowrap', 'max-width:260px',
|
|
24719
|
+
'overflow:hidden', 'text-overflow:ellipsis'
|
|
24720
|
+
].join(';');
|
|
24721
|
+
tag.textContent = m.label;
|
|
24722
|
+
box.appendChild(tag);
|
|
24723
|
+
}
|
|
24724
|
+
agentHost.appendChild(box);
|
|
24725
|
+
}
|
|
24726
|
+
}
|
|
24727
|
+
|
|
24728
|
+
function listenAgentLayout() {
|
|
24729
|
+
if (agentListening) return;
|
|
24730
|
+
agentListening = true;
|
|
24731
|
+
window.addEventListener('scroll', redrawAgentMarks, true);
|
|
24732
|
+
window.addEventListener('resize', redrawAgentMarks);
|
|
24733
|
+
}
|
|
24734
|
+
|
|
24735
|
+
function agentHighlight(selector, labelText) {
|
|
24736
|
+
var el = null;
|
|
24737
|
+
try { el = document.querySelector(String(selector)); } catch (e) { el = null; }
|
|
24738
|
+
if (!el || !el.getBoundingClientRect) return false;
|
|
24739
|
+
ensureAgentStyle();
|
|
24740
|
+
listenAgentLayout();
|
|
24741
|
+
try { el.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'smooth' }); } catch (e) { /* viejo */ }
|
|
24742
|
+
var cursor = ensureAgentCursor();
|
|
24743
|
+
// Tras el scroll suave: el cursor viaja al centro del elemento y, al
|
|
24744
|
+
// llegar, aparece la caja. El orden es lo que se lee como \xABel agente
|
|
24745
|
+
// lo esta se\xF1alando\xBB y no como un recuadro que salta.
|
|
24746
|
+
setTimeout(function () {
|
|
24747
|
+
var r = el.getBoundingClientRect();
|
|
24748
|
+
cursor.style.opacity = '1';
|
|
24749
|
+
cursor.style.left = Math.round(r.left + Math.min(r.width / 2, 40)) + 'px';
|
|
24750
|
+
cursor.style.top = Math.round(r.top + Math.min(r.height / 2, 24)) + 'px';
|
|
24751
|
+
setTimeout(function () {
|
|
24752
|
+
agentMarks.push({ el: el, label: labelText ? String(labelText).slice(0, 80) : '' });
|
|
24753
|
+
redrawAgentMarks();
|
|
24754
|
+
}, 620);
|
|
24755
|
+
}, 380);
|
|
24756
|
+
return true;
|
|
24757
|
+
}
|
|
24758
|
+
|
|
24759
|
+
function agentClear() {
|
|
24760
|
+
agentMarks = [];
|
|
24761
|
+
redrawAgentMarks();
|
|
24762
|
+
if (agentCursor && agentCursor.parentNode) agentCursor.parentNode.removeChild(agentCursor);
|
|
24763
|
+
agentCursor = null;
|
|
24764
|
+
if (agentStyle && agentStyle.parentNode) agentStyle.parentNode.removeChild(agentStyle);
|
|
24765
|
+
agentStyle = null;
|
|
24766
|
+
if (agentListening) {
|
|
24767
|
+
window.removeEventListener('scroll', redrawAgentMarks, true);
|
|
24768
|
+
window.removeEventListener('resize', redrawAgentMarks);
|
|
24769
|
+
agentListening = false;
|
|
24770
|
+
}
|
|
24771
|
+
}
|
|
24772
|
+
|
|
24529
24773
|
function enable(origin) {
|
|
24530
24774
|
if (enabled) return;
|
|
24531
24775
|
enabled = true;
|
|
@@ -24559,6 +24803,8 @@ function inspectorClientSource(opts) {
|
|
|
24559
24803
|
if (data.type === 'enable') enable(e.origin);
|
|
24560
24804
|
else if (data.type === 'disable') disable();
|
|
24561
24805
|
else if (data.type === 'marks' && data.ids) syncMarks(data.ids);
|
|
24806
|
+
else if (data.type === 'agent-highlight' && data.selector) agentHighlight(data.selector, data.label);
|
|
24807
|
+
else if (data.type === 'agent-clear') agentClear();
|
|
24562
24808
|
});
|
|
24563
24809
|
|
|
24564
24810
|
/**
|
|
@@ -24577,6 +24823,11 @@ function inspectorClientSource(opts) {
|
|
|
24577
24823
|
window.__codeamInspector = {
|
|
24578
24824
|
enable: function () { enable('react-native'); },
|
|
24579
24825
|
disable: disable,
|
|
24826
|
+
// La app movil ya llamaba \`marks\` al borrar un chip y no existia:
|
|
24827
|
+
// la marca se quedaba pintada en la pagina.
|
|
24828
|
+
marks: function (ids) { if (ids && ids.length !== undefined) syncMarks(ids); },
|
|
24829
|
+
highlight: function (selector, text) { return agentHighlight(selector, text); },
|
|
24830
|
+
clear: agentClear,
|
|
24580
24831
|
};
|
|
24581
24832
|
}
|
|
24582
24833
|
} catch (e) {
|
|
@@ -24630,6 +24881,12 @@ var TUNNEL_REGISTER_DEADLINE_MS = 45e3;
|
|
|
24630
24881
|
function compileReadyPattern(pattern) {
|
|
24631
24882
|
return new RegExp(pattern, "i");
|
|
24632
24883
|
}
|
|
24884
|
+
var DEV_SERVER_READY_TIMEOUT_MS = 12e4;
|
|
24885
|
+
var MONOREPO_READY_TIMEOUT_MS = 36e4;
|
|
24886
|
+
function devServerReadyTimeoutMs(detection) {
|
|
24887
|
+
const text = [detection.framework, detection.command ?? "", ...detection.args ?? []].join(" ");
|
|
24888
|
+
return /\b(nx|turbo|turborepo|lerna)\b/i.test(text) ? MONOREPO_READY_TIMEOUT_MS : DEV_SERVER_READY_TIMEOUT_MS;
|
|
24889
|
+
}
|
|
24633
24890
|
async function waitForDevServerReady(devServer, readyRe, opts = {
|
|
24634
24891
|
timeoutMs: 12e4
|
|
24635
24892
|
}) {
|
|
@@ -24689,8 +24946,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
24689
24946
|
if (args2.length === 0) return detection;
|
|
24690
24947
|
const binName = args2[0];
|
|
24691
24948
|
if (binName.startsWith("-")) return detection;
|
|
24692
|
-
const binPath =
|
|
24693
|
-
if (!
|
|
24949
|
+
const binPath = path51.join(cwd, "node_modules", ".bin", binName);
|
|
24950
|
+
if (!fs43.existsSync(binPath)) return detection;
|
|
24694
24951
|
return {
|
|
24695
24952
|
...detection,
|
|
24696
24953
|
command: binPath,
|
|
@@ -24784,6 +25041,7 @@ async function provisionDeps(ctx) {
|
|
|
24784
25041
|
pluginAuthToken: ctx.projectEnvAuth.pluginAuthToken
|
|
24785
25042
|
});
|
|
24786
25043
|
}
|
|
25044
|
+
await awaitPrewarmInstall();
|
|
24787
25045
|
const missingDeps = detectMissingNodeDeps(cwd);
|
|
24788
25046
|
let preflightRan = false;
|
|
24789
25047
|
if (missingDeps) {
|
|
@@ -24963,7 +25221,7 @@ async function startDevServer(ctx, extraEnv = {}) {
|
|
|
24963
25221
|
const isNextJs = /next/i.test(detection.framework);
|
|
24964
25222
|
const portProbe = isExpo ? () => waitForExpoManifest(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : isNextJs ? () => waitForPortListening(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : void 0;
|
|
24965
25223
|
const outcome = await waitForDevServerReady(devServer, readyRe, {
|
|
24966
|
-
timeoutMs:
|
|
25224
|
+
timeoutMs: devServerReadyTimeoutMs(detection),
|
|
24967
25225
|
onChunk: (s) => {
|
|
24968
25226
|
outputTail = (outputTail + s).slice(-16e3);
|
|
24969
25227
|
},
|
|
@@ -25089,9 +25347,9 @@ async function bringUpPublicUrl(ctx, tunnelPort) {
|
|
|
25089
25347
|
|
|
25090
25348
|
// src/beads/bd-adapter.ts
|
|
25091
25349
|
var import_child_process21 = require("child_process");
|
|
25092
|
-
var
|
|
25350
|
+
var fs44 = __toESM(require("fs"));
|
|
25093
25351
|
var os31 = __toESM(require("os"));
|
|
25094
|
-
var
|
|
25352
|
+
var path52 = __toESM(require("path"));
|
|
25095
25353
|
var BD_PACKAGE = "@beads/bd";
|
|
25096
25354
|
function resolveBundledBdBinary() {
|
|
25097
25355
|
return _resolveSeam.resolveBundled();
|
|
@@ -25103,11 +25361,11 @@ function _defaultResolveBundled() {
|
|
|
25103
25361
|
} catch {
|
|
25104
25362
|
return null;
|
|
25105
25363
|
}
|
|
25106
|
-
const binDir =
|
|
25364
|
+
const binDir = path52.join(path52.dirname(pkgJsonPath), "bin");
|
|
25107
25365
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
25108
|
-
const binaryPath =
|
|
25366
|
+
const binaryPath = path52.join(binDir, binaryName);
|
|
25109
25367
|
try {
|
|
25110
|
-
|
|
25368
|
+
fs44.accessSync(binaryPath, fs44.constants.F_OK);
|
|
25111
25369
|
return binaryPath;
|
|
25112
25370
|
} catch {
|
|
25113
25371
|
return null;
|
|
@@ -25117,13 +25375,13 @@ function resolveBdOnPath() {
|
|
|
25117
25375
|
return _resolveSeam.resolveOnPath();
|
|
25118
25376
|
}
|
|
25119
25377
|
function _defaultResolveOnPath() {
|
|
25120
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
25378
|
+
const dirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
|
|
25121
25379
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
25122
25380
|
for (const dir of dirs) {
|
|
25123
25381
|
for (const candidate of candidates) {
|
|
25124
|
-
const full =
|
|
25382
|
+
const full = path52.join(dir, candidate);
|
|
25125
25383
|
try {
|
|
25126
|
-
|
|
25384
|
+
fs44.accessSync(full, fs44.constants.F_OK);
|
|
25127
25385
|
return full;
|
|
25128
25386
|
} catch {
|
|
25129
25387
|
}
|
|
@@ -25300,9 +25558,9 @@ function coerceIssue(row, projectKey) {
|
|
|
25300
25558
|
|
|
25301
25559
|
// src/beads/provisioner.ts
|
|
25302
25560
|
var import_child_process24 = require("child_process");
|
|
25303
|
-
var
|
|
25561
|
+
var fs46 = __toESM(require("fs"));
|
|
25304
25562
|
var os33 = __toESM(require("os"));
|
|
25305
|
-
var
|
|
25563
|
+
var path54 = __toESM(require("path"));
|
|
25306
25564
|
|
|
25307
25565
|
// src/beads/install-bd.ts
|
|
25308
25566
|
var import_child_process22 = require("child_process");
|
|
@@ -25367,9 +25625,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
25367
25625
|
|
|
25368
25626
|
// src/beads/install-dolt.ts
|
|
25369
25627
|
var import_child_process23 = require("child_process");
|
|
25370
|
-
var
|
|
25628
|
+
var fs45 = __toESM(require("fs"));
|
|
25371
25629
|
var os32 = __toESM(require("os"));
|
|
25372
|
-
var
|
|
25630
|
+
var path53 = __toESM(require("path"));
|
|
25373
25631
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
25374
25632
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
25375
25633
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -25465,7 +25723,7 @@ var _doltPathSeam = {
|
|
|
25465
25723
|
},
|
|
25466
25724
|
exists: (p2) => {
|
|
25467
25725
|
try {
|
|
25468
|
-
|
|
25726
|
+
fs45.accessSync(p2, fs45.constants.F_OK);
|
|
25469
25727
|
return true;
|
|
25470
25728
|
} catch {
|
|
25471
25729
|
return false;
|
|
@@ -25476,7 +25734,7 @@ function doltBinaryNames(platform3) {
|
|
|
25476
25734
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
25477
25735
|
}
|
|
25478
25736
|
function knownDoltDirs(platform3) {
|
|
25479
|
-
const P3 = platform3 === "win32" ?
|
|
25737
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
25480
25738
|
const home = _doltPathSeam.homedir();
|
|
25481
25739
|
if (platform3 === "win32") {
|
|
25482
25740
|
return [
|
|
@@ -25492,7 +25750,7 @@ function knownDoltDirs(platform3) {
|
|
|
25492
25750
|
].filter(Boolean);
|
|
25493
25751
|
}
|
|
25494
25752
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
25495
|
-
const P3 = platform3 === "win32" ?
|
|
25753
|
+
const P3 = platform3 === "win32" ? path53.win32 : path53.posix;
|
|
25496
25754
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
25497
25755
|
const names = doltBinaryNames(platform3);
|
|
25498
25756
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -25689,14 +25947,14 @@ var _linkSeam = {
|
|
|
25689
25947
|
homedir: () => os33.homedir(),
|
|
25690
25948
|
isWritableDir: (dir) => {
|
|
25691
25949
|
try {
|
|
25692
|
-
|
|
25950
|
+
fs46.accessSync(dir, fs46.constants.W_OK);
|
|
25693
25951
|
return true;
|
|
25694
25952
|
} catch {
|
|
25695
25953
|
return false;
|
|
25696
25954
|
}
|
|
25697
25955
|
},
|
|
25698
25956
|
ensureDir: (dir) => {
|
|
25699
|
-
|
|
25957
|
+
fs46.mkdirSync(dir, { recursive: true });
|
|
25700
25958
|
},
|
|
25701
25959
|
/**
|
|
25702
25960
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -25717,9 +25975,9 @@ var _linkSeam = {
|
|
|
25717
25975
|
* which `linkBdOntoPath` creates if missing.
|
|
25718
25976
|
*/
|
|
25719
25977
|
cliBinDir: () => {
|
|
25720
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
25978
|
+
const pathDirs = (process.env.PATH ?? "").split(path54.delimiter).filter(Boolean);
|
|
25721
25979
|
const home = _linkSeam.homedir();
|
|
25722
|
-
const localBin = home ?
|
|
25980
|
+
const localBin = home ? path54.join(home, ".local", "bin") : null;
|
|
25723
25981
|
if (localBin) {
|
|
25724
25982
|
try {
|
|
25725
25983
|
_linkSeam.ensureDir(localBin);
|
|
@@ -25729,16 +25987,16 @@ var _linkSeam = {
|
|
|
25729
25987
|
const candidates = [];
|
|
25730
25988
|
if (localBin) candidates.push(localBin);
|
|
25731
25989
|
try {
|
|
25732
|
-
candidates.push(
|
|
25990
|
+
candidates.push(path54.dirname(process.execPath));
|
|
25733
25991
|
} catch {
|
|
25734
25992
|
}
|
|
25735
25993
|
candidates.push("/usr/local/bin");
|
|
25736
25994
|
const entry = process.argv[1];
|
|
25737
25995
|
if (entry) {
|
|
25738
25996
|
try {
|
|
25739
|
-
candidates.push(
|
|
25997
|
+
candidates.push(path54.dirname(fs46.realpathSync(entry)));
|
|
25740
25998
|
} catch {
|
|
25741
|
-
candidates.push(
|
|
25999
|
+
candidates.push(path54.dirname(entry));
|
|
25742
26000
|
}
|
|
25743
26001
|
}
|
|
25744
26002
|
const onPathWritable = candidates.find(
|
|
@@ -25750,20 +26008,20 @@ var _linkSeam = {
|
|
|
25750
26008
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
25751
26009
|
readlink: (linkPath) => {
|
|
25752
26010
|
try {
|
|
25753
|
-
return
|
|
26011
|
+
return fs46.readlinkSync(linkPath);
|
|
25754
26012
|
} catch {
|
|
25755
26013
|
return null;
|
|
25756
26014
|
}
|
|
25757
26015
|
},
|
|
25758
|
-
unlink: (linkPath) =>
|
|
25759
|
-
symlink: (target, linkPath) =>
|
|
26016
|
+
unlink: (linkPath) => fs46.unlinkSync(linkPath),
|
|
26017
|
+
symlink: (target, linkPath) => fs46.symlinkSync(target, linkPath)
|
|
25760
26018
|
};
|
|
25761
26019
|
function linkBdOntoPath(binaryPath) {
|
|
25762
26020
|
if (_linkSeam.platform() === "win32") return;
|
|
25763
26021
|
const binDir = _linkSeam.cliBinDir();
|
|
25764
26022
|
if (!binDir) return;
|
|
25765
26023
|
_linkSeam.ensureDir(binDir);
|
|
25766
|
-
const linkPath =
|
|
26024
|
+
const linkPath = path54.join(binDir, "bd");
|
|
25767
26025
|
if (linkPath === binaryPath) return;
|
|
25768
26026
|
const current2 = _linkSeam.readlink(linkPath);
|
|
25769
26027
|
if (current2 === binaryPath) return;
|
|
@@ -25968,7 +26226,7 @@ function dedupeRecipes(agents) {
|
|
|
25968
26226
|
|
|
25969
26227
|
// src/beads/watcher.ts
|
|
25970
26228
|
var crypto4 = __toESM(require("crypto"));
|
|
25971
|
-
var
|
|
26229
|
+
var path55 = __toESM(require("path"));
|
|
25972
26230
|
var API_BASE5 = resolveApiBaseUrl();
|
|
25973
26231
|
var DEBOUNCE_MS2 = 400;
|
|
25974
26232
|
var ZERO_SUMMARY = {
|
|
@@ -25992,7 +26250,7 @@ var BeadsWatcher = class {
|
|
|
25992
26250
|
constructor(opts) {
|
|
25993
26251
|
this.opts = opts;
|
|
25994
26252
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
25995
|
-
this.feedPath = opts.feedPath ??
|
|
26253
|
+
this.feedPath = opts.feedPath ?? path55.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
25996
26254
|
this.apiBase = opts.apiBaseUrl ?? API_BASE5;
|
|
25997
26255
|
}
|
|
25998
26256
|
opts;
|
|
@@ -26409,9 +26667,9 @@ async function configureBeads(action, ctx, deps) {
|
|
|
26409
26667
|
return { enabled: false, running: false };
|
|
26410
26668
|
}
|
|
26411
26669
|
const p3 = await deps.probe();
|
|
26412
|
-
const
|
|
26413
|
-
deps.emit({ type: "beads_status", state:
|
|
26414
|
-
return { enabled:
|
|
26670
|
+
const running3 = p3.serverUp && p3.bdAvailable;
|
|
26671
|
+
deps.emit({ type: "beads_status", state: running3 ? "enabled" : "disabled", running: running3, ...p3 });
|
|
26672
|
+
return { enabled: running3, running: running3, ...p3 };
|
|
26415
26673
|
}
|
|
26416
26674
|
if (action === "disable") {
|
|
26417
26675
|
deps.persist({ enabled: false });
|
|
@@ -26428,9 +26686,9 @@ async function configureBeads(action, ctx, deps) {
|
|
|
26428
26686
|
return { enabled: false, ...p2 };
|
|
26429
26687
|
}
|
|
26430
26688
|
await deps.startWatcher().catch(() => void 0);
|
|
26431
|
-
const
|
|
26432
|
-
deps.emit({ type: "beads_status", state: "enabled", running, ...p2 });
|
|
26433
|
-
return { enabled: true, running, ...p2 };
|
|
26689
|
+
const running2 = true;
|
|
26690
|
+
deps.emit({ type: "beads_status", state: "enabled", running: running2, ...p2 });
|
|
26691
|
+
return { enabled: true, running: running2, ...p2 };
|
|
26434
26692
|
}
|
|
26435
26693
|
|
|
26436
26694
|
// src/skills/configure.ts
|
|
@@ -26567,8 +26825,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
26567
26825
|
function saveFilesTemp(files) {
|
|
26568
26826
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
26569
26827
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
26570
|
-
const tmpPath =
|
|
26571
|
-
|
|
26828
|
+
const tmpPath = path59.join(os39.tmpdir(), `codeam-${(0, import_crypto2.randomUUID)()}-${safeName}`);
|
|
26829
|
+
fs51.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
26572
26830
|
pendingAttachmentFiles.add(tmpPath);
|
|
26573
26831
|
return tmpPath;
|
|
26574
26832
|
});
|
|
@@ -26803,10 +27061,10 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
26803
27061
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
26804
27062
|
};
|
|
26805
27063
|
var envReadH = async (ctx, cmd) => {
|
|
26806
|
-
const envPath =
|
|
27064
|
+
const envPath = path59.join(process.cwd(), ".env");
|
|
26807
27065
|
await restoreProjectEnvIfMissing(process.cwd(), ctx);
|
|
26808
27066
|
try {
|
|
26809
|
-
const raw = await
|
|
27067
|
+
const raw = await fs51.promises.readFile(envPath, "utf8");
|
|
26810
27068
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
26811
27069
|
exists: true,
|
|
26812
27070
|
vars: parseDotenv(raw)
|
|
@@ -26835,7 +27093,7 @@ var envParseH = async (ctx, cmd, parsed) => {
|
|
|
26835
27093
|
const existing = /* @__PURE__ */ new Map();
|
|
26836
27094
|
if (!replace) {
|
|
26837
27095
|
try {
|
|
26838
|
-
const raw = await
|
|
27096
|
+
const raw = await fs51.promises.readFile(path59.join(process.cwd(), ".env"), "utf8");
|
|
26839
27097
|
for (const v of parseDotenv(raw)) existing.set(v.key, v.value);
|
|
26840
27098
|
} catch {
|
|
26841
27099
|
}
|
|
@@ -26875,15 +27133,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
26875
27133
|
}
|
|
26876
27134
|
seen2.add(v.key);
|
|
26877
27135
|
}
|
|
26878
|
-
const envPath =
|
|
26879
|
-
const tmpPath =
|
|
27136
|
+
const envPath = path59.join(process.cwd(), ".env");
|
|
27137
|
+
const tmpPath = path59.join(process.cwd(), ".env.codeam.tmp");
|
|
26880
27138
|
try {
|
|
26881
|
-
await
|
|
26882
|
-
await
|
|
27139
|
+
await fs51.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
27140
|
+
await fs51.promises.rename(tmpPath, envPath);
|
|
26883
27141
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
26884
27142
|
void syncProjectEnvUp(process.cwd(), ctx);
|
|
26885
27143
|
} catch (err) {
|
|
26886
|
-
await
|
|
27144
|
+
await fs51.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
26887
27145
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
26888
27146
|
}
|
|
26889
27147
|
};
|
|
@@ -27215,9 +27473,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
27215
27473
|
function buildNpmInstallInvocation(opts) {
|
|
27216
27474
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
27217
27475
|
const execPath = opts?.execPath ?? process.execPath;
|
|
27218
|
-
const exists2 = opts?.existsSync ??
|
|
27476
|
+
const exists2 = opts?.existsSync ?? fs51.existsSync;
|
|
27219
27477
|
const platform3 = opts?.platform ?? process.platform;
|
|
27220
|
-
const p2 = platform3 === "win32" ?
|
|
27478
|
+
const p2 = platform3 === "win32" ? path59.win32 : path59.posix;
|
|
27221
27479
|
const normalized = entryScript.split(/[\\/]/).join("/");
|
|
27222
27480
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
27223
27481
|
const markerIdx = normalized.indexOf(marker);
|
|
@@ -27239,7 +27497,7 @@ function isPermissionError(stderr) {
|
|
|
27239
27497
|
function resolveGlobalNodeModulesDir(opts) {
|
|
27240
27498
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
27241
27499
|
const platform3 = opts?.platform ?? process.platform;
|
|
27242
|
-
const p2 = platform3 === "win32" ?
|
|
27500
|
+
const p2 = platform3 === "win32" ? path59.win32 : path59.posix;
|
|
27243
27501
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
27244
27502
|
const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
|
|
27245
27503
|
if (markerIdx <= 0) return null;
|
|
@@ -27249,19 +27507,19 @@ function resolveGlobalNodeModulesDir(opts) {
|
|
|
27249
27507
|
var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
|
|
27250
27508
|
function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
27251
27509
|
if (!nodeModulesDir) return 0;
|
|
27252
|
-
const
|
|
27253
|
-
const statSync15 = deps?.statSync ??
|
|
27254
|
-
const rmSync9 = deps?.rmSync ??
|
|
27510
|
+
const readdirSync13 = deps?.readdirSync ?? fs51.readdirSync;
|
|
27511
|
+
const statSync15 = deps?.statSync ?? fs51.statSync;
|
|
27512
|
+
const rmSync9 = deps?.rmSync ?? fs51.rmSync;
|
|
27255
27513
|
let removed = 0;
|
|
27256
27514
|
let entries;
|
|
27257
27515
|
try {
|
|
27258
|
-
entries =
|
|
27516
|
+
entries = readdirSync13(nodeModulesDir);
|
|
27259
27517
|
} catch {
|
|
27260
27518
|
return 0;
|
|
27261
27519
|
}
|
|
27262
27520
|
for (const name of entries) {
|
|
27263
27521
|
if (!/^\.codeam-cli-/.test(name)) continue;
|
|
27264
|
-
const full =
|
|
27522
|
+
const full = path59.join(nodeModulesDir, name);
|
|
27265
27523
|
try {
|
|
27266
27524
|
const st3 = statSync15(full);
|
|
27267
27525
|
if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
|
|
@@ -27650,114 +27908,106 @@ async function runDetectOneShot(generate, timeoutMs = PREVIEW_DETECT_TIMEOUT_MS)
|
|
|
27650
27908
|
if (timer) clearTimeout(timer);
|
|
27651
27909
|
}
|
|
27652
27910
|
}
|
|
27653
|
-
|
|
27654
|
-
if (
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
|
|
27658
|
-
|
|
27659
|
-
|
|
27911
|
+
function originPayload(payload, origin) {
|
|
27912
|
+
if (origin !== "agent") return payload;
|
|
27913
|
+
return { ...payload ?? {}, origin };
|
|
27914
|
+
}
|
|
27915
|
+
async function resolvePreviewDetection(args2) {
|
|
27916
|
+
const { ctx, runtime, pluginAuthToken, origin } = args2;
|
|
27917
|
+
const emit2 = (type, payload) => {
|
|
27660
27918
|
emitPreviewEvent({
|
|
27661
27919
|
sessionId: ctx.sessionId,
|
|
27662
27920
|
pluginId: ctx.pluginId,
|
|
27663
|
-
pluginAuthToken
|
|
27664
|
-
type
|
|
27665
|
-
payload:
|
|
27666
|
-
stage: "detection",
|
|
27667
|
-
message: `Preview detection isn't available on ${ctx.runtime.id} sessions yet \u2014 link a Claude or Codex agent.`
|
|
27668
|
-
}
|
|
27921
|
+
pluginAuthToken,
|
|
27922
|
+
type,
|
|
27923
|
+
payload: originPayload(payload, origin)
|
|
27669
27924
|
});
|
|
27670
|
-
|
|
27925
|
+
};
|
|
27926
|
+
if (typeof runtime.generateOneShot !== "function") {
|
|
27927
|
+
log.info("preview", `runtime ${runtime.id} has no generateOneShot \u2014 emitting unsupported`);
|
|
27928
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27929
|
+
stage: "detection",
|
|
27930
|
+
message: `Preview detection isn't available on ${runtime.id} sessions yet \u2014 link a Claude or Codex agent.`
|
|
27931
|
+
});
|
|
27932
|
+
return null;
|
|
27671
27933
|
}
|
|
27672
|
-
const
|
|
27673
|
-
const
|
|
27674
|
-
|
|
27675
|
-
|
|
27676
|
-
|
|
27677
|
-
|
|
27678
|
-
|
|
27679
|
-
|
|
27680
|
-
|
|
27681
|
-
|
|
27682
|
-
|
|
27683
|
-
|
|
27684
|
-
|
|
27685
|
-
|
|
27686
|
-
|
|
27687
|
-
|
|
27688
|
-
sessionId: ctx.sessionId,
|
|
27689
|
-
pluginId: ctx.pluginId,
|
|
27690
|
-
pluginAuthToken,
|
|
27691
|
-
type: USER_EVENTS.PREVIEW_DETECTION_PENDING
|
|
27934
|
+
const generateOneShot = runtime.generateOneShot.bind(runtime);
|
|
27935
|
+
const fromFile = await readPreviewConfig(process.cwd());
|
|
27936
|
+
if (fromFile) {
|
|
27937
|
+
log.info("preview", `detect: using .codeam/preview.json (${fromFile.framework})`);
|
|
27938
|
+
return fromFile;
|
|
27939
|
+
}
|
|
27940
|
+
emit2(USER_EVENTS.PREVIEW_DETECTION_PENDING);
|
|
27941
|
+
log.info("preview", "detect: invoking generateOneShot");
|
|
27942
|
+
const startedAt = Date.now();
|
|
27943
|
+
const { raw, timedOut, stderr } = await runDetectOneShot(generateOneShot);
|
|
27944
|
+
const tookMs = Date.now() - startedAt;
|
|
27945
|
+
if (timedOut) {
|
|
27946
|
+
log.info("preview", `detect: timed out after ${tookMs}ms \u2014 emitting preview_error`);
|
|
27947
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27948
|
+
stage: "detection",
|
|
27949
|
+
message: `Project detection timed out after ${Math.round(PREVIEW_DETECT_TIMEOUT_MS / 1e3)} s \u2014 the agent did not answer. Try again, or add a .codeam/preview.json override.`
|
|
27692
27950
|
});
|
|
27693
|
-
|
|
27694
|
-
|
|
27695
|
-
|
|
27696
|
-
|
|
27697
|
-
|
|
27698
|
-
|
|
27699
|
-
|
|
27700
|
-
|
|
27701
|
-
pluginId: ctx.pluginId,
|
|
27702
|
-
pluginAuthToken,
|
|
27703
|
-
type: USER_EVENTS.PREVIEW_ERROR,
|
|
27704
|
-
payload: {
|
|
27705
|
-
stage: "detection",
|
|
27706
|
-
message: `Project detection timed out after ${Math.round(PREVIEW_DETECT_TIMEOUT_MS / 1e3)} s \u2014 the agent did not answer. Try again, or add a .codeam/preview.json override.`
|
|
27707
|
-
}
|
|
27708
|
-
});
|
|
27709
|
-
return;
|
|
27710
|
-
}
|
|
27711
|
-
const detection = safeParseDetection(raw);
|
|
27712
|
-
if (!detection) {
|
|
27713
|
-
const failure = describeDetectionFailure(raw);
|
|
27714
|
-
log.info(
|
|
27715
|
-
"preview",
|
|
27716
|
-
`detect: failed after ${tookMs}ms reason=${failure?.reason ?? "unknown"}` + (failure?.missing ? ` missing=${failure.missing.join(",")}` : "") + `
|
|
27951
|
+
return null;
|
|
27952
|
+
}
|
|
27953
|
+
const detection = safeParseDetection(raw);
|
|
27954
|
+
if (!detection) {
|
|
27955
|
+
const failure = describeDetectionFailure(raw);
|
|
27956
|
+
log.info(
|
|
27957
|
+
"preview",
|
|
27958
|
+
`detect: failed after ${tookMs}ms reason=${failure?.reason ?? "unknown"}` + (failure?.missing ? ` missing=${failure.missing.join(",")}` : "") + `
|
|
27717
27959
|
--- salida cruda del agente (acotada) ---
|
|
27718
27960
|
${failure?.rawExcerpt ?? ""}`
|
|
27719
|
-
|
|
27720
|
-
|
|
27721
|
-
|
|
27722
|
-
|
|
27723
|
-
|
|
27724
|
-
|
|
27725
|
-
|
|
27726
|
-
|
|
27727
|
-
|
|
27728
|
-
|
|
27729
|
-
|
|
27730
|
-
|
|
27731
|
-
|
|
27732
|
-
|
|
27733
|
-
}
|
|
27734
|
-
if (isUnsupportedDetection(detection)) {
|
|
27735
|
-
log.info("preview", "detect: framework=unsupported");
|
|
27736
|
-
emitPreviewEvent({
|
|
27737
|
-
sessionId: ctx.sessionId,
|
|
27738
|
-
pluginId: ctx.pluginId,
|
|
27739
|
-
pluginAuthToken,
|
|
27740
|
-
type: USER_EVENTS.PREVIEW_ERROR,
|
|
27741
|
-
payload: {
|
|
27742
|
-
stage: "unsupported",
|
|
27743
|
-
message: detection.notes ?? "No dev server applies to this project."
|
|
27744
|
-
}
|
|
27745
|
-
});
|
|
27746
|
-
return;
|
|
27747
|
-
}
|
|
27748
|
-
log.info("preview", `detect: ${detection.framework} on :${detection.port} (took ${tookMs}ms)`);
|
|
27749
|
-
void writePreviewConfig(process.cwd(), detection).catch((err) => {
|
|
27750
|
-
log.info("preview", `detect: writePreviewConfig failed (non-fatal): ${String(err)}`);
|
|
27961
|
+
);
|
|
27962
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27963
|
+
stage: "detection",
|
|
27964
|
+
// El mensaje sale del diagnostico: decir "JSON invalido" cuando el
|
|
27965
|
+
// agente no contesto manda al usuario a mirar un JSON que no existe.
|
|
27966
|
+
message: (failure?.reason === "no_output" ? describeOneShotAgentError(stderr) : null) ?? failure?.message ?? "Agent returned invalid JSON. Try again, or add a .codeam/preview.json override."
|
|
27967
|
+
});
|
|
27968
|
+
return null;
|
|
27969
|
+
}
|
|
27970
|
+
if (isUnsupportedDetection(detection)) {
|
|
27971
|
+
log.info("preview", "detect: framework=unsupported");
|
|
27972
|
+
emit2(USER_EVENTS.PREVIEW_ERROR, {
|
|
27973
|
+
stage: "unsupported",
|
|
27974
|
+
message: detection.notes ?? "No dev server applies to this project."
|
|
27751
27975
|
});
|
|
27976
|
+
return null;
|
|
27977
|
+
}
|
|
27978
|
+
log.info("preview", `detect: ${detection.framework} on :${detection.port} (took ${tookMs}ms)`);
|
|
27979
|
+
void writePreviewConfig(process.cwd(), detection).catch((err) => {
|
|
27980
|
+
log.info("preview", `detect: writePreviewConfig failed (non-fatal): ${String(err)}`);
|
|
27981
|
+
});
|
|
27982
|
+
return detection;
|
|
27983
|
+
}
|
|
27984
|
+
var requestPreviewDetectH = (ctx) => {
|
|
27985
|
+
if (!ctx.pluginAuthToken) {
|
|
27986
|
+
log.info("preview", "no pluginAuthToken \u2014 skipping detect");
|
|
27987
|
+
return;
|
|
27988
|
+
}
|
|
27989
|
+
const pluginAuthToken = ctx.pluginAuthToken;
|
|
27990
|
+
void (async () => {
|
|
27991
|
+
const detection = await resolvePreviewDetection({ ctx, runtime: ctx.runtime, pluginAuthToken });
|
|
27992
|
+
if (!detection) return;
|
|
27752
27993
|
emitPreviewEvent({
|
|
27753
27994
|
sessionId: ctx.sessionId,
|
|
27754
27995
|
pluginId: ctx.pluginId,
|
|
27755
27996
|
pluginAuthToken,
|
|
27756
27997
|
type: USER_EVENTS.PREVIEW_DETECTION_READY,
|
|
27757
|
-
payload: { detection }
|
|
27998
|
+
payload: { detection: withScriptCandidates(detection) }
|
|
27758
27999
|
});
|
|
27759
28000
|
})();
|
|
27760
28001
|
};
|
|
28002
|
+
function withScriptCandidates(detection) {
|
|
28003
|
+
try {
|
|
28004
|
+
const candidates = listScriptCandidates(process.cwd());
|
|
28005
|
+
return candidates.length > 0 ? { ...detection, candidates } : detection;
|
|
28006
|
+
} catch (err) {
|
|
28007
|
+
log.info("preview", `detect: listing script candidates failed (non-fatal): ${String(err)}`);
|
|
28008
|
+
return detection;
|
|
28009
|
+
}
|
|
28010
|
+
}
|
|
27761
28011
|
var previewPrewarmStarted = false;
|
|
27762
28012
|
function makePreviewReaffirm(args2) {
|
|
27763
28013
|
const token = args2.pluginAuthToken;
|
|
@@ -27787,6 +28037,7 @@ function makePreviewReaffirm(args2) {
|
|
|
27787
28037
|
function prewarmPreviewDetection(runtime) {
|
|
27788
28038
|
if (previewPrewarmStarted) return;
|
|
27789
28039
|
previewPrewarmStarted = true;
|
|
28040
|
+
void prewarmNodeDeps(process.cwd());
|
|
27790
28041
|
if (typeof runtime.generateOneShot !== "function") return;
|
|
27791
28042
|
const generateOneShot = runtime.generateOneShot.bind(runtime);
|
|
27792
28043
|
void (async () => {
|
|
@@ -27821,19 +28072,21 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
27821
28072
|
log.info("preview", "start: no detection in payload");
|
|
27822
28073
|
return;
|
|
27823
28074
|
}
|
|
27824
|
-
startPreviewFromDetection(ctx, rawDetection, ctx.pluginAuthToken);
|
|
28075
|
+
void startPreviewFromDetection(ctx, rawDetection, ctx.pluginAuthToken);
|
|
27825
28076
|
};
|
|
27826
|
-
function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
|
|
28077
|
+
function startPreviewFromDetection(ctx, detection, pluginAuthToken, opts = {}) {
|
|
27827
28078
|
const emit2 = (type, payload) => {
|
|
28079
|
+
const tagged = originPayload(payload, opts.origin) ?? {};
|
|
28080
|
+
opts.onEvent?.(type, tagged);
|
|
27828
28081
|
emitPreviewEvent({
|
|
27829
28082
|
sessionId: ctx.sessionId,
|
|
27830
28083
|
pluginId: ctx.pluginId,
|
|
27831
28084
|
pluginAuthToken,
|
|
27832
28085
|
type,
|
|
27833
|
-
payload
|
|
28086
|
+
payload: tagged
|
|
27834
28087
|
});
|
|
27835
28088
|
};
|
|
27836
|
-
runPreviewStart({
|
|
28089
|
+
return runPreviewStart({
|
|
27837
28090
|
sessionId: ctx.sessionId,
|
|
27838
28091
|
detection,
|
|
27839
28092
|
cwd: process.cwd(),
|
|
@@ -27864,7 +28117,7 @@ function maybeAttachBuildHeal(ctx, pluginAuthToken) {
|
|
|
27864
28117
|
if (!activePreviews.has(ctx.sessionId)) return;
|
|
27865
28118
|
await killPreview(ctx.sessionId);
|
|
27866
28119
|
await new Promise((r) => setTimeout(r, 150));
|
|
27867
|
-
startPreviewFromDetection(ctx, preview.detection, pluginAuthToken);
|
|
28120
|
+
void startPreviewFromDetection(ctx, preview.detection, pluginAuthToken);
|
|
27868
28121
|
})();
|
|
27869
28122
|
},
|
|
27870
28123
|
notify: (message) => {
|
|
@@ -27910,7 +28163,7 @@ var previewRestartH = async (ctx, cmd) => {
|
|
|
27910
28163
|
}
|
|
27911
28164
|
await killPreview(ctx.sessionId);
|
|
27912
28165
|
await new Promise((r) => setTimeout(r, 150));
|
|
27913
|
-
startPreviewFromDetection(ctx, preview.detection, ctx.pluginAuthToken);
|
|
28166
|
+
void startPreviewFromDetection(ctx, preview.detection, ctx.pluginAuthToken);
|
|
27914
28167
|
await ctx.relay.sendResult(cmd.id, "completed", { restarted: true });
|
|
27915
28168
|
};
|
|
27916
28169
|
var savePreviewConfigH = (_ctx, _cmd, parsed) => {
|
|
@@ -28283,11 +28536,11 @@ function resolveTokenValue(args2) {
|
|
|
28283
28536
|
}
|
|
28284
28537
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
28285
28538
|
if (fileFlag) {
|
|
28286
|
-
const
|
|
28539
|
+
const path96 = fileFlag.slice("--token-file=".length);
|
|
28287
28540
|
try {
|
|
28288
|
-
const content =
|
|
28289
|
-
if (content.length === 0) fail(`--token-file ${
|
|
28290
|
-
rmIfExistsQuiet(
|
|
28541
|
+
const content = fs52.readFileSync(path96, "utf8").trim();
|
|
28542
|
+
if (content.length === 0) fail(`--token-file ${path96} is empty`);
|
|
28543
|
+
rmIfExistsQuiet(path96);
|
|
28291
28544
|
return content;
|
|
28292
28545
|
} catch (err) {
|
|
28293
28546
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -28379,12 +28632,12 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
28379
28632
|
}
|
|
28380
28633
|
}
|
|
28381
28634
|
function pairAutoLockPath() {
|
|
28382
|
-
return
|
|
28635
|
+
return path60.join(os40.homedir(), ".codeam", "pair-auto.lock");
|
|
28383
28636
|
}
|
|
28384
28637
|
var procRoot = "/proc";
|
|
28385
28638
|
function readProcFile(rel) {
|
|
28386
28639
|
try {
|
|
28387
|
-
return
|
|
28640
|
+
return fs52.readFileSync(path60.join(procRoot, rel), "utf8");
|
|
28388
28641
|
} catch {
|
|
28389
28642
|
return void 0;
|
|
28390
28643
|
}
|
|
@@ -28405,7 +28658,7 @@ function currentBootId() {
|
|
|
28405
28658
|
function readLockRecord(lockPath) {
|
|
28406
28659
|
let raw;
|
|
28407
28660
|
try {
|
|
28408
|
-
raw =
|
|
28661
|
+
raw = fs52.readFileSync(lockPath, "utf8");
|
|
28409
28662
|
} catch {
|
|
28410
28663
|
return void 0;
|
|
28411
28664
|
}
|
|
@@ -28454,24 +28707,24 @@ function isLiveLockHolder(rec) {
|
|
|
28454
28707
|
}
|
|
28455
28708
|
function releaseOwnLock(lockPath) {
|
|
28456
28709
|
try {
|
|
28457
|
-
if (readLockRecord(lockPath)?.pid === process.pid)
|
|
28710
|
+
if (readLockRecord(lockPath)?.pid === process.pid) fs52.unlinkSync(lockPath);
|
|
28458
28711
|
} catch {
|
|
28459
28712
|
}
|
|
28460
28713
|
}
|
|
28461
28714
|
function daemonLockPath(sessionId) {
|
|
28462
28715
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
28463
|
-
return
|
|
28716
|
+
return path60.join(os40.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
28464
28717
|
}
|
|
28465
28718
|
function acquireDaemonLock(sessionId) {
|
|
28466
28719
|
const lockPath = daemonLockPath(sessionId);
|
|
28467
28720
|
try {
|
|
28468
|
-
|
|
28721
|
+
fs52.mkdirSync(path60.dirname(lockPath), { recursive: true });
|
|
28469
28722
|
try {
|
|
28470
|
-
|
|
28723
|
+
fs52.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
|
|
28471
28724
|
} catch (e) {
|
|
28472
28725
|
if (e.code !== "EEXIST") throw e;
|
|
28473
28726
|
if (isLiveLockHolder(readLockRecord(lockPath))) return false;
|
|
28474
|
-
|
|
28727
|
+
fs52.writeFileSync(lockPath, ownLockBody());
|
|
28475
28728
|
}
|
|
28476
28729
|
const release3 = () => releaseOwnLock(lockPath);
|
|
28477
28730
|
process.once("exit", release3);
|
|
@@ -28491,13 +28744,13 @@ function acquireDaemonLock(sessionId) {
|
|
|
28491
28744
|
function acquireSingletonLock() {
|
|
28492
28745
|
const lockPath = pairAutoLockPath();
|
|
28493
28746
|
try {
|
|
28494
|
-
|
|
28747
|
+
fs52.mkdirSync(path60.dirname(lockPath), { recursive: true });
|
|
28495
28748
|
try {
|
|
28496
|
-
|
|
28749
|
+
fs52.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
|
|
28497
28750
|
} catch (e) {
|
|
28498
28751
|
if (e.code !== "EEXIST") throw e;
|
|
28499
28752
|
if (isLiveLockHolder(readLockRecord(lockPath))) return false;
|
|
28500
|
-
|
|
28753
|
+
fs52.writeFileSync(lockPath, ownLockBody());
|
|
28501
28754
|
}
|
|
28502
28755
|
process.once("exit", () => releaseOwnLock(lockPath));
|
|
28503
28756
|
return true;
|
|
@@ -28914,7 +29167,7 @@ var AgentService = class _AgentService {
|
|
|
28914
29167
|
};
|
|
28915
29168
|
|
|
28916
29169
|
// src/agents/acp/adapters.ts
|
|
28917
|
-
var
|
|
29170
|
+
var path61 = __toESM(require("path"));
|
|
28918
29171
|
|
|
28919
29172
|
// src/agents/kimi/installer.ts
|
|
28920
29173
|
var import_node_child_process19 = require("child_process");
|
|
@@ -29034,13 +29287,13 @@ function resolveBin(pkgName, binName) {
|
|
|
29034
29287
|
try {
|
|
29035
29288
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
29036
29289
|
const manifest = require_(`${pkgName}/package.json`);
|
|
29037
|
-
const pkgDir =
|
|
29290
|
+
const pkgDir = path61.dirname(manifestPath);
|
|
29038
29291
|
const bin = manifest.bin;
|
|
29039
29292
|
if (!bin) return null;
|
|
29040
|
-
if (typeof bin === "string") return
|
|
29293
|
+
if (typeof bin === "string") return path61.resolve(pkgDir, bin);
|
|
29041
29294
|
const target = binName ?? Object.keys(bin)[0];
|
|
29042
29295
|
if (!target || !bin[target]) return null;
|
|
29043
|
-
return
|
|
29296
|
+
return path61.resolve(pkgDir, bin[target]);
|
|
29044
29297
|
} catch {
|
|
29045
29298
|
return null;
|
|
29046
29299
|
}
|
|
@@ -29220,30 +29473,30 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
|
|
|
29220
29473
|
}
|
|
29221
29474
|
|
|
29222
29475
|
// src/agents/acp/runner.ts
|
|
29223
|
-
var
|
|
29224
|
-
var
|
|
29476
|
+
var import_node_crypto11 = require("crypto");
|
|
29477
|
+
var fs69 = __toESM(require("fs"));
|
|
29225
29478
|
var os53 = __toESM(require("os"));
|
|
29226
|
-
var
|
|
29479
|
+
var path80 = __toESM(require("path"));
|
|
29227
29480
|
|
|
29228
29481
|
// src/lib/provider-routing.ts
|
|
29229
|
-
var
|
|
29482
|
+
var fs54 = __toESM(require("fs"));
|
|
29230
29483
|
var os42 = __toESM(require("os"));
|
|
29231
|
-
var
|
|
29484
|
+
var path63 = __toESM(require("path"));
|
|
29232
29485
|
|
|
29233
29486
|
// src/commands/host/house-proxy-config.ts
|
|
29234
|
-
var
|
|
29487
|
+
var fs53 = __toESM(require("fs"));
|
|
29235
29488
|
var os41 = __toESM(require("os"));
|
|
29236
|
-
var
|
|
29489
|
+
var path62 = __toESM(require("path"));
|
|
29237
29490
|
function houseProxyConfigPath() {
|
|
29238
|
-
return
|
|
29491
|
+
return path62.join(os41.homedir(), ".codeam", "house-proxy.json");
|
|
29239
29492
|
}
|
|
29240
29493
|
function persistHouseProxyConfig(config) {
|
|
29241
29494
|
try {
|
|
29242
29495
|
const file = houseProxyConfigPath();
|
|
29243
|
-
|
|
29496
|
+
fs53.mkdirSync(path62.dirname(file), { recursive: true, mode: 448 });
|
|
29244
29497
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
29245
|
-
|
|
29246
|
-
|
|
29498
|
+
fs53.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
29499
|
+
fs53.renameSync(tmp, file);
|
|
29247
29500
|
restrictToOwner(file);
|
|
29248
29501
|
} catch (err) {
|
|
29249
29502
|
log.warn(
|
|
@@ -29254,13 +29507,13 @@ function persistHouseProxyConfig(config) {
|
|
|
29254
29507
|
}
|
|
29255
29508
|
function clearHouseProxyConfig() {
|
|
29256
29509
|
try {
|
|
29257
|
-
|
|
29510
|
+
fs53.rmSync(houseProxyConfigPath(), { force: true });
|
|
29258
29511
|
} catch {
|
|
29259
29512
|
}
|
|
29260
29513
|
}
|
|
29261
29514
|
function readHouseProxyChildEnv() {
|
|
29262
29515
|
try {
|
|
29263
|
-
const raw =
|
|
29516
|
+
const raw = fs53.readFileSync(houseProxyConfigPath(), "utf8");
|
|
29264
29517
|
const parsed = JSON.parse(raw);
|
|
29265
29518
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
29266
29519
|
const o = parsed;
|
|
@@ -29387,14 +29640,14 @@ function redactUrlToOrigin(raw) {
|
|
|
29387
29640
|
}
|
|
29388
29641
|
function readOpencodeProviderOrigins(opts = {}) {
|
|
29389
29642
|
const home = opts.homeDir ?? os42.homedir();
|
|
29390
|
-
const readFile7 = opts.readFile ?? ((f) =>
|
|
29643
|
+
const readFile7 = opts.readFile ?? ((f) => fs54.readFileSync(f, "utf8"));
|
|
29391
29644
|
const candidates = [];
|
|
29392
29645
|
if (opts.cwd) {
|
|
29393
|
-
candidates.push(
|
|
29646
|
+
candidates.push(path63.join(opts.cwd, "opencode.json"), path63.join(opts.cwd, "opencode.jsonc"));
|
|
29394
29647
|
}
|
|
29395
29648
|
candidates.push(
|
|
29396
|
-
|
|
29397
|
-
|
|
29649
|
+
path63.join(home, ".config", "opencode", "opencode.json"),
|
|
29650
|
+
path63.join(home, ".config", "opencode", "opencode.jsonc")
|
|
29398
29651
|
);
|
|
29399
29652
|
const out2 = [];
|
|
29400
29653
|
const seen2 = /* @__PURE__ */ new Set();
|
|
@@ -29501,8 +29754,8 @@ function noteProviderBillingSignal(opts) {
|
|
|
29501
29754
|
}
|
|
29502
29755
|
|
|
29503
29756
|
// src/services/history.service.ts
|
|
29504
|
-
var
|
|
29505
|
-
var
|
|
29757
|
+
var fs55 = __toESM(require("fs"));
|
|
29758
|
+
var path64 = __toESM(require("path"));
|
|
29506
29759
|
var os43 = __toESM(require("os"));
|
|
29507
29760
|
var https6 = __toESM(require("https"));
|
|
29508
29761
|
var http9 = __toESM(require("http"));
|
|
@@ -29564,7 +29817,7 @@ function parseJsonl(filePath) {
|
|
|
29564
29817
|
const messages = [];
|
|
29565
29818
|
let raw;
|
|
29566
29819
|
try {
|
|
29567
|
-
raw =
|
|
29820
|
+
raw = fs55.readFileSync(filePath, "utf8");
|
|
29568
29821
|
} catch (err) {
|
|
29569
29822
|
if (err.code !== "ENOENT") {
|
|
29570
29823
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -29718,7 +29971,7 @@ var HistoryService = class _HistoryService {
|
|
|
29718
29971
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
29719
29972
|
}
|
|
29720
29973
|
get projectDir() {
|
|
29721
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
29974
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path64.join(os43.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
29722
29975
|
}
|
|
29723
29976
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
29724
29977
|
setCurrentConversationId(id) {
|
|
@@ -29730,7 +29983,7 @@ var HistoryService = class _HistoryService {
|
|
|
29730
29983
|
/** Return the current message count in the active conversation. */
|
|
29731
29984
|
getCurrentMessageCount() {
|
|
29732
29985
|
if (!this.currentConversationId) return 0;
|
|
29733
|
-
const filePath =
|
|
29986
|
+
const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
29734
29987
|
return parseJsonl(filePath).length;
|
|
29735
29988
|
}
|
|
29736
29989
|
/**
|
|
@@ -29741,7 +29994,7 @@ var HistoryService = class _HistoryService {
|
|
|
29741
29994
|
const deadline = Date.now() + timeoutMs;
|
|
29742
29995
|
while (Date.now() < deadline) {
|
|
29743
29996
|
if (!this.currentConversationId) return null;
|
|
29744
|
-
const filePath =
|
|
29997
|
+
const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
29745
29998
|
const messages = parseJsonl(filePath);
|
|
29746
29999
|
if (messages.length > previousCount) {
|
|
29747
30000
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -29767,16 +30020,16 @@ var HistoryService = class _HistoryService {
|
|
|
29767
30020
|
const dir = this.projectDir;
|
|
29768
30021
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
29769
30022
|
try {
|
|
29770
|
-
const files =
|
|
30023
|
+
const files = fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
29771
30024
|
try {
|
|
29772
|
-
const stat3 =
|
|
30025
|
+
const stat3 = fs55.statSync(path64.join(dir, e.name));
|
|
29773
30026
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
29774
30027
|
} catch {
|
|
29775
30028
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
29776
30029
|
}
|
|
29777
30030
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
29778
30031
|
if (files.length > 0) {
|
|
29779
|
-
this.currentConversationId =
|
|
30032
|
+
this.currentConversationId = path64.basename(files[0].name, ".jsonl");
|
|
29780
30033
|
}
|
|
29781
30034
|
} catch {
|
|
29782
30035
|
}
|
|
@@ -29810,13 +30063,13 @@ var HistoryService = class _HistoryService {
|
|
|
29810
30063
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
29811
30064
|
let entries;
|
|
29812
30065
|
try {
|
|
29813
|
-
entries =
|
|
30066
|
+
entries = fs55.readdirSync(dir, { withFileTypes: true });
|
|
29814
30067
|
} catch {
|
|
29815
30068
|
return null;
|
|
29816
30069
|
}
|
|
29817
30070
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
29818
30071
|
try {
|
|
29819
|
-
const stat3 =
|
|
30072
|
+
const stat3 = fs55.statSync(path64.join(dir, e.name));
|
|
29820
30073
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
29821
30074
|
} catch {
|
|
29822
30075
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -29825,12 +30078,12 @@ var HistoryService = class _HistoryService {
|
|
|
29825
30078
|
if (files.length === 0) return null;
|
|
29826
30079
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
29827
30080
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
29828
|
-
return this.extractUsageFromFile(
|
|
30081
|
+
return this.extractUsageFromFile(path64.join(dir, targetFile));
|
|
29829
30082
|
}
|
|
29830
30083
|
extractUsageFromFile(filePath) {
|
|
29831
30084
|
let raw;
|
|
29832
30085
|
try {
|
|
29833
|
-
raw =
|
|
30086
|
+
raw = fs55.readFileSync(filePath, "utf8");
|
|
29834
30087
|
} catch {
|
|
29835
30088
|
return null;
|
|
29836
30089
|
}
|
|
@@ -29882,9 +30135,9 @@ var HistoryService = class _HistoryService {
|
|
|
29882
30135
|
let totalCost = 0;
|
|
29883
30136
|
let files;
|
|
29884
30137
|
try {
|
|
29885
|
-
files =
|
|
30138
|
+
files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
29886
30139
|
try {
|
|
29887
|
-
return
|
|
30140
|
+
return fs55.statSync(path64.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
29888
30141
|
} catch {
|
|
29889
30142
|
return false;
|
|
29890
30143
|
}
|
|
@@ -29895,7 +30148,7 @@ var HistoryService = class _HistoryService {
|
|
|
29895
30148
|
for (const file of files) {
|
|
29896
30149
|
let raw;
|
|
29897
30150
|
try {
|
|
29898
|
-
raw =
|
|
30151
|
+
raw = fs55.readFileSync(path64.join(projectDir, file), "utf8");
|
|
29899
30152
|
} catch {
|
|
29900
30153
|
continue;
|
|
29901
30154
|
}
|
|
@@ -29974,7 +30227,7 @@ var HistoryService = class _HistoryService {
|
|
|
29974
30227
|
if (this.runtime.resolveHistoryFile) {
|
|
29975
30228
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
29976
30229
|
}
|
|
29977
|
-
return
|
|
30230
|
+
return path64.join(this.projectDir, `${sessionId}.jsonl`);
|
|
29978
30231
|
}
|
|
29979
30232
|
/**
|
|
29980
30233
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -30012,14 +30265,14 @@ var HistoryService = class _HistoryService {
|
|
|
30012
30265
|
};
|
|
30013
30266
|
});
|
|
30014
30267
|
}
|
|
30015
|
-
return parseJsonl(
|
|
30268
|
+
return parseJsonl(path64.join(this.projectDir, `${sessionId}.jsonl`));
|
|
30016
30269
|
}
|
|
30017
30270
|
/** One in-flight full upload per conversation — the baton mirror and a
|
|
30018
30271
|
* `get_conversation` used to upload the same transcript concurrently. */
|
|
30019
30272
|
uploadsInFlight = /* @__PURE__ */ new Map();
|
|
30020
30273
|
async loadConversation(sessionId) {
|
|
30021
|
-
const
|
|
30022
|
-
if (
|
|
30274
|
+
const inFlight2 = this.uploadsInFlight.get(sessionId);
|
|
30275
|
+
if (inFlight2) return inFlight2;
|
|
30023
30276
|
const run = this.loadConversationNow(sessionId).finally(() => {
|
|
30024
30277
|
this.uploadsInFlight.delete(sessionId);
|
|
30025
30278
|
});
|
|
@@ -30094,7 +30347,7 @@ var HistoryService = class _HistoryService {
|
|
|
30094
30347
|
if (!filePath) return false;
|
|
30095
30348
|
let mtimeMs;
|
|
30096
30349
|
try {
|
|
30097
|
-
mtimeMs =
|
|
30350
|
+
mtimeMs = fs55.statSync(filePath).mtimeMs;
|
|
30098
30351
|
} catch {
|
|
30099
30352
|
return false;
|
|
30100
30353
|
}
|
|
@@ -30169,10 +30422,10 @@ var HistoryService = class _HistoryService {
|
|
|
30169
30422
|
|
|
30170
30423
|
// src/agents/acp/client.ts
|
|
30171
30424
|
var import_node_child_process21 = require("child_process");
|
|
30172
|
-
var
|
|
30425
|
+
var fs56 = __toESM(require("fs/promises"));
|
|
30173
30426
|
var fsSync = __toESM(require("fs"));
|
|
30174
30427
|
var os45 = __toESM(require("os"));
|
|
30175
|
-
var
|
|
30428
|
+
var path66 = __toESM(require("path"));
|
|
30176
30429
|
var import_node_stream = require("stream");
|
|
30177
30430
|
|
|
30178
30431
|
// ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
|
|
@@ -34198,7 +34451,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
|
|
|
34198
34451
|
}
|
|
34199
34452
|
|
|
34200
34453
|
// src/agents/acp/internal-paths.ts
|
|
34201
|
-
var
|
|
34454
|
+
var path65 = __toESM(require("path"));
|
|
34202
34455
|
var os44 = __toESM(require("os"));
|
|
34203
34456
|
var INTERNAL_TOKENS = [".codeam", "house-claude"];
|
|
34204
34457
|
var PROSE_ONLY_TOOL_KINDS = /* @__PURE__ */ new Set(["think", "switch_mode"]);
|
|
@@ -34213,11 +34466,11 @@ function textReferencesInternal(text) {
|
|
|
34213
34466
|
}
|
|
34214
34467
|
function pathIsInternal(p2, homeDir2 = os44.homedir()) {
|
|
34215
34468
|
if (!p2) return false;
|
|
34216
|
-
const abs =
|
|
34217
|
-
const home =
|
|
34218
|
-
const within = (root) => abs === root || abs.startsWith(root +
|
|
34219
|
-
if (within(
|
|
34220
|
-
return within(
|
|
34469
|
+
const abs = path65.resolve(p2);
|
|
34470
|
+
const home = path65.resolve(homeDir2);
|
|
34471
|
+
const within = (root) => abs === root || abs.startsWith(root + path65.sep);
|
|
34472
|
+
if (within(path65.join(home, ".codeam", "self-hosted"))) return false;
|
|
34473
|
+
return within(path65.join(home, ".codeam")) || within(path65.join(home, ".beads")) || abs === path65.join(home, ".codeam-host.log") || abs.includes(`${path65.sep}house-claude${path65.sep}`) || abs.endsWith(`${path65.sep}house-claude`);
|
|
34221
34474
|
}
|
|
34222
34475
|
function toolCallReferencesInternal(call, homeDir2) {
|
|
34223
34476
|
if (call.locations?.some((l) => pathIsInternal(l.path, homeDir2))) return true;
|
|
@@ -35312,7 +35565,7 @@ var AcpClient = class {
|
|
|
35312
35565
|
throw new RequestError(-32002, GUARDRAIL_SECRET_READ_BLOCK_REASON, { uri: params.path });
|
|
35313
35566
|
}
|
|
35314
35567
|
try {
|
|
35315
|
-
const content = await
|
|
35568
|
+
const content = await fs56.readFile(params.path, "utf8");
|
|
35316
35569
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
35317
35570
|
} catch (err) {
|
|
35318
35571
|
const code = err.code;
|
|
@@ -35333,7 +35586,7 @@ var AcpClient = class {
|
|
|
35333
35586
|
throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
|
|
35334
35587
|
}
|
|
35335
35588
|
try {
|
|
35336
|
-
await
|
|
35589
|
+
await fs56.writeFile(params.path, params.content, "utf8");
|
|
35337
35590
|
return {};
|
|
35338
35591
|
} catch (err) {
|
|
35339
35592
|
const code = err.code;
|
|
@@ -35426,25 +35679,25 @@ function knownAgentBinaryDirs() {
|
|
|
35426
35679
|
out2.push("/tmp/codeam-node20/bin");
|
|
35427
35680
|
for (const root of [
|
|
35428
35681
|
"/usr/local/share/nvm/versions/node",
|
|
35429
|
-
|
|
35682
|
+
path66.join(home, ".nvm/versions/node")
|
|
35430
35683
|
]) {
|
|
35431
35684
|
try {
|
|
35432
35685
|
for (const child of fsSync.readdirSync(root)) {
|
|
35433
|
-
out2.push(
|
|
35686
|
+
out2.push(path66.join(root, child, "bin"));
|
|
35434
35687
|
}
|
|
35435
35688
|
} catch {
|
|
35436
35689
|
}
|
|
35437
35690
|
}
|
|
35438
|
-
out2.push(
|
|
35691
|
+
out2.push(path66.join(home, ".volta/bin"));
|
|
35439
35692
|
out2.push("/usr/local/bin");
|
|
35440
35693
|
out2.push("/usr/bin");
|
|
35441
|
-
out2.push(
|
|
35442
|
-
out2.push(
|
|
35694
|
+
out2.push(path66.join(home, ".local/bin"));
|
|
35695
|
+
out2.push(path66.join(home, "bin"));
|
|
35443
35696
|
out2.push(...agentInstallBinDirs());
|
|
35444
35697
|
if (process.platform === "win32") {
|
|
35445
35698
|
const { LOCALAPPDATA, APPDATA } = process.env;
|
|
35446
|
-
if (LOCALAPPDATA) out2.push(
|
|
35447
|
-
if (APPDATA) out2.push(
|
|
35699
|
+
if (LOCALAPPDATA) out2.push(path66.join(LOCALAPPDATA, "cursor-agent"));
|
|
35700
|
+
if (APPDATA) out2.push(path66.join(APPDATA, "npm"));
|
|
35448
35701
|
}
|
|
35449
35702
|
return out2.filter((p2) => {
|
|
35450
35703
|
try {
|
|
@@ -35455,7 +35708,7 @@ function knownAgentBinaryDirs() {
|
|
|
35455
35708
|
});
|
|
35456
35709
|
}
|
|
35457
35710
|
function expandPathForAgentBinaries(existingPath) {
|
|
35458
|
-
const existing = new Set(existingPath.split(
|
|
35711
|
+
const existing = new Set(existingPath.split(path66.delimiter).filter((p2) => p2.length > 0));
|
|
35459
35712
|
const additions = [];
|
|
35460
35713
|
for (const dir of knownAgentBinaryDirs()) {
|
|
35461
35714
|
if (!existing.has(dir)) {
|
|
@@ -35464,7 +35717,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
35464
35717
|
}
|
|
35465
35718
|
}
|
|
35466
35719
|
if (additions.length === 0) return existingPath;
|
|
35467
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
35720
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path66.delimiter);
|
|
35468
35721
|
}
|
|
35469
35722
|
|
|
35470
35723
|
// src/commands/host/agent-install.ts
|
|
@@ -35736,9 +35989,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
|
|
|
35736
35989
|
}
|
|
35737
35990
|
|
|
35738
35991
|
// src/commands/host/agent-provisioning.ts
|
|
35739
|
-
var
|
|
35992
|
+
var fs57 = __toESM(require("fs"));
|
|
35740
35993
|
var os47 = __toESM(require("os"));
|
|
35741
|
-
var
|
|
35994
|
+
var path67 = __toESM(require("path"));
|
|
35742
35995
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
35743
35996
|
claude_code: "claude",
|
|
35744
35997
|
claude: "claude",
|
|
@@ -35755,22 +36008,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
35755
36008
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
35756
36009
|
}
|
|
35757
36010
|
function ensureDir(dir) {
|
|
35758
|
-
|
|
36011
|
+
fs57.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
35759
36012
|
}
|
|
35760
36013
|
function writeFile0600(filePath, contents) {
|
|
35761
|
-
ensureDir(
|
|
35762
|
-
|
|
36014
|
+
ensureDir(path67.dirname(filePath));
|
|
36015
|
+
fs57.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
35763
36016
|
restrictToOwner(filePath);
|
|
35764
36017
|
}
|
|
35765
36018
|
function rmIfExists(filePath) {
|
|
35766
36019
|
try {
|
|
35767
|
-
|
|
36020
|
+
fs57.rmSync(filePath, { force: true });
|
|
35768
36021
|
} catch {
|
|
35769
36022
|
}
|
|
35770
36023
|
}
|
|
35771
36024
|
var claudeProvisioner = {
|
|
35772
36025
|
write(auth, home) {
|
|
35773
|
-
const credentialsJson =
|
|
36026
|
+
const credentialsJson = path67.join(home, ".claude", ".credentials.json");
|
|
35774
36027
|
if (auth.kind === "api_key") {
|
|
35775
36028
|
rmIfExists(credentialsJson);
|
|
35776
36029
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -35782,8 +36035,8 @@ var claudeProvisioner = {
|
|
|
35782
36035
|
} else {
|
|
35783
36036
|
rmIfExists(credentialsJson);
|
|
35784
36037
|
}
|
|
35785
|
-
const claudeJson =
|
|
35786
|
-
if (!
|
|
36038
|
+
const claudeJson = path67.join(home, ".claude.json");
|
|
36039
|
+
if (!fs57.existsSync(claudeJson)) {
|
|
35787
36040
|
writeFile0600(
|
|
35788
36041
|
claudeJson,
|
|
35789
36042
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -35794,7 +36047,7 @@ var claudeProvisioner = {
|
|
|
35794
36047
|
};
|
|
35795
36048
|
var codexProvisioner = {
|
|
35796
36049
|
write(auth, home) {
|
|
35797
|
-
const authJson =
|
|
36050
|
+
const authJson = path67.join(home, ".codex", "auth.json");
|
|
35798
36051
|
if (auth.kind === "api_key") {
|
|
35799
36052
|
writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
|
|
35800
36053
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -35805,8 +36058,8 @@ var codexProvisioner = {
|
|
|
35805
36058
|
};
|
|
35806
36059
|
var geminiProvisioner = {
|
|
35807
36060
|
write(auth, home) {
|
|
35808
|
-
const settingsJson =
|
|
35809
|
-
const oauthCreds =
|
|
36061
|
+
const settingsJson = path67.join(home, ".gemini", "settings.json");
|
|
36062
|
+
const oauthCreds = path67.join(home, ".gemini", "oauth_creds.json");
|
|
35810
36063
|
if (auth.kind === "api_key") {
|
|
35811
36064
|
rmIfExists(oauthCreds);
|
|
35812
36065
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -35819,7 +36072,7 @@ var geminiProvisioner = {
|
|
|
35819
36072
|
};
|
|
35820
36073
|
var cursorProvisioner = {
|
|
35821
36074
|
write(auth, home) {
|
|
35822
|
-
const authJson =
|
|
36075
|
+
const authJson = path67.join(home, ".config", "cursor", "auth.json");
|
|
35823
36076
|
if (auth.kind === "api_key") {
|
|
35824
36077
|
rmIfExists(authJson);
|
|
35825
36078
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -35861,22 +36114,22 @@ max_context_size = 262144
|
|
|
35861
36114
|
var kimiProvisioner = {
|
|
35862
36115
|
write(auth, home) {
|
|
35863
36116
|
const credentialsFiles = [
|
|
35864
|
-
|
|
35865
|
-
|
|
36117
|
+
path67.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
36118
|
+
path67.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
35866
36119
|
];
|
|
35867
36120
|
if (auth.kind === "api_key") {
|
|
35868
36121
|
credentialsFiles.forEach(rmIfExists);
|
|
35869
36122
|
return { KIMI_API_KEY: auth.value };
|
|
35870
36123
|
}
|
|
35871
36124
|
credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
|
|
35872
|
-
writeFile0600(
|
|
36125
|
+
writeFile0600(path67.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
|
|
35873
36126
|
return {};
|
|
35874
36127
|
}
|
|
35875
36128
|
};
|
|
35876
36129
|
var coderabbitProvisioner = {
|
|
35877
36130
|
write(auth, home) {
|
|
35878
|
-
const dir =
|
|
35879
|
-
const authJson =
|
|
36131
|
+
const dir = path67.join(home, ".coderabbit");
|
|
36132
|
+
const authJson = path67.join(dir, "auth.json");
|
|
35880
36133
|
if (auth.kind === "api_key") {
|
|
35881
36134
|
rmIfExists(authJson);
|
|
35882
36135
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -35888,13 +36141,13 @@ var coderabbitProvisioner = {
|
|
|
35888
36141
|
try {
|
|
35889
36142
|
const parsed = JSON.parse(value);
|
|
35890
36143
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
35891
|
-
file =
|
|
36144
|
+
file = path67.basename(parsed.file);
|
|
35892
36145
|
contents = parsed.contents;
|
|
35893
36146
|
}
|
|
35894
36147
|
} catch {
|
|
35895
36148
|
}
|
|
35896
36149
|
}
|
|
35897
|
-
writeFile0600(
|
|
36150
|
+
writeFile0600(path67.join(dir, file), contents);
|
|
35898
36151
|
return {};
|
|
35899
36152
|
}
|
|
35900
36153
|
};
|
|
@@ -35931,16 +36184,16 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir(
|
|
|
35931
36184
|
}
|
|
35932
36185
|
|
|
35933
36186
|
// src/beads/workflow-hint.ts
|
|
35934
|
-
var
|
|
35935
|
-
var
|
|
36187
|
+
var fs58 = __toESM(require("fs"));
|
|
36188
|
+
var path69 = __toESM(require("path"));
|
|
35936
36189
|
|
|
35937
36190
|
// src/agents/claude-memory-file.ts
|
|
35938
36191
|
var os48 = __toESM(require("os"));
|
|
35939
|
-
var
|
|
36192
|
+
var path68 = __toESM(require("path"));
|
|
35940
36193
|
function claudeMemoryFile(homeDir2, env = process.env) {
|
|
35941
|
-
if (homeDir2) return
|
|
36194
|
+
if (homeDir2) return path68.join(homeDir2, ".claude", "CLAUDE.md");
|
|
35942
36195
|
const configDir = env.CLAUDE_CONFIG_DIR?.trim();
|
|
35943
|
-
return configDir ?
|
|
36196
|
+
return configDir ? path68.join(configDir, "CLAUDE.md") : path68.join(os48.homedir(), ".claude", "CLAUDE.md");
|
|
35944
36197
|
}
|
|
35945
36198
|
|
|
35946
36199
|
// src/beads/workflow-hint.ts
|
|
@@ -35970,11 +36223,11 @@ function ensureBeadsWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
|
|
|
35970
36223
|
try {
|
|
35971
36224
|
let existing = "";
|
|
35972
36225
|
try {
|
|
35973
|
-
existing =
|
|
36226
|
+
existing = fs58.readFileSync(file, "utf8");
|
|
35974
36227
|
} catch {
|
|
35975
36228
|
}
|
|
35976
36229
|
if (existing.includes(BEADS_HINT)) return;
|
|
35977
|
-
|
|
36230
|
+
fs58.mkdirSync(path69.dirname(file), { recursive: true });
|
|
35978
36231
|
let next;
|
|
35979
36232
|
const open = existing.indexOf(BEADS_HINT_MARKER);
|
|
35980
36233
|
const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
|
|
@@ -35987,40 +36240,40 @@ ${BEADS_HINT}
|
|
|
35987
36240
|
` : `${BEADS_HINT}
|
|
35988
36241
|
`;
|
|
35989
36242
|
}
|
|
35990
|
-
|
|
36243
|
+
fs58.writeFileSync(file, next);
|
|
35991
36244
|
} catch {
|
|
35992
36245
|
}
|
|
35993
36246
|
}
|
|
35994
36247
|
|
|
35995
36248
|
// src/agents/agent-standard.ts
|
|
35996
|
-
var
|
|
35997
|
-
var
|
|
36249
|
+
var fs59 = __toESM(require("fs"));
|
|
36250
|
+
var path70 = __toESM(require("path"));
|
|
35998
36251
|
var os49 = __toESM(require("os"));
|
|
35999
36252
|
function ensureAgentStandard(homeDir2, file = claudeMemoryFile(homeDir2)) {
|
|
36000
36253
|
try {
|
|
36001
36254
|
let existing = "";
|
|
36002
36255
|
try {
|
|
36003
|
-
existing =
|
|
36256
|
+
existing = fs59.readFileSync(file, "utf8");
|
|
36004
36257
|
} catch {
|
|
36005
36258
|
}
|
|
36006
36259
|
if (existing.includes(AGENT_STANDARD_MARKER)) return;
|
|
36007
|
-
|
|
36260
|
+
fs59.mkdirSync(path70.dirname(file), { recursive: true });
|
|
36008
36261
|
const next = existing.trim() ? `${existing.trimEnd()}
|
|
36009
36262
|
|
|
36010
36263
|
${AGENT_STANDARD_BLOCK}
|
|
36011
36264
|
` : `${AGENT_STANDARD_BLOCK}
|
|
36012
36265
|
`;
|
|
36013
|
-
|
|
36266
|
+
fs59.writeFileSync(file, next);
|
|
36014
36267
|
} catch {
|
|
36015
36268
|
}
|
|
36016
36269
|
}
|
|
36017
36270
|
var _agentStandardSeam = {
|
|
36018
36271
|
isLocalSession: () => isLocalSession(),
|
|
36019
|
-
markerPath: (sessionId) =>
|
|
36020
|
-
exists: (p2) =>
|
|
36272
|
+
markerPath: (sessionId) => path70.join(os49.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
|
|
36273
|
+
exists: (p2) => fs59.existsSync(p2),
|
|
36021
36274
|
write: (p2) => {
|
|
36022
|
-
|
|
36023
|
-
|
|
36275
|
+
fs59.mkdirSync(path70.dirname(p2), { recursive: true });
|
|
36276
|
+
fs59.writeFileSync(p2, "");
|
|
36024
36277
|
}
|
|
36025
36278
|
};
|
|
36026
36279
|
function isClaude(agent) {
|
|
@@ -36713,15 +36966,15 @@ function withholdTrailingPartialFenceMarker(text) {
|
|
|
36713
36966
|
|
|
36714
36967
|
// src/agents/acp/onboarding.ts
|
|
36715
36968
|
var import_child_process28 = require("child_process");
|
|
36716
|
-
var
|
|
36969
|
+
var fs60 = __toESM(require("fs"));
|
|
36717
36970
|
var os50 = __toESM(require("os"));
|
|
36718
|
-
var
|
|
36971
|
+
var path71 = __toESM(require("path"));
|
|
36719
36972
|
var _onboardingSeam = {
|
|
36720
|
-
markerPath: (sessionId) =>
|
|
36721
|
-
exists: (p2) =>
|
|
36973
|
+
markerPath: (sessionId) => path71.join(os50.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
36974
|
+
exists: (p2) => fs60.existsSync(p2),
|
|
36722
36975
|
write: (p2) => {
|
|
36723
|
-
|
|
36724
|
-
|
|
36976
|
+
fs60.mkdirSync(path71.dirname(p2), { recursive: true });
|
|
36977
|
+
fs60.writeFileSync(p2, "");
|
|
36725
36978
|
},
|
|
36726
36979
|
disabled: () => {
|
|
36727
36980
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -36758,7 +37011,7 @@ function resolveRepoName(cwd) {
|
|
|
36758
37011
|
if (name) return name;
|
|
36759
37012
|
}
|
|
36760
37013
|
}
|
|
36761
|
-
const base =
|
|
37014
|
+
const base = path71.basename(cwd || "");
|
|
36762
37015
|
if (base && !isUuid(base)) return base;
|
|
36763
37016
|
return "this project";
|
|
36764
37017
|
}
|
|
@@ -37150,13 +37403,13 @@ var import_crypto4 = require("crypto");
|
|
|
37150
37403
|
|
|
37151
37404
|
// src/services/turn-files/git-changeset.ts
|
|
37152
37405
|
var import_child_process29 = require("child_process");
|
|
37153
|
-
var
|
|
37154
|
-
var
|
|
37406
|
+
var fs62 = __toESM(require("fs/promises"));
|
|
37407
|
+
var path73 = __toESM(require("path"));
|
|
37155
37408
|
|
|
37156
37409
|
// src/services/turn-files/review-ignore.ts
|
|
37157
37410
|
var import_ignore2 = __toESM(require("ignore"));
|
|
37158
|
-
var
|
|
37159
|
-
var
|
|
37411
|
+
var fs61 = __toESM(require("fs"));
|
|
37412
|
+
var path72 = __toESM(require("path"));
|
|
37160
37413
|
var CURATED_REVIEW_IGNORE = [
|
|
37161
37414
|
// Google Cloud SDK (the incident) — installs a huge python tree.
|
|
37162
37415
|
"google-cloud-sdk/",
|
|
@@ -37195,7 +37448,7 @@ var CURATED_REVIEW_IGNORE = [
|
|
|
37195
37448
|
function makeReviewIgnore(repoRoot) {
|
|
37196
37449
|
const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
|
|
37197
37450
|
try {
|
|
37198
|
-
const custom =
|
|
37451
|
+
const custom = fs61.readFileSync(path72.join(repoRoot, ".codeam", "reviewignore"), "utf8");
|
|
37199
37452
|
ig.add(custom);
|
|
37200
37453
|
} catch {
|
|
37201
37454
|
}
|
|
@@ -37240,7 +37493,7 @@ async function collectRepoChangeset(opts) {
|
|
|
37240
37493
|
let stats;
|
|
37241
37494
|
if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
|
|
37242
37495
|
const lineCount = await readUntrackedLineCount(
|
|
37243
|
-
|
|
37496
|
+
path73.join(opts.repoRoot, row.filePath)
|
|
37244
37497
|
);
|
|
37245
37498
|
stats = { added: lineCount, removed: 0 };
|
|
37246
37499
|
} else {
|
|
@@ -37271,7 +37524,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
37271
37524
|
}
|
|
37272
37525
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
37273
37526
|
try {
|
|
37274
|
-
const content = await
|
|
37527
|
+
const content = await fs62.readFile(absPath, "utf8");
|
|
37275
37528
|
let count = 0;
|
|
37276
37529
|
let pos = -1;
|
|
37277
37530
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -37363,7 +37616,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
37363
37616
|
});
|
|
37364
37617
|
}
|
|
37365
37618
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
37366
|
-
const
|
|
37619
|
+
const fs81 = await import("fs/promises");
|
|
37367
37620
|
const out2 = [];
|
|
37368
37621
|
await walk(workingDir, 0);
|
|
37369
37622
|
return out2;
|
|
@@ -37371,7 +37624,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
37371
37624
|
if (depth > maxDepth) return;
|
|
37372
37625
|
let entries = [];
|
|
37373
37626
|
try {
|
|
37374
|
-
const dirents = await
|
|
37627
|
+
const dirents = await fs81.readdir(dir, { withFileTypes: true });
|
|
37375
37628
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
37376
37629
|
} catch {
|
|
37377
37630
|
return;
|
|
@@ -37382,8 +37635,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
37382
37635
|
if (hasGit) {
|
|
37383
37636
|
out2.push({
|
|
37384
37637
|
repoRoot: dir,
|
|
37385
|
-
repoPath:
|
|
37386
|
-
repoName:
|
|
37638
|
+
repoPath: path73.relative(workingDir, dir),
|
|
37639
|
+
repoName: path73.basename(dir)
|
|
37387
37640
|
});
|
|
37388
37641
|
return;
|
|
37389
37642
|
}
|
|
@@ -37391,14 +37644,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
37391
37644
|
if (!entry.isDirectory) continue;
|
|
37392
37645
|
if (entry.name === "node_modules") continue;
|
|
37393
37646
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
37394
|
-
await walk(
|
|
37647
|
+
await walk(path73.join(dir, entry.name), depth + 1);
|
|
37395
37648
|
}
|
|
37396
37649
|
}
|
|
37397
37650
|
}
|
|
37398
37651
|
|
|
37399
37652
|
// src/services/turn-files/files-outbox.ts
|
|
37400
|
-
var
|
|
37401
|
-
var
|
|
37653
|
+
var fs63 = __toESM(require("fs/promises"));
|
|
37654
|
+
var path74 = __toESM(require("path"));
|
|
37402
37655
|
var import_os12 = require("os");
|
|
37403
37656
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
37404
37657
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -37431,16 +37684,16 @@ var FilesOutbox = class {
|
|
|
37431
37684
|
backoffIndex = 0;
|
|
37432
37685
|
stopped = false;
|
|
37433
37686
|
constructor(opts) {
|
|
37434
|
-
const base = opts.baseDir ??
|
|
37435
|
-
this.filePath =
|
|
37687
|
+
const base = opts.baseDir ?? path74.join(homeDir(), HOME_OUTBOX_DIR);
|
|
37688
|
+
this.filePath = path74.join(base, `${opts.sessionId}.jsonl`);
|
|
37436
37689
|
this.post = opts.post;
|
|
37437
37690
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
37438
37691
|
}
|
|
37439
37692
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
37440
37693
|
* line is durable on disk (not once the POST succeeds). */
|
|
37441
37694
|
async enqueue(entry) {
|
|
37442
|
-
await
|
|
37443
|
-
await
|
|
37695
|
+
await fs63.mkdir(path74.dirname(this.filePath), { recursive: true });
|
|
37696
|
+
await fs63.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
37444
37697
|
this.backoffIndex = 0;
|
|
37445
37698
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
37446
37699
|
}
|
|
@@ -37531,7 +37784,7 @@ var FilesOutbox = class {
|
|
|
37531
37784
|
async readAll() {
|
|
37532
37785
|
let raw = "";
|
|
37533
37786
|
try {
|
|
37534
|
-
raw = await
|
|
37787
|
+
raw = await fs63.readFile(this.filePath, "utf8");
|
|
37535
37788
|
} catch {
|
|
37536
37789
|
return [];
|
|
37537
37790
|
}
|
|
@@ -37555,12 +37808,12 @@ var FilesOutbox = class {
|
|
|
37555
37808
|
async rewrite(entries) {
|
|
37556
37809
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
37557
37810
|
if (entries.length === 0) {
|
|
37558
|
-
await
|
|
37811
|
+
await fs63.unlink(this.filePath).catch(() => void 0);
|
|
37559
37812
|
return;
|
|
37560
37813
|
}
|
|
37561
37814
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
37562
|
-
await
|
|
37563
|
-
await
|
|
37815
|
+
await fs63.writeFile(tmpPath, payload, "utf8");
|
|
37816
|
+
await fs63.rename(tmpPath, this.filePath);
|
|
37564
37817
|
}
|
|
37565
37818
|
};
|
|
37566
37819
|
function applyJitter(ms) {
|
|
@@ -38108,8 +38361,8 @@ async function postCredentialSync(opts, fetchImpl = fetch) {
|
|
|
38108
38361
|
|
|
38109
38362
|
// src/packs/gates.ts
|
|
38110
38363
|
var import_node_child_process22 = require("child_process");
|
|
38111
|
-
var
|
|
38112
|
-
var
|
|
38364
|
+
var fs64 = __toESM(require("fs"));
|
|
38365
|
+
var path75 = __toESM(require("path"));
|
|
38113
38366
|
var defaultCommandRunner = (file, args2, cwd, timeoutMs, env) => new Promise((resolve12) => {
|
|
38114
38367
|
(0, import_node_child_process22.execFile)(
|
|
38115
38368
|
file,
|
|
@@ -38159,7 +38412,7 @@ async function changedFiles(run, cwd, from, to) {
|
|
|
38159
38412
|
}
|
|
38160
38413
|
function readWorkspaceFile(cwd, relPath) {
|
|
38161
38414
|
try {
|
|
38162
|
-
return
|
|
38415
|
+
return fs64.readFileSync(path75.join(cwd, relPath), "utf8");
|
|
38163
38416
|
} catch {
|
|
38164
38417
|
return null;
|
|
38165
38418
|
}
|
|
@@ -38168,14 +38421,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
|
|
|
38168
38421
|
var CHECKS_TIMEOUT_MS = 5 * 6e4;
|
|
38169
38422
|
function detectChecksCommand(cwd) {
|
|
38170
38423
|
try {
|
|
38171
|
-
const cfg = JSON.parse(
|
|
38424
|
+
const cfg = JSON.parse(fs64.readFileSync(path75.join(cwd, ".codeam", "pack.json"), "utf8"));
|
|
38172
38425
|
if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
|
|
38173
38426
|
return cfg.checksCommand.trim();
|
|
38174
38427
|
}
|
|
38175
38428
|
} catch {
|
|
38176
38429
|
}
|
|
38177
38430
|
try {
|
|
38178
|
-
const pkg = JSON.parse(
|
|
38431
|
+
const pkg = JSON.parse(fs64.readFileSync(path75.join(cwd, "package.json"), "utf8"));
|
|
38179
38432
|
const test = pkg.scripts?.test;
|
|
38180
38433
|
if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
|
|
38181
38434
|
return "npm test";
|
|
@@ -38193,39 +38446,39 @@ ${res.stderr}`.trim();
|
|
|
38193
38446
|
}
|
|
38194
38447
|
|
|
38195
38448
|
// src/packs/run-store.ts
|
|
38196
|
-
var
|
|
38197
|
-
var
|
|
38449
|
+
var fs65 = __toESM(require("fs"));
|
|
38450
|
+
var path76 = __toESM(require("path"));
|
|
38198
38451
|
var crypto5 = __toESM(require("crypto"));
|
|
38199
38452
|
function packsDir(cwd) {
|
|
38200
|
-
return
|
|
38453
|
+
return path76.join(cwd, ".codeam", "packs");
|
|
38201
38454
|
}
|
|
38202
38455
|
function runDir(cwd, runId) {
|
|
38203
|
-
return
|
|
38456
|
+
return path76.join(packsDir(cwd), runId);
|
|
38204
38457
|
}
|
|
38205
38458
|
function newRunId() {
|
|
38206
38459
|
return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
|
|
38207
38460
|
}
|
|
38208
38461
|
function writeJsonAtomic(file, value) {
|
|
38209
|
-
|
|
38462
|
+
fs65.mkdirSync(path76.dirname(file), { recursive: true });
|
|
38210
38463
|
const tmp = `${file}.tmp`;
|
|
38211
|
-
|
|
38212
|
-
|
|
38464
|
+
fs65.writeFileSync(tmp, JSON.stringify(value, null, 2));
|
|
38465
|
+
fs65.renameSync(tmp, file);
|
|
38213
38466
|
}
|
|
38214
38467
|
function saveRun(cwd, state) {
|
|
38215
|
-
writeJsonAtomic(
|
|
38468
|
+
writeJsonAtomic(path76.join(runDir(cwd, state.runId), "run.json"), state);
|
|
38216
38469
|
}
|
|
38217
38470
|
function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
|
|
38218
38471
|
const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
|
|
38219
|
-
writeJsonAtomic(
|
|
38472
|
+
writeJsonAtomic(path76.join(runDir(cwd, runId), name), handoff);
|
|
38220
38473
|
}
|
|
38221
38474
|
function loadLatestRun(cwd) {
|
|
38222
38475
|
try {
|
|
38223
38476
|
const dir = packsDir(cwd);
|
|
38224
|
-
const entries =
|
|
38477
|
+
const entries = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
38225
38478
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
38226
|
-
const file =
|
|
38479
|
+
const file = path76.join(dir, entries[i], "run.json");
|
|
38227
38480
|
try {
|
|
38228
|
-
const parsed = JSON.parse(
|
|
38481
|
+
const parsed = JSON.parse(fs65.readFileSync(file, "utf8"));
|
|
38229
38482
|
if (parsed && typeof parsed.runId === "string") return parsed;
|
|
38230
38483
|
} catch {
|
|
38231
38484
|
}
|
|
@@ -38236,17 +38489,17 @@ function loadLatestRun(cwd) {
|
|
|
38236
38489
|
}
|
|
38237
38490
|
function ensureLedgerIgnored(cwd) {
|
|
38238
38491
|
try {
|
|
38239
|
-
const gitDir =
|
|
38240
|
-
if (!
|
|
38241
|
-
const exclude =
|
|
38492
|
+
const gitDir = path76.join(cwd, ".git");
|
|
38493
|
+
if (!fs65.existsSync(gitDir)) return;
|
|
38494
|
+
const exclude = path76.join(gitDir, "info", "exclude");
|
|
38242
38495
|
let existing = "";
|
|
38243
38496
|
try {
|
|
38244
|
-
existing =
|
|
38497
|
+
existing = fs65.readFileSync(exclude, "utf8");
|
|
38245
38498
|
} catch {
|
|
38246
38499
|
}
|
|
38247
38500
|
if (existing.includes(".codeam/packs/")) return;
|
|
38248
|
-
|
|
38249
|
-
|
|
38501
|
+
fs65.mkdirSync(path76.dirname(exclude), { recursive: true });
|
|
38502
|
+
fs65.writeFileSync(exclude, `${existing.trimEnd()}
|
|
38250
38503
|
.codeam/packs/
|
|
38251
38504
|
`.trimStart());
|
|
38252
38505
|
} catch {
|
|
@@ -39226,8 +39479,175 @@ async function mcpRouter() {
|
|
|
39226
39479
|
});
|
|
39227
39480
|
}
|
|
39228
39481
|
|
|
39482
|
+
// src/commands/preview-mcp.ts
|
|
39483
|
+
var PREVIEW_MCP_SERVER_NAME = "codeagent_preview";
|
|
39484
|
+
var PREVIEW_IPC_URL_ENV = "CODEAM_PREVIEW_IPC_URL";
|
|
39485
|
+
var PREVIEW_IPC_TOKEN_ENV = "CODEAM_PREVIEW_IPC_TOKEN";
|
|
39486
|
+
var START_TIMEOUT_MS = 27e4;
|
|
39487
|
+
var SHORT_TIMEOUT_MS = 2e4;
|
|
39488
|
+
var PREVIEW_TOOLS = [
|
|
39489
|
+
{
|
|
39490
|
+
name: "start_preview",
|
|
39491
|
+
description: "Open this project's live Preview in the user's CodeAgent app \u2014 the same thing as their Preview button: it installs dependencies if needed, starts the dev server, publishes it on a public URL and switches the user's screen to it. Use it after you change anything visual (UI, styles, layout, copy) so you and the user can check the result, or whenever the user asks to see the app. Returns the public URL (you can curl it) or the exact error. Reuses a preview that is already running. Usually leave the arguments out: the project is detected automatically. Pass command/args/port only if you know the exact dev command.",
|
|
39492
|
+
inputSchema: {
|
|
39493
|
+
type: "object",
|
|
39494
|
+
properties: {
|
|
39495
|
+
command: { type: "string", description: 'Dev server executable, e.g. "npm". Optional.' },
|
|
39496
|
+
args: { type: "array", items: { type: "string" }, description: 'e.g. ["run","dev"]. Optional.' },
|
|
39497
|
+
port: { type: "number", description: "Port the dev server listens on. Required with command." },
|
|
39498
|
+
framework: { type: "string", description: 'Label shown to the user, e.g. "next". Optional.' }
|
|
39499
|
+
},
|
|
39500
|
+
additionalProperties: false
|
|
39501
|
+
}
|
|
39502
|
+
},
|
|
39503
|
+
{
|
|
39504
|
+
name: "preview_status",
|
|
39505
|
+
description: "Current state of the Preview: running (with its URL), starting, error (with the reason) or idle. Use it when start_preview answered that the preview is still starting.",
|
|
39506
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
39507
|
+
},
|
|
39508
|
+
{
|
|
39509
|
+
name: "highlight_element",
|
|
39510
|
+
description: 'Point at an element in the running Preview: the user sees your cursor move to it and a labelled box drawn around it, scrolled into view. Use it to show the user exactly what you changed or what you are talking about ("this button", "the header spacing"). Takes a CSS selector (prefer ids, data-testid or specific classes you saw in the code). Several calls add several marks; clear_highlights removes them.',
|
|
39511
|
+
inputSchema: {
|
|
39512
|
+
type: "object",
|
|
39513
|
+
properties: {
|
|
39514
|
+
selector: { type: "string", description: 'CSS selector, e.g. "#checkout" or "[data-testid=hero-cta]".' },
|
|
39515
|
+
label: { type: "string", description: 'Short caption on the mark, e.g. "New CTA". Optional.' }
|
|
39516
|
+
},
|
|
39517
|
+
required: ["selector"],
|
|
39518
|
+
additionalProperties: false
|
|
39519
|
+
}
|
|
39520
|
+
},
|
|
39521
|
+
{
|
|
39522
|
+
name: "clear_highlights",
|
|
39523
|
+
description: "Remove every mark you drew in the Preview with highlight_element.",
|
|
39524
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
39525
|
+
},
|
|
39526
|
+
{
|
|
39527
|
+
name: "stop_preview",
|
|
39528
|
+
description: "Stop the Preview (dev server + public URL). Only when the user asks, or to restart it cleanly.",
|
|
39529
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
39530
|
+
}
|
|
39531
|
+
];
|
|
39532
|
+
function previewMcpServer(bridge) {
|
|
39533
|
+
if (!bridge) return null;
|
|
39534
|
+
return {
|
|
39535
|
+
name: PREVIEW_MCP_SERVER_NAME,
|
|
39536
|
+
// Same runtime + entrypoint as this CLI — never trust the agent's PATH.
|
|
39537
|
+
command: process.execPath,
|
|
39538
|
+
args: [process.argv[1], "preview-mcp"],
|
|
39539
|
+
env: [
|
|
39540
|
+
{ name: PREVIEW_IPC_URL_ENV, value: bridge.url },
|
|
39541
|
+
{ name: PREVIEW_IPC_TOKEN_ENV, value: bridge.token }
|
|
39542
|
+
]
|
|
39543
|
+
};
|
|
39544
|
+
}
|
|
39545
|
+
function httpCall(baseUrl, token) {
|
|
39546
|
+
return async (path96, method, body, timeoutMs) => {
|
|
39547
|
+
const ac = new AbortController();
|
|
39548
|
+
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
|
39549
|
+
try {
|
|
39550
|
+
const res = await fetch(`${baseUrl}${path96}`, {
|
|
39551
|
+
method,
|
|
39552
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
39553
|
+
...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
|
|
39554
|
+
signal: ac.signal
|
|
39555
|
+
});
|
|
39556
|
+
return await res.json();
|
|
39557
|
+
} finally {
|
|
39558
|
+
clearTimeout(timer);
|
|
39559
|
+
}
|
|
39560
|
+
};
|
|
39561
|
+
}
|
|
39562
|
+
async function runPreviewTool(name, args2, call) {
|
|
39563
|
+
switch (name) {
|
|
39564
|
+
case "start_preview":
|
|
39565
|
+
return describeResult(await call("/preview/start", "POST", args2, START_TIMEOUT_MS));
|
|
39566
|
+
case "preview_status":
|
|
39567
|
+
return describeResult(await call("/preview/status", "GET", void 0, SHORT_TIMEOUT_MS));
|
|
39568
|
+
case "highlight_element":
|
|
39569
|
+
return describeAck(await call("/preview/highlight", "POST", args2, SHORT_TIMEOUT_MS));
|
|
39570
|
+
case "clear_highlights":
|
|
39571
|
+
return describeAck(await call("/preview/highlight", "POST", { clear: true }, SHORT_TIMEOUT_MS));
|
|
39572
|
+
case "stop_preview":
|
|
39573
|
+
return describeAck(await call("/preview/stop", "POST", {}, SHORT_TIMEOUT_MS));
|
|
39574
|
+
default:
|
|
39575
|
+
return { text: `Unknown tool: ${name}`, isError: true };
|
|
39576
|
+
}
|
|
39577
|
+
}
|
|
39578
|
+
function describeResult(raw) {
|
|
39579
|
+
const r = raw && typeof raw === "object" ? raw : {};
|
|
39580
|
+
switch (r.status) {
|
|
39581
|
+
case "running": {
|
|
39582
|
+
const inspector = r.inspector ? " You can point at elements with highlight_element." : " (No element highlighting for this framework.)";
|
|
39583
|
+
return {
|
|
39584
|
+
text: `Preview ${r.reused ? "already running" : "is live"}: ${String(r.url)} (${String(r.framework)}). The user's app is showing it now.${inspector}`,
|
|
39585
|
+
isError: false
|
|
39586
|
+
};
|
|
39587
|
+
}
|
|
39588
|
+
case "starting":
|
|
39589
|
+
return { text: String(r.message ?? "The preview is starting."), isError: false };
|
|
39590
|
+
case "idle":
|
|
39591
|
+
return { text: "No preview is running.", isError: false };
|
|
39592
|
+
case "error":
|
|
39593
|
+
return {
|
|
39594
|
+
text: `Preview failed at ${String(r.stage)}: ${String(r.message)}`,
|
|
39595
|
+
isError: true
|
|
39596
|
+
};
|
|
39597
|
+
default:
|
|
39598
|
+
return { text: `Unexpected answer from the preview bridge: ${JSON.stringify(raw)}`, isError: true };
|
|
39599
|
+
}
|
|
39600
|
+
}
|
|
39601
|
+
function describeAck(raw) {
|
|
39602
|
+
const r = raw && typeof raw === "object" ? raw : {};
|
|
39603
|
+
return { text: String(r.message ?? r.error ?? "done"), isError: r.ok !== true };
|
|
39604
|
+
}
|
|
39605
|
+
async function previewMcp() {
|
|
39606
|
+
const url2 = process.env[PREVIEW_IPC_URL_ENV];
|
|
39607
|
+
const token = process.env[PREVIEW_IPC_TOKEN_ENV];
|
|
39608
|
+
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
39609
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
39610
|
+
const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
39611
|
+
const call = url2 && token ? httpCall(url2, token) : null;
|
|
39612
|
+
const server = new Server({ name: PREVIEW_MCP_SERVER_NAME, version: "1.0.0" }, { capabilities: { tools: {} } });
|
|
39613
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: PREVIEW_TOOLS }));
|
|
39614
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
39615
|
+
if (!call) {
|
|
39616
|
+
return {
|
|
39617
|
+
content: [{ type: "text", text: "Preview is not available in this session." }],
|
|
39618
|
+
isError: true
|
|
39619
|
+
};
|
|
39620
|
+
}
|
|
39621
|
+
try {
|
|
39622
|
+
const { text, isError: isError2 } = await runPreviewTool(
|
|
39623
|
+
req.params.name,
|
|
39624
|
+
req.params.arguments ?? {},
|
|
39625
|
+
call
|
|
39626
|
+
);
|
|
39627
|
+
return { content: [{ type: "text", text }], isError: isError2 };
|
|
39628
|
+
} catch (err) {
|
|
39629
|
+
const aborted = err instanceof Error && err.name === "AbortError";
|
|
39630
|
+
return {
|
|
39631
|
+
content: [
|
|
39632
|
+
{
|
|
39633
|
+
type: "text",
|
|
39634
|
+
text: aborted ? "The preview is taking long \u2014 it keeps going in the background; call preview_status shortly." : `Preview bridge unreachable: ${err instanceof Error ? err.message : String(err)}`
|
|
39635
|
+
}
|
|
39636
|
+
],
|
|
39637
|
+
isError: !aborted
|
|
39638
|
+
};
|
|
39639
|
+
}
|
|
39640
|
+
});
|
|
39641
|
+
await server.connect(new StdioServerTransport());
|
|
39642
|
+
}
|
|
39643
|
+
|
|
39229
39644
|
// src/integrations/provision.ts
|
|
39230
39645
|
function buildMcpServersForStart(ctx) {
|
|
39646
|
+
const servers = buildIntegrationMcpServers(ctx);
|
|
39647
|
+
const preview = previewMcpServer(ctx.preview ?? null);
|
|
39648
|
+
return preview ? [...servers, preview] : servers;
|
|
39649
|
+
}
|
|
39650
|
+
function buildIntegrationMcpServers(ctx) {
|
|
39231
39651
|
const manifest = readIntegrationsManifest();
|
|
39232
39652
|
if (!manifest || manifest.integrations.length === 0) return [];
|
|
39233
39653
|
if (!ctx.pluginAuthToken) {
|
|
@@ -39399,6 +39819,299 @@ function mergeWithLocalMcpServers(integrationServers) {
|
|
|
39399
39819
|
return merged;
|
|
39400
39820
|
}
|
|
39401
39821
|
|
|
39822
|
+
// src/commands/start/agent-preview-bridge.ts
|
|
39823
|
+
var http11 = __toESM(require("http"));
|
|
39824
|
+
var import_node_crypto10 = require("crypto");
|
|
39825
|
+
var START_WAIT_MS = 24e4;
|
|
39826
|
+
var MAX_SELECTOR = 500;
|
|
39827
|
+
var MAX_LABEL = 80;
|
|
39828
|
+
var AgentPreviewBridge = class {
|
|
39829
|
+
server = null;
|
|
39830
|
+
listening = null;
|
|
39831
|
+
token = (0, import_node_crypto10.randomBytes)(24).toString("hex");
|
|
39832
|
+
ctx = null;
|
|
39833
|
+
/** The bring-up in flight, so two tool calls never start two dev servers. */
|
|
39834
|
+
inflight = null;
|
|
39835
|
+
lastError = null;
|
|
39836
|
+
bound = null;
|
|
39837
|
+
/** Start the loopback server once. `null` when it could not bind — the
|
|
39838
|
+
* preview tools are then simply absent, never a failed session. */
|
|
39839
|
+
listen() {
|
|
39840
|
+
if (this.listening) return this.listening;
|
|
39841
|
+
this.listening = new Promise((resolve12) => {
|
|
39842
|
+
const server = http11.createServer((req, res) => {
|
|
39843
|
+
void this.handle(req, res);
|
|
39844
|
+
});
|
|
39845
|
+
server.on("error", (err) => {
|
|
39846
|
+
log.warn("agent-preview", `bridge failed to listen: ${String(err)}`);
|
|
39847
|
+
resolve12(null);
|
|
39848
|
+
});
|
|
39849
|
+
server.listen(0, "127.0.0.1", () => {
|
|
39850
|
+
const addr = server.address();
|
|
39851
|
+
if (!addr || typeof addr === "string") {
|
|
39852
|
+
resolve12(null);
|
|
39853
|
+
return;
|
|
39854
|
+
}
|
|
39855
|
+
server.unref();
|
|
39856
|
+
this.server = server;
|
|
39857
|
+
this.bound = { url: `http://127.0.0.1:${addr.port}`, token: this.token };
|
|
39858
|
+
resolve12(this.bound);
|
|
39859
|
+
});
|
|
39860
|
+
});
|
|
39861
|
+
return this.listening;
|
|
39862
|
+
}
|
|
39863
|
+
/** The bound address once {@link listen} resolved, else null (sync, for
|
|
39864
|
+
* the MCP list rebuilds that happen mid-session). */
|
|
39865
|
+
address() {
|
|
39866
|
+
return this.bound;
|
|
39867
|
+
}
|
|
39868
|
+
/** Bind the live session. Tool calls before this answer "still starting". */
|
|
39869
|
+
attach(ctx) {
|
|
39870
|
+
this.ctx = ctx;
|
|
39871
|
+
}
|
|
39872
|
+
close() {
|
|
39873
|
+
this.server?.close();
|
|
39874
|
+
this.server = null;
|
|
39875
|
+
}
|
|
39876
|
+
// ─── Operations (public for tests) ─────────────────────────────────────
|
|
39877
|
+
async start(override, waitMs = START_WAIT_MS) {
|
|
39878
|
+
const ctx = this.ctx;
|
|
39879
|
+
if (!ctx?.pluginAuthToken) {
|
|
39880
|
+
return {
|
|
39881
|
+
status: "error",
|
|
39882
|
+
stage: "session",
|
|
39883
|
+
message: "The session is still starting (or has no pairing token) \u2014 try again in a few seconds."
|
|
39884
|
+
};
|
|
39885
|
+
}
|
|
39886
|
+
if (!this.inflight) {
|
|
39887
|
+
const run = this.launch(ctx, ctx.pluginAuthToken, override);
|
|
39888
|
+
this.inflight = run;
|
|
39889
|
+
void run.finally(() => {
|
|
39890
|
+
if (this.inflight === run) this.inflight = null;
|
|
39891
|
+
});
|
|
39892
|
+
}
|
|
39893
|
+
const inflight = this.inflight;
|
|
39894
|
+
let timer;
|
|
39895
|
+
const pending = new Promise((resolve12) => {
|
|
39896
|
+
timer = setTimeout(
|
|
39897
|
+
() => resolve12({
|
|
39898
|
+
status: "starting",
|
|
39899
|
+
message: "The preview is still coming up (dependencies or a slow dev server). It keeps going in the background \u2014 call preview_status in a minute."
|
|
39900
|
+
}),
|
|
39901
|
+
waitMs
|
|
39902
|
+
);
|
|
39903
|
+
timer.unref?.();
|
|
39904
|
+
});
|
|
39905
|
+
try {
|
|
39906
|
+
return await Promise.race([inflight, pending]);
|
|
39907
|
+
} finally {
|
|
39908
|
+
if (timer) clearTimeout(timer);
|
|
39909
|
+
}
|
|
39910
|
+
}
|
|
39911
|
+
status() {
|
|
39912
|
+
const ctx = this.ctx;
|
|
39913
|
+
if (!ctx) return { status: "idle" };
|
|
39914
|
+
const active2 = serving(ctx.sessionId);
|
|
39915
|
+
if (active2) return running(active2, true);
|
|
39916
|
+
if (this.inflight) return { status: "starting", message: "The preview is starting." };
|
|
39917
|
+
if (this.lastError) return { status: "error", ...this.lastError };
|
|
39918
|
+
return { status: "idle" };
|
|
39919
|
+
}
|
|
39920
|
+
async highlight(input) {
|
|
39921
|
+
const ctx = this.ctx;
|
|
39922
|
+
if (!ctx?.pluginAuthToken) return { ok: false, message: "The session is still starting." };
|
|
39923
|
+
const active2 = serving(ctx.sessionId);
|
|
39924
|
+
if (!active2) {
|
|
39925
|
+
return { ok: false, message: "No preview is running \u2014 call start_preview first." };
|
|
39926
|
+
}
|
|
39927
|
+
if (!active2.inspector) {
|
|
39928
|
+
return {
|
|
39929
|
+
ok: false,
|
|
39930
|
+
message: `Element highlighting needs the web inspector, which ${active2.framework} previews don't have.`
|
|
39931
|
+
};
|
|
39932
|
+
}
|
|
39933
|
+
let payload;
|
|
39934
|
+
if (input.clear === true) {
|
|
39935
|
+
payload = { clear: true };
|
|
39936
|
+
} else {
|
|
39937
|
+
const selector = typeof input.selector === "string" ? input.selector.trim() : "";
|
|
39938
|
+
if (!selector || selector.length > MAX_SELECTOR) {
|
|
39939
|
+
return { ok: false, message: `selector must be a CSS selector of 1-${MAX_SELECTOR} characters.` };
|
|
39940
|
+
}
|
|
39941
|
+
const label = typeof input.label === "string" ? input.label.trim().slice(0, MAX_LABEL) : "";
|
|
39942
|
+
payload = label ? { selector, label } : { selector };
|
|
39943
|
+
}
|
|
39944
|
+
const res = await postPreviewEvent({
|
|
39945
|
+
sessionId: ctx.sessionId,
|
|
39946
|
+
pluginId: ctx.pluginId,
|
|
39947
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
39948
|
+
type: USER_EVENTS.PREVIEW_AGENT_HIGHLIGHT,
|
|
39949
|
+
payload
|
|
39950
|
+
});
|
|
39951
|
+
if (!res.ok) {
|
|
39952
|
+
return { ok: false, message: `Could not reach the app (${res.status}): ${res.message}` };
|
|
39953
|
+
}
|
|
39954
|
+
return {
|
|
39955
|
+
ok: true,
|
|
39956
|
+
message: payload.clear === true ? "Cleared your marks from the preview." : `Marked ${String(payload.selector)} in the user's preview. If the selector matches nothing, no mark appears.`
|
|
39957
|
+
};
|
|
39958
|
+
}
|
|
39959
|
+
async stop() {
|
|
39960
|
+
const ctx = this.ctx;
|
|
39961
|
+
if (!ctx?.pluginAuthToken) return { ok: false, message: "The session is still starting." };
|
|
39962
|
+
if (!activePreviews.has(ctx.sessionId)) return { ok: true, message: "No preview was running." };
|
|
39963
|
+
await killPreview(ctx.sessionId);
|
|
39964
|
+
resetBuildHealState(ctx.sessionId);
|
|
39965
|
+
await postPreviewEvent({
|
|
39966
|
+
sessionId: ctx.sessionId,
|
|
39967
|
+
pluginId: ctx.pluginId,
|
|
39968
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
39969
|
+
type: USER_EVENTS.PREVIEW_STOPPED,
|
|
39970
|
+
payload: { reason: "user", origin: "agent" }
|
|
39971
|
+
});
|
|
39972
|
+
return { ok: true, message: "Preview stopped." };
|
|
39973
|
+
}
|
|
39974
|
+
// ─── Internals ─────────────────────────────────────────────────────────
|
|
39975
|
+
async launch(ctx, pluginAuthToken, override) {
|
|
39976
|
+
this.lastError = null;
|
|
39977
|
+
const already = serving(ctx.sessionId);
|
|
39978
|
+
if (already) {
|
|
39979
|
+
await postPreviewEvent({
|
|
39980
|
+
sessionId: ctx.sessionId,
|
|
39981
|
+
pluginId: ctx.pluginId,
|
|
39982
|
+
pluginAuthToken,
|
|
39983
|
+
type: USER_EVENTS.PREVIEW_READY,
|
|
39984
|
+
payload: {
|
|
39985
|
+
url: already.url,
|
|
39986
|
+
framework: already.framework,
|
|
39987
|
+
port: already.detection.port,
|
|
39988
|
+
origin: "agent"
|
|
39989
|
+
}
|
|
39990
|
+
});
|
|
39991
|
+
return running(already, true);
|
|
39992
|
+
}
|
|
39993
|
+
void postPreviewEvent({
|
|
39994
|
+
sessionId: ctx.sessionId,
|
|
39995
|
+
pluginId: ctx.pluginId,
|
|
39996
|
+
pluginAuthToken,
|
|
39997
|
+
type: USER_EVENTS.PREVIEW_DETECTION_PENDING,
|
|
39998
|
+
payload: { origin: "agent" }
|
|
39999
|
+
});
|
|
40000
|
+
const detection = (override && detectionFromOverride(override)) ?? await resolvePreviewDetection({ ctx, runtime: ctx.getRuntime(), pluginAuthToken, origin: "agent" });
|
|
40001
|
+
if (!detection) {
|
|
40002
|
+
const err2 = { stage: "detection", message: "Could not work out how to start this project." };
|
|
40003
|
+
this.lastError = err2;
|
|
40004
|
+
return { status: "error", ...err2 };
|
|
40005
|
+
}
|
|
40006
|
+
let failure = null;
|
|
40007
|
+
await startPreviewFromDetection(ctx, detection, pluginAuthToken, {
|
|
40008
|
+
origin: "agent",
|
|
40009
|
+
onEvent: (type, payload) => {
|
|
40010
|
+
if (type === USER_EVENTS.PREVIEW_ERROR) {
|
|
40011
|
+
failure = {
|
|
40012
|
+
stage: String(payload.stage ?? "spawn"),
|
|
40013
|
+
message: String(payload.message ?? "The preview failed to start.")
|
|
40014
|
+
};
|
|
40015
|
+
}
|
|
40016
|
+
}
|
|
40017
|
+
});
|
|
40018
|
+
const up = serving(ctx.sessionId);
|
|
40019
|
+
if (up) return running(up, false);
|
|
40020
|
+
const err = failure ?? { stage: "spawn", message: "The preview did not come up." };
|
|
40021
|
+
this.lastError = err;
|
|
40022
|
+
return { status: "error", ...err };
|
|
40023
|
+
}
|
|
40024
|
+
async handle(req, res) {
|
|
40025
|
+
const reply = (code, body) => {
|
|
40026
|
+
res.writeHead(code, { "content-type": "application/json" });
|
|
40027
|
+
res.end(JSON.stringify(body));
|
|
40028
|
+
};
|
|
40029
|
+
if (!authorized(req.headers.authorization, this.token)) return reply(401, { error: "unauthorized" });
|
|
40030
|
+
try {
|
|
40031
|
+
const body = req.method === "POST" ? await readJson(req) : {};
|
|
40032
|
+
switch (`${req.method} ${req.url}`) {
|
|
40033
|
+
case "POST /preview/start":
|
|
40034
|
+
return reply(200, await this.start(overrideFrom(body)));
|
|
40035
|
+
case "GET /preview/status":
|
|
40036
|
+
return reply(200, this.status());
|
|
40037
|
+
case "POST /preview/highlight":
|
|
40038
|
+
return reply(200, await this.highlight(body));
|
|
40039
|
+
case "POST /preview/stop":
|
|
40040
|
+
return reply(200, await this.stop());
|
|
40041
|
+
default:
|
|
40042
|
+
return reply(404, { error: "not found" });
|
|
40043
|
+
}
|
|
40044
|
+
} catch (err) {
|
|
40045
|
+
log.warn("agent-preview", `bridge request failed: ${String(err)}`);
|
|
40046
|
+
return reply(500, { error: err instanceof Error ? err.message : String(err) });
|
|
40047
|
+
}
|
|
40048
|
+
}
|
|
40049
|
+
};
|
|
40050
|
+
function serving(sessionId) {
|
|
40051
|
+
const active2 = activePreviews.get(sessionId);
|
|
40052
|
+
if (!active2 || active2.devServer && active2.devServer.exitCode !== null) return null;
|
|
40053
|
+
return active2;
|
|
40054
|
+
}
|
|
40055
|
+
function running(active2, reused) {
|
|
40056
|
+
return {
|
|
40057
|
+
status: "running",
|
|
40058
|
+
url: active2.url,
|
|
40059
|
+
framework: active2.framework,
|
|
40060
|
+
...reused ? { reused: true } : {},
|
|
40061
|
+
inspector: Boolean(active2.inspector)
|
|
40062
|
+
};
|
|
40063
|
+
}
|
|
40064
|
+
function detectionFromOverride(o) {
|
|
40065
|
+
if (!o.command || !Number.isInteger(o.port) || o.port <= 0 || o.port > 65535) return null;
|
|
40066
|
+
return {
|
|
40067
|
+
framework: o.framework?.trim() || "custom",
|
|
40068
|
+
command: o.command,
|
|
40069
|
+
args: Array.isArray(o.args) ? o.args.map(String) : [],
|
|
40070
|
+
port: o.port,
|
|
40071
|
+
// Any Local/ready/listening line; the TCP probe is the real fallback.
|
|
40072
|
+
ready_pattern: o.ready_pattern?.trim() || "(ready|local:|listening|started server|compiled)"
|
|
40073
|
+
};
|
|
40074
|
+
}
|
|
40075
|
+
function overrideFrom(body) {
|
|
40076
|
+
if (typeof body.command !== "string" || typeof body.port !== "number") return void 0;
|
|
40077
|
+
return {
|
|
40078
|
+
command: body.command,
|
|
40079
|
+
args: Array.isArray(body.args) ? body.args.map(String) : void 0,
|
|
40080
|
+
port: body.port,
|
|
40081
|
+
framework: typeof body.framework === "string" ? body.framework : void 0,
|
|
40082
|
+
ready_pattern: typeof body.ready_pattern === "string" ? body.ready_pattern : void 0
|
|
40083
|
+
};
|
|
40084
|
+
}
|
|
40085
|
+
function authorized(header, token) {
|
|
40086
|
+
const presented = Buffer.from((header ?? "").replace(/^Bearer\s+/i, ""));
|
|
40087
|
+
const expected = Buffer.from(token);
|
|
40088
|
+
return presented.length === expected.length && (0, import_node_crypto10.timingSafeEqual)(presented, expected);
|
|
40089
|
+
}
|
|
40090
|
+
function readJson(req) {
|
|
40091
|
+
return new Promise((resolve12, reject) => {
|
|
40092
|
+
let raw = "";
|
|
40093
|
+
req.setEncoding("utf8");
|
|
40094
|
+
req.on("data", (chunk) => {
|
|
40095
|
+
raw += chunk;
|
|
40096
|
+
if (raw.length > 64e3) {
|
|
40097
|
+
reject(new Error("body too large"));
|
|
40098
|
+
req.destroy();
|
|
40099
|
+
}
|
|
40100
|
+
});
|
|
40101
|
+
req.on("end", () => {
|
|
40102
|
+
if (!raw) return resolve12({});
|
|
40103
|
+
try {
|
|
40104
|
+
const parsed = JSON.parse(raw);
|
|
40105
|
+
resolve12(parsed && typeof parsed === "object" ? parsed : {});
|
|
40106
|
+
} catch {
|
|
40107
|
+
reject(new Error("invalid JSON"));
|
|
40108
|
+
}
|
|
40109
|
+
});
|
|
40110
|
+
req.on("error", reject);
|
|
40111
|
+
});
|
|
40112
|
+
}
|
|
40113
|
+
var agentPreviewBridge = new AgentPreviewBridge();
|
|
40114
|
+
|
|
39402
40115
|
// src/integrations/detect-stack.ts
|
|
39403
40116
|
var import_node_fs13 = __toESM(require("fs"));
|
|
39404
40117
|
var import_node_path13 = __toESM(require("path"));
|
|
@@ -40539,7 +41252,8 @@ async function integrationsSyncH(ctx) {
|
|
|
40539
41252
|
sessionId: opts.sessionId,
|
|
40540
41253
|
pluginId: opts.pluginId,
|
|
40541
41254
|
pluginAuthToken: opts.pluginAuthToken,
|
|
40542
|
-
pollSecret: opts.pollSecret
|
|
41255
|
+
pollSecret: opts.pollSecret,
|
|
41256
|
+
preview: agentPreviewBridge.address()
|
|
40543
41257
|
})
|
|
40544
41258
|
);
|
|
40545
41259
|
const applied = await client3.reprovisionMcp(servers);
|
|
@@ -41176,7 +41890,7 @@ var AcpHistory = class {
|
|
|
41176
41890
|
this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
|
|
41177
41891
|
}
|
|
41178
41892
|
this.messages.push({
|
|
41179
|
-
id: (0,
|
|
41893
|
+
id: (0, import_node_crypto11.randomUUID)(),
|
|
41180
41894
|
role: "user",
|
|
41181
41895
|
text,
|
|
41182
41896
|
timestamp: Date.now(),
|
|
@@ -41192,7 +41906,7 @@ var AcpHistory = class {
|
|
|
41192
41906
|
appendAgentReply(text, agentId = this.opts.agent) {
|
|
41193
41907
|
if (text.length === 0) return;
|
|
41194
41908
|
this.messages.push({
|
|
41195
|
-
id: (0,
|
|
41909
|
+
id: (0, import_node_crypto11.randomUUID)(),
|
|
41196
41910
|
role: "agent",
|
|
41197
41911
|
text,
|
|
41198
41912
|
timestamp: Date.now(),
|
|
@@ -41723,17 +42437,17 @@ async function runAcpSession(opts) {
|
|
|
41723
42437
|
switchCredentialEnv = provisionAgentCredentials(agentId, auth);
|
|
41724
42438
|
},
|
|
41725
42439
|
provisionHouseProxy: ({ baseUrl, token, model, managedAgentId }) => {
|
|
41726
|
-
const claudeConfigDir =
|
|
42440
|
+
const claudeConfigDir = path80.join(
|
|
41727
42441
|
os53.homedir(),
|
|
41728
42442
|
".codeam",
|
|
41729
42443
|
"house-claude",
|
|
41730
42444
|
`switch-${opts.pluginId}`
|
|
41731
42445
|
);
|
|
41732
42446
|
try {
|
|
41733
|
-
|
|
42447
|
+
fs69.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
|
|
41734
42448
|
} catch {
|
|
41735
42449
|
}
|
|
41736
|
-
const memoryFile =
|
|
42450
|
+
const memoryFile = path80.join(claudeConfigDir, "CLAUDE.md");
|
|
41737
42451
|
ensureBeadsWorkflowHint(void 0, memoryFile);
|
|
41738
42452
|
ensureAgentStandard(void 0, memoryFile);
|
|
41739
42453
|
const cfg = {
|
|
@@ -42956,8 +43670,8 @@ function pickPinnedSession(pinnedId, listSessions2) {
|
|
|
42956
43670
|
}
|
|
42957
43671
|
|
|
42958
43672
|
// src/agents/retired-proxy-cleanup.ts
|
|
42959
|
-
var
|
|
42960
|
-
var
|
|
43673
|
+
var fs70 = __toESM(require("fs"));
|
|
43674
|
+
var path81 = __toESM(require("path"));
|
|
42961
43675
|
var os54 = __toESM(require("os"));
|
|
42962
43676
|
var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
|
|
42963
43677
|
var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
|
|
@@ -42969,10 +43683,10 @@ function isHeadroomHook(group) {
|
|
|
42969
43683
|
}
|
|
42970
43684
|
function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
|
|
42971
43685
|
const out2 = { inspected: false, changed: false, removed: [] };
|
|
42972
|
-
const file =
|
|
43686
|
+
const file = path81.join(homeDir2, ".claude", "settings.json");
|
|
42973
43687
|
let parsed;
|
|
42974
43688
|
try {
|
|
42975
|
-
parsed = JSON.parse(
|
|
43689
|
+
parsed = JSON.parse(fs70.readFileSync(file, "utf8"));
|
|
42976
43690
|
} catch {
|
|
42977
43691
|
return out2;
|
|
42978
43692
|
}
|
|
@@ -43014,9 +43728,9 @@ function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
|
|
|
43014
43728
|
if (!out2.changed) return out2;
|
|
43015
43729
|
try {
|
|
43016
43730
|
const tmp = `${file}.codeam.tmp`;
|
|
43017
|
-
|
|
43731
|
+
fs70.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
|
|
43018
43732
|
`, { mode: 384 });
|
|
43019
|
-
|
|
43733
|
+
fs70.renameSync(tmp, file);
|
|
43020
43734
|
} catch {
|
|
43021
43735
|
out2.changed = false;
|
|
43022
43736
|
}
|
|
@@ -43548,7 +44262,7 @@ var AcpDriver = class {
|
|
|
43548
44262
|
};
|
|
43549
44263
|
|
|
43550
44264
|
// src/baton/transcript-mirror.ts
|
|
43551
|
-
var
|
|
44265
|
+
var fs71 = __toESM(require("fs"));
|
|
43552
44266
|
var TranscriptMirror = class {
|
|
43553
44267
|
constructor(deps) {
|
|
43554
44268
|
this.deps = deps;
|
|
@@ -43642,7 +44356,7 @@ var TranscriptMirror = class {
|
|
|
43642
44356
|
}
|
|
43643
44357
|
};
|
|
43644
44358
|
function defaultWatch(file, onChange) {
|
|
43645
|
-
const w3 =
|
|
44359
|
+
const w3 = fs71.watch(file, { persistent: false }, () => onChange());
|
|
43646
44360
|
return () => w3.close();
|
|
43647
44361
|
}
|
|
43648
44362
|
|
|
@@ -43988,16 +44702,16 @@ function keepDeviceAwake(deps = {}) {
|
|
|
43988
44702
|
}
|
|
43989
44703
|
|
|
43990
44704
|
// src/agents/claude/onboarding.ts
|
|
43991
|
-
var
|
|
44705
|
+
var fs72 = __toESM(require("fs"));
|
|
43992
44706
|
var os56 = __toESM(require("os"));
|
|
43993
|
-
var
|
|
44707
|
+
var path82 = __toESM(require("path"));
|
|
43994
44708
|
var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
|
|
43995
44709
|
function ensureClaudeOnboarded(cwd) {
|
|
43996
44710
|
try {
|
|
43997
|
-
const file =
|
|
44711
|
+
const file = path82.join(os56.homedir(), ".claude.json");
|
|
43998
44712
|
let config = {};
|
|
43999
44713
|
try {
|
|
44000
|
-
config = JSON.parse(
|
|
44714
|
+
config = JSON.parse(fs72.readFileSync(file, "utf8"));
|
|
44001
44715
|
} catch {
|
|
44002
44716
|
}
|
|
44003
44717
|
let changed = false;
|
|
@@ -44022,8 +44736,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
44022
44736
|
}
|
|
44023
44737
|
}
|
|
44024
44738
|
if (!changed) return;
|
|
44025
|
-
|
|
44026
|
-
|
|
44739
|
+
fs72.mkdirSync(path82.dirname(file), { recursive: true });
|
|
44740
|
+
fs72.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
44027
44741
|
log.info(
|
|
44028
44742
|
"claude",
|
|
44029
44743
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -44146,12 +44860,20 @@ async function start(requestedAgent, presetSession) {
|
|
|
44146
44860
|
agent: isHouseProxyEnv(process.env) ? houseRailWireId(process.env) : session.agent
|
|
44147
44861
|
});
|
|
44148
44862
|
}
|
|
44863
|
+
const previewBridge = await agentPreviewBridge.listen();
|
|
44864
|
+
agentPreviewBridge.attach({
|
|
44865
|
+
sessionId: session.id,
|
|
44866
|
+
pluginId,
|
|
44867
|
+
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
44868
|
+
getRuntime: () => createInteractiveAgentStrategy(session.agent, createOsStrategy())
|
|
44869
|
+
});
|
|
44149
44870
|
const mcpServers = mergeWithLocalMcpServers(
|
|
44150
44871
|
buildMcpServersForStart({
|
|
44151
44872
|
sessionId: session.id,
|
|
44152
44873
|
pluginId,
|
|
44153
44874
|
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
44154
|
-
pollSecret: session.pollSecret
|
|
44875
|
+
pollSecret: session.pollSecret,
|
|
44876
|
+
preview: previewBridge
|
|
44155
44877
|
})
|
|
44156
44878
|
);
|
|
44157
44879
|
provisionSkillsForStart();
|
|
@@ -44792,7 +45514,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
44792
45514
|
var import_child_process30 = require("child_process");
|
|
44793
45515
|
var import_util4 = require("util");
|
|
44794
45516
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
44795
|
-
var
|
|
45517
|
+
var path83 = __toESM(require("path"));
|
|
44796
45518
|
var execFileP5 = (0, import_util4.promisify)(import_child_process30.execFile);
|
|
44797
45519
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
44798
45520
|
function resetStdinForChild() {
|
|
@@ -45281,7 +46003,7 @@ var GitHubCodespacesProvider = class {
|
|
|
45281
46003
|
});
|
|
45282
46004
|
}
|
|
45283
46005
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45284
|
-
const remoteDir =
|
|
46006
|
+
const remoteDir = path83.posix.dirname(remotePath);
|
|
45285
46007
|
const parts = [
|
|
45286
46008
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
45287
46009
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -45351,7 +46073,7 @@ function shellQuote(s) {
|
|
|
45351
46073
|
// src/services/providers/gitpod.ts
|
|
45352
46074
|
var import_child_process31 = require("child_process");
|
|
45353
46075
|
var import_util5 = require("util");
|
|
45354
|
-
var
|
|
46076
|
+
var path84 = __toESM(require("path"));
|
|
45355
46077
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
45356
46078
|
var execFileP6 = (0, import_util5.promisify)(import_child_process31.execFile);
|
|
45357
46079
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -45591,7 +46313,7 @@ var GitpodProvider = class {
|
|
|
45591
46313
|
});
|
|
45592
46314
|
}
|
|
45593
46315
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45594
|
-
const remoteDir =
|
|
46316
|
+
const remoteDir = path84.posix.dirname(remotePath);
|
|
45595
46317
|
const parts = [
|
|
45596
46318
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
45597
46319
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -45627,7 +46349,7 @@ function shellQuote2(s) {
|
|
|
45627
46349
|
// src/services/providers/gitlab-workspaces.ts
|
|
45628
46350
|
var import_child_process32 = require("child_process");
|
|
45629
46351
|
var import_util6 = require("util");
|
|
45630
|
-
var
|
|
46352
|
+
var path85 = __toESM(require("path"));
|
|
45631
46353
|
var execFileP7 = (0, import_util6.promisify)(import_child_process32.execFile);
|
|
45632
46354
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
45633
46355
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -45887,7 +46609,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
45887
46609
|
}
|
|
45888
46610
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45889
46611
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
45890
|
-
const remoteDir =
|
|
46612
|
+
const remoteDir = path85.posix.dirname(remotePath);
|
|
45891
46613
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
45892
46614
|
if (options.mode != null) {
|
|
45893
46615
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -45955,7 +46677,7 @@ function shellQuote3(s) {
|
|
|
45955
46677
|
// src/services/providers/railway.ts
|
|
45956
46678
|
var import_child_process33 = require("child_process");
|
|
45957
46679
|
var import_util7 = require("util");
|
|
45958
|
-
var
|
|
46680
|
+
var path86 = __toESM(require("path"));
|
|
45959
46681
|
var execFileP8 = (0, import_util7.promisify)(import_child_process33.execFile);
|
|
45960
46682
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
45961
46683
|
function resetStdinForChild4() {
|
|
@@ -46191,7 +46913,7 @@ var RailwayProvider = class {
|
|
|
46191
46913
|
if (!projectId || !serviceId) {
|
|
46192
46914
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
46193
46915
|
}
|
|
46194
|
-
const remoteDir =
|
|
46916
|
+
const remoteDir = path86.posix.dirname(remotePath);
|
|
46195
46917
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
46196
46918
|
if (options.mode != null) {
|
|
46197
46919
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -46731,10 +47453,10 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
46731
47453
|
}
|
|
46732
47454
|
|
|
46733
47455
|
// src/commands/host/host-client.ts
|
|
46734
|
-
var
|
|
47456
|
+
var fs73 = __toESM(require("fs"));
|
|
46735
47457
|
var os57 = __toESM(require("os"));
|
|
46736
|
-
var
|
|
46737
|
-
var
|
|
47458
|
+
var path87 = __toESM(require("path"));
|
|
47459
|
+
var import_node_crypto12 = require("crypto");
|
|
46738
47460
|
function sampleCpuTimes() {
|
|
46739
47461
|
let idle = 0;
|
|
46740
47462
|
let total = 0;
|
|
@@ -46781,7 +47503,7 @@ function apiBase() {
|
|
|
46781
47503
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
46782
47504
|
}
|
|
46783
47505
|
function hostIdentityPath() {
|
|
46784
|
-
return
|
|
47506
|
+
return path87.join(os57.homedir(), ".codeam", "host-agent.json");
|
|
46785
47507
|
}
|
|
46786
47508
|
function collectOsInfo() {
|
|
46787
47509
|
return {
|
|
@@ -46793,7 +47515,7 @@ function collectOsInfo() {
|
|
|
46793
47515
|
}
|
|
46794
47516
|
function loadHostIdentity() {
|
|
46795
47517
|
try {
|
|
46796
|
-
const raw =
|
|
47518
|
+
const raw = fs73.readFileSync(hostIdentityPath(), "utf8");
|
|
46797
47519
|
const parsed = JSON.parse(raw);
|
|
46798
47520
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
46799
47521
|
const p2 = parsed;
|
|
@@ -46812,8 +47534,8 @@ function loadHostIdentity() {
|
|
|
46812
47534
|
}
|
|
46813
47535
|
function saveHostIdentity(identity) {
|
|
46814
47536
|
const file = hostIdentityPath();
|
|
46815
|
-
|
|
46816
|
-
|
|
47537
|
+
fs73.mkdirSync(path87.dirname(file), { recursive: true, mode: 448 });
|
|
47538
|
+
fs73.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
46817
47539
|
encoding: "utf8",
|
|
46818
47540
|
mode: 384
|
|
46819
47541
|
});
|
|
@@ -46858,7 +47580,7 @@ function isTerminalEnrollError(err) {
|
|
|
46858
47580
|
}
|
|
46859
47581
|
function deleteHostIdentity() {
|
|
46860
47582
|
try {
|
|
46861
|
-
|
|
47583
|
+
fs73.rmSync(hostIdentityPath(), { force: true });
|
|
46862
47584
|
} catch {
|
|
46863
47585
|
}
|
|
46864
47586
|
}
|
|
@@ -46886,8 +47608,8 @@ function resolveHostLabel(label) {
|
|
|
46886
47608
|
return resolved.slice(0, 80);
|
|
46887
47609
|
}
|
|
46888
47610
|
async function redeemEnrollToken(token, label) {
|
|
46889
|
-
const controlPollSecret = (0,
|
|
46890
|
-
const pluginSecretHash = (0,
|
|
47611
|
+
const controlPollSecret = (0, import_node_crypto12.randomBytes)(32).toString("base64url");
|
|
47612
|
+
const pluginSecretHash = (0, import_node_crypto12.createHash)("sha256").update(controlPollSecret).digest("hex");
|
|
46891
47613
|
const data = await postJson("/api/self-hosted/redeem", {
|
|
46892
47614
|
token,
|
|
46893
47615
|
label: resolveHostLabel(label),
|
|
@@ -47072,8 +47794,8 @@ async function host(args2) {
|
|
|
47072
47794
|
// src/commands/host-agent.ts
|
|
47073
47795
|
var import_node_child_process30 = require("child_process");
|
|
47074
47796
|
var os62 = __toESM(require("os"));
|
|
47075
|
-
var
|
|
47076
|
-
var
|
|
47797
|
+
var fs78 = __toESM(require("fs"));
|
|
47798
|
+
var path92 = __toESM(require("path"));
|
|
47077
47799
|
|
|
47078
47800
|
// src/skills/persist-from-payload.ts
|
|
47079
47801
|
function persistOrClearSkillsFromPayload(skills) {
|
|
@@ -47082,13 +47804,13 @@ function persistOrClearSkillsFromPayload(skills) {
|
|
|
47082
47804
|
}
|
|
47083
47805
|
|
|
47084
47806
|
// src/commands/host/session-state.ts
|
|
47085
|
-
var
|
|
47807
|
+
var fs74 = __toESM(require("fs"));
|
|
47086
47808
|
var os58 = __toESM(require("os"));
|
|
47087
|
-
var
|
|
47809
|
+
var path88 = __toESM(require("path"));
|
|
47088
47810
|
function hostSessionStatePath(env = process.env) {
|
|
47089
47811
|
const override = env.CODEAM_HOST_SESSION_STATE_FILE;
|
|
47090
47812
|
if (override && override.trim()) return override.trim();
|
|
47091
|
-
return
|
|
47813
|
+
return path88.join(os58.homedir(), ".codeam", "host-agent-sessions.json");
|
|
47092
47814
|
}
|
|
47093
47815
|
function isRecord5(v) {
|
|
47094
47816
|
if (typeof v !== "object" || v === null) return false;
|
|
@@ -47099,7 +47821,7 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
|
|
|
47099
47821
|
return {
|
|
47100
47822
|
load() {
|
|
47101
47823
|
try {
|
|
47102
|
-
const raw = JSON.parse(
|
|
47824
|
+
const raw = JSON.parse(fs74.readFileSync(file, "utf8"));
|
|
47103
47825
|
return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) : [];
|
|
47104
47826
|
} catch {
|
|
47105
47827
|
return [];
|
|
@@ -47107,18 +47829,18 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
|
|
|
47107
47829
|
},
|
|
47108
47830
|
save(list) {
|
|
47109
47831
|
try {
|
|
47110
|
-
|
|
47832
|
+
fs74.mkdirSync(path88.dirname(file), { recursive: true, mode: 448 });
|
|
47111
47833
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
47112
|
-
|
|
47834
|
+
fs74.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
|
|
47113
47835
|
mode: 384
|
|
47114
47836
|
});
|
|
47115
|
-
|
|
47837
|
+
fs74.renameSync(tmp, file);
|
|
47116
47838
|
} catch {
|
|
47117
47839
|
}
|
|
47118
47840
|
},
|
|
47119
47841
|
clear() {
|
|
47120
47842
|
try {
|
|
47121
|
-
|
|
47843
|
+
fs74.rmSync(file, { force: true });
|
|
47122
47844
|
} catch {
|
|
47123
47845
|
}
|
|
47124
47846
|
}
|
|
@@ -47141,9 +47863,9 @@ function planSessionResume(records, max) {
|
|
|
47141
47863
|
return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
|
|
47142
47864
|
}
|
|
47143
47865
|
function pickSavedSessionForWorkspace(sessions3, cwd) {
|
|
47144
|
-
const target =
|
|
47866
|
+
const target = path88.resolve(cwd);
|
|
47145
47867
|
const matches = sessions3.filter(
|
|
47146
|
-
(s) => !!s.cwd &&
|
|
47868
|
+
(s) => !!s.cwd && path88.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
|
|
47147
47869
|
);
|
|
47148
47870
|
if (matches.length === 0) return null;
|
|
47149
47871
|
matches.sort((a, b) => b.pairedAt - a.pairedAt);
|
|
@@ -47151,25 +47873,25 @@ function pickSavedSessionForWorkspace(sessions3, cwd) {
|
|
|
47151
47873
|
}
|
|
47152
47874
|
|
|
47153
47875
|
// src/commands/host/workspace.ts
|
|
47154
|
-
var
|
|
47876
|
+
var fs75 = __toESM(require("fs"));
|
|
47155
47877
|
var os59 = __toESM(require("os"));
|
|
47156
|
-
var
|
|
47878
|
+
var path89 = __toESM(require("path"));
|
|
47157
47879
|
var import_node_child_process25 = require("child_process");
|
|
47158
47880
|
var import_node_util5 = require("util");
|
|
47159
47881
|
var execFileP9 = (0, import_node_util5.promisify)(import_node_child_process25.execFile);
|
|
47160
47882
|
function isAbsolutePathTarget(target) {
|
|
47161
|
-
return
|
|
47883
|
+
return path89.isAbsolute(target);
|
|
47162
47884
|
}
|
|
47163
47885
|
function selfHostedWorkspaceRoot() {
|
|
47164
|
-
return
|
|
47886
|
+
return path89.join(os59.homedir(), ".codeam", "self-hosted");
|
|
47165
47887
|
}
|
|
47166
47888
|
function deployIdFromWorkspace(cwd) {
|
|
47167
47889
|
if (!cwd) return null;
|
|
47168
47890
|
const root = selfHostedWorkspaceRoot();
|
|
47169
|
-
const resolved =
|
|
47170
|
-
const rel =
|
|
47171
|
-
if (!rel || rel.startsWith("..") ||
|
|
47172
|
-
const parts = rel.split(
|
|
47891
|
+
const resolved = path89.resolve(cwd);
|
|
47892
|
+
const rel = path89.relative(root, resolved);
|
|
47893
|
+
if (!rel || rel.startsWith("..") || path89.isAbsolute(rel)) return null;
|
|
47894
|
+
const parts = rel.split(path89.sep).filter(Boolean);
|
|
47173
47895
|
if (parts.length !== 1) return null;
|
|
47174
47896
|
return parts[0];
|
|
47175
47897
|
}
|
|
@@ -47241,15 +47963,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
|
|
|
47241
47963
|
const isGitlab = provider === "gitlab";
|
|
47242
47964
|
if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
|
|
47243
47965
|
if (!cloneToken) return;
|
|
47244
|
-
const credFile =
|
|
47966
|
+
const credFile = path89.join(dest, ".git", "codeam-credentials");
|
|
47245
47967
|
const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
|
|
47246
47968
|
` : `https://x-access-token:${cloneToken}@github.com
|
|
47247
47969
|
`;
|
|
47248
|
-
|
|
47970
|
+
fs75.writeFileSync(credFile, credLine, { mode: 384 });
|
|
47249
47971
|
restrictToOwner(credFile);
|
|
47250
47972
|
const env = nonInteractiveGitEnv();
|
|
47251
47973
|
const git2 = (args2) => execFileP9("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
47252
|
-
const credFilePosix = credFile.split(
|
|
47974
|
+
const credFilePosix = credFile.split(path89.sep).join("/");
|
|
47253
47975
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
47254
47976
|
});
|
|
47255
47977
|
await git2([
|
|
@@ -47282,17 +48004,17 @@ function maskToken(text, cloneToken) {
|
|
|
47282
48004
|
}
|
|
47283
48005
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
|
|
47284
48006
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
47285
|
-
if (!
|
|
48007
|
+
if (!fs75.existsSync(repoOrPath)) {
|
|
47286
48008
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
47287
48009
|
}
|
|
47288
48010
|
return repoOrPath;
|
|
47289
48011
|
}
|
|
47290
|
-
const dest =
|
|
47291
|
-
if (
|
|
48012
|
+
const dest = path89.join(selfHostedWorkspaceRoot(), deployId);
|
|
48013
|
+
if (fs75.existsSync(path89.join(dest, ".git"))) {
|
|
47292
48014
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
|
|
47293
48015
|
return dest;
|
|
47294
48016
|
}
|
|
47295
|
-
|
|
48017
|
+
fs75.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
47296
48018
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
|
|
47297
48019
|
const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
|
|
47298
48020
|
try {
|
|
@@ -47311,11 +48033,11 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
|
|
|
47311
48033
|
|
|
47312
48034
|
// src/commands/host/git-tooling.ts
|
|
47313
48035
|
var import_node_child_process26 = require("child_process");
|
|
47314
|
-
var
|
|
48036
|
+
var fs76 = __toESM(require("fs"));
|
|
47315
48037
|
var os60 = __toESM(require("os"));
|
|
47316
|
-
var
|
|
48038
|
+
var path90 = __toESM(require("path"));
|
|
47317
48039
|
function codeamBinDir() {
|
|
47318
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
48040
|
+
return process.env.CODEAM_BIN_DIR ?? path90.join(os60.homedir(), ".codeam", "bin");
|
|
47319
48041
|
}
|
|
47320
48042
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
47321
48043
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -47347,7 +48069,7 @@ async function download(url2, dest) {
|
|
|
47347
48069
|
const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
|
|
47348
48070
|
if (!res.ok || !res.body) return false;
|
|
47349
48071
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
47350
|
-
|
|
48072
|
+
fs76.writeFileSync(dest, buf);
|
|
47351
48073
|
return true;
|
|
47352
48074
|
} catch {
|
|
47353
48075
|
return false;
|
|
@@ -47370,8 +48092,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
47370
48092
|
const version3 = await resolveVersionFn(token);
|
|
47371
48093
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
47372
48094
|
const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
47373
|
-
const tmpRoot =
|
|
47374
|
-
const archive =
|
|
48095
|
+
const tmpRoot = fs76.mkdtempSync(path90.join(os60.tmpdir(), "codeam-gh-"));
|
|
48096
|
+
const archive = path90.join(tmpRoot, `${asset}.${ext}`);
|
|
47375
48097
|
if (!await downloadFn(url2, archive)) {
|
|
47376
48098
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
47377
48099
|
return null;
|
|
@@ -47381,16 +48103,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
47381
48103
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
47382
48104
|
return null;
|
|
47383
48105
|
}
|
|
47384
|
-
const extractedBin =
|
|
47385
|
-
if (!
|
|
48106
|
+
const extractedBin = path90.join(tmpRoot, asset, "bin", binaryName);
|
|
48107
|
+
if (!fs76.existsSync(extractedBin)) {
|
|
47386
48108
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
47387
48109
|
return null;
|
|
47388
48110
|
}
|
|
47389
48111
|
const binDir = codeamBinDir();
|
|
47390
|
-
|
|
47391
|
-
const target =
|
|
47392
|
-
|
|
47393
|
-
|
|
48112
|
+
fs76.mkdirSync(binDir, { recursive: true });
|
|
48113
|
+
const target = path90.join(binDir, binaryName);
|
|
48114
|
+
fs76.copyFileSync(extractedBin, target);
|
|
48115
|
+
fs76.chmodSync(target, 493);
|
|
47394
48116
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
47395
48117
|
return target;
|
|
47396
48118
|
} catch (e) {
|
|
@@ -47427,19 +48149,19 @@ async function ensureGhAuth(runner, ghCmd, token) {
|
|
|
47427
48149
|
}
|
|
47428
48150
|
function ghConfigDir() {
|
|
47429
48151
|
if (process.env.GH_CONFIG_DIR) return process.env.GH_CONFIG_DIR;
|
|
47430
|
-
if (process.env.XDG_CONFIG_HOME) return
|
|
48152
|
+
if (process.env.XDG_CONFIG_HOME) return path90.join(process.env.XDG_CONFIG_HOME, "gh");
|
|
47431
48153
|
if (process.platform === "win32" && process.env.APPDATA) {
|
|
47432
|
-
return
|
|
48154
|
+
return path90.join(process.env.APPDATA, "GitHub CLI");
|
|
47433
48155
|
}
|
|
47434
|
-
return
|
|
48156
|
+
return path90.join(os60.homedir(), ".config", "gh");
|
|
47435
48157
|
}
|
|
47436
48158
|
function writeGhHostsToken(token) {
|
|
47437
48159
|
try {
|
|
47438
48160
|
const dir = ghConfigDir();
|
|
47439
|
-
const file =
|
|
47440
|
-
if (
|
|
47441
|
-
|
|
47442
|
-
|
|
48161
|
+
const file = path90.join(dir, "hosts.yml");
|
|
48162
|
+
if (fs76.existsSync(file)) return false;
|
|
48163
|
+
fs76.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
48164
|
+
fs76.writeFileSync(
|
|
47443
48165
|
file,
|
|
47444
48166
|
`github.com:
|
|
47445
48167
|
oauth_token: ${token}
|
|
@@ -47482,8 +48204,8 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
47482
48204
|
const version3 = await resolveLatestGlabVersion();
|
|
47483
48205
|
const asset = `glab_${version3}_${osToken}_${arch2}`;
|
|
47484
48206
|
const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
|
|
47485
|
-
const tmpRoot =
|
|
47486
|
-
const archive =
|
|
48207
|
+
const tmpRoot = fs76.mkdtempSync(path90.join(os60.tmpdir(), "codeam-glab-"));
|
|
48208
|
+
const archive = path90.join(tmpRoot, `${asset}.${ext}`);
|
|
47487
48209
|
if (!await downloadFn(url2, archive)) {
|
|
47488
48210
|
log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
|
|
47489
48211
|
return null;
|
|
@@ -47494,20 +48216,20 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
47494
48216
|
return null;
|
|
47495
48217
|
}
|
|
47496
48218
|
const candidates = [
|
|
47497
|
-
|
|
47498
|
-
|
|
47499
|
-
|
|
48219
|
+
path90.join(tmpRoot, "bin", binaryName),
|
|
48220
|
+
path90.join(tmpRoot, asset, "bin", binaryName),
|
|
48221
|
+
path90.join(tmpRoot, binaryName)
|
|
47500
48222
|
];
|
|
47501
|
-
const extractedBin = candidates.find((c2) =>
|
|
48223
|
+
const extractedBin = candidates.find((c2) => fs76.existsSync(c2));
|
|
47502
48224
|
if (!extractedBin) {
|
|
47503
48225
|
log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
|
|
47504
48226
|
return null;
|
|
47505
48227
|
}
|
|
47506
48228
|
const binDir = codeamBinDir();
|
|
47507
|
-
|
|
47508
|
-
const target =
|
|
47509
|
-
|
|
47510
|
-
|
|
48229
|
+
fs76.mkdirSync(binDir, { recursive: true });
|
|
48230
|
+
const target = path90.join(binDir, binaryName);
|
|
48231
|
+
fs76.copyFileSync(extractedBin, target);
|
|
48232
|
+
fs76.chmodSync(target, 493);
|
|
47511
48233
|
log.info("host-agent", `glab installed to ${target} (v${version3})`);
|
|
47512
48234
|
return target;
|
|
47513
48235
|
} catch (e) {
|
|
@@ -47589,9 +48311,9 @@ var defaultGitToolingRunner = {
|
|
|
47589
48311
|
var import_node_child_process28 = require("child_process");
|
|
47590
48312
|
|
|
47591
48313
|
// src/lib/updateNotifier.ts
|
|
47592
|
-
var
|
|
48314
|
+
var fs77 = __toESM(require("fs"));
|
|
47593
48315
|
var os61 = __toESM(require("os"));
|
|
47594
|
-
var
|
|
48316
|
+
var path91 = __toESM(require("path"));
|
|
47595
48317
|
var https8 = __toESM(require("https"));
|
|
47596
48318
|
var import_node_child_process27 = require("child_process");
|
|
47597
48319
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
@@ -47600,12 +48322,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
47600
48322
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
47601
48323
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
47602
48324
|
function cachePath() {
|
|
47603
|
-
const dir =
|
|
47604
|
-
return
|
|
48325
|
+
const dir = path91.join(os61.homedir(), ".codeam");
|
|
48326
|
+
return path91.join(dir, "update-check.json");
|
|
47605
48327
|
}
|
|
47606
48328
|
function readCache() {
|
|
47607
48329
|
try {
|
|
47608
|
-
const raw =
|
|
48330
|
+
const raw = fs77.readFileSync(cachePath(), "utf8");
|
|
47609
48331
|
const parsed = JSON.parse(raw);
|
|
47610
48332
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
47611
48333
|
return parsed;
|
|
@@ -47616,10 +48338,10 @@ function readCache() {
|
|
|
47616
48338
|
function writeCache(cache) {
|
|
47617
48339
|
try {
|
|
47618
48340
|
const file = cachePath();
|
|
47619
|
-
|
|
48341
|
+
fs77.mkdirSync(path91.dirname(file), { recursive: true });
|
|
47620
48342
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
47621
|
-
|
|
47622
|
-
|
|
48343
|
+
fs77.writeFileSync(tmp, JSON.stringify(cache));
|
|
48344
|
+
fs77.renameSync(tmp, file);
|
|
47623
48345
|
} catch {
|
|
47624
48346
|
}
|
|
47625
48347
|
}
|
|
@@ -47693,8 +48415,8 @@ function isLinkedInstall() {
|
|
|
47693
48415
|
timeout: 2e3
|
|
47694
48416
|
}).trim();
|
|
47695
48417
|
if (!root) return false;
|
|
47696
|
-
const pkgPath =
|
|
47697
|
-
return
|
|
48418
|
+
const pkgPath = path91.join(root, PKG_NAME);
|
|
48419
|
+
return fs77.lstatSync(pkgPath).isSymbolicLink();
|
|
47698
48420
|
} catch {
|
|
47699
48421
|
return false;
|
|
47700
48422
|
}
|
|
@@ -47730,7 +48452,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
47730
48452
|
return;
|
|
47731
48453
|
}
|
|
47732
48454
|
try {
|
|
47733
|
-
|
|
48455
|
+
fs77.unlinkSync(cachePath());
|
|
47734
48456
|
} catch {
|
|
47735
48457
|
}
|
|
47736
48458
|
process.stderr.write(` ${import_picocolors12.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -47746,7 +48468,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
47746
48468
|
if (process.env.NODE_ENV === "test") return;
|
|
47747
48469
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47748
48470
|
if (process.env.CI) return;
|
|
47749
|
-
const current2 = true ? "2.75.
|
|
48471
|
+
const current2 = true ? "2.75.26" : null;
|
|
47750
48472
|
if (!current2) return;
|
|
47751
48473
|
const cache = readCache();
|
|
47752
48474
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47763,7 +48485,7 @@ function checkForUpdates() {
|
|
|
47763
48485
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47764
48486
|
if (process.env.CI) return;
|
|
47765
48487
|
if (!process.stdout.isTTY) return;
|
|
47766
|
-
const current2 = true ? "2.75.
|
|
48488
|
+
const current2 = true ? "2.75.26" : null;
|
|
47767
48489
|
if (!current2) return;
|
|
47768
48490
|
const cache = readCache();
|
|
47769
48491
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47786,7 +48508,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
47786
48508
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
47787
48509
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
47788
48510
|
function currentCliVersion() {
|
|
47789
|
-
return true ? "2.75.
|
|
48511
|
+
return true ? "2.75.26" : null;
|
|
47790
48512
|
}
|
|
47791
48513
|
async function installedVersion(deps) {
|
|
47792
48514
|
const ls = await deps.run(
|
|
@@ -48519,13 +49241,13 @@ var HostAgentSupervisor = class {
|
|
|
48519
49241
|
const relay = this.relay;
|
|
48520
49242
|
if (!relay) return;
|
|
48521
49243
|
const raw = cmd.payload?.path;
|
|
48522
|
-
const target = typeof raw === "string" && raw.trim() ?
|
|
49244
|
+
const target = typeof raw === "string" && raw.trim() ? path92.resolve(raw.trim()) : os62.homedir();
|
|
48523
49245
|
try {
|
|
48524
|
-
const dirents = await
|
|
49246
|
+
const dirents = await fs78.promises.readdir(target, { withFileTypes: true });
|
|
48525
49247
|
const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
|
|
48526
49248
|
(a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
|
|
48527
49249
|
);
|
|
48528
|
-
const parent =
|
|
49250
|
+
const parent = path92.dirname(target);
|
|
48529
49251
|
await relay.sendResult(cmd.id, "completed", {
|
|
48530
49252
|
path: target,
|
|
48531
49253
|
// null at the filesystem root so the UI can hide the ".." affordance.
|
|
@@ -48872,14 +49594,14 @@ var HostAgentSupervisor = class {
|
|
|
48872
49594
|
...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
|
|
48873
49595
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
48874
49596
|
};
|
|
48875
|
-
const houseConfigDir =
|
|
49597
|
+
const houseConfigDir = path92.join(
|
|
48876
49598
|
os62.homedir(),
|
|
48877
49599
|
".codeam",
|
|
48878
49600
|
"house-claude",
|
|
48879
49601
|
payload.deployId
|
|
48880
49602
|
);
|
|
48881
49603
|
try {
|
|
48882
|
-
|
|
49604
|
+
fs78.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
48883
49605
|
} catch {
|
|
48884
49606
|
}
|
|
48885
49607
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -48913,13 +49635,13 @@ var HostAgentSupervisor = class {
|
|
|
48913
49635
|
if ((payload.repoProvider ?? "github") === "gitlab") {
|
|
48914
49636
|
const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
|
|
48915
49637
|
if (glabCmd) {
|
|
48916
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
49638
|
+
childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
|
|
48917
49639
|
await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
|
|
48918
49640
|
}
|
|
48919
49641
|
} else {
|
|
48920
49642
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
48921
49643
|
if (ghCmd) {
|
|
48922
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
49644
|
+
childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
|
|
48923
49645
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
48924
49646
|
}
|
|
48925
49647
|
}
|
|
@@ -48947,9 +49669,9 @@ var HostAgentSupervisor = class {
|
|
|
48947
49669
|
);
|
|
48948
49670
|
if (!payload.suppressOnboardingWelcome) {
|
|
48949
49671
|
try {
|
|
48950
|
-
const cfgDir = childEnv.CLAUDE_CONFIG_DIR ||
|
|
48951
|
-
const projectDir =
|
|
48952
|
-
const hasPriorConversation =
|
|
49672
|
+
const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path92.join(os62.homedir(), ".claude");
|
|
49673
|
+
const projectDir = path92.join(cfgDir, "projects", encodeCwd(cwd));
|
|
49674
|
+
const hasPriorConversation = fs78.existsSync(projectDir) && fs78.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
|
|
48953
49675
|
if (hasPriorConversation) {
|
|
48954
49676
|
childEnv.CODEAM_RESUME_LATEST = "1";
|
|
48955
49677
|
log.info(
|
|
@@ -49100,7 +49822,7 @@ var HostAgentSupervisor = class {
|
|
|
49100
49822
|
fallbackResumeTarget() {
|
|
49101
49823
|
const session = getActiveSession();
|
|
49102
49824
|
if (!session || !session.pluginId || !session.pollSecret || !session.agent) return null;
|
|
49103
|
-
const cwd = session.cwd &&
|
|
49825
|
+
const cwd = session.cwd && fs78.existsSync(session.cwd) ? session.cwd : process.cwd();
|
|
49104
49826
|
const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
|
|
49105
49827
|
return { deployId, cwd, session };
|
|
49106
49828
|
}
|
|
@@ -49120,7 +49842,7 @@ var HostAgentSupervisor = class {
|
|
|
49120
49842
|
if (this.children.has(deployId)) return;
|
|
49121
49843
|
const st3 = this.resumeStateFor(target);
|
|
49122
49844
|
try {
|
|
49123
|
-
const cwd =
|
|
49845
|
+
const cwd = fs78.existsSync(target.cwd) ? target.cwd : process.cwd();
|
|
49124
49846
|
const proc = this.resumeSpawner(
|
|
49125
49847
|
{ ...readHouseProxyChildEnv(), CODEAM_RESUME_SESSION_ID: session.id },
|
|
49126
49848
|
cwd
|
|
@@ -49338,12 +50060,12 @@ var HostAgentSupervisor = class {
|
|
|
49338
50060
|
this.untrackChild(deployId);
|
|
49339
50061
|
}
|
|
49340
50062
|
const dirs = [
|
|
49341
|
-
|
|
49342
|
-
|
|
50063
|
+
path92.join(selfHostedWorkspaceRoot(), deployId),
|
|
50064
|
+
path92.join(os62.homedir(), ".codeam", "house-claude", deployId)
|
|
49343
50065
|
];
|
|
49344
50066
|
for (const dir of dirs) {
|
|
49345
50067
|
try {
|
|
49346
|
-
|
|
50068
|
+
fs78.rmSync(dir, { recursive: true, force: true });
|
|
49347
50069
|
} catch (err) {
|
|
49348
50070
|
log.warn(
|
|
49349
50071
|
"host-agent",
|
|
@@ -49502,9 +50224,9 @@ async function invite() {
|
|
|
49502
50224
|
// src/commands/doctor.ts
|
|
49503
50225
|
var import_node_dns = require("dns");
|
|
49504
50226
|
var import_node_util6 = require("util");
|
|
49505
|
-
var
|
|
49506
|
-
var
|
|
49507
|
-
var
|
|
50227
|
+
var import_node_crypto13 = require("crypto");
|
|
50228
|
+
var fs79 = __toESM(require("fs"));
|
|
50229
|
+
var path93 = __toESM(require("path"));
|
|
49508
50230
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
49509
50231
|
var dnsResolveP = (0, import_node_util6.promisify)(import_node_dns.resolve);
|
|
49510
50232
|
async function checkDns(apiBase2) {
|
|
@@ -49560,13 +50282,13 @@ async function checkHealth(apiBase2) {
|
|
|
49560
50282
|
}
|
|
49561
50283
|
}
|
|
49562
50284
|
function checkConfigDir() {
|
|
49563
|
-
const dir =
|
|
50285
|
+
const dir = path93.join(require("os").homedir(), ".codeam");
|
|
49564
50286
|
try {
|
|
49565
|
-
|
|
49566
|
-
const probe =
|
|
49567
|
-
|
|
49568
|
-
const read =
|
|
49569
|
-
|
|
50287
|
+
fs79.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
50288
|
+
const probe = path93.join(dir, ".doctor-probe");
|
|
50289
|
+
fs79.writeFileSync(probe, "ok", { mode: 384 });
|
|
50290
|
+
const read = fs79.readFileSync(probe, "utf8");
|
|
50291
|
+
fs79.unlinkSync(probe);
|
|
49570
50292
|
if (read !== "ok") throw new Error("write/read round-trip mismatch");
|
|
49571
50293
|
return {
|
|
49572
50294
|
id: "config-dir",
|
|
@@ -49630,7 +50352,7 @@ function checkNodePty() {
|
|
|
49630
50352
|
detail: "not required on this platform"
|
|
49631
50353
|
};
|
|
49632
50354
|
}
|
|
49633
|
-
const vendoredPath =
|
|
50355
|
+
const vendoredPath = path93.join(__dirname, "vendor", "node-pty");
|
|
49634
50356
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
49635
50357
|
try {
|
|
49636
50358
|
require(target);
|
|
@@ -49672,9 +50394,9 @@ function checkChokidar() {
|
|
|
49672
50394
|
}
|
|
49673
50395
|
async function doctor(args2 = []) {
|
|
49674
50396
|
const json = args2.includes("--json");
|
|
49675
|
-
const cliVersion = true ? "2.75.
|
|
50397
|
+
const cliVersion = true ? "2.75.26" : "0.0.0-dev";
|
|
49676
50398
|
const apiBase2 = resolveApiBaseUrl();
|
|
49677
|
-
const diagnosticId = (0,
|
|
50399
|
+
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
49678
50400
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
49679
50401
|
const [dns, health] = await Promise.all([
|
|
49680
50402
|
checkDns(apiBase2),
|
|
@@ -50196,7 +50918,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
50196
50918
|
// src/commands/version.ts
|
|
50197
50919
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
50198
50920
|
function version2() {
|
|
50199
|
-
const v = true ? "2.75.
|
|
50921
|
+
const v = true ? "2.75.26" : "unknown";
|
|
50200
50922
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
50201
50923
|
}
|
|
50202
50924
|
|
|
@@ -50397,6 +51119,9 @@ async function main() {
|
|
|
50397
51119
|
if (command === "mcp-run") {
|
|
50398
51120
|
return mcpRun(args);
|
|
50399
51121
|
}
|
|
51122
|
+
if (command === "preview-mcp") {
|
|
51123
|
+
return previewMcp();
|
|
51124
|
+
}
|
|
50400
51125
|
if (command === "mcp-warm") {
|
|
50401
51126
|
await mcpWarm(args);
|
|
50402
51127
|
return;
|