codeam-cli 2.61.80 → 2.61.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +841 -330
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -89,6 +89,165 @@ var require_src = __commonJS({
|
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
+
// src/integrations/convex-admin-mcp.ts
|
|
93
|
+
var convex_admin_mcp_exports = {};
|
|
94
|
+
__export(convex_admin_mcp_exports, {
|
|
95
|
+
callConvexTool: () => callConvexTool,
|
|
96
|
+
deploymentNameFromKey: () => deploymentNameFromKey,
|
|
97
|
+
runConvexAdminMcp: () => runConvexAdminMcp
|
|
98
|
+
});
|
|
99
|
+
function deploymentNameFromKey(key) {
|
|
100
|
+
const prefix = key.split("|")[0];
|
|
101
|
+
const segs = prefix.split(":");
|
|
102
|
+
if ((segs[0] === "dev" || segs[0] === "prod" || segs[0] === "preview") && segs[1]) {
|
|
103
|
+
return segs[1];
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
async function adminQuery(baseUrl, key, api, body, fetchImpl = fetch) {
|
|
108
|
+
const res = await fetchImpl(`${baseUrl}/api/${api}`, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: { Authorization: `Convex ${key}`, "Content-Type": "application/json" },
|
|
111
|
+
body: JSON.stringify(body)
|
|
112
|
+
});
|
|
113
|
+
const text = await res.text();
|
|
114
|
+
const ok = res.ok && !/"status"\s*:\s*"error"/.test(text);
|
|
115
|
+
return { ok, text };
|
|
116
|
+
}
|
|
117
|
+
async function callConvexTool(baseUrl, key, tool, args2, fetchImpl = fetch) {
|
|
118
|
+
switch (tool) {
|
|
119
|
+
case "tables":
|
|
120
|
+
return adminQuery(baseUrl, key, "query", {
|
|
121
|
+
path: "_system/frontend/getTableMapping",
|
|
122
|
+
args: {},
|
|
123
|
+
format: "json"
|
|
124
|
+
}, fetchImpl);
|
|
125
|
+
case "schema":
|
|
126
|
+
return adminQuery(baseUrl, key, "query", {
|
|
127
|
+
path: "_system/frontend/getSchemas",
|
|
128
|
+
args: {},
|
|
129
|
+
format: "json"
|
|
130
|
+
}, fetchImpl);
|
|
131
|
+
case "data":
|
|
132
|
+
return adminQuery(baseUrl, key, "query", {
|
|
133
|
+
path: "_system/cli/queryTable",
|
|
134
|
+
args: { tableName: String(args2.table ?? ""), order: "desc", limit: Number(args2.limit ?? 50) },
|
|
135
|
+
format: "json"
|
|
136
|
+
}, fetchImpl);
|
|
137
|
+
case "run_query":
|
|
138
|
+
return adminQuery(baseUrl, key, "query", {
|
|
139
|
+
path: String(args2.functionPath ?? ""),
|
|
140
|
+
args: args2.args ?? {},
|
|
141
|
+
format: "json"
|
|
142
|
+
}, fetchImpl);
|
|
143
|
+
case "run_mutation":
|
|
144
|
+
return adminQuery(baseUrl, key, "mutation", {
|
|
145
|
+
path: String(args2.functionPath ?? ""),
|
|
146
|
+
args: args2.args ?? {},
|
|
147
|
+
format: "json"
|
|
148
|
+
}, fetchImpl);
|
|
149
|
+
default:
|
|
150
|
+
return { ok: false, text: `Unknown tool: ${tool}` };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function runConvexAdminMcp(client3, id) {
|
|
154
|
+
const token = await client3.getToken(id);
|
|
155
|
+
const key = token.accessToken;
|
|
156
|
+
const name = deploymentNameFromKey(key);
|
|
157
|
+
if (!name) {
|
|
158
|
+
process.stderr.write(
|
|
159
|
+
`[codeam mcp-run convex] could not derive a deployment from the deploy key (expected a dev/prod deploy key like dev:name|\u2026 \u2014 got prefix "${key.split(":")[0]}"). Generate a deploy key at Convex Dashboard \u2192 Project Settings \u2192 Deploy Keys.
|
|
160
|
+
`
|
|
161
|
+
);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
const baseUrl = `https://${name}.convex.cloud`;
|
|
165
|
+
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
166
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
167
|
+
const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
168
|
+
const server = new Server(
|
|
169
|
+
{ name: "convex", version: "1.0.0" },
|
|
170
|
+
{ capabilities: { tools: {} } }
|
|
171
|
+
);
|
|
172
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
173
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
174
|
+
const tool = req.params.name;
|
|
175
|
+
const args2 = req.params.arguments ?? {};
|
|
176
|
+
try {
|
|
177
|
+
const { ok, text } = await callConvexTool(baseUrl, key, tool, args2);
|
|
178
|
+
return { content: [{ type: "text", text }], isError: !ok };
|
|
179
|
+
} catch (err) {
|
|
180
|
+
return {
|
|
181
|
+
content: [
|
|
182
|
+
{
|
|
183
|
+
type: "text",
|
|
184
|
+
text: `Convex admin API request failed: ${err instanceof Error ? err.message : String(err)}`
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
isError: true
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
await server.connect(new StdioServerTransport());
|
|
192
|
+
}
|
|
193
|
+
var TOOLS;
|
|
194
|
+
var init_convex_admin_mcp = __esm({
|
|
195
|
+
"src/integrations/convex-admin-mcp.ts"() {
|
|
196
|
+
"use strict";
|
|
197
|
+
TOOLS = [
|
|
198
|
+
{
|
|
199
|
+
name: "tables",
|
|
200
|
+
description: "List the tables in the connected Convex deployment (name + id). Start here to discover the schema.",
|
|
201
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "schema",
|
|
205
|
+
description: "Get the deployed schema (table definitions + validators) of the Convex deployment.",
|
|
206
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false }
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "data",
|
|
210
|
+
description: "Read documents from a table (most-recent first). Provide the table name.",
|
|
211
|
+
inputSchema: {
|
|
212
|
+
type: "object",
|
|
213
|
+
properties: {
|
|
214
|
+
table: { type: "string", description: "The table name (from `tables`)." },
|
|
215
|
+
limit: { type: "number", description: "Max documents to return (default 50)." }
|
|
216
|
+
},
|
|
217
|
+
required: ["table"],
|
|
218
|
+
additionalProperties: false
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "run_query",
|
|
223
|
+
description: 'Run a read-only Convex query function by its path (e.g. "messages:list") with JSON args.',
|
|
224
|
+
inputSchema: {
|
|
225
|
+
type: "object",
|
|
226
|
+
properties: {
|
|
227
|
+
functionPath: { type: "string", description: 'Function path, e.g. "messages:list".' },
|
|
228
|
+
args: { type: "object", description: "Arguments object for the function (default {})." }
|
|
229
|
+
},
|
|
230
|
+
required: ["functionPath"],
|
|
231
|
+
additionalProperties: false
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "run_mutation",
|
|
236
|
+
description: "Run a Convex mutation function by its path with JSON args (writes data).",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: "object",
|
|
239
|
+
properties: {
|
|
240
|
+
functionPath: { type: "string" },
|
|
241
|
+
args: { type: "object" }
|
|
242
|
+
},
|
|
243
|
+
required: ["functionPath"],
|
|
244
|
+
additionalProperties: false
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
92
251
|
// src/integrations/http-relay.ts
|
|
93
252
|
var http_relay_exports = {};
|
|
94
253
|
__export(http_relay_exports, {
|
|
@@ -1521,15 +1680,19 @@ var INTEGRATION_REGISTRY = {
|
|
|
1521
1680
|
name: "Convex",
|
|
1522
1681
|
icon: "convex",
|
|
1523
1682
|
category: "database",
|
|
1524
|
-
// LIVE — api_key rail (the user pastes a Convex DEPLOY KEY).
|
|
1525
|
-
// ⚠️ Convex's
|
|
1526
|
-
//
|
|
1527
|
-
//
|
|
1528
|
-
//
|
|
1529
|
-
//
|
|
1530
|
-
//
|
|
1531
|
-
//
|
|
1532
|
-
//
|
|
1683
|
+
// LIVE — api_key rail (the user pastes a Convex DEPLOY KEY) + a BUILT-IN MCP.
|
|
1684
|
+
// ⚠️ Convex's OWN `convex mcp start` server CANNOT work headlessly: it
|
|
1685
|
+
// categorically requires an INTERACTIVE `npx convex dev`/`login`
|
|
1686
|
+
// personal-access-token and REJECTS every headless credential — OAuth token,
|
|
1687
|
+
// dev/prod deploy key, self-hosted admin key, with every flag
|
|
1688
|
+
// (--deployment/--prod/--project-dir) — all return "Not Authorized: Run
|
|
1689
|
+
// `npx convex dev` to login" (verified LIVE, exhaustively, 2026-08-03; it
|
|
1690
|
+
// also HANGS on the failed auth = the mareado/no-Stop wedge). BUT the
|
|
1691
|
+
// deployment's own HTTP admin API accepts the deploy key directly
|
|
1692
|
+
// (`Authorization: Convex <deployKey>` → 200; verified). So we serve Convex's
|
|
1693
|
+
// tools ourselves via a BUILT-IN MCP (delivery.builtin) against that admin
|
|
1694
|
+
// API — see apps/cli/src/integrations/convex-admin-mcp.ts. The user still
|
|
1695
|
+
// pastes a deploy key (Dashboard → Project Settings → Deploy Keys).
|
|
1533
1696
|
enabled: true,
|
|
1534
1697
|
auth: {
|
|
1535
1698
|
kind: "api_key",
|
|
@@ -1545,15 +1708,14 @@ var INTEGRATION_REGISTRY = {
|
|
|
1545
1708
|
},
|
|
1546
1709
|
delivery: {
|
|
1547
1710
|
mcp: {
|
|
1548
|
-
//
|
|
1549
|
-
//
|
|
1550
|
-
//
|
|
1551
|
-
//
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
}
|
|
1711
|
+
// BUILT-IN MCP: the CLI serves Convex's tools itself against the
|
|
1712
|
+
// deployment admin REST API with the brokered deploy key (Convex's own
|
|
1713
|
+
// `convex mcp start` rejects all headless creds — see the note above).
|
|
1714
|
+
// No spawned child, no npx. command/args/envMapping are empty.
|
|
1715
|
+
builtin: "convex-admin",
|
|
1716
|
+
command: "",
|
|
1717
|
+
args: [],
|
|
1718
|
+
envMapping: {}
|
|
1557
1719
|
}
|
|
1558
1720
|
}
|
|
1559
1721
|
},
|
|
@@ -2462,11 +2624,11 @@ function quiet(fn) {
|
|
|
2462
2624
|
log.debug(TAG, "ignored sync error", err);
|
|
2463
2625
|
}
|
|
2464
2626
|
}
|
|
2465
|
-
function rmIfExistsQuiet(
|
|
2627
|
+
function rmIfExistsQuiet(path84) {
|
|
2466
2628
|
try {
|
|
2467
|
-
fs2.rmSync(
|
|
2629
|
+
fs2.rmSync(path84, { force: true });
|
|
2468
2630
|
} catch (err) {
|
|
2469
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
2631
|
+
log.debug(TAG, `rmIfExists failed for ${path84}`, err);
|
|
2470
2632
|
}
|
|
2471
2633
|
}
|
|
2472
2634
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -2612,9 +2774,9 @@ var _default = makeConfig();
|
|
|
2612
2774
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
2613
2775
|
|
|
2614
2776
|
// src/commands/pair-auto.ts
|
|
2615
|
-
var
|
|
2777
|
+
var fs61 = __toESM(require("fs"));
|
|
2616
2778
|
var os49 = __toESM(require("os"));
|
|
2617
|
-
var
|
|
2779
|
+
var path65 = __toESM(require("path"));
|
|
2618
2780
|
var import_crypto4 = require("crypto");
|
|
2619
2781
|
|
|
2620
2782
|
// src/services/telemetry.service.ts
|
|
@@ -2650,8 +2812,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
2650
2812
|
return decodedFile;
|
|
2651
2813
|
};
|
|
2652
2814
|
}
|
|
2653
|
-
function normalizeWindowsPath(
|
|
2654
|
-
return
|
|
2815
|
+
function normalizeWindowsPath(path84) {
|
|
2816
|
+
return path84.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
2655
2817
|
}
|
|
2656
2818
|
|
|
2657
2819
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -5131,9 +5293,9 @@ async function addSourceContext(frames) {
|
|
|
5131
5293
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
5132
5294
|
return frames;
|
|
5133
5295
|
}
|
|
5134
|
-
function getContextLinesFromFile(
|
|
5296
|
+
function getContextLinesFromFile(path84, ranges, output) {
|
|
5135
5297
|
return new Promise((resolve9) => {
|
|
5136
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
5298
|
+
const stream = (0, import_node_fs.createReadStream)(path84);
|
|
5137
5299
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
5138
5300
|
input: stream
|
|
5139
5301
|
});
|
|
@@ -5148,7 +5310,7 @@ function getContextLinesFromFile(path82, ranges, output) {
|
|
|
5148
5310
|
let rangeStart = range[0];
|
|
5149
5311
|
let rangeEnd = range[1];
|
|
5150
5312
|
function onStreamError() {
|
|
5151
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
5313
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path84, 1);
|
|
5152
5314
|
lineReaded.close();
|
|
5153
5315
|
lineReaded.removeAllListeners();
|
|
5154
5316
|
destroyStreamAndResolve();
|
|
@@ -5209,8 +5371,8 @@ function clearLineContext(frame) {
|
|
|
5209
5371
|
delete frame.context_line;
|
|
5210
5372
|
delete frame.post_context;
|
|
5211
5373
|
}
|
|
5212
|
-
function shouldSkipContextLinesForFile(
|
|
5213
|
-
return
|
|
5374
|
+
function shouldSkipContextLinesForFile(path84) {
|
|
5375
|
+
return path84.startsWith("node:") || path84.endsWith(".min.js") || path84.endsWith(".min.cjs") || path84.endsWith(".min.mjs") || path84.startsWith("data:");
|
|
5214
5376
|
}
|
|
5215
5377
|
function shouldSkipContextLinesForFrame(frame) {
|
|
5216
5378
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -7364,7 +7526,7 @@ function readAnonId() {
|
|
|
7364
7526
|
}
|
|
7365
7527
|
function superProperties() {
|
|
7366
7528
|
return {
|
|
7367
|
-
cliVersion: true ? "2.61.
|
|
7529
|
+
cliVersion: true ? "2.61.82" : "0.0.0-dev",
|
|
7368
7530
|
nodeVersion: process.version,
|
|
7369
7531
|
platform: process.platform,
|
|
7370
7532
|
arch: process.arch,
|
|
@@ -7545,7 +7707,7 @@ var os4 = __toESM(require("os"));
|
|
|
7545
7707
|
// package.json
|
|
7546
7708
|
var package_default = {
|
|
7547
7709
|
name: "codeam-cli",
|
|
7548
|
-
version: "2.61.
|
|
7710
|
+
version: "2.61.82",
|
|
7549
7711
|
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.",
|
|
7550
7712
|
type: "commonjs",
|
|
7551
7713
|
main: "dist/index.js",
|
|
@@ -7828,6 +7990,50 @@ async function postPreviewEvent(input) {
|
|
|
7828
7990
|
};
|
|
7829
7991
|
}
|
|
7830
7992
|
}
|
|
7993
|
+
async function pushProjectEnv(input) {
|
|
7994
|
+
try {
|
|
7995
|
+
await _transport.postJsonAuthed(
|
|
7996
|
+
`${API_BASE}/api/project-env/push`,
|
|
7997
|
+
{
|
|
7998
|
+
sessionId: input.sessionId,
|
|
7999
|
+
pluginId: input.pluginId,
|
|
8000
|
+
projectKey: input.projectKey,
|
|
8001
|
+
projectLabel: input.projectLabel,
|
|
8002
|
+
content: input.content,
|
|
8003
|
+
keyCount: input.keyCount
|
|
8004
|
+
},
|
|
8005
|
+
input.pluginAuthToken
|
|
8006
|
+
);
|
|
8007
|
+
return { ok: true };
|
|
8008
|
+
} catch (err) {
|
|
8009
|
+
const e = err;
|
|
8010
|
+
return {
|
|
8011
|
+
ok: false,
|
|
8012
|
+
status: typeof e.statusCode === "number" ? e.statusCode : 0,
|
|
8013
|
+
message: e.message || "unknown"
|
|
8014
|
+
};
|
|
8015
|
+
}
|
|
8016
|
+
}
|
|
8017
|
+
async function pullProjectEnv(input) {
|
|
8018
|
+
try {
|
|
8019
|
+
const res = await _transport.postJsonAuthed(
|
|
8020
|
+
`${API_BASE}/api/project-env/pull`,
|
|
8021
|
+
{
|
|
8022
|
+
sessionId: input.sessionId,
|
|
8023
|
+
pluginId: input.pluginId,
|
|
8024
|
+
projectKey: input.projectKey
|
|
8025
|
+
},
|
|
8026
|
+
input.pluginAuthToken
|
|
8027
|
+
);
|
|
8028
|
+
if (res && res.exists === true && typeof res.content === "string") {
|
|
8029
|
+
const keyCount = typeof res.keyCount === "number" ? res.keyCount : 0;
|
|
8030
|
+
return { content: res.content, keyCount };
|
|
8031
|
+
}
|
|
8032
|
+
return null;
|
|
8033
|
+
} catch {
|
|
8034
|
+
return null;
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
7831
8037
|
async function postBatonEvent(input) {
|
|
7832
8038
|
try {
|
|
7833
8039
|
await _transport.postJsonAuthed(
|
|
@@ -8777,7 +8983,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
8777
8983
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
8778
8984
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
8779
8985
|
// pair/reconnect). Older backends ignore the extra field.
|
|
8780
|
-
..."2.61.
|
|
8986
|
+
..."2.61.82" ? { ideVersion: "2.61.82" } : {}
|
|
8781
8987
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
8782
8988
|
}
|
|
8783
8989
|
/**
|
|
@@ -10151,9 +10357,9 @@ function closeAllTerminals() {
|
|
|
10151
10357
|
}
|
|
10152
10358
|
|
|
10153
10359
|
// src/commands/start/handlers.ts
|
|
10154
|
-
var
|
|
10360
|
+
var fs60 = __toESM(require("fs"));
|
|
10155
10361
|
var os48 = __toESM(require("os"));
|
|
10156
|
-
var
|
|
10362
|
+
var path64 = __toESM(require("path"));
|
|
10157
10363
|
var import_crypto3 = require("crypto");
|
|
10158
10364
|
var import_child_process24 = require("child_process");
|
|
10159
10365
|
|
|
@@ -15386,8 +15592,8 @@ function pickLine(obj) {
|
|
|
15386
15592
|
function toHunk(raw, groupSeverity) {
|
|
15387
15593
|
if (!raw || typeof raw !== "object") return null;
|
|
15388
15594
|
const o = raw;
|
|
15389
|
-
const
|
|
15390
|
-
if (!
|
|
15595
|
+
const path84 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
15596
|
+
if (!path84) return null;
|
|
15391
15597
|
const message = asString(
|
|
15392
15598
|
pick(o, [
|
|
15393
15599
|
"comment",
|
|
@@ -15404,7 +15610,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
15404
15610
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
15405
15611
|
const locObj = pick(o, ["location"]) ?? o;
|
|
15406
15612
|
return {
|
|
15407
|
-
path:
|
|
15613
|
+
path: path84.trim(),
|
|
15408
15614
|
line: pickLine(o) ?? pickLine(locObj),
|
|
15409
15615
|
severity,
|
|
15410
15616
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -15487,10 +15693,10 @@ function parsePlain(stdout) {
|
|
|
15487
15693
|
for (const line of stdout.split(/\r?\n/)) {
|
|
15488
15694
|
const m = line.match(HUNK_LINE_RE);
|
|
15489
15695
|
if (!m) continue;
|
|
15490
|
-
const [,
|
|
15491
|
-
if (!
|
|
15696
|
+
const [, path84, lineNo, sevToken, message] = m;
|
|
15697
|
+
if (!path84 || !lineNo || !message) continue;
|
|
15492
15698
|
hunks.push({
|
|
15493
|
-
path:
|
|
15699
|
+
path: path84.trim(),
|
|
15494
15700
|
line: Number(lineNo),
|
|
15495
15701
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
15496
15702
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -19891,7 +20097,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
19891
20097
|
if (process.env.NODE_ENV === "test") return;
|
|
19892
20098
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
19893
20099
|
if (process.env.CI) return;
|
|
19894
|
-
const current = true ? "2.61.
|
|
20100
|
+
const current = true ? "2.61.82" : null;
|
|
19895
20101
|
if (!current) return;
|
|
19896
20102
|
const cache = readCache();
|
|
19897
20103
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -19908,7 +20114,7 @@ function checkForUpdates() {
|
|
|
19908
20114
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
19909
20115
|
if (process.env.CI) return;
|
|
19910
20116
|
if (!process.stdout.isTTY) return;
|
|
19911
|
-
const current = true ? "2.61.
|
|
20117
|
+
const current = true ? "2.61.82" : null;
|
|
19912
20118
|
if (!current) return;
|
|
19913
20119
|
const cache = readCache();
|
|
19914
20120
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -19928,7 +20134,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
19928
20134
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
19929
20135
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
19930
20136
|
function currentCliVersion() {
|
|
19931
|
-
return true ? "2.61.
|
|
20137
|
+
return true ? "2.61.82" : null;
|
|
19932
20138
|
}
|
|
19933
20139
|
function runCmd(cmd, args2, timeoutMs) {
|
|
19934
20140
|
return new Promise((resolve9) => {
|
|
@@ -21588,9 +21794,213 @@ function reclaimOwnOrphanPort(port) {
|
|
|
21588
21794
|
return true;
|
|
21589
21795
|
}
|
|
21590
21796
|
|
|
21797
|
+
// src/services/preview/host-allow.ts
|
|
21798
|
+
var import_fs = require("fs");
|
|
21799
|
+
var path50 = __toESM(require("path"));
|
|
21800
|
+
var NEXT_ALLOWED_ORIGINS = [
|
|
21801
|
+
"*.trycloudflare.com",
|
|
21802
|
+
"*.preview.codeagent-mobile.com",
|
|
21803
|
+
"*.codeagent-mobile.com"
|
|
21804
|
+
];
|
|
21805
|
+
var VITE_ALLOWED_HOSTS = [
|
|
21806
|
+
".trycloudflare.com",
|
|
21807
|
+
".preview.codeagent-mobile.com",
|
|
21808
|
+
".codeagent-mobile.com"
|
|
21809
|
+
];
|
|
21810
|
+
var CONFIG_BASENAMES = {
|
|
21811
|
+
next: "next.config",
|
|
21812
|
+
vite: "vite.config"
|
|
21813
|
+
};
|
|
21814
|
+
var CONFIG_EXTS = [".ts", ".mjs", ".js", ".cjs", ".mts"];
|
|
21815
|
+
var MARKER_DIR = ".codeam";
|
|
21816
|
+
var MARKER_FILE = "preview-host-allow.json";
|
|
21817
|
+
var ORIG_INFIX = ".codeam-orig";
|
|
21818
|
+
function markerPath(cwd) {
|
|
21819
|
+
return path50.join(cwd, MARKER_DIR, MARKER_FILE);
|
|
21820
|
+
}
|
|
21821
|
+
async function fileExists(p2) {
|
|
21822
|
+
try {
|
|
21823
|
+
await import_fs.promises.access(p2);
|
|
21824
|
+
return true;
|
|
21825
|
+
} catch {
|
|
21826
|
+
return false;
|
|
21827
|
+
}
|
|
21828
|
+
}
|
|
21829
|
+
async function findConfigFile(cwd, framework) {
|
|
21830
|
+
const base = CONFIG_BASENAMES[framework];
|
|
21831
|
+
for (const ext of CONFIG_EXTS) {
|
|
21832
|
+
if (await fileExists(path50.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
|
|
21833
|
+
}
|
|
21834
|
+
return null;
|
|
21835
|
+
}
|
|
21836
|
+
async function dependsOn(cwd, pkgName) {
|
|
21837
|
+
try {
|
|
21838
|
+
const raw = await import_fs.promises.readFile(path50.join(cwd, "package.json"), "utf8");
|
|
21839
|
+
const pkg = JSON.parse(raw);
|
|
21840
|
+
return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
|
|
21841
|
+
} catch {
|
|
21842
|
+
return false;
|
|
21843
|
+
}
|
|
21844
|
+
}
|
|
21845
|
+
async function isEsmConfig(cwd, configFile) {
|
|
21846
|
+
const ext = path50.extname(configFile);
|
|
21847
|
+
if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
|
|
21848
|
+
if (ext === ".cjs") return false;
|
|
21849
|
+
try {
|
|
21850
|
+
const raw = await import_fs.promises.readFile(path50.join(cwd, "package.json"), "utf8");
|
|
21851
|
+
return JSON.parse(raw).type === "module";
|
|
21852
|
+
} catch {
|
|
21853
|
+
return false;
|
|
21854
|
+
}
|
|
21855
|
+
}
|
|
21856
|
+
function nextShim(origBasename, esm) {
|
|
21857
|
+
const list = JSON.stringify(NEXT_ALLOWED_ORIGINS);
|
|
21858
|
+
const merge = `
|
|
21859
|
+
function __codeamWithAllow(cfg) {
|
|
21860
|
+
var c = cfg && typeof cfg === 'object' ? Object.assign({}, cfg) : {};
|
|
21861
|
+
var existing = Array.isArray(c.allowedDevOrigins) ? c.allowedDevOrigins : [];
|
|
21862
|
+
c.allowedDevOrigins = Array.from(new Set(existing.concat(${list})));
|
|
21863
|
+
return c;
|
|
21864
|
+
}
|
|
21865
|
+
function __codeamMerge(base) {
|
|
21866
|
+
if (typeof base === 'function') {
|
|
21867
|
+
return function () {
|
|
21868
|
+
var r = base.apply(null, arguments);
|
|
21869
|
+
return r && typeof r.then === 'function' ? r.then(__codeamWithAllow) : __codeamWithAllow(r);
|
|
21870
|
+
};
|
|
21871
|
+
}
|
|
21872
|
+
return base && typeof base.then === 'function' ? base.then(__codeamWithAllow) : __codeamWithAllow(base);
|
|
21873
|
+
}`;
|
|
21874
|
+
if (origBasename) {
|
|
21875
|
+
return esm ? `// codeam preview host-allow shim \u2014 auto-generated, restored on preview stop.
|
|
21876
|
+
import __codeamUser from './${origBasename}';
|
|
21877
|
+
${merge}
|
|
21878
|
+
export default __codeamMerge(__codeamUser);
|
|
21879
|
+
` : `// codeam preview host-allow shim \u2014 auto-generated, restored on preview stop.
|
|
21880
|
+
var __codeamUser = require('./${origBasename}');
|
|
21881
|
+
${merge}
|
|
21882
|
+
module.exports = __codeamMerge(__codeamUser && __codeamUser.default ? __codeamUser.default : __codeamUser);
|
|
21883
|
+
`;
|
|
21884
|
+
}
|
|
21885
|
+
return esm ? `// codeam preview host-allow shim \u2014 auto-generated, removed on preview stop.
|
|
21886
|
+
export default { allowedDevOrigins: ${list} };
|
|
21887
|
+
` : `// codeam preview host-allow shim \u2014 auto-generated, removed on preview stop.
|
|
21888
|
+
module.exports = { allowedDevOrigins: ${list} };
|
|
21889
|
+
`;
|
|
21890
|
+
}
|
|
21891
|
+
function viteShim(origBasename, esm) {
|
|
21892
|
+
const list = JSON.stringify(VITE_ALLOWED_HOSTS);
|
|
21893
|
+
const merge = `
|
|
21894
|
+
function __codeamWithAllow(cfg) {
|
|
21895
|
+
var c = cfg && typeof cfg === 'object' ? Object.assign({}, cfg) : {};
|
|
21896
|
+
var server = Object.assign({}, c.server || {});
|
|
21897
|
+
if (server.allowedHosts === true) { c.server = server; return c; }
|
|
21898
|
+
var existing = Array.isArray(server.allowedHosts) ? server.allowedHosts : [];
|
|
21899
|
+
server.allowedHosts = Array.from(new Set(existing.concat(${list})));
|
|
21900
|
+
c.server = server;
|
|
21901
|
+
return c;
|
|
21902
|
+
}
|
|
21903
|
+
function __codeamMerge(base) {
|
|
21904
|
+
if (typeof base === 'function') {
|
|
21905
|
+
return function () {
|
|
21906
|
+
var r = base.apply(null, arguments);
|
|
21907
|
+
return r && typeof r.then === 'function' ? r.then(__codeamWithAllow) : __codeamWithAllow(r);
|
|
21908
|
+
};
|
|
21909
|
+
}
|
|
21910
|
+
return base && typeof base.then === 'function' ? base.then(__codeamWithAllow) : __codeamWithAllow(base);
|
|
21911
|
+
}`;
|
|
21912
|
+
if (origBasename) {
|
|
21913
|
+
return esm ? `// codeam preview host-allow shim \u2014 auto-generated, restored on preview stop.
|
|
21914
|
+
import __codeamUser from './${origBasename}';
|
|
21915
|
+
${merge}
|
|
21916
|
+
export default __codeamMerge(__codeamUser);
|
|
21917
|
+
` : `// codeam preview host-allow shim \u2014 auto-generated, restored on preview stop.
|
|
21918
|
+
var __codeamUser = require('./${origBasename}');
|
|
21919
|
+
${merge}
|
|
21920
|
+
module.exports = __codeamMerge(__codeamUser && __codeamUser.default ? __codeamUser.default : __codeamUser);
|
|
21921
|
+
`;
|
|
21922
|
+
}
|
|
21923
|
+
return esm ? `// codeam preview host-allow shim \u2014 auto-generated, removed on preview stop.
|
|
21924
|
+
export default { server: { allowedHosts: ${list} } };
|
|
21925
|
+
` : `// codeam preview host-allow shim \u2014 auto-generated, removed on preview stop.
|
|
21926
|
+
module.exports = { server: { allowedHosts: ${list} } };
|
|
21927
|
+
`;
|
|
21928
|
+
}
|
|
21929
|
+
function shimFor(framework, origBasename, esm) {
|
|
21930
|
+
return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
|
|
21931
|
+
}
|
|
21932
|
+
async function writeMarker(cwd, marker) {
|
|
21933
|
+
await import_fs.promises.mkdir(path50.join(cwd, MARKER_DIR), { recursive: true });
|
|
21934
|
+
await import_fs.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
|
|
21935
|
+
}
|
|
21936
|
+
async function readMarker(cwd) {
|
|
21937
|
+
try {
|
|
21938
|
+
const parsed = JSON.parse(await import_fs.promises.readFile(markerPath(cwd), "utf8"));
|
|
21939
|
+
return parsed && parsed.configFile ? parsed : null;
|
|
21940
|
+
} catch {
|
|
21941
|
+
return null;
|
|
21942
|
+
}
|
|
21943
|
+
}
|
|
21944
|
+
async function restorePreviewHostAllow(cwd) {
|
|
21945
|
+
const marker = await readMarker(cwd);
|
|
21946
|
+
if (!marker) return;
|
|
21947
|
+
try {
|
|
21948
|
+
const configAbs = path50.join(cwd, marker.configFile);
|
|
21949
|
+
if (marker.backupFile) {
|
|
21950
|
+
const backupAbs = path50.join(cwd, marker.backupFile);
|
|
21951
|
+
if (await fileExists(backupAbs)) {
|
|
21952
|
+
await import_fs.promises.rm(configAbs, { force: true });
|
|
21953
|
+
await import_fs.promises.rename(backupAbs, configAbs);
|
|
21954
|
+
}
|
|
21955
|
+
} else {
|
|
21956
|
+
await import_fs.promises.rm(configAbs, { force: true });
|
|
21957
|
+
}
|
|
21958
|
+
} catch (err) {
|
|
21959
|
+
log.warn("preview", `host-allow restore failed: ${err instanceof Error ? err.message : err}`);
|
|
21960
|
+
} finally {
|
|
21961
|
+
await import_fs.promises.rm(markerPath(cwd), { force: true }).catch(() => void 0);
|
|
21962
|
+
}
|
|
21963
|
+
}
|
|
21964
|
+
async function applyPreviewHostAllow(cwd) {
|
|
21965
|
+
try {
|
|
21966
|
+
await restorePreviewHostAllow(cwd);
|
|
21967
|
+
let framework = null;
|
|
21968
|
+
let existing = null;
|
|
21969
|
+
for (const f of ["next", "vite"]) {
|
|
21970
|
+
const cfg = await findConfigFile(cwd, f);
|
|
21971
|
+
if (cfg) {
|
|
21972
|
+
framework = f;
|
|
21973
|
+
existing = cfg;
|
|
21974
|
+
break;
|
|
21975
|
+
}
|
|
21976
|
+
}
|
|
21977
|
+
if (!framework) {
|
|
21978
|
+
if (await dependsOn(cwd, "next")) framework = "next";
|
|
21979
|
+
else if (await dependsOn(cwd, "vite")) framework = "vite";
|
|
21980
|
+
}
|
|
21981
|
+
if (!framework) return;
|
|
21982
|
+
if (existing) {
|
|
21983
|
+
const ext = path50.extname(existing);
|
|
21984
|
+
const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
|
|
21985
|
+
const esm = await isEsmConfig(cwd, existing);
|
|
21986
|
+
await import_fs.promises.rename(path50.join(cwd, existing), path50.join(cwd, origBasename));
|
|
21987
|
+
await import_fs.promises.writeFile(path50.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
|
|
21988
|
+
await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
|
|
21989
|
+
log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
|
|
21990
|
+
} else {
|
|
21991
|
+
const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
|
|
21992
|
+
await import_fs.promises.writeFile(path50.join(cwd, configFile), shimFor(framework, null, true), "utf8");
|
|
21993
|
+
await writeMarker(cwd, { framework, configFile, backupFile: null });
|
|
21994
|
+
log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
|
|
21995
|
+
}
|
|
21996
|
+
} catch (err) {
|
|
21997
|
+
log.warn("preview", `host-allow apply skipped: ${err instanceof Error ? err.message : err}`);
|
|
21998
|
+
}
|
|
21999
|
+
}
|
|
22000
|
+
|
|
21591
22001
|
// src/services/preview/cloudflared.ts
|
|
21592
22002
|
var import_child_process15 = require("child_process");
|
|
21593
|
-
var
|
|
22003
|
+
var import_fs2 = require("fs");
|
|
21594
22004
|
var import_promises = __toESM(require("fs/promises"));
|
|
21595
22005
|
var import_os9 = __toESM(require("os"));
|
|
21596
22006
|
var import_path4 = __toESM(require("path"));
|
|
@@ -21631,7 +22041,7 @@ async function downloadCloudflared(target) {
|
|
|
21631
22041
|
const tmp = `${target}.download.tgz`;
|
|
21632
22042
|
await (0, import_promises2.pipeline)(
|
|
21633
22043
|
response.body,
|
|
21634
|
-
(0,
|
|
22044
|
+
(0, import_fs2.createWriteStream)(tmp)
|
|
21635
22045
|
);
|
|
21636
22046
|
try {
|
|
21637
22047
|
await extractTgz(tmp, import_path4.default.dirname(target));
|
|
@@ -21648,7 +22058,7 @@ async function downloadCloudflared(target) {
|
|
|
21648
22058
|
}
|
|
21649
22059
|
await (0, import_promises2.pipeline)(
|
|
21650
22060
|
response.body,
|
|
21651
|
-
(0,
|
|
22061
|
+
(0, import_fs2.createWriteStream)(target, { mode: 493 })
|
|
21652
22062
|
);
|
|
21653
22063
|
}
|
|
21654
22064
|
async function isExecutableBinary(p2) {
|
|
@@ -21909,7 +22319,7 @@ async function waitForPortListening(port, opts) {
|
|
|
21909
22319
|
}
|
|
21910
22320
|
|
|
21911
22321
|
// src/services/preview/provision-deps.ts
|
|
21912
|
-
var
|
|
22322
|
+
var import_fs3 = require("fs");
|
|
21913
22323
|
var import_path6 = __toESM(require("path"));
|
|
21914
22324
|
|
|
21915
22325
|
// src/services/preview/run-setup.ts
|
|
@@ -22057,7 +22467,7 @@ function pickMigrationScript(scripts) {
|
|
|
22057
22467
|
}
|
|
22058
22468
|
async function exists(p2) {
|
|
22059
22469
|
try {
|
|
22060
|
-
await
|
|
22470
|
+
await import_fs3.promises.access(p2);
|
|
22061
22471
|
return true;
|
|
22062
22472
|
} catch {
|
|
22063
22473
|
return false;
|
|
@@ -22074,20 +22484,20 @@ async function ensureEnvFile(cwd, generated) {
|
|
|
22074
22484
|
}
|
|
22075
22485
|
const sample = await firstExisting(cwd, ENV_SAMPLES);
|
|
22076
22486
|
if (sample) {
|
|
22077
|
-
const body = await
|
|
22078
|
-
await
|
|
22487
|
+
const body = await import_fs3.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
|
|
22488
|
+
await import_fs3.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
22079
22489
|
log.info("provision", `wrote .env from ${sample}`);
|
|
22080
22490
|
return;
|
|
22081
22491
|
}
|
|
22082
22492
|
if (generated.length > 0) {
|
|
22083
22493
|
const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
|
|
22084
|
-
await
|
|
22494
|
+
await import_fs3.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
|
|
22085
22495
|
log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
|
|
22086
22496
|
}
|
|
22087
22497
|
}
|
|
22088
22498
|
async function readPackageJson(cwd) {
|
|
22089
22499
|
try {
|
|
22090
|
-
return JSON.parse(await
|
|
22500
|
+
return JSON.parse(await import_fs3.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
|
|
22091
22501
|
} catch {
|
|
22092
22502
|
return null;
|
|
22093
22503
|
}
|
|
@@ -22128,9 +22538,9 @@ async function provisionProjectDependencies(cwd) {
|
|
|
22128
22538
|
generated = detectServicesFromDeps(pkg);
|
|
22129
22539
|
if (generated.length > 0) {
|
|
22130
22540
|
const dir = import_path6.default.join(cwd, ".codeam", "provision");
|
|
22131
|
-
await
|
|
22541
|
+
await import_fs3.promises.mkdir(dir, { recursive: true });
|
|
22132
22542
|
const file = import_path6.default.join(dir, "compose.generated.yaml");
|
|
22133
|
-
await
|
|
22543
|
+
await import_fs3.promises.writeFile(file, renderComposeYaml(generated));
|
|
22134
22544
|
log.info(
|
|
22135
22545
|
"provision",
|
|
22136
22546
|
`no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
|
|
@@ -22151,12 +22561,12 @@ async function provisionProjectDependencies(cwd) {
|
|
|
22151
22561
|
}
|
|
22152
22562
|
|
|
22153
22563
|
// src/services/preview/setup-deps.ts
|
|
22154
|
-
var
|
|
22564
|
+
var import_fs4 = __toESM(require("fs"));
|
|
22155
22565
|
var import_path7 = __toESM(require("path"));
|
|
22156
22566
|
function detectMissingNodeDeps(cwd) {
|
|
22157
|
-
if (!
|
|
22158
|
-
if (
|
|
22159
|
-
if (
|
|
22567
|
+
if (!import_fs4.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
|
|
22568
|
+
if (import_fs4.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
|
|
22569
|
+
if (import_fs4.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
|
|
22160
22570
|
return { cmd: "yarn", args: ["install"] };
|
|
22161
22571
|
}
|
|
22162
22572
|
return { cmd: "npm", args: ["install", "--legacy-peer-deps"] };
|
|
@@ -22248,6 +22658,7 @@ async function killPreview(sessionId) {
|
|
|
22248
22658
|
if (preview.tunnel) killProcessTree(preview.tunnel, "SIGKILL");
|
|
22249
22659
|
}, 250);
|
|
22250
22660
|
sigkillTimer.unref?.();
|
|
22661
|
+
await restorePreviewHostAllow(preview.cwd);
|
|
22251
22662
|
activePreviews.delete(sessionId);
|
|
22252
22663
|
}
|
|
22253
22664
|
async function killAllPreviews() {
|
|
@@ -22259,10 +22670,153 @@ function activePreviewSessionIds() {
|
|
|
22259
22670
|
}
|
|
22260
22671
|
|
|
22261
22672
|
// src/services/preview/start-orchestrator.ts
|
|
22262
|
-
var
|
|
22263
|
-
var
|
|
22264
|
-
var
|
|
22673
|
+
var import_child_process19 = require("child_process");
|
|
22674
|
+
var fs54 = __toESM(require("fs"));
|
|
22675
|
+
var path57 = __toESM(require("path"));
|
|
22265
22676
|
var import_which2 = __toESM(require("which"));
|
|
22677
|
+
|
|
22678
|
+
// src/services/project-env/index.ts
|
|
22679
|
+
var import_fs5 = require("fs");
|
|
22680
|
+
var path56 = __toESM(require("path"));
|
|
22681
|
+
|
|
22682
|
+
// src/beads/project-key.ts
|
|
22683
|
+
var import_child_process18 = require("child_process");
|
|
22684
|
+
var crypto2 = __toESM(require("crypto"));
|
|
22685
|
+
var fs52 = __toESM(require("fs"));
|
|
22686
|
+
var path55 = __toESM(require("path"));
|
|
22687
|
+
function normalizeOrigin(raw) {
|
|
22688
|
+
const trimmed = raw.trim();
|
|
22689
|
+
if (!trimmed) return null;
|
|
22690
|
+
let host2;
|
|
22691
|
+
let pathPart;
|
|
22692
|
+
const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
|
|
22693
|
+
if (scpLike && !trimmed.includes("://")) {
|
|
22694
|
+
host2 = scpLike[1];
|
|
22695
|
+
pathPart = scpLike[2];
|
|
22696
|
+
} else {
|
|
22697
|
+
let url2;
|
|
22698
|
+
try {
|
|
22699
|
+
url2 = new URL(trimmed);
|
|
22700
|
+
} catch {
|
|
22701
|
+
return null;
|
|
22702
|
+
}
|
|
22703
|
+
host2 = url2.hostname;
|
|
22704
|
+
pathPart = url2.pathname;
|
|
22705
|
+
}
|
|
22706
|
+
host2 = host2.toLowerCase();
|
|
22707
|
+
pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
22708
|
+
if (!host2 || !pathPart) return null;
|
|
22709
|
+
return `${host2}/${pathPart}`;
|
|
22710
|
+
}
|
|
22711
|
+
function findRepoRoot(cwd) {
|
|
22712
|
+
let dir = path55.resolve(cwd);
|
|
22713
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22714
|
+
for (let i = 0; i < 256; i++) {
|
|
22715
|
+
if (seen.has(dir)) return null;
|
|
22716
|
+
seen.add(dir);
|
|
22717
|
+
try {
|
|
22718
|
+
const stat3 = fs52.statSync(path55.join(dir, ".git"), { throwIfNoEntry: false });
|
|
22719
|
+
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
22720
|
+
} catch {
|
|
22721
|
+
}
|
|
22722
|
+
const parent = path55.dirname(dir);
|
|
22723
|
+
if (parent === dir) return null;
|
|
22724
|
+
dir = parent;
|
|
22725
|
+
}
|
|
22726
|
+
return null;
|
|
22727
|
+
}
|
|
22728
|
+
var _execSeam2 = {
|
|
22729
|
+
exec: (file, args2, opts) => {
|
|
22730
|
+
const out2 = (0, import_child_process18.execFileSync)(file, args2, opts);
|
|
22731
|
+
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
22732
|
+
},
|
|
22733
|
+
realpath: (p2) => fs52.realpathSync(p2)
|
|
22734
|
+
};
|
|
22735
|
+
function readOrigin(cwd) {
|
|
22736
|
+
try {
|
|
22737
|
+
const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
|
|
22738
|
+
cwd,
|
|
22739
|
+
timeout: 1e3,
|
|
22740
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
22741
|
+
encoding: "utf8"
|
|
22742
|
+
});
|
|
22743
|
+
return raw.trim() || null;
|
|
22744
|
+
} catch {
|
|
22745
|
+
return null;
|
|
22746
|
+
}
|
|
22747
|
+
}
|
|
22748
|
+
function deriveProjectIdentity(cwd = process.cwd()) {
|
|
22749
|
+
const repoRoot = findRepoRoot(cwd) ?? cwd;
|
|
22750
|
+
const origin = readOrigin(repoRoot);
|
|
22751
|
+
const normalized = origin ? normalizeOrigin(origin) : null;
|
|
22752
|
+
if (normalized) {
|
|
22753
|
+
const label = normalized.split("/").pop() || normalized;
|
|
22754
|
+
return { projectKey: normalized, projectLabel: label };
|
|
22755
|
+
}
|
|
22756
|
+
let real = repoRoot;
|
|
22757
|
+
try {
|
|
22758
|
+
real = _execSeam2.realpath(repoRoot);
|
|
22759
|
+
} catch {
|
|
22760
|
+
}
|
|
22761
|
+
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
22762
|
+
return { projectKey: `path:${hash}`, projectLabel: path55.basename(real) || "project" };
|
|
22763
|
+
}
|
|
22764
|
+
|
|
22765
|
+
// src/services/project-env/index.ts
|
|
22766
|
+
async function readIfExists(p2) {
|
|
22767
|
+
try {
|
|
22768
|
+
return await import_fs5.promises.readFile(p2, "utf8");
|
|
22769
|
+
} catch {
|
|
22770
|
+
return null;
|
|
22771
|
+
}
|
|
22772
|
+
}
|
|
22773
|
+
async function syncProjectEnvUp(cwd, ctx) {
|
|
22774
|
+
if (!ctx.pluginAuthToken) return;
|
|
22775
|
+
const content = await readIfExists(path56.join(cwd, ".env"));
|
|
22776
|
+
if (content == null) return;
|
|
22777
|
+
try {
|
|
22778
|
+
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
22779
|
+
const keyCount = parseDotenv(content).length;
|
|
22780
|
+
const res = await pushProjectEnv({
|
|
22781
|
+
sessionId: ctx.sessionId,
|
|
22782
|
+
pluginId: ctx.pluginId,
|
|
22783
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
22784
|
+
projectKey,
|
|
22785
|
+
projectLabel,
|
|
22786
|
+
content,
|
|
22787
|
+
keyCount
|
|
22788
|
+
});
|
|
22789
|
+
if (res.ok) log.info("project-env", `pushed .env (${keyCount} vars) for ${projectLabel}`);
|
|
22790
|
+
else log.debug("project-env", `push .env failed (${res.status}) \u2014 non-fatal`);
|
|
22791
|
+
} catch (err) {
|
|
22792
|
+
log.debug("project-env", `push .env skipped: ${err instanceof Error ? err.message : err}`);
|
|
22793
|
+
}
|
|
22794
|
+
}
|
|
22795
|
+
async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
22796
|
+
if (!ctx.pluginAuthToken) return false;
|
|
22797
|
+
const envPath = path56.join(cwd, ".env");
|
|
22798
|
+
if (await readIfExists(envPath) != null) return false;
|
|
22799
|
+
try {
|
|
22800
|
+
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
22801
|
+
const stored = await pullProjectEnv({
|
|
22802
|
+
sessionId: ctx.sessionId,
|
|
22803
|
+
pluginId: ctx.pluginId,
|
|
22804
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
22805
|
+
projectKey
|
|
22806
|
+
});
|
|
22807
|
+
if (!stored) return false;
|
|
22808
|
+
const tmp = path56.join(cwd, ".env.codeam-restore.tmp");
|
|
22809
|
+
await import_fs5.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
|
|
22810
|
+
await import_fs5.promises.rename(tmp, envPath);
|
|
22811
|
+
log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
|
|
22812
|
+
return true;
|
|
22813
|
+
} catch (err) {
|
|
22814
|
+
log.debug("project-env", `restore .env skipped: ${err instanceof Error ? err.message : err}`);
|
|
22815
|
+
return false;
|
|
22816
|
+
}
|
|
22817
|
+
}
|
|
22818
|
+
|
|
22819
|
+
// src/services/preview/start-orchestrator.ts
|
|
22266
22820
|
var INSTALL_TIMEOUT_MS = 5 * 6e4;
|
|
22267
22821
|
var SETUP_TIMEOUT_MS = 2 * 6e4;
|
|
22268
22822
|
var TUNNEL_REGISTER_DEADLINE_MS = 45e3;
|
|
@@ -22328,8 +22882,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
22328
22882
|
if (args2.length === 0) return detection;
|
|
22329
22883
|
const binName = args2[0];
|
|
22330
22884
|
if (binName.startsWith("-")) return detection;
|
|
22331
|
-
const binPath =
|
|
22332
|
-
if (!
|
|
22885
|
+
const binPath = path57.join(cwd, "node_modules", ".bin", binName);
|
|
22886
|
+
if (!fs54.existsSync(binPath)) return detection;
|
|
22333
22887
|
return {
|
|
22334
22888
|
...detection,
|
|
22335
22889
|
command: binPath,
|
|
@@ -22375,7 +22929,8 @@ async function runPreviewStart(args2) {
|
|
|
22375
22929
|
tunnel: tun.tunnel,
|
|
22376
22930
|
url: tun.url,
|
|
22377
22931
|
framework: detection.framework,
|
|
22378
|
-
detection
|
|
22932
|
+
detection,
|
|
22933
|
+
cwd: ctx.cwd
|
|
22379
22934
|
});
|
|
22380
22935
|
recordPreviewPort(detection.port, dev.devServer.pid, sessionId, Date.now());
|
|
22381
22936
|
log.info("preview", `ready: ${detection.framework} at ${tun.url}`);
|
|
@@ -22387,6 +22942,13 @@ async function runPreviewStart(args2) {
|
|
|
22387
22942
|
}
|
|
22388
22943
|
async function provisionDeps(ctx) {
|
|
22389
22944
|
const { detection, cwd, emit: emit2, emitProgress } = ctx;
|
|
22945
|
+
if (ctx.projectEnvAuth?.pluginAuthToken) {
|
|
22946
|
+
await restoreProjectEnvIfMissing(cwd, {
|
|
22947
|
+
sessionId: ctx.sessionId,
|
|
22948
|
+
pluginId: ctx.projectEnvAuth.pluginId,
|
|
22949
|
+
pluginAuthToken: ctx.projectEnvAuth.pluginAuthToken
|
|
22950
|
+
});
|
|
22951
|
+
}
|
|
22390
22952
|
const missingDeps = detectMissingNodeDeps(cwd);
|
|
22391
22953
|
let preflightRan = false;
|
|
22392
22954
|
if (missingDeps) {
|
|
@@ -22534,9 +23096,10 @@ async function startDevServer(ctx) {
|
|
|
22534
23096
|
return null;
|
|
22535
23097
|
}
|
|
22536
23098
|
}
|
|
23099
|
+
await applyPreviewHostAllow(cwd);
|
|
22537
23100
|
const spawnable = normalizeDetectionForSpawn(detection, cwd);
|
|
22538
23101
|
emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
|
|
22539
|
-
const devServer = (0,
|
|
23102
|
+
const devServer = (0, import_child_process19.spawn)(spawnable.command, spawnable.args, {
|
|
22540
23103
|
cwd,
|
|
22541
23104
|
env: { ...process.env, ...spawnable.env ?? {} },
|
|
22542
23105
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -22661,7 +23224,7 @@ async function establishTunnel(ctx, dev) {
|
|
|
22661
23224
|
`cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
|
|
22662
23225
|
);
|
|
22663
23226
|
}
|
|
22664
|
-
const candidate = (0,
|
|
23227
|
+
const candidate = (0, import_child_process19.spawn)(
|
|
22665
23228
|
bin,
|
|
22666
23229
|
["tunnel", "--url", `http://localhost:${detection.port}`],
|
|
22667
23230
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -22692,10 +23255,10 @@ async function establishTunnel(ctx, dev) {
|
|
|
22692
23255
|
}
|
|
22693
23256
|
|
|
22694
23257
|
// src/beads/bd-adapter.ts
|
|
22695
|
-
var
|
|
22696
|
-
var
|
|
23258
|
+
var import_child_process20 = require("child_process");
|
|
23259
|
+
var fs55 = __toESM(require("fs"));
|
|
22697
23260
|
var os42 = __toESM(require("os"));
|
|
22698
|
-
var
|
|
23261
|
+
var path58 = __toESM(require("path"));
|
|
22699
23262
|
var BD_PACKAGE = "@beads/bd";
|
|
22700
23263
|
function resolveBundledBdBinary() {
|
|
22701
23264
|
return _resolveSeam.resolveBundled();
|
|
@@ -22707,11 +23270,11 @@ function _defaultResolveBundled() {
|
|
|
22707
23270
|
} catch {
|
|
22708
23271
|
return null;
|
|
22709
23272
|
}
|
|
22710
|
-
const binDir =
|
|
23273
|
+
const binDir = path58.join(path58.dirname(pkgJsonPath), "bin");
|
|
22711
23274
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
22712
|
-
const binaryPath =
|
|
23275
|
+
const binaryPath = path58.join(binDir, binaryName);
|
|
22713
23276
|
try {
|
|
22714
|
-
|
|
23277
|
+
fs55.accessSync(binaryPath, fs55.constants.F_OK);
|
|
22715
23278
|
return binaryPath;
|
|
22716
23279
|
} catch {
|
|
22717
23280
|
return null;
|
|
@@ -22721,13 +23284,13 @@ function resolveBdOnPath() {
|
|
|
22721
23284
|
return _resolveSeam.resolveOnPath();
|
|
22722
23285
|
}
|
|
22723
23286
|
function _defaultResolveOnPath() {
|
|
22724
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
23287
|
+
const dirs = (process.env.PATH ?? "").split(path58.delimiter).filter(Boolean);
|
|
22725
23288
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
22726
23289
|
for (const dir of dirs) {
|
|
22727
23290
|
for (const candidate of candidates) {
|
|
22728
|
-
const full =
|
|
23291
|
+
const full = path58.join(dir, candidate);
|
|
22729
23292
|
try {
|
|
22730
|
-
|
|
23293
|
+
fs55.accessSync(full, fs55.constants.F_OK);
|
|
22731
23294
|
return full;
|
|
22732
23295
|
} catch {
|
|
22733
23296
|
}
|
|
@@ -22746,7 +23309,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
|
|
|
22746
23309
|
return new Promise((resolve9) => {
|
|
22747
23310
|
let proc;
|
|
22748
23311
|
try {
|
|
22749
|
-
proc = (0,
|
|
23312
|
+
proc = (0, import_child_process20.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
|
|
22750
23313
|
} catch (err) {
|
|
22751
23314
|
resolve9({ code: -1, stdout: "", stderr: err.message });
|
|
22752
23315
|
return;
|
|
@@ -22904,12 +23467,12 @@ function coerceIssue(row, projectKey) {
|
|
|
22904
23467
|
|
|
22905
23468
|
// src/beads/provisioner.ts
|
|
22906
23469
|
var import_child_process23 = require("child_process");
|
|
22907
|
-
var
|
|
23470
|
+
var fs57 = __toESM(require("fs"));
|
|
22908
23471
|
var os44 = __toESM(require("os"));
|
|
22909
|
-
var
|
|
23472
|
+
var path60 = __toESM(require("path"));
|
|
22910
23473
|
|
|
22911
23474
|
// src/beads/install-bd.ts
|
|
22912
|
-
var
|
|
23475
|
+
var import_child_process21 = require("child_process");
|
|
22913
23476
|
var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
|
|
22914
23477
|
var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
|
|
22915
23478
|
function resolveInstallStrategy(platform3) {
|
|
@@ -22940,7 +23503,7 @@ function _defaultInstallSpawn(strategy) {
|
|
|
22940
23503
|
return new Promise((resolve9) => {
|
|
22941
23504
|
let proc;
|
|
22942
23505
|
try {
|
|
22943
|
-
proc = (0,
|
|
23506
|
+
proc = (0, import_child_process21.spawn)(strategy.command, strategy.args, { env: process.env });
|
|
22944
23507
|
} catch (err) {
|
|
22945
23508
|
resolve9({ ok: false, code: -1, stderr: err.message });
|
|
22946
23509
|
return;
|
|
@@ -22970,10 +23533,10 @@ async function installBd(platform3 = process.platform) {
|
|
|
22970
23533
|
}
|
|
22971
23534
|
|
|
22972
23535
|
// src/beads/install-dolt.ts
|
|
22973
|
-
var
|
|
22974
|
-
var
|
|
23536
|
+
var import_child_process22 = require("child_process");
|
|
23537
|
+
var fs56 = __toESM(require("fs"));
|
|
22975
23538
|
var os43 = __toESM(require("os"));
|
|
22976
|
-
var
|
|
23539
|
+
var path59 = __toESM(require("path"));
|
|
22977
23540
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
22978
23541
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
22979
23542
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -23069,7 +23632,7 @@ var _doltPathSeam = {
|
|
|
23069
23632
|
},
|
|
23070
23633
|
exists: (p2) => {
|
|
23071
23634
|
try {
|
|
23072
|
-
|
|
23635
|
+
fs56.accessSync(p2, fs56.constants.F_OK);
|
|
23073
23636
|
return true;
|
|
23074
23637
|
} catch {
|
|
23075
23638
|
return false;
|
|
@@ -23080,7 +23643,7 @@ function doltBinaryNames(platform3) {
|
|
|
23080
23643
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
23081
23644
|
}
|
|
23082
23645
|
function knownDoltDirs(platform3) {
|
|
23083
|
-
const P3 = platform3 === "win32" ?
|
|
23646
|
+
const P3 = platform3 === "win32" ? path59.win32 : path59.posix;
|
|
23084
23647
|
const home = _doltPathSeam.homedir();
|
|
23085
23648
|
if (platform3 === "win32") {
|
|
23086
23649
|
return [
|
|
@@ -23096,7 +23659,7 @@ function knownDoltDirs(platform3) {
|
|
|
23096
23659
|
].filter(Boolean);
|
|
23097
23660
|
}
|
|
23098
23661
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
23099
|
-
const P3 = platform3 === "win32" ?
|
|
23662
|
+
const P3 = platform3 === "win32" ? path59.win32 : path59.posix;
|
|
23100
23663
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
23101
23664
|
const names = doltBinaryNames(platform3);
|
|
23102
23665
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -23132,7 +23695,7 @@ function _defaultDoltInstallSpawn(strategy) {
|
|
|
23132
23695
|
};
|
|
23133
23696
|
let proc;
|
|
23134
23697
|
try {
|
|
23135
|
-
proc = (0,
|
|
23698
|
+
proc = (0, import_child_process22.spawn)(strategy.command, strategy.args, {
|
|
23136
23699
|
env: process.env,
|
|
23137
23700
|
stdio: ["ignore", "pipe", "pipe"]
|
|
23138
23701
|
});
|
|
@@ -23229,89 +23792,6 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
23229
23792
|
return { up: false, started: false };
|
|
23230
23793
|
}
|
|
23231
23794
|
|
|
23232
|
-
// src/beads/project-key.ts
|
|
23233
|
-
var import_child_process22 = require("child_process");
|
|
23234
|
-
var crypto2 = __toESM(require("crypto"));
|
|
23235
|
-
var fs54 = __toESM(require("fs"));
|
|
23236
|
-
var path57 = __toESM(require("path"));
|
|
23237
|
-
function normalizeOrigin(raw) {
|
|
23238
|
-
const trimmed = raw.trim();
|
|
23239
|
-
if (!trimmed) return null;
|
|
23240
|
-
let host2;
|
|
23241
|
-
let pathPart;
|
|
23242
|
-
const scpLike = /^[^/@]+@([^:]+):(.+)$/.exec(trimmed);
|
|
23243
|
-
if (scpLike && !trimmed.includes("://")) {
|
|
23244
|
-
host2 = scpLike[1];
|
|
23245
|
-
pathPart = scpLike[2];
|
|
23246
|
-
} else {
|
|
23247
|
-
let url2;
|
|
23248
|
-
try {
|
|
23249
|
-
url2 = new URL(trimmed);
|
|
23250
|
-
} catch {
|
|
23251
|
-
return null;
|
|
23252
|
-
}
|
|
23253
|
-
host2 = url2.hostname;
|
|
23254
|
-
pathPart = url2.pathname;
|
|
23255
|
-
}
|
|
23256
|
-
host2 = host2.toLowerCase();
|
|
23257
|
-
pathPart = pathPart.replace(/^\/+/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
23258
|
-
if (!host2 || !pathPart) return null;
|
|
23259
|
-
return `${host2}/${pathPart}`;
|
|
23260
|
-
}
|
|
23261
|
-
function findRepoRoot(cwd) {
|
|
23262
|
-
let dir = path57.resolve(cwd);
|
|
23263
|
-
const seen = /* @__PURE__ */ new Set();
|
|
23264
|
-
for (let i = 0; i < 256; i++) {
|
|
23265
|
-
if (seen.has(dir)) return null;
|
|
23266
|
-
seen.add(dir);
|
|
23267
|
-
try {
|
|
23268
|
-
const stat3 = fs54.statSync(path57.join(dir, ".git"), { throwIfNoEntry: false });
|
|
23269
|
-
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
23270
|
-
} catch {
|
|
23271
|
-
}
|
|
23272
|
-
const parent = path57.dirname(dir);
|
|
23273
|
-
if (parent === dir) return null;
|
|
23274
|
-
dir = parent;
|
|
23275
|
-
}
|
|
23276
|
-
return null;
|
|
23277
|
-
}
|
|
23278
|
-
var _execSeam2 = {
|
|
23279
|
-
exec: (file, args2, opts) => {
|
|
23280
|
-
const out2 = (0, import_child_process22.execFileSync)(file, args2, opts);
|
|
23281
|
-
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
23282
|
-
},
|
|
23283
|
-
realpath: (p2) => fs54.realpathSync(p2)
|
|
23284
|
-
};
|
|
23285
|
-
function readOrigin(cwd) {
|
|
23286
|
-
try {
|
|
23287
|
-
const raw = _execSeam2.exec("git", ["remote", "get-url", "origin"], {
|
|
23288
|
-
cwd,
|
|
23289
|
-
timeout: 1e3,
|
|
23290
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
23291
|
-
encoding: "utf8"
|
|
23292
|
-
});
|
|
23293
|
-
return raw.trim() || null;
|
|
23294
|
-
} catch {
|
|
23295
|
-
return null;
|
|
23296
|
-
}
|
|
23297
|
-
}
|
|
23298
|
-
function deriveProjectIdentity(cwd = process.cwd()) {
|
|
23299
|
-
const repoRoot = findRepoRoot(cwd) ?? cwd;
|
|
23300
|
-
const origin = readOrigin(repoRoot);
|
|
23301
|
-
const normalized = origin ? normalizeOrigin(origin) : null;
|
|
23302
|
-
if (normalized) {
|
|
23303
|
-
const label = normalized.split("/").pop() || normalized;
|
|
23304
|
-
return { projectKey: normalized, projectLabel: label };
|
|
23305
|
-
}
|
|
23306
|
-
let real = repoRoot;
|
|
23307
|
-
try {
|
|
23308
|
-
real = _execSeam2.realpath(repoRoot);
|
|
23309
|
-
} catch {
|
|
23310
|
-
}
|
|
23311
|
-
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
23312
|
-
return { projectKey: `path:${hash}`, projectLabel: path57.basename(real) || "project" };
|
|
23313
|
-
}
|
|
23314
|
-
|
|
23315
23795
|
// src/beads/project-prefix.ts
|
|
23316
23796
|
var crypto3 = __toESM(require("crypto"));
|
|
23317
23797
|
function prefixForProjectKey(projectKey) {
|
|
@@ -23359,14 +23839,14 @@ var _linkSeam = {
|
|
|
23359
23839
|
homedir: () => os44.homedir(),
|
|
23360
23840
|
isWritableDir: (dir) => {
|
|
23361
23841
|
try {
|
|
23362
|
-
|
|
23842
|
+
fs57.accessSync(dir, fs57.constants.W_OK);
|
|
23363
23843
|
return true;
|
|
23364
23844
|
} catch {
|
|
23365
23845
|
return false;
|
|
23366
23846
|
}
|
|
23367
23847
|
},
|
|
23368
23848
|
ensureDir: (dir) => {
|
|
23369
|
-
|
|
23849
|
+
fs57.mkdirSync(dir, { recursive: true });
|
|
23370
23850
|
},
|
|
23371
23851
|
/**
|
|
23372
23852
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -23387,9 +23867,9 @@ var _linkSeam = {
|
|
|
23387
23867
|
* which `linkBdOntoPath` creates if missing.
|
|
23388
23868
|
*/
|
|
23389
23869
|
cliBinDir: () => {
|
|
23390
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
23870
|
+
const pathDirs = (process.env.PATH ?? "").split(path60.delimiter).filter(Boolean);
|
|
23391
23871
|
const home = _linkSeam.homedir();
|
|
23392
|
-
const localBin = home ?
|
|
23872
|
+
const localBin = home ? path60.join(home, ".local", "bin") : null;
|
|
23393
23873
|
if (localBin) {
|
|
23394
23874
|
try {
|
|
23395
23875
|
_linkSeam.ensureDir(localBin);
|
|
@@ -23399,16 +23879,16 @@ var _linkSeam = {
|
|
|
23399
23879
|
const candidates = [];
|
|
23400
23880
|
if (localBin) candidates.push(localBin);
|
|
23401
23881
|
try {
|
|
23402
|
-
candidates.push(
|
|
23882
|
+
candidates.push(path60.dirname(process.execPath));
|
|
23403
23883
|
} catch {
|
|
23404
23884
|
}
|
|
23405
23885
|
candidates.push("/usr/local/bin");
|
|
23406
23886
|
const entry = process.argv[1];
|
|
23407
23887
|
if (entry) {
|
|
23408
23888
|
try {
|
|
23409
|
-
candidates.push(
|
|
23889
|
+
candidates.push(path60.dirname(fs57.realpathSync(entry)));
|
|
23410
23890
|
} catch {
|
|
23411
|
-
candidates.push(
|
|
23891
|
+
candidates.push(path60.dirname(entry));
|
|
23412
23892
|
}
|
|
23413
23893
|
}
|
|
23414
23894
|
const onPathWritable = candidates.find(
|
|
@@ -23420,20 +23900,20 @@ var _linkSeam = {
|
|
|
23420
23900
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
23421
23901
|
readlink: (linkPath) => {
|
|
23422
23902
|
try {
|
|
23423
|
-
return
|
|
23903
|
+
return fs57.readlinkSync(linkPath);
|
|
23424
23904
|
} catch {
|
|
23425
23905
|
return null;
|
|
23426
23906
|
}
|
|
23427
23907
|
},
|
|
23428
|
-
unlink: (linkPath) =>
|
|
23429
|
-
symlink: (target, linkPath) =>
|
|
23908
|
+
unlink: (linkPath) => fs57.unlinkSync(linkPath),
|
|
23909
|
+
symlink: (target, linkPath) => fs57.symlinkSync(target, linkPath)
|
|
23430
23910
|
};
|
|
23431
23911
|
function linkBdOntoPath(binaryPath) {
|
|
23432
23912
|
if (_linkSeam.platform() === "win32") return;
|
|
23433
23913
|
const binDir = _linkSeam.cliBinDir();
|
|
23434
23914
|
if (!binDir) return;
|
|
23435
23915
|
_linkSeam.ensureDir(binDir);
|
|
23436
|
-
const linkPath =
|
|
23916
|
+
const linkPath = path60.join(binDir, "bd");
|
|
23437
23917
|
if (linkPath === binaryPath) return;
|
|
23438
23918
|
const current = _linkSeam.readlink(linkPath);
|
|
23439
23919
|
if (current === binaryPath) return;
|
|
@@ -23628,7 +24108,7 @@ function dedupeRecipes(agents) {
|
|
|
23628
24108
|
|
|
23629
24109
|
// src/beads/watcher.ts
|
|
23630
24110
|
var crypto4 = __toESM(require("crypto"));
|
|
23631
|
-
var
|
|
24111
|
+
var path61 = __toESM(require("path"));
|
|
23632
24112
|
var API_BASE6 = resolveApiBaseUrl();
|
|
23633
24113
|
var DEBOUNCE_MS2 = 400;
|
|
23634
24114
|
var ZERO_SUMMARY = {
|
|
@@ -23652,7 +24132,7 @@ var BeadsWatcher = class {
|
|
|
23652
24132
|
constructor(opts) {
|
|
23653
24133
|
this.opts = opts;
|
|
23654
24134
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
23655
|
-
this.feedPath = opts.feedPath ??
|
|
24135
|
+
this.feedPath = opts.feedPath ?? path61.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
23656
24136
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
23657
24137
|
}
|
|
23658
24138
|
opts;
|
|
@@ -24151,8 +24631,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
24151
24631
|
function saveFilesTemp(files) {
|
|
24152
24632
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
24153
24633
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
24154
|
-
const tmpPath =
|
|
24155
|
-
|
|
24634
|
+
const tmpPath = path64.join(os48.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
24635
|
+
fs60.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
24156
24636
|
pendingAttachmentFiles.add(tmpPath);
|
|
24157
24637
|
return tmpPath;
|
|
24158
24638
|
});
|
|
@@ -24364,9 +24844,10 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
24364
24844
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
24365
24845
|
};
|
|
24366
24846
|
var envReadH = async (ctx, cmd) => {
|
|
24367
|
-
const envPath =
|
|
24847
|
+
const envPath = path64.join(process.cwd(), ".env");
|
|
24848
|
+
await restoreProjectEnvIfMissing(process.cwd(), ctx);
|
|
24368
24849
|
try {
|
|
24369
|
-
const raw = await
|
|
24850
|
+
const raw = await fs60.promises.readFile(envPath, "utf8");
|
|
24370
24851
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
24371
24852
|
exists: true,
|
|
24372
24853
|
vars: parseDotenv(raw)
|
|
@@ -24397,14 +24878,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
24397
24878
|
}
|
|
24398
24879
|
seen.add(v.key);
|
|
24399
24880
|
}
|
|
24400
|
-
const envPath =
|
|
24401
|
-
const tmpPath =
|
|
24881
|
+
const envPath = path64.join(process.cwd(), ".env");
|
|
24882
|
+
const tmpPath = path64.join(process.cwd(), ".env.codeam.tmp");
|
|
24402
24883
|
try {
|
|
24403
|
-
await
|
|
24404
|
-
await
|
|
24884
|
+
await fs60.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
24885
|
+
await fs60.promises.rename(tmpPath, envPath);
|
|
24405
24886
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
24887
|
+
void syncProjectEnvUp(process.cwd(), ctx);
|
|
24406
24888
|
} catch (err) {
|
|
24407
|
-
await
|
|
24889
|
+
await fs60.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
24408
24890
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
24409
24891
|
}
|
|
24410
24892
|
};
|
|
@@ -24453,7 +24935,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
24453
24935
|
let configuredAgent = rawAgentId;
|
|
24454
24936
|
if (!configuredAgent) {
|
|
24455
24937
|
try {
|
|
24456
|
-
const raw = JSON.parse(
|
|
24938
|
+
const raw = JSON.parse(fs60.readFileSync(headroomConfigPath(), "utf8"));
|
|
24457
24939
|
configuredAgent = raw.agent ?? "";
|
|
24458
24940
|
} catch {
|
|
24459
24941
|
}
|
|
@@ -24487,7 +24969,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
24487
24969
|
persist: persistHeadroomConfig,
|
|
24488
24970
|
readEnabled: () => {
|
|
24489
24971
|
try {
|
|
24490
|
-
const raw = JSON.parse(
|
|
24972
|
+
const raw = JSON.parse(fs60.readFileSync(headroomConfigPath(), "utf8"));
|
|
24491
24973
|
return raw.enabled === true;
|
|
24492
24974
|
} catch {
|
|
24493
24975
|
return false;
|
|
@@ -24791,7 +25273,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
24791
25273
|
}
|
|
24792
25274
|
let headroomActive = false;
|
|
24793
25275
|
try {
|
|
24794
|
-
const raw = JSON.parse(
|
|
25276
|
+
const raw = JSON.parse(fs60.readFileSync(headroomConfigPath(), "utf8"));
|
|
24795
25277
|
headroomActive = raw.enabled === true;
|
|
24796
25278
|
} catch {
|
|
24797
25279
|
}
|
|
@@ -24801,7 +25283,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
24801
25283
|
}
|
|
24802
25284
|
let existingConfig = { enabled: true };
|
|
24803
25285
|
try {
|
|
24804
|
-
existingConfig = JSON.parse(
|
|
25286
|
+
existingConfig = JSON.parse(fs60.readFileSync(headroomConfigPath(), "utf8"));
|
|
24805
25287
|
} catch {
|
|
24806
25288
|
}
|
|
24807
25289
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -24914,9 +25396,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
24914
25396
|
function buildNpmInstallInvocation(opts) {
|
|
24915
25397
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
24916
25398
|
const execPath = opts?.execPath ?? process.execPath;
|
|
24917
|
-
const exists2 = opts?.existsSync ??
|
|
25399
|
+
const exists2 = opts?.existsSync ?? fs60.existsSync;
|
|
24918
25400
|
const platform3 = opts?.platform ?? process.platform;
|
|
24919
|
-
const p2 = platform3 === "win32" ?
|
|
25401
|
+
const p2 = platform3 === "win32" ? path64.win32 : path64.posix;
|
|
24920
25402
|
const normalized = entryScript.split(/[\\/]/).join("/");
|
|
24921
25403
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
24922
25404
|
const markerIdx = normalized.indexOf(marker);
|
|
@@ -24938,7 +25420,7 @@ function isPermissionError(stderr) {
|
|
|
24938
25420
|
function resolveGlobalNodeModulesDir(opts) {
|
|
24939
25421
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
24940
25422
|
const platform3 = opts?.platform ?? process.platform;
|
|
24941
|
-
const p2 = platform3 === "win32" ?
|
|
25423
|
+
const p2 = platform3 === "win32" ? path64.win32 : path64.posix;
|
|
24942
25424
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
24943
25425
|
const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
|
|
24944
25426
|
if (markerIdx <= 0) return null;
|
|
@@ -24948,9 +25430,9 @@ function resolveGlobalNodeModulesDir(opts) {
|
|
|
24948
25430
|
var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
|
|
24949
25431
|
function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
24950
25432
|
if (!nodeModulesDir) return 0;
|
|
24951
|
-
const readdirSync12 = deps?.readdirSync ??
|
|
24952
|
-
const statSync17 = deps?.statSync ??
|
|
24953
|
-
const rmSync8 = deps?.rmSync ??
|
|
25433
|
+
const readdirSync12 = deps?.readdirSync ?? fs60.readdirSync;
|
|
25434
|
+
const statSync17 = deps?.statSync ?? fs60.statSync;
|
|
25435
|
+
const rmSync8 = deps?.rmSync ?? fs60.rmSync;
|
|
24954
25436
|
let removed = 0;
|
|
24955
25437
|
let entries;
|
|
24956
25438
|
try {
|
|
@@ -24960,7 +25442,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
|
24960
25442
|
}
|
|
24961
25443
|
for (const name of entries) {
|
|
24962
25444
|
if (!/^\.codeam-cli-/.test(name)) continue;
|
|
24963
|
-
const full =
|
|
25445
|
+
const full = path64.join(nodeModulesDir, name);
|
|
24964
25446
|
try {
|
|
24965
25447
|
const st3 = statSync17(full);
|
|
24966
25448
|
if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
|
|
@@ -25449,7 +25931,12 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
|
|
|
25449
25931
|
sessionId: ctx.sessionId,
|
|
25450
25932
|
detection,
|
|
25451
25933
|
cwd: process.cwd(),
|
|
25452
|
-
emit: emit2
|
|
25934
|
+
emit: emit2,
|
|
25935
|
+
// Auth for the per-repo `.env` vault restore, performed INSIDE the bring-up
|
|
25936
|
+
// (provisionDeps stage, after the reuse short-circuit) so a fresh session of
|
|
25937
|
+
// this repo picks up its saved `.env` before the dev server spawns. Optional
|
|
25938
|
+
// — a caller without a token just skips the restore.
|
|
25939
|
+
projectEnvAuth: { pluginId: ctx.pluginId, pluginAuthToken }
|
|
25453
25940
|
}).catch((err) => {
|
|
25454
25941
|
const message = err instanceof Error ? err.message : String(err);
|
|
25455
25942
|
log.warn("preview", `start crashed before ready: ${message}`);
|
|
@@ -25822,11 +26309,11 @@ function resolveTokenValue(args2) {
|
|
|
25822
26309
|
}
|
|
25823
26310
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
25824
26311
|
if (fileFlag) {
|
|
25825
|
-
const
|
|
26312
|
+
const path84 = fileFlag.slice("--token-file=".length);
|
|
25826
26313
|
try {
|
|
25827
|
-
const content =
|
|
25828
|
-
if (content.length === 0) fail(`--token-file ${
|
|
25829
|
-
rmIfExistsQuiet(
|
|
26314
|
+
const content = fs61.readFileSync(path84, "utf8").trim();
|
|
26315
|
+
if (content.length === 0) fail(`--token-file ${path84} is empty`);
|
|
26316
|
+
rmIfExistsQuiet(path84);
|
|
25830
26317
|
return content;
|
|
25831
26318
|
} catch (err) {
|
|
25832
26319
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -25916,7 +26403,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
25916
26403
|
}
|
|
25917
26404
|
}
|
|
25918
26405
|
function pairAutoLockPath() {
|
|
25919
|
-
return
|
|
26406
|
+
return path65.join(os49.homedir(), ".codeam", "pair-auto.lock");
|
|
25920
26407
|
}
|
|
25921
26408
|
function isLivePairAuto(pid) {
|
|
25922
26409
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -25926,7 +26413,7 @@ function isLivePairAuto(pid) {
|
|
|
25926
26413
|
if (e.code !== "EPERM") return false;
|
|
25927
26414
|
}
|
|
25928
26415
|
try {
|
|
25929
|
-
return
|
|
26416
|
+
return fs61.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
25930
26417
|
} catch {
|
|
25931
26418
|
return true;
|
|
25932
26419
|
}
|
|
@@ -25936,24 +26423,24 @@ function isLiveCodeam(pid) {
|
|
|
25936
26423
|
}
|
|
25937
26424
|
function daemonLockPath(sessionId) {
|
|
25938
26425
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
25939
|
-
return
|
|
26426
|
+
return path65.join(os49.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
25940
26427
|
}
|
|
25941
26428
|
function acquireDaemonLock(sessionId) {
|
|
25942
26429
|
const lockPath = daemonLockPath(sessionId);
|
|
25943
26430
|
try {
|
|
25944
|
-
|
|
26431
|
+
fs61.mkdirSync(path65.dirname(lockPath), { recursive: true });
|
|
25945
26432
|
try {
|
|
25946
|
-
|
|
26433
|
+
fs61.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
25947
26434
|
} catch (e) {
|
|
25948
26435
|
if (e.code !== "EEXIST") throw e;
|
|
25949
|
-
const holder = Number(
|
|
26436
|
+
const holder = Number(fs61.readFileSync(lockPath, "utf8").trim());
|
|
25950
26437
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
25951
|
-
|
|
26438
|
+
fs61.writeFileSync(lockPath, String(process.pid));
|
|
25952
26439
|
}
|
|
25953
26440
|
const release3 = () => {
|
|
25954
26441
|
try {
|
|
25955
|
-
if (
|
|
25956
|
-
|
|
26442
|
+
if (fs61.existsSync(lockPath) && Number(fs61.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
26443
|
+
fs61.unlinkSync(lockPath);
|
|
25957
26444
|
}
|
|
25958
26445
|
} catch {
|
|
25959
26446
|
}
|
|
@@ -25975,19 +26462,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
25975
26462
|
function acquireSingletonLock() {
|
|
25976
26463
|
const lockPath = pairAutoLockPath();
|
|
25977
26464
|
try {
|
|
25978
|
-
|
|
26465
|
+
fs61.mkdirSync(path65.dirname(lockPath), { recursive: true });
|
|
25979
26466
|
try {
|
|
25980
|
-
|
|
26467
|
+
fs61.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
25981
26468
|
} catch (e) {
|
|
25982
26469
|
if (e.code !== "EEXIST") throw e;
|
|
25983
|
-
const holder = Number(
|
|
26470
|
+
const holder = Number(fs61.readFileSync(lockPath, "utf8").trim());
|
|
25984
26471
|
if (isLivePairAuto(holder)) return false;
|
|
25985
|
-
|
|
26472
|
+
fs61.writeFileSync(lockPath, String(process.pid));
|
|
25986
26473
|
}
|
|
25987
26474
|
process.once("exit", () => {
|
|
25988
26475
|
try {
|
|
25989
|
-
if (
|
|
25990
|
-
|
|
26476
|
+
if (fs61.existsSync(lockPath) && Number(fs61.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
26477
|
+
fs61.unlinkSync(lockPath);
|
|
25991
26478
|
}
|
|
25992
26479
|
} catch {
|
|
25993
26480
|
}
|
|
@@ -26439,10 +26926,10 @@ var AgentService = class _AgentService {
|
|
|
26439
26926
|
};
|
|
26440
26927
|
|
|
26441
26928
|
// src/agents/acp/adapters.ts
|
|
26442
|
-
var
|
|
26929
|
+
var path67 = __toESM(require("path"));
|
|
26443
26930
|
|
|
26444
26931
|
// src/agents/acp/agent-binary.ts
|
|
26445
|
-
var
|
|
26932
|
+
var import_fs6 = __toESM(require("fs"));
|
|
26446
26933
|
var import_os11 = __toESM(require("os"));
|
|
26447
26934
|
var import_path8 = __toESM(require("path"));
|
|
26448
26935
|
var import_child_process26 = require("child_process");
|
|
@@ -26472,7 +26959,7 @@ function defaultSdkDir() {
|
|
|
26472
26959
|
return resolveSdkDirViaRequire();
|
|
26473
26960
|
}
|
|
26474
26961
|
function resolveClaudeNativeBinary(deps = {}) {
|
|
26475
|
-
const existsSync27 = deps.existsSync ??
|
|
26962
|
+
const existsSync27 = deps.existsSync ?? import_fs6.default.existsSync;
|
|
26476
26963
|
const platformKey = deps.platformKey ?? currentPlatformKey();
|
|
26477
26964
|
const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
|
|
26478
26965
|
if (!sdkDir) return null;
|
|
@@ -26530,7 +27017,7 @@ async function waitForCommandOnPath(cmd, opts = {}) {
|
|
|
26530
27017
|
return check();
|
|
26531
27018
|
}
|
|
26532
27019
|
function resolveCursorAgentBinary(deps = {}) {
|
|
26533
|
-
const existsSync27 = deps.existsSync ??
|
|
27020
|
+
const existsSync27 = deps.existsSync ?? import_fs6.default.existsSync;
|
|
26534
27021
|
const platform3 = deps.platform ?? process.platform;
|
|
26535
27022
|
const env = deps.env ?? process.env;
|
|
26536
27023
|
if (platform3 === "win32") {
|
|
@@ -26729,13 +27216,13 @@ function resolveBin(pkgName, binName) {
|
|
|
26729
27216
|
try {
|
|
26730
27217
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
26731
27218
|
const manifest = require_(`${pkgName}/package.json`);
|
|
26732
|
-
const pkgDir =
|
|
27219
|
+
const pkgDir = path67.dirname(manifestPath);
|
|
26733
27220
|
const bin = manifest.bin;
|
|
26734
27221
|
if (!bin) return null;
|
|
26735
|
-
if (typeof bin === "string") return
|
|
27222
|
+
if (typeof bin === "string") return path67.resolve(pkgDir, bin);
|
|
26736
27223
|
const target = binName ?? Object.keys(bin)[0];
|
|
26737
27224
|
if (!target || !bin[target]) return null;
|
|
26738
|
-
return
|
|
27225
|
+
return path67.resolve(pkgDir, bin[target]);
|
|
26739
27226
|
} catch {
|
|
26740
27227
|
return null;
|
|
26741
27228
|
}
|
|
@@ -26885,8 +27372,8 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
|
|
|
26885
27372
|
var import_node_crypto11 = require("crypto");
|
|
26886
27373
|
|
|
26887
27374
|
// src/services/history.service.ts
|
|
26888
|
-
var
|
|
26889
|
-
var
|
|
27375
|
+
var fs63 = __toESM(require("fs"));
|
|
27376
|
+
var path68 = __toESM(require("path"));
|
|
26890
27377
|
var os51 = __toESM(require("os"));
|
|
26891
27378
|
var https7 = __toESM(require("https"));
|
|
26892
27379
|
var http6 = __toESM(require("http"));
|
|
@@ -26914,7 +27401,7 @@ function parseJsonl(filePath) {
|
|
|
26914
27401
|
const messages = [];
|
|
26915
27402
|
let raw;
|
|
26916
27403
|
try {
|
|
26917
|
-
raw =
|
|
27404
|
+
raw = fs63.readFileSync(filePath, "utf8");
|
|
26918
27405
|
} catch (err) {
|
|
26919
27406
|
if (err.code !== "ENOENT") {
|
|
26920
27407
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -27055,7 +27542,7 @@ var HistoryService = class _HistoryService {
|
|
|
27055
27542
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
27056
27543
|
}
|
|
27057
27544
|
get projectDir() {
|
|
27058
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
27545
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path68.join(os51.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
27059
27546
|
}
|
|
27060
27547
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
27061
27548
|
setCurrentConversationId(id) {
|
|
@@ -27067,7 +27554,7 @@ var HistoryService = class _HistoryService {
|
|
|
27067
27554
|
/** Return the current message count in the active conversation. */
|
|
27068
27555
|
getCurrentMessageCount() {
|
|
27069
27556
|
if (!this.currentConversationId) return 0;
|
|
27070
|
-
const filePath =
|
|
27557
|
+
const filePath = path68.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
27071
27558
|
return parseJsonl(filePath).length;
|
|
27072
27559
|
}
|
|
27073
27560
|
/**
|
|
@@ -27078,7 +27565,7 @@ var HistoryService = class _HistoryService {
|
|
|
27078
27565
|
const deadline = Date.now() + timeoutMs;
|
|
27079
27566
|
while (Date.now() < deadline) {
|
|
27080
27567
|
if (!this.currentConversationId) return null;
|
|
27081
|
-
const filePath =
|
|
27568
|
+
const filePath = path68.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
27082
27569
|
const messages = parseJsonl(filePath);
|
|
27083
27570
|
if (messages.length > previousCount) {
|
|
27084
27571
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -27104,16 +27591,16 @@ var HistoryService = class _HistoryService {
|
|
|
27104
27591
|
const dir = this.projectDir;
|
|
27105
27592
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
27106
27593
|
try {
|
|
27107
|
-
const files =
|
|
27594
|
+
const files = fs63.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
27108
27595
|
try {
|
|
27109
|
-
const stat3 =
|
|
27596
|
+
const stat3 = fs63.statSync(path68.join(dir, e.name));
|
|
27110
27597
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
27111
27598
|
} catch {
|
|
27112
27599
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
27113
27600
|
}
|
|
27114
27601
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
27115
27602
|
if (files.length > 0) {
|
|
27116
|
-
this.currentConversationId =
|
|
27603
|
+
this.currentConversationId = path68.basename(files[0].name, ".jsonl");
|
|
27117
27604
|
}
|
|
27118
27605
|
} catch {
|
|
27119
27606
|
}
|
|
@@ -27147,13 +27634,13 @@ var HistoryService = class _HistoryService {
|
|
|
27147
27634
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
27148
27635
|
let entries;
|
|
27149
27636
|
try {
|
|
27150
|
-
entries =
|
|
27637
|
+
entries = fs63.readdirSync(dir, { withFileTypes: true });
|
|
27151
27638
|
} catch {
|
|
27152
27639
|
return null;
|
|
27153
27640
|
}
|
|
27154
27641
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
27155
27642
|
try {
|
|
27156
|
-
const stat3 =
|
|
27643
|
+
const stat3 = fs63.statSync(path68.join(dir, e.name));
|
|
27157
27644
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
27158
27645
|
} catch {
|
|
27159
27646
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -27162,12 +27649,12 @@ var HistoryService = class _HistoryService {
|
|
|
27162
27649
|
if (files.length === 0) return null;
|
|
27163
27650
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
27164
27651
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
27165
|
-
return this.extractUsageFromFile(
|
|
27652
|
+
return this.extractUsageFromFile(path68.join(dir, targetFile));
|
|
27166
27653
|
}
|
|
27167
27654
|
extractUsageFromFile(filePath) {
|
|
27168
27655
|
let raw;
|
|
27169
27656
|
try {
|
|
27170
|
-
raw =
|
|
27657
|
+
raw = fs63.readFileSync(filePath, "utf8");
|
|
27171
27658
|
} catch {
|
|
27172
27659
|
return null;
|
|
27173
27660
|
}
|
|
@@ -27212,9 +27699,9 @@ var HistoryService = class _HistoryService {
|
|
|
27212
27699
|
let totalCost = 0;
|
|
27213
27700
|
let files;
|
|
27214
27701
|
try {
|
|
27215
|
-
files =
|
|
27702
|
+
files = fs63.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
27216
27703
|
try {
|
|
27217
|
-
return
|
|
27704
|
+
return fs63.statSync(path68.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
27218
27705
|
} catch {
|
|
27219
27706
|
return false;
|
|
27220
27707
|
}
|
|
@@ -27225,7 +27712,7 @@ var HistoryService = class _HistoryService {
|
|
|
27225
27712
|
for (const file of files) {
|
|
27226
27713
|
let raw;
|
|
27227
27714
|
try {
|
|
27228
|
-
raw =
|
|
27715
|
+
raw = fs63.readFileSync(path68.join(projectDir, file), "utf8");
|
|
27229
27716
|
} catch {
|
|
27230
27717
|
continue;
|
|
27231
27718
|
}
|
|
@@ -27304,7 +27791,7 @@ var HistoryService = class _HistoryService {
|
|
|
27304
27791
|
if (this.runtime.resolveHistoryFile) {
|
|
27305
27792
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
27306
27793
|
}
|
|
27307
|
-
return
|
|
27794
|
+
return path68.join(this.projectDir, `${sessionId}.jsonl`);
|
|
27308
27795
|
}
|
|
27309
27796
|
/**
|
|
27310
27797
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -27338,7 +27825,7 @@ var HistoryService = class _HistoryService {
|
|
|
27338
27825
|
};
|
|
27339
27826
|
});
|
|
27340
27827
|
}
|
|
27341
|
-
return parseJsonl(
|
|
27828
|
+
return parseJsonl(path68.join(this.projectDir, `${sessionId}.jsonl`));
|
|
27342
27829
|
}
|
|
27343
27830
|
async loadConversation(sessionId) {
|
|
27344
27831
|
const messages = this.readConversation(sessionId);
|
|
@@ -27406,7 +27893,7 @@ var HistoryService = class _HistoryService {
|
|
|
27406
27893
|
if (!filePath) return false;
|
|
27407
27894
|
let mtimeMs;
|
|
27408
27895
|
try {
|
|
27409
|
-
mtimeMs =
|
|
27896
|
+
mtimeMs = fs63.statSync(filePath).mtimeMs;
|
|
27410
27897
|
} catch {
|
|
27411
27898
|
return false;
|
|
27412
27899
|
}
|
|
@@ -27481,10 +27968,10 @@ var HistoryService = class _HistoryService {
|
|
|
27481
27968
|
|
|
27482
27969
|
// src/agents/acp/client.ts
|
|
27483
27970
|
var import_node_child_process29 = require("child_process");
|
|
27484
|
-
var
|
|
27971
|
+
var fs64 = __toESM(require("fs/promises"));
|
|
27485
27972
|
var fsSync = __toESM(require("fs"));
|
|
27486
27973
|
var os53 = __toESM(require("os"));
|
|
27487
|
-
var
|
|
27974
|
+
var path70 = __toESM(require("path"));
|
|
27488
27975
|
var import_node_stream = require("stream");
|
|
27489
27976
|
|
|
27490
27977
|
// ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
|
|
@@ -31510,7 +31997,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
|
|
|
31510
31997
|
}
|
|
31511
31998
|
|
|
31512
31999
|
// src/agents/acp/internal-paths.ts
|
|
31513
|
-
var
|
|
32000
|
+
var path69 = __toESM(require("path"));
|
|
31514
32001
|
var os52 = __toESM(require("os"));
|
|
31515
32002
|
var INTERNAL_TOKENS = [".codeam", "house-claude"];
|
|
31516
32003
|
function textReferencesInternal(text) {
|
|
@@ -31519,10 +32006,10 @@ function textReferencesInternal(text) {
|
|
|
31519
32006
|
}
|
|
31520
32007
|
function pathIsInternal(p2, homeDir2 = os52.homedir()) {
|
|
31521
32008
|
if (!p2) return false;
|
|
31522
|
-
const abs =
|
|
31523
|
-
const home =
|
|
31524
|
-
const within = (root) => abs === root || abs.startsWith(root +
|
|
31525
|
-
return within(
|
|
32009
|
+
const abs = path69.resolve(p2);
|
|
32010
|
+
const home = path69.resolve(homeDir2);
|
|
32011
|
+
const within = (root) => abs === root || abs.startsWith(root + path69.sep);
|
|
32012
|
+
return within(path69.join(home, ".codeam")) || within(path69.join(home, ".beads")) || abs === path69.join(home, ".codeam-host.log") || abs.includes(`${path69.sep}house-claude${path69.sep}`) || abs.endsWith(`${path69.sep}house-claude`);
|
|
31526
32013
|
}
|
|
31527
32014
|
function toolCallReferencesInternal(call) {
|
|
31528
32015
|
if (textReferencesInternal(call.title)) return true;
|
|
@@ -32351,7 +32838,7 @@ var AcpClient = class {
|
|
|
32351
32838
|
throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
|
|
32352
32839
|
}
|
|
32353
32840
|
try {
|
|
32354
|
-
const content = await
|
|
32841
|
+
const content = await fs64.readFile(params.path, "utf8");
|
|
32355
32842
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
32356
32843
|
} catch (err) {
|
|
32357
32844
|
const code = err.code;
|
|
@@ -32374,7 +32861,7 @@ var AcpClient = class {
|
|
|
32374
32861
|
throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
|
|
32375
32862
|
}
|
|
32376
32863
|
try {
|
|
32377
|
-
await
|
|
32864
|
+
await fs64.writeFile(params.path, params.content, "utf8");
|
|
32378
32865
|
return {};
|
|
32379
32866
|
} catch (err) {
|
|
32380
32867
|
const code = err.code;
|
|
@@ -32439,24 +32926,24 @@ function knownAgentBinaryDirs() {
|
|
|
32439
32926
|
out2.push("/tmp/codeam-node20/bin");
|
|
32440
32927
|
for (const root of [
|
|
32441
32928
|
"/usr/local/share/nvm/versions/node",
|
|
32442
|
-
|
|
32929
|
+
path70.join(home, ".nvm/versions/node")
|
|
32443
32930
|
]) {
|
|
32444
32931
|
try {
|
|
32445
32932
|
for (const child of fsSync.readdirSync(root)) {
|
|
32446
|
-
out2.push(
|
|
32933
|
+
out2.push(path70.join(root, child, "bin"));
|
|
32447
32934
|
}
|
|
32448
32935
|
} catch {
|
|
32449
32936
|
}
|
|
32450
32937
|
}
|
|
32451
|
-
out2.push(
|
|
32938
|
+
out2.push(path70.join(home, ".volta/bin"));
|
|
32452
32939
|
out2.push("/usr/local/bin");
|
|
32453
32940
|
out2.push("/usr/bin");
|
|
32454
|
-
out2.push(
|
|
32455
|
-
out2.push(
|
|
32941
|
+
out2.push(path70.join(home, ".local/bin"));
|
|
32942
|
+
out2.push(path70.join(home, "bin"));
|
|
32456
32943
|
if (process.platform === "win32") {
|
|
32457
32944
|
const { LOCALAPPDATA, APPDATA } = process.env;
|
|
32458
|
-
if (LOCALAPPDATA) out2.push(
|
|
32459
|
-
if (APPDATA) out2.push(
|
|
32945
|
+
if (LOCALAPPDATA) out2.push(path70.join(LOCALAPPDATA, "cursor-agent"));
|
|
32946
|
+
if (APPDATA) out2.push(path70.join(APPDATA, "npm"));
|
|
32460
32947
|
}
|
|
32461
32948
|
return out2.filter((p2) => {
|
|
32462
32949
|
try {
|
|
@@ -32468,7 +32955,7 @@ function knownAgentBinaryDirs() {
|
|
|
32468
32955
|
}
|
|
32469
32956
|
function expandPathForAgentBinaries(existingPath) {
|
|
32470
32957
|
const existing = new Set(
|
|
32471
|
-
existingPath.split(
|
|
32958
|
+
existingPath.split(path70.delimiter).filter((p2) => p2.length > 0)
|
|
32472
32959
|
);
|
|
32473
32960
|
const additions = [];
|
|
32474
32961
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -32478,7 +32965,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
32478
32965
|
}
|
|
32479
32966
|
}
|
|
32480
32967
|
if (additions.length === 0) return existingPath;
|
|
32481
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
32968
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path70.delimiter);
|
|
32482
32969
|
}
|
|
32483
32970
|
|
|
32484
32971
|
// src/agents/acp/headroom-budget-proxy.ts
|
|
@@ -32960,15 +33447,15 @@ function commonPrefixLength(a, b) {
|
|
|
32960
33447
|
|
|
32961
33448
|
// src/agents/acp/onboarding.ts
|
|
32962
33449
|
var import_child_process27 = require("child_process");
|
|
32963
|
-
var
|
|
33450
|
+
var fs65 = __toESM(require("fs"));
|
|
32964
33451
|
var os54 = __toESM(require("os"));
|
|
32965
|
-
var
|
|
33452
|
+
var path71 = __toESM(require("path"));
|
|
32966
33453
|
var _onboardingSeam = {
|
|
32967
|
-
markerPath: (sessionId) =>
|
|
32968
|
-
exists: (p2) =>
|
|
33454
|
+
markerPath: (sessionId) => path71.join(os54.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
33455
|
+
exists: (p2) => fs65.existsSync(p2),
|
|
32969
33456
|
write: (p2) => {
|
|
32970
|
-
|
|
32971
|
-
|
|
33457
|
+
fs65.mkdirSync(path71.dirname(p2), { recursive: true });
|
|
33458
|
+
fs65.writeFileSync(p2, "");
|
|
32972
33459
|
},
|
|
32973
33460
|
disabled: () => {
|
|
32974
33461
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -33005,7 +33492,7 @@ function resolveRepoName(cwd) {
|
|
|
33005
33492
|
if (name) return name;
|
|
33006
33493
|
}
|
|
33007
33494
|
}
|
|
33008
|
-
const base =
|
|
33495
|
+
const base = path71.basename(cwd || "");
|
|
33009
33496
|
if (base && !isUuid(base)) return base;
|
|
33010
33497
|
return "this project";
|
|
33011
33498
|
}
|
|
@@ -33263,13 +33750,13 @@ var import_crypto5 = require("crypto");
|
|
|
33263
33750
|
|
|
33264
33751
|
// src/services/turn-files/git-changeset.ts
|
|
33265
33752
|
var import_child_process28 = require("child_process");
|
|
33266
|
-
var
|
|
33267
|
-
var
|
|
33753
|
+
var fs67 = __toESM(require("fs/promises"));
|
|
33754
|
+
var path73 = __toESM(require("path"));
|
|
33268
33755
|
|
|
33269
33756
|
// src/services/turn-files/review-ignore.ts
|
|
33270
33757
|
var import_ignore2 = __toESM(require("ignore"));
|
|
33271
|
-
var
|
|
33272
|
-
var
|
|
33758
|
+
var fs66 = __toESM(require("fs"));
|
|
33759
|
+
var path72 = __toESM(require("path"));
|
|
33273
33760
|
var CURATED_REVIEW_IGNORE = [
|
|
33274
33761
|
// Google Cloud SDK (the incident) — installs a huge python tree.
|
|
33275
33762
|
"google-cloud-sdk/",
|
|
@@ -33308,7 +33795,7 @@ var CURATED_REVIEW_IGNORE = [
|
|
|
33308
33795
|
function makeReviewIgnore(repoRoot) {
|
|
33309
33796
|
const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
|
|
33310
33797
|
try {
|
|
33311
|
-
const custom =
|
|
33798
|
+
const custom = fs66.readFileSync(path72.join(repoRoot, ".codeam", "reviewignore"), "utf8");
|
|
33312
33799
|
ig.add(custom);
|
|
33313
33800
|
} catch {
|
|
33314
33801
|
}
|
|
@@ -33353,7 +33840,7 @@ async function collectRepoChangeset(opts) {
|
|
|
33353
33840
|
let stats;
|
|
33354
33841
|
if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
|
|
33355
33842
|
const lineCount = await readUntrackedLineCount(
|
|
33356
|
-
|
|
33843
|
+
path73.join(opts.repoRoot, row.filePath)
|
|
33357
33844
|
);
|
|
33358
33845
|
stats = { added: lineCount, removed: 0 };
|
|
33359
33846
|
} else {
|
|
@@ -33384,7 +33871,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
33384
33871
|
}
|
|
33385
33872
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
33386
33873
|
try {
|
|
33387
|
-
const content = await
|
|
33874
|
+
const content = await fs67.readFile(absPath, "utf8");
|
|
33388
33875
|
let count = 0;
|
|
33389
33876
|
let pos = -1;
|
|
33390
33877
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -33476,7 +33963,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
33476
33963
|
});
|
|
33477
33964
|
}
|
|
33478
33965
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
33479
|
-
const
|
|
33966
|
+
const fs74 = await import("fs/promises");
|
|
33480
33967
|
const out2 = [];
|
|
33481
33968
|
await walk(workingDir, 0);
|
|
33482
33969
|
return out2;
|
|
@@ -33484,7 +33971,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
33484
33971
|
if (depth > maxDepth) return;
|
|
33485
33972
|
let entries = [];
|
|
33486
33973
|
try {
|
|
33487
|
-
const dirents = await
|
|
33974
|
+
const dirents = await fs74.readdir(dir, { withFileTypes: true });
|
|
33488
33975
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
33489
33976
|
} catch {
|
|
33490
33977
|
return;
|
|
@@ -33495,8 +33982,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
33495
33982
|
if (hasGit) {
|
|
33496
33983
|
out2.push({
|
|
33497
33984
|
repoRoot: dir,
|
|
33498
|
-
repoPath:
|
|
33499
|
-
repoName:
|
|
33985
|
+
repoPath: path73.relative(workingDir, dir),
|
|
33986
|
+
repoName: path73.basename(dir)
|
|
33500
33987
|
});
|
|
33501
33988
|
return;
|
|
33502
33989
|
}
|
|
@@ -33504,14 +33991,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
33504
33991
|
if (!entry.isDirectory) continue;
|
|
33505
33992
|
if (entry.name === "node_modules") continue;
|
|
33506
33993
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
33507
|
-
await walk(
|
|
33994
|
+
await walk(path73.join(dir, entry.name), depth + 1);
|
|
33508
33995
|
}
|
|
33509
33996
|
}
|
|
33510
33997
|
}
|
|
33511
33998
|
|
|
33512
33999
|
// src/services/turn-files/files-outbox.ts
|
|
33513
|
-
var
|
|
33514
|
-
var
|
|
34000
|
+
var fs68 = __toESM(require("fs/promises"));
|
|
34001
|
+
var path74 = __toESM(require("path"));
|
|
33515
34002
|
var import_os12 = require("os");
|
|
33516
34003
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
33517
34004
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -33544,16 +34031,16 @@ var FilesOutbox = class {
|
|
|
33544
34031
|
backoffIndex = 0;
|
|
33545
34032
|
stopped = false;
|
|
33546
34033
|
constructor(opts) {
|
|
33547
|
-
const base = opts.baseDir ??
|
|
33548
|
-
this.filePath =
|
|
34034
|
+
const base = opts.baseDir ?? path74.join(homeDir(), HOME_OUTBOX_DIR);
|
|
34035
|
+
this.filePath = path74.join(base, `${opts.sessionId}.jsonl`);
|
|
33549
34036
|
this.post = opts.post;
|
|
33550
34037
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
33551
34038
|
}
|
|
33552
34039
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
33553
34040
|
* line is durable on disk (not once the POST succeeds). */
|
|
33554
34041
|
async enqueue(entry) {
|
|
33555
|
-
await
|
|
33556
|
-
await
|
|
34042
|
+
await fs68.mkdir(path74.dirname(this.filePath), { recursive: true });
|
|
34043
|
+
await fs68.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
33557
34044
|
this.backoffIndex = 0;
|
|
33558
34045
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
33559
34046
|
}
|
|
@@ -33644,7 +34131,7 @@ var FilesOutbox = class {
|
|
|
33644
34131
|
async readAll() {
|
|
33645
34132
|
let raw = "";
|
|
33646
34133
|
try {
|
|
33647
|
-
raw = await
|
|
34134
|
+
raw = await fs68.readFile(this.filePath, "utf8");
|
|
33648
34135
|
} catch {
|
|
33649
34136
|
return [];
|
|
33650
34137
|
}
|
|
@@ -33668,12 +34155,12 @@ var FilesOutbox = class {
|
|
|
33668
34155
|
async rewrite(entries) {
|
|
33669
34156
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
33670
34157
|
if (entries.length === 0) {
|
|
33671
|
-
await
|
|
34158
|
+
await fs68.unlink(this.filePath).catch(() => void 0);
|
|
33672
34159
|
return;
|
|
33673
34160
|
}
|
|
33674
34161
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
33675
|
-
await
|
|
33676
|
-
await
|
|
34162
|
+
await fs68.writeFile(tmpPath, payload, "utf8");
|
|
34163
|
+
await fs68.rename(tmpPath, this.filePath);
|
|
33677
34164
|
}
|
|
33678
34165
|
};
|
|
33679
34166
|
function applyJitter(ms) {
|
|
@@ -34418,11 +34905,13 @@ async function startTaskH(ctx) {
|
|
|
34418
34905
|
}
|
|
34419
34906
|
await streaming.beginTurn();
|
|
34420
34907
|
history.appendUserPrompt(promptText);
|
|
34908
|
+
let turnClosed = false;
|
|
34421
34909
|
try {
|
|
34422
34910
|
const reply = await client3.prompt(blocks);
|
|
34423
34911
|
const finalText = streaming.getCurrentText();
|
|
34424
34912
|
if (agentHooks(opts.agent)?.classifyCompletedReply?.(finalText) === "upgrade_required") {
|
|
34425
34913
|
await streaming.closeWithBubble(CURSOR_UPGRADE_MESSAGE);
|
|
34914
|
+
turnClosed = true;
|
|
34426
34915
|
history.appendAgentReply(CURSOR_UPGRADE_MESSAGE);
|
|
34427
34916
|
void history.flush();
|
|
34428
34917
|
log.info("acpRunner", `start_task \u2190 cursor-plan-upgrade-required id=${cmd.id.slice(0, 8)}`);
|
|
@@ -34430,6 +34919,7 @@ async function startTaskH(ctx) {
|
|
|
34430
34919
|
} else if (replyIsHouseAgentLimit(finalText)) {
|
|
34431
34920
|
const houseBubble = houseAgentLimitMessage(finalText);
|
|
34432
34921
|
await streaming.closeWithBubble(houseBubble);
|
|
34922
|
+
turnClosed = true;
|
|
34433
34923
|
history.appendAgentReply(houseBubble);
|
|
34434
34924
|
void history.flush();
|
|
34435
34925
|
turnFiles.flushTurn().catch((err) => {
|
|
@@ -34441,6 +34931,7 @@ async function startTaskH(ctx) {
|
|
|
34441
34931
|
});
|
|
34442
34932
|
} else if (replyIsAuthFailure(finalText)) {
|
|
34443
34933
|
await streaming.closeWithBubble(AUTH_FAILURE_MESSAGE);
|
|
34934
|
+
turnClosed = true;
|
|
34444
34935
|
history.appendAgentReply(AUTH_FAILURE_MESSAGE);
|
|
34445
34936
|
void history.flush();
|
|
34446
34937
|
turnFiles.flushTurn().catch((err) => {
|
|
@@ -34451,6 +34942,7 @@ async function startTaskH(ctx) {
|
|
|
34451
34942
|
await relay.sendResult(cmd.id, "failed", { error: "agent reply reported auth failure" });
|
|
34452
34943
|
} else if (shouldOfferOneMRecovery({ detail: "", recentStderr: recentStderr.join("\n"), finalText })) {
|
|
34453
34944
|
await streaming.closeWithBubble(ONE_M_CREDITS_MESSAGE);
|
|
34945
|
+
turnClosed = true;
|
|
34454
34946
|
history.appendAgentReply(ONE_M_CREDITS_MESSAGE);
|
|
34455
34947
|
void history.flush();
|
|
34456
34948
|
turnFiles.flushTurn().catch((err) => {
|
|
@@ -34463,6 +34955,7 @@ async function startTaskH(ctx) {
|
|
|
34463
34955
|
});
|
|
34464
34956
|
} else {
|
|
34465
34957
|
await streaming.closeTurnWithInteractiveDetection();
|
|
34958
|
+
turnClosed = true;
|
|
34466
34959
|
const replyLine = formatAgentReplyLine(finalText);
|
|
34467
34960
|
if (replyLine.length > 0) {
|
|
34468
34961
|
showInfo(replyLine);
|
|
@@ -34481,6 +34974,13 @@ async function startTaskH(ctx) {
|
|
|
34481
34974
|
await relay.sendResult(cmd.id, "completed", { stopReason: reply.stopReason });
|
|
34482
34975
|
}
|
|
34483
34976
|
} catch (err) {
|
|
34977
|
+
if (turnClosed) {
|
|
34978
|
+
log.warn(
|
|
34979
|
+
"acpRunner",
|
|
34980
|
+
`post-close ack failed (turn already delivered) id=${cmd.id.slice(0, 8)}: ${describeError(err)}`
|
|
34981
|
+
);
|
|
34982
|
+
return;
|
|
34983
|
+
}
|
|
34484
34984
|
const hadText = streaming.hasVisibleProgress();
|
|
34485
34985
|
const detail = describeError(err);
|
|
34486
34986
|
log.warn("acpRunner", `prompt failed: ${detail}`);
|
|
@@ -36918,8 +37418,8 @@ function startClaudeCredentialSync(opts) {
|
|
|
36918
37418
|
}
|
|
36919
37419
|
|
|
36920
37420
|
// src/beads/workflow-hint.ts
|
|
36921
|
-
var
|
|
36922
|
-
var
|
|
37421
|
+
var fs70 = __toESM(require("fs"));
|
|
37422
|
+
var path76 = __toESM(require("path"));
|
|
36923
37423
|
var os55 = __toESM(require("os"));
|
|
36924
37424
|
var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
|
|
36925
37425
|
var BEADS_HINT = `${BEADS_HINT_MARKER}
|
|
@@ -36936,20 +37436,20 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
|
|
|
36936
37436
|
${BEADS_HINT_MARKER}`;
|
|
36937
37437
|
function ensureBeadsWorkflowHint(homeDir2 = os55.homedir()) {
|
|
36938
37438
|
try {
|
|
36939
|
-
const file =
|
|
37439
|
+
const file = path76.join(homeDir2, ".claude", "CLAUDE.md");
|
|
36940
37440
|
let existing = "";
|
|
36941
37441
|
try {
|
|
36942
|
-
existing =
|
|
37442
|
+
existing = fs70.readFileSync(file, "utf8");
|
|
36943
37443
|
} catch {
|
|
36944
37444
|
}
|
|
36945
37445
|
if (existing.includes(BEADS_HINT_MARKER)) return;
|
|
36946
|
-
|
|
37446
|
+
fs70.mkdirSync(path76.dirname(file), { recursive: true });
|
|
36947
37447
|
const next = existing.trim() ? `${existing.trimEnd()}
|
|
36948
37448
|
|
|
36949
37449
|
${BEADS_HINT}
|
|
36950
37450
|
` : `${BEADS_HINT}
|
|
36951
37451
|
`;
|
|
36952
|
-
|
|
37452
|
+
fs70.writeFileSync(file, next);
|
|
36953
37453
|
} catch {
|
|
36954
37454
|
}
|
|
36955
37455
|
}
|
|
@@ -37321,7 +37821,7 @@ var AcpDriver = class {
|
|
|
37321
37821
|
};
|
|
37322
37822
|
|
|
37323
37823
|
// src/baton/transcript-mirror.ts
|
|
37324
|
-
var
|
|
37824
|
+
var fs71 = __toESM(require("fs"));
|
|
37325
37825
|
var TranscriptMirror = class {
|
|
37326
37826
|
constructor(deps) {
|
|
37327
37827
|
this.deps = deps;
|
|
@@ -37388,7 +37888,7 @@ var TranscriptMirror = class {
|
|
|
37388
37888
|
}
|
|
37389
37889
|
};
|
|
37390
37890
|
function defaultWatch(file, onChange) {
|
|
37391
|
-
const w3 =
|
|
37891
|
+
const w3 = fs71.watch(file, { persistent: false }, () => onChange());
|
|
37392
37892
|
return () => w3.close();
|
|
37393
37893
|
}
|
|
37394
37894
|
|
|
@@ -37650,16 +38150,16 @@ function toEpochMs(ts) {
|
|
|
37650
38150
|
}
|
|
37651
38151
|
|
|
37652
38152
|
// src/agents/claude/onboarding.ts
|
|
37653
|
-
var
|
|
38153
|
+
var fs72 = __toESM(require("fs"));
|
|
37654
38154
|
var os57 = __toESM(require("os"));
|
|
37655
|
-
var
|
|
38155
|
+
var path77 = __toESM(require("path"));
|
|
37656
38156
|
var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
|
|
37657
38157
|
function ensureClaudeOnboarded(cwd) {
|
|
37658
38158
|
try {
|
|
37659
|
-
const file =
|
|
38159
|
+
const file = path77.join(os57.homedir(), ".claude.json");
|
|
37660
38160
|
let config = {};
|
|
37661
38161
|
try {
|
|
37662
|
-
config = JSON.parse(
|
|
38162
|
+
config = JSON.parse(fs72.readFileSync(file, "utf8"));
|
|
37663
38163
|
} catch {
|
|
37664
38164
|
}
|
|
37665
38165
|
let changed = false;
|
|
@@ -37684,8 +38184,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
37684
38184
|
}
|
|
37685
38185
|
}
|
|
37686
38186
|
if (!changed) return;
|
|
37687
|
-
|
|
37688
|
-
|
|
38187
|
+
fs72.mkdirSync(path77.dirname(file), { recursive: true });
|
|
38188
|
+
fs72.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
37689
38189
|
log.info(
|
|
37690
38190
|
"claude",
|
|
37691
38191
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -38412,7 +38912,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
38412
38912
|
var import_child_process29 = require("child_process");
|
|
38413
38913
|
var import_util4 = require("util");
|
|
38414
38914
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
38415
|
-
var
|
|
38915
|
+
var path78 = __toESM(require("path"));
|
|
38416
38916
|
var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
|
|
38417
38917
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
38418
38918
|
function resetStdinForChild() {
|
|
@@ -38901,7 +39401,7 @@ var GitHubCodespacesProvider = class {
|
|
|
38901
39401
|
});
|
|
38902
39402
|
}
|
|
38903
39403
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
38904
|
-
const remoteDir =
|
|
39404
|
+
const remoteDir = path78.posix.dirname(remotePath);
|
|
38905
39405
|
const parts = [
|
|
38906
39406
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
38907
39407
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -38971,7 +39471,7 @@ function shellQuote(s) {
|
|
|
38971
39471
|
// src/services/providers/gitpod.ts
|
|
38972
39472
|
var import_child_process30 = require("child_process");
|
|
38973
39473
|
var import_util5 = require("util");
|
|
38974
|
-
var
|
|
39474
|
+
var path79 = __toESM(require("path"));
|
|
38975
39475
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
38976
39476
|
var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
|
|
38977
39477
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -39211,7 +39711,7 @@ var GitpodProvider = class {
|
|
|
39211
39711
|
});
|
|
39212
39712
|
}
|
|
39213
39713
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
39214
|
-
const remoteDir =
|
|
39714
|
+
const remoteDir = path79.posix.dirname(remotePath);
|
|
39215
39715
|
const parts = [
|
|
39216
39716
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
39217
39717
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -39247,7 +39747,7 @@ function shellQuote2(s) {
|
|
|
39247
39747
|
// src/services/providers/gitlab-workspaces.ts
|
|
39248
39748
|
var import_child_process31 = require("child_process");
|
|
39249
39749
|
var import_util6 = require("util");
|
|
39250
|
-
var
|
|
39750
|
+
var path80 = __toESM(require("path"));
|
|
39251
39751
|
var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
|
|
39252
39752
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
39253
39753
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -39507,7 +40007,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
39507
40007
|
}
|
|
39508
40008
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
39509
40009
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
39510
|
-
const remoteDir =
|
|
40010
|
+
const remoteDir = path80.posix.dirname(remotePath);
|
|
39511
40011
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
39512
40012
|
if (options.mode != null) {
|
|
39513
40013
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -39575,7 +40075,7 @@ function shellQuote3(s) {
|
|
|
39575
40075
|
// src/services/providers/railway.ts
|
|
39576
40076
|
var import_child_process32 = require("child_process");
|
|
39577
40077
|
var import_util7 = require("util");
|
|
39578
|
-
var
|
|
40078
|
+
var path81 = __toESM(require("path"));
|
|
39579
40079
|
var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
|
|
39580
40080
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
39581
40081
|
function resetStdinForChild4() {
|
|
@@ -39811,7 +40311,7 @@ var RailwayProvider = class {
|
|
|
39811
40311
|
if (!projectId || !serviceId) {
|
|
39812
40312
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
39813
40313
|
}
|
|
39814
|
-
const remoteDir =
|
|
40314
|
+
const remoteDir = path81.posix.dirname(remotePath);
|
|
39815
40315
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
39816
40316
|
if (options.mode != null) {
|
|
39817
40317
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -40457,8 +40957,8 @@ async function invite() {
|
|
|
40457
40957
|
var import_node_dns = require("dns");
|
|
40458
40958
|
var import_node_util5 = require("util");
|
|
40459
40959
|
var import_node_crypto13 = require("crypto");
|
|
40460
|
-
var
|
|
40461
|
-
var
|
|
40960
|
+
var fs73 = __toESM(require("fs"));
|
|
40961
|
+
var path82 = __toESM(require("path"));
|
|
40462
40962
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
40463
40963
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
40464
40964
|
async function checkDns(apiBase2) {
|
|
@@ -40514,13 +41014,13 @@ async function checkHealth(apiBase2) {
|
|
|
40514
41014
|
}
|
|
40515
41015
|
}
|
|
40516
41016
|
function checkConfigDir() {
|
|
40517
|
-
const dir =
|
|
41017
|
+
const dir = path82.join(require("os").homedir(), ".codeam");
|
|
40518
41018
|
try {
|
|
40519
|
-
|
|
40520
|
-
const probe =
|
|
40521
|
-
|
|
40522
|
-
const read2 =
|
|
40523
|
-
|
|
41019
|
+
fs73.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
41020
|
+
const probe = path82.join(dir, ".doctor-probe");
|
|
41021
|
+
fs73.writeFileSync(probe, "ok", { mode: 384 });
|
|
41022
|
+
const read2 = fs73.readFileSync(probe, "utf8");
|
|
41023
|
+
fs73.unlinkSync(probe);
|
|
40524
41024
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
40525
41025
|
return {
|
|
40526
41026
|
id: "config-dir",
|
|
@@ -40584,7 +41084,7 @@ function checkNodePty() {
|
|
|
40584
41084
|
detail: "not required on this platform"
|
|
40585
41085
|
};
|
|
40586
41086
|
}
|
|
40587
|
-
const vendoredPath =
|
|
41087
|
+
const vendoredPath = path82.join(__dirname, "vendor", "node-pty");
|
|
40588
41088
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
40589
41089
|
try {
|
|
40590
41090
|
require(target);
|
|
@@ -40626,7 +41126,7 @@ function checkChokidar() {
|
|
|
40626
41126
|
}
|
|
40627
41127
|
async function doctor(args2 = []) {
|
|
40628
41128
|
const json = args2.includes("--json");
|
|
40629
|
-
const cliVersion = true ? "2.61.
|
|
41129
|
+
const cliVersion = true ? "2.61.82" : "0.0.0-dev";
|
|
40630
41130
|
const apiBase2 = resolveApiBaseUrl();
|
|
40631
41131
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
40632
41132
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -41167,6 +41667,17 @@ async function mcpRun(args2) {
|
|
|
41167
41667
|
`);
|
|
41168
41668
|
process.exit(1);
|
|
41169
41669
|
}
|
|
41670
|
+
if (delivery.builtin === "convex-admin") {
|
|
41671
|
+
const client4 = new IntegrationTokenClient({
|
|
41672
|
+
sessionId,
|
|
41673
|
+
pluginId,
|
|
41674
|
+
pluginAuthToken,
|
|
41675
|
+
pollSecret: process.env.CODEAM_MCP_POLL_SECRET
|
|
41676
|
+
});
|
|
41677
|
+
const { runConvexAdminMcp: runConvexAdminMcp2 } = await Promise.resolve().then(() => (init_convex_admin_mcp(), convex_admin_mcp_exports));
|
|
41678
|
+
await runConvexAdminMcp2(client4, id);
|
|
41679
|
+
return;
|
|
41680
|
+
}
|
|
41170
41681
|
if (delivery.httpUrl) {
|
|
41171
41682
|
const httpClient = new IntegrationTokenClient({
|
|
41172
41683
|
sessionId,
|
|
@@ -41205,7 +41716,7 @@ async function mcpRun(args2) {
|
|
|
41205
41716
|
// src/commands/version.ts
|
|
41206
41717
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
41207
41718
|
function version2() {
|
|
41208
|
-
const v = true ? "2.61.
|
|
41719
|
+
const v = true ? "2.61.82" : "unknown";
|
|
41209
41720
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
41210
41721
|
}
|
|
41211
41722
|
|