codeam-cli 2.61.5 → 2.61.8
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 +19 -0
- package/dist/index.js +148 -31
- package/dist/postinstall.js +33 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ 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.61.7] — 2026-07-16
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Auto-resume the user's session on host-agent restart (no churn)
|
|
12
|
+
- **cli:** Engines-compat test uses CommonJS require (was import.meta → tsc fail)
|
|
13
|
+
|
|
14
|
+
## [2.61.5] — 2026-07-16
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **cli:** ACP chrome-leak canary + detector (stability monitor, part 2)
|
|
19
|
+
- **ci:** Canary seeds onboarding + auths via in-house MiniMax backend
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **ci:** Canary auths by subscription (CLAUDE_CODE_OAUTH_TOKEN), not API key
|
|
24
|
+
- **cli:** Stop the changeset reporter from spamming install/SDK files
|
|
25
|
+
|
|
7
26
|
## [2.61.4] — 2026-07-16
|
|
8
27
|
|
|
9
28
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -5975,7 +5975,7 @@ function readAnonId() {
|
|
|
5975
5975
|
}
|
|
5976
5976
|
function superProperties() {
|
|
5977
5977
|
return {
|
|
5978
|
-
cliVersion: true ? "2.61.
|
|
5978
|
+
cliVersion: true ? "2.61.8" : "0.0.0-dev",
|
|
5979
5979
|
nodeVersion: process.version,
|
|
5980
5980
|
platform: process.platform,
|
|
5981
5981
|
arch: process.arch,
|
|
@@ -6156,7 +6156,7 @@ var os4 = __toESM(require("os"));
|
|
|
6156
6156
|
// package.json
|
|
6157
6157
|
var package_default = {
|
|
6158
6158
|
name: "codeam-cli",
|
|
6159
|
-
version: "2.61.
|
|
6159
|
+
version: "2.61.8",
|
|
6160
6160
|
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.",
|
|
6161
6161
|
type: "commonjs",
|
|
6162
6162
|
main: "dist/index.js",
|
|
@@ -6225,7 +6225,7 @@ var package_default = {
|
|
|
6225
6225
|
url: "https://github.com/sponsors/edgar-durand"
|
|
6226
6226
|
},
|
|
6227
6227
|
engines: {
|
|
6228
|
-
node: ">=
|
|
6228
|
+
node: ">=22.0.0"
|
|
6229
6229
|
},
|
|
6230
6230
|
dependencies: {
|
|
6231
6231
|
"@agentclientprotocol/claude-agent-acp": "0.59.0",
|
|
@@ -7299,7 +7299,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
7299
7299
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7300
7300
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7301
7301
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7302
|
-
..."2.61.
|
|
7302
|
+
..."2.61.8" ? { ideVersion: "2.61.8" } : {}
|
|
7303
7303
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7304
7304
|
}
|
|
7305
7305
|
/**
|
|
@@ -17900,7 +17900,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
17900
17900
|
if (process.env.NODE_ENV === "test") return;
|
|
17901
17901
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17902
17902
|
if (process.env.CI) return;
|
|
17903
|
-
const current = true ? "2.61.
|
|
17903
|
+
const current = true ? "2.61.8" : null;
|
|
17904
17904
|
if (!current) return;
|
|
17905
17905
|
const cache = readCache();
|
|
17906
17906
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17917,7 +17917,7 @@ function checkForUpdates() {
|
|
|
17917
17917
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
17918
17918
|
if (process.env.CI) return;
|
|
17919
17919
|
if (!process.stdout.isTTY) return;
|
|
17920
|
-
const current = true ? "2.61.
|
|
17920
|
+
const current = true ? "2.61.8" : null;
|
|
17921
17921
|
if (!current) return;
|
|
17922
17922
|
const cache = readCache();
|
|
17923
17923
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -17937,7 +17937,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
17937
17937
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
17938
17938
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
17939
17939
|
function currentCliVersion() {
|
|
17940
|
-
return true ? "2.61.
|
|
17940
|
+
return true ? "2.61.8" : null;
|
|
17941
17941
|
}
|
|
17942
17942
|
function runCmd(cmd, args2, timeoutMs) {
|
|
17943
17943
|
return new Promise((resolve8) => {
|
|
@@ -18254,6 +18254,15 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process23.s
|
|
|
18254
18254
|
stdio: ["ignore", "pipe", "pipe"],
|
|
18255
18255
|
detached: false
|
|
18256
18256
|
});
|
|
18257
|
+
var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process23.spawn)(process.execPath, [process.argv[1]], {
|
|
18258
|
+
cwd,
|
|
18259
|
+
// CODEAM_AUTO_APPROVE=1 → ACP path (baton off). CODEAM_RESUME_LATEST=1 →
|
|
18260
|
+
// continue the user's most-recent conversation instead of opening an empty
|
|
18261
|
+
// one (runAcpSession loads it via the ACP session/list RPC).
|
|
18262
|
+
env: { ...process.env, ...env, CODEAM_AUTO_APPROVE: "1", CODEAM_RESUME_LATEST: "1" },
|
|
18263
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
18264
|
+
detached: false
|
|
18265
|
+
});
|
|
18257
18266
|
var defaultOnIdentityRejected = () => {
|
|
18258
18267
|
deleteHostIdentity();
|
|
18259
18268
|
log.warn("host-agent", "host identity rejected by backend \u2014 wiped sealed identity, exiting");
|
|
@@ -18268,6 +18277,7 @@ var HostAgentSupervisor = class {
|
|
|
18268
18277
|
this.identity = identity;
|
|
18269
18278
|
this.deps = deps;
|
|
18270
18279
|
this.spawnChild = deps.spawnChild ?? defaultSpawner;
|
|
18280
|
+
this.resumeSpawner = deps.resumeSpawner ?? defaultResumeSpawner;
|
|
18271
18281
|
this.resolveAgentAuth = deps.resolveAgentAuth ?? unsealAgentAuth;
|
|
18272
18282
|
this.setupHeadroom = deps.setupHeadroom ?? setupHeadroomForSelfHosted;
|
|
18273
18283
|
this.isHeadroomInstalled = deps.isHeadroomInstalled ?? (() => defaultHeadroomRunner.which("headroom"));
|
|
@@ -18284,6 +18294,7 @@ var HostAgentSupervisor = class {
|
|
|
18284
18294
|
deps;
|
|
18285
18295
|
children = /* @__PURE__ */ new Map();
|
|
18286
18296
|
spawnChild;
|
|
18297
|
+
resumeSpawner;
|
|
18287
18298
|
resolveAgentAuth;
|
|
18288
18299
|
setupHeadroom;
|
|
18289
18300
|
/** Probe whether Headroom is already installed (defaults to `which headroom`). */
|
|
@@ -18344,6 +18355,7 @@ var HostAgentSupervisor = class {
|
|
|
18344
18355
|
void this.beat();
|
|
18345
18356
|
this.heartbeatTimer = setInterval(() => void this.beat(), HEARTBEAT_INTERVAL_MS);
|
|
18346
18357
|
this.heartbeatTimer.unref?.();
|
|
18358
|
+
this.resumePersistedSession();
|
|
18347
18359
|
void reportSessionEvent(
|
|
18348
18360
|
{ hostId: this.identity.hostId, hostToken: this.identity.hostToken },
|
|
18349
18361
|
{ event: "reconcile", activeDeployIds: this.activeSessions().map((s) => s.id) }
|
|
@@ -18933,6 +18945,60 @@ var HostAgentSupervisor = class {
|
|
|
18933
18945
|
spawnSessionChild(env, cwd, args2 = []) {
|
|
18934
18946
|
return this.spawnChild({ ...env, ...readHeadroomChildEnv() }, cwd, args2);
|
|
18935
18947
|
}
|
|
18948
|
+
/**
|
|
18949
|
+
* Auto-resume the user's last active session on supervisor boot (2026-07-16
|
|
18950
|
+
* churn fix). Before this, a restart / self-update killed the session child
|
|
18951
|
+
* and never re-spawned it — the session lost its heartbeat, went "CLI
|
|
18952
|
+
* disconnected", and the user had to reconnect by hand (churn right after an
|
|
18953
|
+
* update). Spawn bare `codeam` via the resume spawner (reconnects the SAME
|
|
18954
|
+
* pluginId via start(), then heartbeats) so the session comes back on its own
|
|
18955
|
+
* in its ORIGINAL ACP shape (self-hosted/codespace = ACP-only; the resume
|
|
18956
|
+
* spawner sets CODEAM_AUTO_APPROVE=1 to keep the local baton/native-TUI OFF).
|
|
18957
|
+
*
|
|
18958
|
+
* Best-effort + guarded: no-op when there's no persisted session, when the
|
|
18959
|
+
* persisted session lacks the reconnect material (pluginId + pollSecret +
|
|
18960
|
+
* agent), or when a fresh deploy already owns a child this boot.
|
|
18961
|
+
*/
|
|
18962
|
+
resumePersistedSession() {
|
|
18963
|
+
try {
|
|
18964
|
+
if (this.children.size > 0) return;
|
|
18965
|
+
const session = getActiveSession();
|
|
18966
|
+
if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
|
|
18967
|
+
const cwd = process.cwd();
|
|
18968
|
+
const proc = this.resumeSpawner({ ...readHeadroomChildEnv() }, cwd);
|
|
18969
|
+
const child = {
|
|
18970
|
+
deployId: session.id,
|
|
18971
|
+
proc,
|
|
18972
|
+
agent: session.agent,
|
|
18973
|
+
startedAt: Date.now()
|
|
18974
|
+
};
|
|
18975
|
+
this.children.set(session.id, child);
|
|
18976
|
+
let tail = "";
|
|
18977
|
+
const appendTail = (buf) => {
|
|
18978
|
+
tail = (tail + buf.toString("utf8")).slice(-2e3);
|
|
18979
|
+
};
|
|
18980
|
+
proc.stdout?.on("data", appendTail);
|
|
18981
|
+
proc.stderr?.on("data", appendTail);
|
|
18982
|
+
proc.once("exit", (code) => {
|
|
18983
|
+
if (this.children.get(session.id)?.proc === proc) this.children.delete(session.id);
|
|
18984
|
+
if (typeof code === "number" && code !== 0) {
|
|
18985
|
+
log.warn(
|
|
18986
|
+
"host-agent",
|
|
18987
|
+
`resumed session ${session.id.slice(0, 8)} exited (${code}): ${tail.trim().slice(-300)}`
|
|
18988
|
+
);
|
|
18989
|
+
}
|
|
18990
|
+
});
|
|
18991
|
+
log.info(
|
|
18992
|
+
"host-agent",
|
|
18993
|
+
`resumed session ${session.id.slice(0, 8)} pluginId=${session.pluginId.slice(0, 12)} (ACP)`
|
|
18994
|
+
);
|
|
18995
|
+
} catch (err) {
|
|
18996
|
+
log.warn(
|
|
18997
|
+
"host-agent",
|
|
18998
|
+
`resume persisted session failed (best-effort): ${err instanceof Error ? err.message : String(err)}`
|
|
18999
|
+
);
|
|
19000
|
+
}
|
|
19001
|
+
}
|
|
18936
19002
|
/**
|
|
18937
19003
|
* Run the backend-supplied per-agent CLI install script (e.g.
|
|
18938
19004
|
* `claude.ai/install.sh`, `npm i -g @openai/codex`). Best-effort + bounded:
|
|
@@ -29005,6 +29071,7 @@ var AcpClient = class {
|
|
|
29005
29071
|
* the conversation — whereas one without it falls back to a fresh
|
|
29006
29072
|
* `session/new`. Set once during {@link startOnce}. */
|
|
29007
29073
|
supportsLoadSession = false;
|
|
29074
|
+
supportsListSessions = false;
|
|
29008
29075
|
/** Idle watchdog for the in-flight prompt. The `Client` handlers
|
|
29009
29076
|
* (`sessionUpdate` / `requestPermission`) reach for this to keep
|
|
29010
29077
|
* the turn alive while the adapter is demonstrably working. Null
|
|
@@ -29189,6 +29256,7 @@ var AcpClient = class {
|
|
|
29189
29256
|
`initialize \u2190 ok protocolVersion=${initialize.protocolVersion} agentCaps=${JSON.stringify(initialize.agentCapabilities ?? {}).slice(0, 200)}`
|
|
29190
29257
|
);
|
|
29191
29258
|
this.supportsLoadSession = initialize.agentCapabilities?.loadSession === true;
|
|
29259
|
+
this.supportsListSessions = !!initialize.agentCapabilities?.sessionCapabilities?.list;
|
|
29192
29260
|
log.info("acpClient", "newSession \u2192 sending");
|
|
29193
29261
|
let startupTimer;
|
|
29194
29262
|
const startupFailure = new Promise((_2, reject) => {
|
|
@@ -29432,14 +29500,44 @@ var AcpClient = class {
|
|
|
29432
29500
|
return;
|
|
29433
29501
|
}
|
|
29434
29502
|
log.info("acpClient", `loadSession \u2192 sessionId=${sessionId.slice(0, 8)}`);
|
|
29435
|
-
|
|
29436
|
-
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29503
|
+
this.opts.beginLoadReplay?.();
|
|
29504
|
+
try {
|
|
29505
|
+
await this.connection.loadSession({
|
|
29506
|
+
sessionId,
|
|
29507
|
+
cwd: this.opts.cwd,
|
|
29508
|
+
mcpServers: this.opts.mcpServers ?? []
|
|
29509
|
+
});
|
|
29510
|
+
} finally {
|
|
29511
|
+
this.opts.endLoadReplay?.();
|
|
29512
|
+
}
|
|
29440
29513
|
this.sessionId = sessionId;
|
|
29441
29514
|
log.info("acpClient", `loadSession \u2190 ok sessionId=${sessionId.slice(0, 8)}`);
|
|
29442
29515
|
}
|
|
29516
|
+
/**
|
|
29517
|
+
* Enumerate the workspace's conversations via the ACP `session/list` RPC.
|
|
29518
|
+
* Agent-agnostic — works for ANY adapter that advertises
|
|
29519
|
+
* `sessionCapabilities.list` (claude/codex/gemini alike), so the mobile RECENT
|
|
29520
|
+
* list no longer depends on per-agent JSONL scanning. Maps SessionInfo (id +
|
|
29521
|
+
* agent-authored title + updatedAt) to the backend's RECENT-list shape.
|
|
29522
|
+
*
|
|
29523
|
+
* Returns null when the agent doesn't advertise `list` (caller falls back or
|
|
29524
|
+
* skips). Best-effort — never throws out to the caller.
|
|
29525
|
+
*/
|
|
29526
|
+
async listSessions() {
|
|
29527
|
+
if (!this.connection || !this.supportsListSessions) return null;
|
|
29528
|
+
try {
|
|
29529
|
+
const res = await this.connection.listSessions({ cwd: this.opts.cwd });
|
|
29530
|
+
return (res.sessions ?? []).map((s) => ({
|
|
29531
|
+
id: s.sessionId,
|
|
29532
|
+
summary: s.title ?? "",
|
|
29533
|
+
// updatedAt is an ISO string; fall back to now on absent/unparseable.
|
|
29534
|
+
timestamp: s.updatedAt ? Date.parse(s.updatedAt) || Date.now() : Date.now()
|
|
29535
|
+
}));
|
|
29536
|
+
} catch (err) {
|
|
29537
|
+
log.trace("acpClient", "listSessions failed (best-effort)", err);
|
|
29538
|
+
return null;
|
|
29539
|
+
}
|
|
29540
|
+
}
|
|
29443
29541
|
/**
|
|
29444
29542
|
* Switch the active session's model via the non-standard
|
|
29445
29543
|
* `session/set_model` RPC. The standard ACP SDK doesn't expose
|
|
@@ -32267,17 +32365,17 @@ var AcpHistory = class {
|
|
|
32267
32365
|
async flush() {
|
|
32268
32366
|
if (this.summary === null || this.messages.length === 0) return;
|
|
32269
32367
|
const timestamp = Date.now();
|
|
32368
|
+
const current = { id: this.opts.acpSessionId, summary: this.summary, timestamp };
|
|
32369
|
+
let sessions3 = [current];
|
|
32370
|
+
const listed = this.opts.listSessions ? await this.opts.listSessions() : null;
|
|
32371
|
+
if (listed && listed.length > 0) {
|
|
32372
|
+
sessions3 = listed.map(
|
|
32373
|
+
(s) => s.id === this.opts.acpSessionId && !s.summary ? { ...s, summary: this.summary } : s
|
|
32374
|
+
);
|
|
32375
|
+
if (!sessions3.some((s) => s.id === this.opts.acpSessionId)) sessions3.unshift(current);
|
|
32376
|
+
}
|
|
32270
32377
|
await Promise.all([
|
|
32271
|
-
this.publisher.pushSessionList({
|
|
32272
|
-
agentId: this.opts.agent,
|
|
32273
|
-
sessions: [
|
|
32274
|
-
{
|
|
32275
|
-
id: this.opts.acpSessionId,
|
|
32276
|
-
summary: this.summary,
|
|
32277
|
-
timestamp
|
|
32278
|
-
}
|
|
32279
|
-
]
|
|
32280
|
-
}),
|
|
32378
|
+
this.publisher.pushSessionList({ agentId: this.opts.agent, sessions: sessions3 }),
|
|
32281
32379
|
this.publisher.pushConversation({
|
|
32282
32380
|
agentId: this.opts.agent,
|
|
32283
32381
|
sessionId: this.opts.acpSessionId,
|
|
@@ -32323,6 +32421,10 @@ function computeAdapterExtraEnv(params) {
|
|
|
32323
32421
|
);
|
|
32324
32422
|
return env;
|
|
32325
32423
|
}
|
|
32424
|
+
function pickLatestResumableConversation(sessions3, currentId) {
|
|
32425
|
+
const prior = (sessions3 ?? []).filter((s) => s.id !== currentId).sort((a, b) => b.timestamp - a.timestamp)[0];
|
|
32426
|
+
return prior?.id ?? null;
|
|
32427
|
+
}
|
|
32326
32428
|
async function runAcpSession(opts) {
|
|
32327
32429
|
const publisher = new AcpPublisher({
|
|
32328
32430
|
sessionId: opts.sessionId,
|
|
@@ -32471,16 +32573,24 @@ async function runAcpSession(opts) {
|
|
|
32471
32573
|
});
|
|
32472
32574
|
return;
|
|
32473
32575
|
}
|
|
32474
|
-
|
|
32475
|
-
|
|
32476
|
-
initialize,
|
|
32477
|
-
model: handshakeModel,
|
|
32478
|
-
tier: handshakeTier
|
|
32479
|
-
} = handshake;
|
|
32576
|
+
let acpSessionId = handshake.sessionId;
|
|
32577
|
+
const { initialize, model: handshakeModel, tier: handshakeTier } = handshake;
|
|
32480
32578
|
log.trace(
|
|
32481
32579
|
"acpRunner",
|
|
32482
32580
|
`adapter handshake ok protocolVersion=${initialize.protocolVersion} sessionId=${acpSessionId.slice(0, 8)}`
|
|
32483
32581
|
);
|
|
32582
|
+
if (process.env.CODEAM_RESUME_LATEST === "1") {
|
|
32583
|
+
try {
|
|
32584
|
+
const priorId = pickLatestResumableConversation(await client3.listSessions(), acpSessionId);
|
|
32585
|
+
if (priorId) {
|
|
32586
|
+
await client3.loadSession(priorId);
|
|
32587
|
+
acpSessionId = priorId;
|
|
32588
|
+
log.info("acpRunner", `auto-resumed latest conversation ${priorId.slice(0, 8)}`);
|
|
32589
|
+
}
|
|
32590
|
+
} catch (err) {
|
|
32591
|
+
log.trace("acpRunner", "auto-resume-latest failed (best-effort)", err);
|
|
32592
|
+
}
|
|
32593
|
+
}
|
|
32484
32594
|
showSuccess(`${opts.agent} online (ACP) \u2014 awaiting prompts from mobile.`);
|
|
32485
32595
|
showRelayNotice();
|
|
32486
32596
|
void publisher.publishOutput({
|
|
@@ -32502,7 +32612,14 @@ async function runAcpSession(opts) {
|
|
|
32502
32612
|
});
|
|
32503
32613
|
const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
|
|
32504
32614
|
const models = await runtime.listModels();
|
|
32505
|
-
const history = new AcpHistory(publisher, {
|
|
32615
|
+
const history = new AcpHistory(publisher, {
|
|
32616
|
+
agent: opts.agent,
|
|
32617
|
+
acpSessionId,
|
|
32618
|
+
// Agent-agnostic RECENT list: enumerate via the ACP session/list RPC (any
|
|
32619
|
+
// adapter advertising sessionCapabilities.list). Returns null on unsupported
|
|
32620
|
+
// agents → flush() falls back to the current session only.
|
|
32621
|
+
listSessions: () => client3.listSessions()
|
|
32622
|
+
});
|
|
32506
32623
|
const jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
|
|
32507
32624
|
pluginAuthToken: opts.pluginAuthToken
|
|
32508
32625
|
});
|
|
@@ -37277,7 +37394,7 @@ function checkChokidar() {
|
|
|
37277
37394
|
}
|
|
37278
37395
|
async function doctor(args2 = []) {
|
|
37279
37396
|
const json = args2.includes("--json");
|
|
37280
|
-
const cliVersion = true ? "2.61.
|
|
37397
|
+
const cliVersion = true ? "2.61.8" : "0.0.0-dev";
|
|
37281
37398
|
const apiBase2 = resolveApiBaseUrl();
|
|
37282
37399
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
37283
37400
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -37788,7 +37905,7 @@ async function mcpRun(args2) {
|
|
|
37788
37905
|
// src/commands/version.ts
|
|
37789
37906
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
37790
37907
|
function version2() {
|
|
37791
|
-
const v = true ? "2.61.
|
|
37908
|
+
const v = true ? "2.61.8" : "unknown";
|
|
37792
37909
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
37793
37910
|
}
|
|
37794
37911
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// src/postinstall.ts
|
|
5
|
+
var c = {
|
|
6
|
+
reset: "\x1B[0m",
|
|
7
|
+
bold: "\x1B[1m",
|
|
8
|
+
dim: "\x1B[2m",
|
|
9
|
+
green: "\x1B[32m",
|
|
10
|
+
cyan: "\x1B[36m",
|
|
11
|
+
violet: "\x1B[35m",
|
|
12
|
+
white: "\x1B[97m"
|
|
13
|
+
};
|
|
14
|
+
var lines = [
|
|
15
|
+
"",
|
|
16
|
+
` ${c.violet}${c.bold}codeam-cli${c.reset} ${c.dim}\u2014 Claude Code remote control${c.reset}`,
|
|
17
|
+
"",
|
|
18
|
+
` ${c.dim}1.${c.reset} Pair your phone:`,
|
|
19
|
+
` ${c.cyan}codeam pair${c.reset}`,
|
|
20
|
+
"",
|
|
21
|
+
` ${c.dim}2.${c.reset} Launch Claude Code with mobile control:`,
|
|
22
|
+
` ${c.cyan}codeam${c.reset}`,
|
|
23
|
+
"",
|
|
24
|
+
` ${c.dim}Other commands:${c.reset}`,
|
|
25
|
+
` ${c.white}codeam sessions${c.reset} ${c.dim}list paired devices${c.reset}`,
|
|
26
|
+
` ${c.white}codeam status${c.reset} ${c.dim}show connection info${c.reset}`,
|
|
27
|
+
` ${c.white}codeam logout${c.reset} ${c.dim}remove all sessions${c.reset}`,
|
|
28
|
+
"",
|
|
29
|
+
` ${c.dim}Requires Claude Code:${c.reset} ${c.green}npm install -g @anthropic-ai/claude-code${c.reset}`,
|
|
30
|
+
` ${c.dim}Mobile app:${c.reset} ${c.green}https://www.codeagent-mobile.com${c.reset}`,
|
|
31
|
+
""
|
|
32
|
+
];
|
|
33
|
+
process.stdout.write(lines.join("\n") + "\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.61.
|
|
3
|
+
"version": "2.61.8",
|
|
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",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"url": "https://github.com/sponsors/edgar-durand"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
72
|
-
"node": ">=
|
|
72
|
+
"node": ">=22.0.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@agentclientprotocol/claude-agent-acp": "0.59.0",
|