codeam-cli 2.75.2 → 2.75.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.js +212 -66
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.75.2] — 2026-09-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Declare the credits_changed user event
|
|
12
|
+
|
|
13
|
+
### CI
|
|
14
|
+
|
|
15
|
+
- **release:** Wait up to 7.5 min for npm to serve the published version (#754)
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **cli:** A managed-rail outage must never be blamed on Anthropic (#757)
|
|
20
|
+
|
|
21
|
+
## [2.75.1] — 2026-09-12
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **cli:** Managed sessions announce the managed agent, not the Claude Code runtime (#753)
|
|
26
|
+
|
|
7
27
|
## [2.75.0] — 2026-09-12
|
|
8
28
|
|
|
9
29
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -271,8 +271,8 @@ var init_stdio_proxy = __esm({
|
|
|
271
271
|
}
|
|
272
272
|
async spawnChild(stdout, preResolved) {
|
|
273
273
|
const spec = preResolved ?? await this.opts.spawnSpec();
|
|
274
|
-
const
|
|
275
|
-
const child =
|
|
274
|
+
const spawn49 = this.opts.spawnImpl ?? import_node_child_process33.spawn;
|
|
275
|
+
const child = spawn49(spec.command, spec.args, {
|
|
276
276
|
env: { ...process.env, ...spec.env },
|
|
277
277
|
// env only — never argv
|
|
278
278
|
stdio: ["pipe", "pipe", "inherit"]
|
|
@@ -300,7 +300,9 @@ var convex_admin_mcp_exports = {};
|
|
|
300
300
|
__export(convex_admin_mcp_exports, {
|
|
301
301
|
callConvexTool: () => callConvexTool,
|
|
302
302
|
deploymentNameFromKey: () => deploymentNameFromKey,
|
|
303
|
-
|
|
303
|
+
resolveConvexBin: () => resolveConvexBin,
|
|
304
|
+
runConvexAdminMcp: () => runConvexAdminMcp,
|
|
305
|
+
runConvexDeploy: () => runConvexDeploy
|
|
304
306
|
});
|
|
305
307
|
function deploymentNameFromKey(key) {
|
|
306
308
|
const prefix = key.split("|")[0];
|
|
@@ -310,6 +312,81 @@ function deploymentNameFromKey(key) {
|
|
|
310
312
|
}
|
|
311
313
|
return null;
|
|
312
314
|
}
|
|
315
|
+
function defaultSpawn(timeoutMs) {
|
|
316
|
+
return (cmd, args2, opts) => new Promise((resolve11) => {
|
|
317
|
+
let out2 = "";
|
|
318
|
+
let err = "";
|
|
319
|
+
let done = false;
|
|
320
|
+
const finish = (code) => {
|
|
321
|
+
if (done) return;
|
|
322
|
+
done = true;
|
|
323
|
+
resolve11({ code, stdout: out2, stderr: err });
|
|
324
|
+
};
|
|
325
|
+
let child;
|
|
326
|
+
try {
|
|
327
|
+
child = (0, import_node_child_process34.spawn)(cmd, args2, { cwd: opts.cwd, env: opts.env, stdio: ["ignore", "pipe", "pipe"] });
|
|
328
|
+
} catch (e) {
|
|
329
|
+
finish(1);
|
|
330
|
+
err = e instanceof Error ? e.message : String(e);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const timer = setTimeout(() => {
|
|
334
|
+
try {
|
|
335
|
+
child.kill("SIGKILL");
|
|
336
|
+
} catch {
|
|
337
|
+
}
|
|
338
|
+
err += `
|
|
339
|
+
[codeam] convex deploy timed out after ${Math.round(timeoutMs / 1e3)}s`;
|
|
340
|
+
finish(124);
|
|
341
|
+
}, timeoutMs);
|
|
342
|
+
child.stdout?.on("data", (c2) => {
|
|
343
|
+
out2 += c2.toString();
|
|
344
|
+
});
|
|
345
|
+
child.stderr?.on("data", (c2) => {
|
|
346
|
+
err += c2.toString();
|
|
347
|
+
});
|
|
348
|
+
child.on("error", (e) => {
|
|
349
|
+
clearTimeout(timer);
|
|
350
|
+
err += (err ? "\n" : "") + e.message;
|
|
351
|
+
finish(1);
|
|
352
|
+
});
|
|
353
|
+
child.on("close", (code) => {
|
|
354
|
+
clearTimeout(timer);
|
|
355
|
+
finish(code ?? 1);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function resolveConvexBin(cwd) {
|
|
360
|
+
const local = path95.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
|
|
361
|
+
if (fs83.existsSync(local)) return { cmd: local, args: [] };
|
|
362
|
+
return { cmd: "npx", args: ["--yes", "convex"] };
|
|
363
|
+
}
|
|
364
|
+
function redact(text, key) {
|
|
365
|
+
if (!key) return text;
|
|
366
|
+
return text.split(key).join("***");
|
|
367
|
+
}
|
|
368
|
+
async function runConvexDeploy(key, args2, opts = {}) {
|
|
369
|
+
const cwd = args2.projectDir ?? opts.cwd ?? process.cwd();
|
|
370
|
+
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
371
|
+
const run = opts.spawnImpl ?? defaultSpawn(timeoutMs);
|
|
372
|
+
const bin = resolveConvexBin(cwd);
|
|
373
|
+
const argv = [...bin.args, "deploy"];
|
|
374
|
+
if (args2.previewName) argv.push("--preview-create", String(args2.previewName));
|
|
375
|
+
const { code, stdout, stderr } = await run(bin.cmd, argv, {
|
|
376
|
+
cwd,
|
|
377
|
+
// The ONLY place the secret travels.
|
|
378
|
+
env: { ...process.env, CONVEX_DEPLOY_KEY: key }
|
|
379
|
+
});
|
|
380
|
+
const body = redact([stdout, stderr].filter(Boolean).join("\n").trim(), key);
|
|
381
|
+
if (code === 0) {
|
|
382
|
+
return { ok: true, text: body || "Convex deploy completed." };
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
ok: false,
|
|
386
|
+
text: `Convex deploy failed (exit ${code}).
|
|
387
|
+
${body}`
|
|
388
|
+
};
|
|
389
|
+
}
|
|
313
390
|
async function adminQuery(baseUrl, key, api, body, fetchImpl = fetch) {
|
|
314
391
|
const res = await fetchImpl(`${baseUrl}/api/${api}`, {
|
|
315
392
|
method: "POST",
|
|
@@ -320,7 +397,24 @@ async function adminQuery(baseUrl, key, api, body, fetchImpl = fetch) {
|
|
|
320
397
|
const ok = res.ok && !/"status"\s*:\s*"error"/.test(text);
|
|
321
398
|
return { ok, text };
|
|
322
399
|
}
|
|
323
|
-
async function callConvexTool(baseUrl, key, tool, args2, fetchImpl = fetch) {
|
|
400
|
+
async function callConvexTool(baseUrl, key, tool, args2, fetchImpl = fetch, deployOpts = {}) {
|
|
401
|
+
switch (tool) {
|
|
402
|
+
case "deploy":
|
|
403
|
+
return runConvexDeploy(
|
|
404
|
+
key,
|
|
405
|
+
{
|
|
406
|
+
projectDir: typeof args2.projectDir === "string" ? args2.projectDir : void 0,
|
|
407
|
+
previewName: typeof args2.previewName === "string" ? args2.previewName : void 0
|
|
408
|
+
},
|
|
409
|
+
deployOpts
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
if (!baseUrl) {
|
|
413
|
+
return {
|
|
414
|
+
ok: false,
|
|
415
|
+
text: `The connected Convex deploy key is a PROJECT key, which names no single deployment, so '${tool}' (and the other data tools) cannot reach one. Use the 'deploy' tool \u2014 it resolves the target from the key itself \u2014 or reconnect Convex with a dev/prod deploy key (Convex Dashboard \u2192 Project Settings \u2192 Deploy Keys) to enable the data tools.`
|
|
416
|
+
};
|
|
417
|
+
}
|
|
324
418
|
switch (tool) {
|
|
325
419
|
case "tables":
|
|
326
420
|
return adminQuery(baseUrl, key, "query", {
|
|
@@ -362,12 +456,11 @@ async function runConvexAdminMcp(client3, id) {
|
|
|
362
456
|
const name = deploymentNameFromKey(key);
|
|
363
457
|
if (!name) {
|
|
364
458
|
process.stderr.write(
|
|
365
|
-
`[codeam mcp-run convex]
|
|
459
|
+
`[codeam mcp-run convex] the deploy key names no single deployment (prefix "${key.split(":")[0]}"): the data tools are unavailable, 'deploy' still works. For the data tools, reconnect with a dev/prod deploy key (Convex Dashboard \u2192 Project Settings \u2192 Deploy Keys).
|
|
366
460
|
`
|
|
367
461
|
);
|
|
368
|
-
process.exit(1);
|
|
369
462
|
}
|
|
370
|
-
const baseUrl = `https://${name}.convex.cloud
|
|
463
|
+
const baseUrl = name ? `https://${name}.convex.cloud` : "";
|
|
371
464
|
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
372
465
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
373
466
|
const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
@@ -396,10 +489,13 @@ async function runConvexAdminMcp(client3, id) {
|
|
|
396
489
|
});
|
|
397
490
|
await server.connect(new StdioServerTransport());
|
|
398
491
|
}
|
|
399
|
-
var TOOLS;
|
|
492
|
+
var import_node_child_process34, fs83, path95, TOOLS;
|
|
400
493
|
var init_convex_admin_mcp = __esm({
|
|
401
494
|
"src/integrations/convex-admin-mcp.ts"() {
|
|
402
495
|
"use strict";
|
|
496
|
+
import_node_child_process34 = require("child_process");
|
|
497
|
+
fs83 = __toESM(require("fs"));
|
|
498
|
+
path95 = __toESM(require("path"));
|
|
403
499
|
TOOLS = [
|
|
404
500
|
{
|
|
405
501
|
name: "tables",
|
|
@@ -449,6 +545,24 @@ var init_convex_admin_mcp = __esm({
|
|
|
449
545
|
required: ["functionPath"],
|
|
450
546
|
additionalProperties: false
|
|
451
547
|
}
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
name: "deploy",
|
|
551
|
+
description: 'Deploy this repo\'s `convex/` functions, schema and indexes to the Convex deployment this integration is connected to. Use this after editing anything under `convex/` \u2014 a function you just wrote does NOT exist for the running app until it is deployed ("Could not find public function for ..." means exactly this). Do NOT run `npx convex deploy` or `npx convex dev` in the shell: those need an interactive login, and this tool already holds the credential.',
|
|
552
|
+
inputSchema: {
|
|
553
|
+
type: "object",
|
|
554
|
+
properties: {
|
|
555
|
+
projectDir: {
|
|
556
|
+
type: "string",
|
|
557
|
+
description: "Repo root holding the `convex/` directory. Defaults to the session cwd."
|
|
558
|
+
},
|
|
559
|
+
previewName: {
|
|
560
|
+
type: "string",
|
|
561
|
+
description: "Only for a PREVIEW deploy key: name the preview deployment to create (e.g. a branch name)."
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
additionalProperties: false
|
|
565
|
+
}
|
|
452
566
|
}
|
|
453
567
|
];
|
|
454
568
|
}
|
|
@@ -889,12 +1003,34 @@ var AGENT_REGISTRY = {
|
|
|
889
1003
|
displayName: "Gemini CLI",
|
|
890
1004
|
binaryName: "gemini",
|
|
891
1005
|
enabled: true,
|
|
892
|
-
//
|
|
893
|
-
//
|
|
894
|
-
//
|
|
895
|
-
//
|
|
896
|
-
|
|
897
|
-
|
|
1006
|
+
// ⚠️ API KEY ONLY since 2026-06-18, when Google stopped Gemini CLI (and the
|
|
1007
|
+
// Gemini Code Assist IDE extensions) serving requests for AI Pro, AI Ultra
|
|
1008
|
+
// and free users, in the move to Antigravity CLI. Its announcement is
|
|
1009
|
+
// explicit about what survives: "Gemini CLI will remain accessible via paid
|
|
1010
|
+
// Gemini and Gemini Enterprise Agent Platform API keys."
|
|
1011
|
+
//
|
|
1012
|
+
// So the agent stays — `@google/gemini-cli` is NOT deprecated, it still
|
|
1013
|
+
// ships weekly — but the OAuth door has to go: it captures a
|
|
1014
|
+
// `~/.gemini/oauth_creds.json` from a CONSUMER Google account, which is
|
|
1015
|
+
// exactly the tier that no longer serves requests. We used to PREFER that
|
|
1016
|
+
// path, so it was the one we recommended first; on 2026-09-15 prod held 63
|
|
1017
|
+
// Gemini links, 46 of them OAuth, 19 created after 2026-09-01 and the
|
|
1018
|
+
// newest that same day. Three months of sending people through a bricked
|
|
1019
|
+
// door — each one landing on `isGeminiIneligibleTier` at first use.
|
|
1020
|
+
//
|
|
1021
|
+
// ⚠️ Antigravity CLI is NOT a drop-in replacement for us: no official ACP
|
|
1022
|
+
// mode (google-antigravity/antigravity-cli#31 open, 192 comments, zero
|
|
1023
|
+
// `acp` hits in the repo as of 2026-09-15), and every third-party ACP
|
|
1024
|
+
// adapter warns that driving `agy` that way matches what Google's FAQ calls
|
|
1025
|
+
// a ToS violation — risking the USER's Google account. Our whole Gemini
|
|
1026
|
+
// path is ACP, so adopting it would mean shipping that risk. Revisit only
|
|
1027
|
+
// when #31 ships an official mode.
|
|
1028
|
+
//
|
|
1029
|
+
// Existing OAuth rows are NOT migrated: `supportedAuthMethods` gates the
|
|
1030
|
+
// LINK call only, so the 46 stay readable and simply keep failing at the
|
|
1031
|
+
// provider, where the ineligible-tier message already explains why.
|
|
1032
|
+
supportedAuthKinds: ["api_key"],
|
|
1033
|
+
preferredAuthKind: "api_key",
|
|
898
1034
|
// Not listed by `headroom wrap --help` — runs native.
|
|
899
1035
|
headroomWrappable: false,
|
|
900
1036
|
// Native ACP server: `gemini --skip-trust --acp`.
|
|
@@ -2058,6 +2194,16 @@ var INTEGRATION_REGISTRY = {
|
|
|
2058
2194
|
// tools ourselves via a BUILT-IN MCP (delivery.builtin) against that admin
|
|
2059
2195
|
// API — see apps/cli/src/integrations/convex-admin-mcp.ts. The user still
|
|
2060
2196
|
// pastes a deploy key (Dashboard → Project Settings → Deploy Keys).
|
|
2197
|
+
//
|
|
2198
|
+
// ⚠️ That built-in ALSO owns `deploy`, and it is the only way an agent can
|
|
2199
|
+
// push `convex/` changes. Deploying is bundle + push, not a REST call, so
|
|
2200
|
+
// that one tool drives Convex's own CLI with the deploy key injected into
|
|
2201
|
+
// THAT CHILD's env — the agent's shell never sees the credential. Before
|
|
2202
|
+
// it existed the agent had the credential's power through the MCP but no
|
|
2203
|
+
// way to deploy, so it looped on `npx convex dev` (interactive login) and
|
|
2204
|
+
// asked the user to paste the token into the chat; the user ended up
|
|
2205
|
+
// re-entering the SAME key by hand in Environment Variables, after burning
|
|
2206
|
+
// real credits (2026-09-15).
|
|
2061
2207
|
enabled: true,
|
|
2062
2208
|
auth: {
|
|
2063
2209
|
kind: "api_key",
|
|
@@ -3256,11 +3402,11 @@ function quiet(fn) {
|
|
|
3256
3402
|
log.debug(TAG, "ignored sync error", err);
|
|
3257
3403
|
}
|
|
3258
3404
|
}
|
|
3259
|
-
function rmIfExistsQuiet(
|
|
3405
|
+
function rmIfExistsQuiet(path97) {
|
|
3260
3406
|
try {
|
|
3261
|
-
fs2.rmSync(
|
|
3407
|
+
fs2.rmSync(path97, { force: true });
|
|
3262
3408
|
} catch (err) {
|
|
3263
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
3409
|
+
log.debug(TAG, `rmIfExists failed for ${path97}`, err);
|
|
3264
3410
|
}
|
|
3265
3411
|
}
|
|
3266
3412
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -3467,8 +3613,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
3467
3613
|
return decodedFile;
|
|
3468
3614
|
};
|
|
3469
3615
|
}
|
|
3470
|
-
function normalizeWindowsPath(
|
|
3471
|
-
return
|
|
3616
|
+
function normalizeWindowsPath(path97) {
|
|
3617
|
+
return path97.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
3472
3618
|
}
|
|
3473
3619
|
|
|
3474
3620
|
// ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
|
|
@@ -6201,13 +6347,13 @@ var PostHogCoreStateless = class {
|
|
|
6201
6347
|
sentFromRoute += batchMessages.length;
|
|
6202
6348
|
}
|
|
6203
6349
|
}
|
|
6204
|
-
async _sendOtlpBatch({ path:
|
|
6350
|
+
async _sendOtlpBatch({ path: path97, payload }) {
|
|
6205
6351
|
if (this.disabled) return {
|
|
6206
6352
|
kind: "fatal",
|
|
6207
6353
|
error: new Error("The client is disabled")
|
|
6208
6354
|
};
|
|
6209
6355
|
const serialized = JSON.stringify(payload);
|
|
6210
|
-
const url2 = `${this.host}/i/v1/${
|
|
6356
|
+
const url2 = `${this.host}/i/v1/${path97}?token=${encodeURIComponent(this.apiKey)}`;
|
|
6211
6357
|
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
|
|
6212
6358
|
const fetchOptions = {
|
|
6213
6359
|
method: "POST",
|
|
@@ -7447,14 +7593,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
|
|
|
7447
7593
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
7448
7594
|
return frames;
|
|
7449
7595
|
}
|
|
7450
|
-
async function openRegularSourceFile(
|
|
7596
|
+
async function openRegularSourceFile(path97, openSourceFile, logger) {
|
|
7451
7597
|
let fileHandle;
|
|
7452
7598
|
let isValid = false;
|
|
7453
7599
|
try {
|
|
7454
|
-
fileHandle = await openSourceFile(
|
|
7600
|
+
fileHandle = await openSourceFile(path97, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
|
|
7455
7601
|
const fileStat = await fileHandle.stat();
|
|
7456
7602
|
if (!fileStat.isFile()) return;
|
|
7457
|
-
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${
|
|
7603
|
+
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path97}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
|
|
7458
7604
|
isValid = true;
|
|
7459
7605
|
return fileHandle;
|
|
7460
7606
|
} catch {
|
|
@@ -7464,8 +7610,8 @@ async function openRegularSourceFile(path96, openSourceFile, logger) {
|
|
|
7464
7610
|
});
|
|
7465
7611
|
}
|
|
7466
7612
|
}
|
|
7467
|
-
async function getContextLinesFromFile(
|
|
7468
|
-
const fileHandle = await openRegularSourceFile(
|
|
7613
|
+
async function getContextLinesFromFile(path97, ranges, output, cacheKey, openSourceFile, logger) {
|
|
7614
|
+
const fileHandle = await openRegularSourceFile(path97, openSourceFile, logger);
|
|
7469
7615
|
if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
7470
7616
|
const openedFileHandle = fileHandle;
|
|
7471
7617
|
return new Promise((resolve11) => {
|
|
@@ -7567,22 +7713,22 @@ function clearLineContext(frame) {
|
|
|
7567
7713
|
delete frame.context_line;
|
|
7568
7714
|
delete frame.post_context;
|
|
7569
7715
|
}
|
|
7570
|
-
function shouldSkipContextLinesForFile(
|
|
7571
|
-
return
|
|
7716
|
+
function shouldSkipContextLinesForFile(path97) {
|
|
7717
|
+
return path97.startsWith("node:") || path97.endsWith(".min.js") || path97.endsWith(".min.cjs") || path97.endsWith(".min.mjs") || path97.startsWith("data:");
|
|
7572
7718
|
}
|
|
7573
7719
|
function shouldSkipContextLinesForFrame(frame) {
|
|
7574
7720
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
7575
7721
|
if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
|
|
7576
7722
|
return false;
|
|
7577
7723
|
}
|
|
7578
|
-
function makeSourceCacheKey(
|
|
7579
|
-
if ((0, import_node_path.isAbsolute)(
|
|
7724
|
+
function makeSourceCacheKey(path97, basePath) {
|
|
7725
|
+
if ((0, import_node_path.isAbsolute)(path97)) return JSON.stringify([
|
|
7580
7726
|
null,
|
|
7581
|
-
|
|
7727
|
+
path97
|
|
7582
7728
|
]);
|
|
7583
7729
|
return void 0 === basePath ? void 0 : JSON.stringify([
|
|
7584
7730
|
basePath,
|
|
7585
|
-
|
|
7731
|
+
path97
|
|
7586
7732
|
]);
|
|
7587
7733
|
}
|
|
7588
7734
|
function rangeExistsInContentCache(cacheKey, range) {
|
|
@@ -10243,7 +10389,7 @@ function readAnonId() {
|
|
|
10243
10389
|
}
|
|
10244
10390
|
function superProperties() {
|
|
10245
10391
|
return {
|
|
10246
|
-
cliVersion: true ? "2.75.
|
|
10392
|
+
cliVersion: true ? "2.75.3" : "0.0.0-dev",
|
|
10247
10393
|
nodeVersion: process.version,
|
|
10248
10394
|
platform: process.platform,
|
|
10249
10395
|
arch: process.arch,
|
|
@@ -10485,7 +10631,7 @@ var http = __toESM(require("http"));
|
|
|
10485
10631
|
// package.json
|
|
10486
10632
|
var package_default = {
|
|
10487
10633
|
name: "codeam-cli",
|
|
10488
|
-
version: "2.75.
|
|
10634
|
+
version: "2.75.3",
|
|
10489
10635
|
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.",
|
|
10490
10636
|
type: "commonjs",
|
|
10491
10637
|
main: "dist/index.js",
|
|
@@ -12176,7 +12322,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12176
12322
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12177
12323
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12178
12324
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12179
|
-
..."2.75.
|
|
12325
|
+
..."2.75.3" ? { ideVersion: "2.75.3" } : {}
|
|
12180
12326
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
12181
12327
|
}
|
|
12182
12328
|
/**
|
|
@@ -19812,8 +19958,8 @@ function pickLine(obj) {
|
|
|
19812
19958
|
function toHunk(raw, groupSeverity) {
|
|
19813
19959
|
if (!raw || typeof raw !== "object") return null;
|
|
19814
19960
|
const o = raw;
|
|
19815
|
-
const
|
|
19816
|
-
if (!
|
|
19961
|
+
const path97 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
19962
|
+
if (!path97) return null;
|
|
19817
19963
|
const message = asString(
|
|
19818
19964
|
pick(o, [
|
|
19819
19965
|
"comment",
|
|
@@ -19830,7 +19976,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
19830
19976
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
19831
19977
|
const locObj = pick(o, ["location"]) ?? o;
|
|
19832
19978
|
return {
|
|
19833
|
-
path:
|
|
19979
|
+
path: path97.trim(),
|
|
19834
19980
|
line: pickLine(o) ?? pickLine(locObj),
|
|
19835
19981
|
severity,
|
|
19836
19982
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -19913,10 +20059,10 @@ function parsePlain(stdout) {
|
|
|
19913
20059
|
for (const line of stdout.split(/\r?\n/)) {
|
|
19914
20060
|
const m = line.match(HUNK_LINE_RE);
|
|
19915
20061
|
if (!m) continue;
|
|
19916
|
-
const [,
|
|
19917
|
-
if (!
|
|
20062
|
+
const [, path97, lineNo, sevToken, message] = m;
|
|
20063
|
+
if (!path97 || !lineNo || !message) continue;
|
|
19918
20064
|
hunks.push({
|
|
19919
|
-
path:
|
|
20065
|
+
path: path97.trim(),
|
|
19920
20066
|
line: Number(lineNo),
|
|
19921
20067
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
19922
20068
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -20634,14 +20780,14 @@ function defaultSdkDir() {
|
|
|
20634
20780
|
return resolveSdkDirViaRequire();
|
|
20635
20781
|
}
|
|
20636
20782
|
function resolveClaudeNativeBinary(deps = {}) {
|
|
20637
|
-
const
|
|
20783
|
+
const existsSync30 = deps.existsSync ?? import_fs.default.existsSync;
|
|
20638
20784
|
const platformKey = deps.platformKey ?? currentPlatformKey();
|
|
20639
20785
|
const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
|
|
20640
20786
|
if (!sdkDir) return null;
|
|
20641
20787
|
const scopeDir = import_path4.default.dirname(sdkDir);
|
|
20642
20788
|
const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
|
|
20643
20789
|
const candidate = import_path4.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
|
|
20644
|
-
return
|
|
20790
|
+
return existsSync30(candidate) ? candidate : null;
|
|
20645
20791
|
}
|
|
20646
20792
|
var realSleep = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
20647
20793
|
async function waitForClaudeNativeBinary(opts = {}) {
|
|
@@ -20723,18 +20869,18 @@ function augmentUserLocalBinPaths(deps = {}) {
|
|
|
20723
20869
|
env.PATH = [...additions, ...parts].join(p2.delimiter);
|
|
20724
20870
|
}
|
|
20725
20871
|
function resolveCursorAgentBinary(deps = {}) {
|
|
20726
|
-
const
|
|
20872
|
+
const existsSync30 = deps.existsSync ?? import_fs.default.existsSync;
|
|
20727
20873
|
const platform3 = deps.platform ?? process.platform;
|
|
20728
20874
|
const env = deps.env ?? process.env;
|
|
20729
20875
|
if (platform3 === "win32") {
|
|
20730
20876
|
const localAppData = env.LOCALAPPDATA;
|
|
20731
20877
|
if (!localAppData) return null;
|
|
20732
20878
|
const exe = import_path4.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
|
|
20733
|
-
return
|
|
20879
|
+
return existsSync30(exe) ? exe : null;
|
|
20734
20880
|
}
|
|
20735
20881
|
const home = deps.homedir ?? import_os4.default.homedir();
|
|
20736
20882
|
const unix = import_path4.default.posix.join(home, ".local", "bin", "cursor-agent");
|
|
20737
|
-
return
|
|
20883
|
+
return existsSync30(unix) ? unix : null;
|
|
20738
20884
|
}
|
|
20739
20885
|
async function waitForCursorAgent(opts = {}) {
|
|
20740
20886
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
@@ -24510,7 +24656,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
24510
24656
|
if (process.env.NODE_ENV === "test") return;
|
|
24511
24657
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
24512
24658
|
if (process.env.CI) return;
|
|
24513
|
-
const current2 = true ? "2.75.
|
|
24659
|
+
const current2 = true ? "2.75.3" : null;
|
|
24514
24660
|
if (!current2) return;
|
|
24515
24661
|
const cache = readCache();
|
|
24516
24662
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -24527,7 +24673,7 @@ function checkForUpdates() {
|
|
|
24527
24673
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
24528
24674
|
if (process.env.CI) return;
|
|
24529
24675
|
if (!process.stdout.isTTY) return;
|
|
24530
|
-
const current2 = true ? "2.75.
|
|
24676
|
+
const current2 = true ? "2.75.3" : null;
|
|
24531
24677
|
if (!current2) return;
|
|
24532
24678
|
const cache = readCache();
|
|
24533
24679
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -24550,7 +24696,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
24550
24696
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
24551
24697
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
24552
24698
|
function currentCliVersion() {
|
|
24553
|
-
return true ? "2.75.
|
|
24699
|
+
return true ? "2.75.3" : null;
|
|
24554
24700
|
}
|
|
24555
24701
|
async function installedVersion(deps) {
|
|
24556
24702
|
const ls = await deps.run(
|
|
@@ -26527,7 +26673,7 @@ async function defaultFetchJson(url2) {
|
|
|
26527
26673
|
async function readUsageReport(deps = {}) {
|
|
26528
26674
|
const port = deps.port ?? HEADROOM_PROXY_PORT;
|
|
26529
26675
|
const base = `http://127.0.0.1:${port}`;
|
|
26530
|
-
const get4 = deps.fetchJson ?? ((
|
|
26676
|
+
const get4 = deps.fetchJson ?? ((path97) => defaultFetchJson(`${base}${path97}`));
|
|
26531
26677
|
let history;
|
|
26532
26678
|
try {
|
|
26533
26679
|
history = await get4("/stats-history");
|
|
@@ -32301,11 +32447,11 @@ function resolveTokenValue(args2) {
|
|
|
32301
32447
|
}
|
|
32302
32448
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
32303
32449
|
if (fileFlag) {
|
|
32304
|
-
const
|
|
32450
|
+
const path97 = fileFlag.slice("--token-file=".length);
|
|
32305
32451
|
try {
|
|
32306
|
-
const content = fs66.readFileSync(
|
|
32307
|
-
if (content.length === 0) fail(`--token-file ${
|
|
32308
|
-
rmIfExistsQuiet(
|
|
32452
|
+
const content = fs66.readFileSync(path97, "utf8").trim();
|
|
32453
|
+
if (content.length === 0) fail(`--token-file ${path97} is empty`);
|
|
32454
|
+
rmIfExistsQuiet(path97);
|
|
32309
32455
|
return content;
|
|
32310
32456
|
} catch (err) {
|
|
32311
32457
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -39238,12 +39384,12 @@ function buildRelaunchProxyEnv(baseEnv) {
|
|
|
39238
39384
|
return env;
|
|
39239
39385
|
}
|
|
39240
39386
|
var relaunchProxyWithoutBudget = async () => {
|
|
39241
|
-
const { spawn:
|
|
39387
|
+
const { spawn: spawn49 } = await import("child_process");
|
|
39242
39388
|
killHeadroomProxy();
|
|
39243
39389
|
await new Promise((r) => setTimeout(r, 500));
|
|
39244
39390
|
const proxyEnv = buildRelaunchProxyEnv(process.env);
|
|
39245
39391
|
try {
|
|
39246
|
-
const proxy =
|
|
39392
|
+
const proxy = spawn49(
|
|
39247
39393
|
"headroom",
|
|
39248
39394
|
["proxy", "--port", "8787"],
|
|
39249
39395
|
{ stdio: "ignore", detached: true, env: proxyEnv }
|
|
@@ -40775,7 +40921,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
40775
40921
|
});
|
|
40776
40922
|
}
|
|
40777
40923
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
40778
|
-
const
|
|
40924
|
+
const fs84 = await import("fs/promises");
|
|
40779
40925
|
const out2 = [];
|
|
40780
40926
|
await walk(workingDir, 0);
|
|
40781
40927
|
return out2;
|
|
@@ -40783,7 +40929,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
40783
40929
|
if (depth > maxDepth) return;
|
|
40784
40930
|
let entries = [];
|
|
40785
40931
|
try {
|
|
40786
|
-
const dirents = await
|
|
40932
|
+
const dirents = await fs84.readdir(dir, { withFileTypes: true });
|
|
40787
40933
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
40788
40934
|
} catch {
|
|
40789
40935
|
return;
|
|
@@ -49989,7 +50135,7 @@ function checkChokidar() {
|
|
|
49989
50135
|
}
|
|
49990
50136
|
async function doctor(args2 = []) {
|
|
49991
50137
|
const json = args2.includes("--json");
|
|
49992
|
-
const cliVersion = true ? "2.75.
|
|
50138
|
+
const cliVersion = true ? "2.75.3" : "0.0.0-dev";
|
|
49993
50139
|
const apiBase2 = resolveApiBaseUrl();
|
|
49994
50140
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
49995
50141
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -50186,7 +50332,7 @@ async function completion(args2) {
|
|
|
50186
50332
|
}
|
|
50187
50333
|
|
|
50188
50334
|
// src/integrations/mcp-run.ts
|
|
50189
|
-
var
|
|
50335
|
+
var import_node_child_process35 = require("child_process");
|
|
50190
50336
|
|
|
50191
50337
|
// src/integrations/launcher-env.ts
|
|
50192
50338
|
var LAUNCHER_ENV = Object.freeze({
|
|
@@ -50270,7 +50416,7 @@ function resolveDelivery(id) {
|
|
|
50270
50416
|
function commandExists(command2) {
|
|
50271
50417
|
try {
|
|
50272
50418
|
const probe = process.platform === "win32" ? "where" : "which";
|
|
50273
|
-
(0,
|
|
50419
|
+
(0, import_node_child_process35.execFileSync)(probe, [command2], { stdio: "ignore" });
|
|
50274
50420
|
return true;
|
|
50275
50421
|
} catch {
|
|
50276
50422
|
return false;
|
|
@@ -50303,7 +50449,7 @@ function ensureCommand(command2) {
|
|
|
50303
50449
|
}
|
|
50304
50450
|
if (command2 === "uvx") {
|
|
50305
50451
|
try {
|
|
50306
|
-
(0,
|
|
50452
|
+
(0, import_node_child_process35.execSync)("curl -LsSf https://astral.sh/uv/install.sh | sh", {
|
|
50307
50453
|
stdio: ["ignore", process.stderr, process.stderr],
|
|
50308
50454
|
timeout: 18e4,
|
|
50309
50455
|
env: { ...process.env, UV_NO_MODIFY_PATH: "1" }
|
|
@@ -50312,7 +50458,7 @@ function ensureCommand(command2) {
|
|
|
50312
50458
|
}
|
|
50313
50459
|
if (resolveLauncherPath(command2) !== command2) return;
|
|
50314
50460
|
try {
|
|
50315
|
-
(0,
|
|
50461
|
+
(0, import_node_child_process35.execSync)("python3 -m pip install --user --quiet uv", {
|
|
50316
50462
|
stdio: ["ignore", process.stderr, process.stderr],
|
|
50317
50463
|
timeout: 18e4
|
|
50318
50464
|
});
|
|
@@ -50390,7 +50536,7 @@ async function mcpRun(args2) {
|
|
|
50390
50536
|
}
|
|
50391
50537
|
|
|
50392
50538
|
// src/integrations/mcp-warm.ts
|
|
50393
|
-
var
|
|
50539
|
+
var import_node_child_process36 = require("child_process");
|
|
50394
50540
|
function specOf(delivery) {
|
|
50395
50541
|
if (!delivery.command) return null;
|
|
50396
50542
|
const spec = (delivery.args ?? []).find((a) => !a.startsWith("-"));
|
|
@@ -50434,7 +50580,7 @@ var WARM_TOTAL_BUDGET_MS = 10 * 6e4;
|
|
|
50434
50580
|
var WARM_CONCURRENCY = 4;
|
|
50435
50581
|
function runCapturing(command2, args2, timeoutMs) {
|
|
50436
50582
|
return new Promise((resolve11) => {
|
|
50437
|
-
const child = (0,
|
|
50583
|
+
const child = (0, import_node_child_process36.spawn)(command2, args2, {
|
|
50438
50584
|
env: { ...process.env, ...LAUNCHER_ENV },
|
|
50439
50585
|
stdio: ["ignore", "ignore", "pipe"],
|
|
50440
50586
|
// `npx`/`uv` are `.cmd` shims on Windows; Node ≥ 20.12 refuses to spawn a
|
|
@@ -50513,7 +50659,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
50513
50659
|
// src/commands/version.ts
|
|
50514
50660
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
50515
50661
|
function version2() {
|
|
50516
|
-
const v = true ? "2.75.
|
|
50662
|
+
const v = true ? "2.75.3" : "unknown";
|
|
50517
50663
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
50518
50664
|
}
|
|
50519
50665
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.3",
|
|
4
4
|
"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 — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|