codeam-cli 2.39.64 → 2.39.66
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 +80 -52
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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.39.65] — 2026-06-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **self-hosted:** Run sessions in AUTO mode (auto-approve permissions)
|
|
12
|
+
|
|
13
|
+
## [2.39.64] — 2026-06-20
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **host-agent:** Handle self_hosted_refresh_credentials (in-place re-auth)
|
|
18
|
+
|
|
7
19
|
## [2.39.63] — 2026-06-20
|
|
8
20
|
|
|
9
21
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -5388,7 +5388,7 @@ function readAnonId() {
|
|
|
5388
5388
|
}
|
|
5389
5389
|
function superProperties() {
|
|
5390
5390
|
return {
|
|
5391
|
-
cliVersion: true ? "2.39.
|
|
5391
|
+
cliVersion: true ? "2.39.66" : "0.0.0-dev",
|
|
5392
5392
|
nodeVersion: process.version,
|
|
5393
5393
|
platform: process.platform,
|
|
5394
5394
|
arch: process.arch,
|
|
@@ -5547,7 +5547,7 @@ var os4 = __toESM(require("os"));
|
|
|
5547
5547
|
// package.json
|
|
5548
5548
|
var package_default = {
|
|
5549
5549
|
name: "codeam-cli",
|
|
5550
|
-
version: "2.39.
|
|
5550
|
+
version: "2.39.66",
|
|
5551
5551
|
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.",
|
|
5552
5552
|
type: "commonjs",
|
|
5553
5553
|
main: "dist/index.js",
|
|
@@ -14143,29 +14143,32 @@ var activePreviews = /* @__PURE__ */ new Map();
|
|
|
14143
14143
|
function registerPreview(sessionId, preview) {
|
|
14144
14144
|
activePreviews.set(sessionId, preview);
|
|
14145
14145
|
}
|
|
14146
|
-
|
|
14147
|
-
const
|
|
14148
|
-
if (
|
|
14149
|
-
if (
|
|
14146
|
+
function killProcessTree(child, signal = "SIGTERM") {
|
|
14147
|
+
const pid = child.pid;
|
|
14148
|
+
if (pid == null) return;
|
|
14149
|
+
if (process.platform !== "win32") {
|
|
14150
14150
|
try {
|
|
14151
|
-
|
|
14151
|
+
process.kill(-pid, signal);
|
|
14152
|
+
return;
|
|
14152
14153
|
} catch {
|
|
14153
14154
|
}
|
|
14154
14155
|
}
|
|
14155
|
-
await new Promise((r) => setTimeout(r, 100));
|
|
14156
14156
|
try {
|
|
14157
|
-
|
|
14157
|
+
child.kill(signal);
|
|
14158
14158
|
} catch {
|
|
14159
14159
|
}
|
|
14160
|
+
}
|
|
14161
|
+
async function killPreview(sessionId) {
|
|
14162
|
+
const preview = activePreviews.get(sessionId);
|
|
14163
|
+
if (!preview) return;
|
|
14164
|
+
if (preview.tunnel) {
|
|
14165
|
+
killProcessTree(preview.tunnel, "SIGTERM");
|
|
14166
|
+
}
|
|
14167
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
14168
|
+
killProcessTree(preview.devServer, "SIGTERM");
|
|
14160
14169
|
const sigkillTimer = setTimeout(() => {
|
|
14161
|
-
|
|
14162
|
-
|
|
14163
|
-
} catch {
|
|
14164
|
-
}
|
|
14165
|
-
try {
|
|
14166
|
-
preview.tunnel?.kill("SIGKILL");
|
|
14167
|
-
} catch {
|
|
14168
|
-
}
|
|
14170
|
+
killProcessTree(preview.devServer, "SIGKILL");
|
|
14171
|
+
if (preview.tunnel) killProcessTree(preview.tunnel, "SIGKILL");
|
|
14169
14172
|
}, 250);
|
|
14170
14173
|
sigkillTimer.unref?.();
|
|
14171
14174
|
activePreviews.delete(sessionId);
|
|
@@ -16225,17 +16228,42 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16225
16228
|
});
|
|
16226
16229
|
return;
|
|
16227
16230
|
}
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16231
|
+
if (raceExisting) {
|
|
16232
|
+
log.info(
|
|
16233
|
+
"preview",
|
|
16234
|
+
`reclaiming stale preview holding port ${detection.port} for session=${ctx.sessionId} (exit=${raceExisting.devServer.exitCode})`
|
|
16235
|
+
);
|
|
16236
|
+
await killPreview(ctx.sessionId);
|
|
16237
|
+
const freeDeadline = Date.now() + 4e3;
|
|
16238
|
+
while (await isPortListening(detection.port) && Date.now() < freeDeadline) {
|
|
16239
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
16236
16240
|
}
|
|
16237
|
-
|
|
16238
|
-
|
|
16241
|
+
if (await isPortListening(detection.port)) {
|
|
16242
|
+
void postPreviewEvent({
|
|
16243
|
+
sessionId: ctx.sessionId,
|
|
16244
|
+
pluginId: ctx.pluginId,
|
|
16245
|
+
pluginAuthToken,
|
|
16246
|
+
type: "preview_error",
|
|
16247
|
+
payload: {
|
|
16248
|
+
stage: "spawn",
|
|
16249
|
+
message: `Port ${detection.port} is still in use after stopping the previous preview. Wait a moment and try again.`
|
|
16250
|
+
}
|
|
16251
|
+
});
|
|
16252
|
+
return;
|
|
16253
|
+
}
|
|
16254
|
+
} else {
|
|
16255
|
+
void postPreviewEvent({
|
|
16256
|
+
sessionId: ctx.sessionId,
|
|
16257
|
+
pluginId: ctx.pluginId,
|
|
16258
|
+
pluginAuthToken,
|
|
16259
|
+
type: "preview_error",
|
|
16260
|
+
payload: {
|
|
16261
|
+
stage: "spawn",
|
|
16262
|
+
message: `Port ${detection.port} is already in use by another process, so the dev server can't start there. Stop whatever is listening on port ${detection.port} and try the preview again.`
|
|
16263
|
+
}
|
|
16264
|
+
});
|
|
16265
|
+
return;
|
|
16266
|
+
}
|
|
16239
16267
|
}
|
|
16240
16268
|
const spawnable = normalizeDetectionForSpawn(detection, process.cwd());
|
|
16241
16269
|
emitProgress(
|
|
@@ -16245,7 +16273,14 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16245
16273
|
const devServer = (0, import_child_process20.spawn)(spawnable.command, spawnable.args, {
|
|
16246
16274
|
cwd: process.cwd(),
|
|
16247
16275
|
env: { ...process.env, ...spawnable.env ?? {} },
|
|
16248
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
16276
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
16277
|
+
// POSIX: lead a new process group so teardown can SIGTERM the whole
|
|
16278
|
+
// tree. Dev servers fork worker children that bind the port; killing
|
|
16279
|
+
// only the direct child orphans them and leaks the port, so the next
|
|
16280
|
+
// preview_start hits EADDRINUSE on a port we already hold. Group-kill
|
|
16281
|
+
// (killProcessTree) reaps the workers too. Windows has no process
|
|
16282
|
+
// groups — leave detached off there (direct kill is the only option).
|
|
16283
|
+
detached: process.platform !== "win32"
|
|
16249
16284
|
});
|
|
16250
16285
|
emitProgress("BIND_PORT", String(detection.port));
|
|
16251
16286
|
emitProgress("WAITING_FOR_READY", detection.ready_pattern);
|
|
@@ -16264,6 +16299,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16264
16299
|
portProbe: isNextJs ? () => waitForPortListening(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : void 0
|
|
16265
16300
|
});
|
|
16266
16301
|
if (outcome.kind === "exited") {
|
|
16302
|
+
killProcessTree(devServer, "SIGTERM");
|
|
16267
16303
|
void postPreviewEvent({
|
|
16268
16304
|
sessionId: ctx.sessionId,
|
|
16269
16305
|
pluginId: ctx.pluginId,
|
|
@@ -16278,10 +16314,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16278
16314
|
return;
|
|
16279
16315
|
}
|
|
16280
16316
|
if (outcome.kind === "timeout") {
|
|
16281
|
-
|
|
16282
|
-
devServer.kill("SIGTERM");
|
|
16283
|
-
} catch {
|
|
16284
|
-
}
|
|
16317
|
+
killProcessTree(devServer, "SIGTERM");
|
|
16285
16318
|
void postPreviewEvent({
|
|
16286
16319
|
sessionId: ctx.sessionId,
|
|
16287
16320
|
pluginId: ctx.pluginId,
|
|
@@ -16310,10 +16343,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16310
16343
|
}
|
|
16311
16344
|
}
|
|
16312
16345
|
if (!expoUrl) {
|
|
16313
|
-
|
|
16314
|
-
devServer.kill("SIGTERM");
|
|
16315
|
-
} catch {
|
|
16316
|
-
}
|
|
16346
|
+
killProcessTree(devServer, "SIGTERM");
|
|
16317
16347
|
void postPreviewEvent({
|
|
16318
16348
|
sessionId: ctx.sessionId,
|
|
16319
16349
|
pluginId: ctx.pluginId,
|
|
@@ -16329,10 +16359,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16329
16359
|
try {
|
|
16330
16360
|
bin = await resolveCloudflared();
|
|
16331
16361
|
} catch (e) {
|
|
16332
|
-
|
|
16333
|
-
devServer.kill("SIGTERM");
|
|
16334
|
-
} catch {
|
|
16335
|
-
}
|
|
16362
|
+
killProcessTree(devServer, "SIGTERM");
|
|
16336
16363
|
void postPreviewEvent({
|
|
16337
16364
|
sessionId: ctx.sessionId,
|
|
16338
16365
|
pluginId: ctx.pluginId,
|
|
@@ -16426,10 +16453,7 @@ var previewStartH = (ctx, _cmd, parsed) => {
|
|
|
16426
16453
|
}
|
|
16427
16454
|
}
|
|
16428
16455
|
if (!parsedUrl) {
|
|
16429
|
-
|
|
16430
|
-
devServer.kill("SIGTERM");
|
|
16431
|
-
} catch {
|
|
16432
|
-
}
|
|
16456
|
+
killProcessTree(devServer, "SIGTERM");
|
|
16433
16457
|
void postPreviewEvent({
|
|
16434
16458
|
sessionId: ctx.sessionId,
|
|
16435
16459
|
pluginId: ctx.pluginId,
|
|
@@ -17367,7 +17391,7 @@ function checkForUpdates() {
|
|
|
17367
17391
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17368
17392
|
if (process.env.CI) return;
|
|
17369
17393
|
if (!process.stdout.isTTY) return;
|
|
17370
|
-
const current = true ? "2.39.
|
|
17394
|
+
const current = true ? "2.39.66" : null;
|
|
17371
17395
|
if (!current) return;
|
|
17372
17396
|
const cache = readCache();
|
|
17373
17397
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17772,7 +17796,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process13.s
|
|
|
17772
17796
|
detached: false
|
|
17773
17797
|
});
|
|
17774
17798
|
function currentCliVersion() {
|
|
17775
|
-
return true ? "2.39.
|
|
17799
|
+
return true ? "2.39.66" : null;
|
|
17776
17800
|
}
|
|
17777
17801
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17778
17802
|
return new Promise((resolve7) => {
|
|
@@ -18145,6 +18169,7 @@ var HostAgentSupervisor = class {
|
|
|
18145
18169
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
18146
18170
|
};
|
|
18147
18171
|
}
|
|
18172
|
+
childEnv = { ...childEnv, CODEAM_AUTO_APPROVE: "1" };
|
|
18148
18173
|
if (payload.agentInstallScript) {
|
|
18149
18174
|
report("installing", "installing agent CLI");
|
|
18150
18175
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
@@ -25718,10 +25743,13 @@ async function start(requestedAgent) {
|
|
|
25718
25743
|
adapter,
|
|
25719
25744
|
cwd,
|
|
25720
25745
|
getBeads,
|
|
25721
|
-
// AUTO mode
|
|
25722
|
-
// answer permission prompts, so auto-approve them rather than stall
|
|
25723
|
-
// turn (the agent-agnostic equivalent of
|
|
25724
|
-
|
|
25746
|
+
// AUTO mode for headless, mobile-driven sessions: no human at the box
|
|
25747
|
+
// to answer permission prompts, so auto-approve them rather than stall
|
|
25748
|
+
// the turn (the agent-agnostic equivalent of
|
|
25749
|
+
// --dangerously-skip-permissions). Both surfaces qualify — a GitHub
|
|
25750
|
+
// Codespace (`CODESPACES=true`) and a self-hosted deploy (the host-agent
|
|
25751
|
+
// sets `CODEAM_AUTO_APPROVE=1` on the pair-auto child).
|
|
25752
|
+
autoApprovePermissions: process.env.CODESPACES === "true" || process.env.CODEAM_AUTO_APPROVE === "1"
|
|
25725
25753
|
});
|
|
25726
25754
|
return;
|
|
25727
25755
|
}
|
|
@@ -28383,7 +28411,7 @@ function checkChokidar() {
|
|
|
28383
28411
|
}
|
|
28384
28412
|
async function doctor(args2 = []) {
|
|
28385
28413
|
const json = args2.includes("--json");
|
|
28386
|
-
const cliVersion = true ? "2.39.
|
|
28414
|
+
const cliVersion = true ? "2.39.66" : "0.0.0-dev";
|
|
28387
28415
|
const apiBase2 = resolveApiBaseUrl();
|
|
28388
28416
|
const diagnosticId = (0, import_node_crypto8.randomUUID)();
|
|
28389
28417
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -28582,7 +28610,7 @@ async function completion(args2) {
|
|
|
28582
28610
|
// src/commands/version.ts
|
|
28583
28611
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
28584
28612
|
function version2() {
|
|
28585
|
-
const v = true ? "2.39.
|
|
28613
|
+
const v = true ? "2.39.66" : "unknown";
|
|
28586
28614
|
console.log(`${import_picocolors14.default.bold("codeam-cli")} ${import_picocolors14.default.cyan(v)}`);
|
|
28587
28615
|
}
|
|
28588
28616
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.66",
|
|
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",
|