codeam-cli 2.26.14 → 2.26.16
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 +88 -6
- package/package.json +1 -1
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.26.15] — 2026-06-05
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Refuse to link Codex when local auth.json is already expired (#258)
|
|
12
|
+
|
|
13
|
+
## [2.26.14] — 2026-06-04
|
|
14
|
+
|
|
15
|
+
### Chore
|
|
16
|
+
|
|
17
|
+
- **deps:** Bump actions/setup-node from 4 to 6 (#246)
|
|
18
|
+
- **deps:** Bump actions/checkout from 4 to 6 (#247)
|
|
19
|
+
- **deps:** Bump org.jetbrains.kotlin.jvm in /apps/jetbrains-plugin (#248)
|
|
20
|
+
- **cli:** Bump which 2.0.2 → 5.0.0 (#251)
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **cli:** Drop redundant install from agent setup_commands + warn agent (#256)
|
|
25
|
+
|
|
7
26
|
## [2.26.13] — 2026-06-04
|
|
8
27
|
|
|
9
28
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -486,7 +486,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
486
486
|
// package.json
|
|
487
487
|
var package_default = {
|
|
488
488
|
name: "codeam-cli",
|
|
489
|
-
version: "2.26.
|
|
489
|
+
version: "2.26.16",
|
|
490
490
|
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.",
|
|
491
491
|
type: "commonjs",
|
|
492
492
|
main: "dist/index.js",
|
|
@@ -787,6 +787,21 @@ async function postLinkCredential(input) {
|
|
|
787
787
|
};
|
|
788
788
|
}
|
|
789
789
|
}
|
|
790
|
+
async function postLinkErrorSignal(input) {
|
|
791
|
+
try {
|
|
792
|
+
await _transport.postJsonAuthed(
|
|
793
|
+
`${API_BASE}/api/plugin/agents/${input.agentId}/link-error`,
|
|
794
|
+
{
|
|
795
|
+
sessionId: input.sessionId,
|
|
796
|
+
pluginId: input.pluginId,
|
|
797
|
+
code: input.code,
|
|
798
|
+
reason: input.reason
|
|
799
|
+
},
|
|
800
|
+
input.pluginAuthToken
|
|
801
|
+
);
|
|
802
|
+
} catch {
|
|
803
|
+
}
|
|
804
|
+
}
|
|
790
805
|
async function postAiResult(input) {
|
|
791
806
|
const body = {
|
|
792
807
|
sessionId: input.sessionId,
|
|
@@ -5843,7 +5858,7 @@ function readAnonId() {
|
|
|
5843
5858
|
}
|
|
5844
5859
|
function superProperties() {
|
|
5845
5860
|
return {
|
|
5846
|
-
cliVersion: true ? "2.26.
|
|
5861
|
+
cliVersion: true ? "2.26.16" : "0.0.0-dev",
|
|
5847
5862
|
nodeVersion: process.version,
|
|
5848
5863
|
platform: process.platform,
|
|
5849
5864
|
arch: process.arch,
|
|
@@ -10888,6 +10903,40 @@ async function extractLocalCodexToken() {
|
|
|
10888
10903
|
function codexCredentialsPaths() {
|
|
10889
10904
|
return [codexCredentialsPath()];
|
|
10890
10905
|
}
|
|
10906
|
+
function validateLocalCodexToken(credential) {
|
|
10907
|
+
let parsed;
|
|
10908
|
+
try {
|
|
10909
|
+
parsed = JSON.parse(credential);
|
|
10910
|
+
} catch {
|
|
10911
|
+
return { status: "unknown" };
|
|
10912
|
+
}
|
|
10913
|
+
const directExp = typeof parsed.expires_at === "number" ? parsed.expires_at : typeof parsed.tokens?.expires_at === "number" ? parsed.tokens.expires_at : void 0;
|
|
10914
|
+
const jwtExp = decodeJwtExp(parsed.tokens?.id_token);
|
|
10915
|
+
const exp = directExp ?? jwtExp;
|
|
10916
|
+
if (exp === void 0) return { status: "unknown" };
|
|
10917
|
+
const expiresAt = exp < 1e12 ? exp * 1e3 : exp;
|
|
10918
|
+
if (Date.now() >= expiresAt) {
|
|
10919
|
+
return {
|
|
10920
|
+
status: "expired",
|
|
10921
|
+
reason: "Codex OAuth access token expired",
|
|
10922
|
+
expiresAt
|
|
10923
|
+
};
|
|
10924
|
+
}
|
|
10925
|
+
return { status: "valid", expiresAt };
|
|
10926
|
+
}
|
|
10927
|
+
function decodeJwtExp(jwt) {
|
|
10928
|
+
if (!jwt) return void 0;
|
|
10929
|
+
const parts = jwt.split(".");
|
|
10930
|
+
if (parts.length !== 3) return void 0;
|
|
10931
|
+
try {
|
|
10932
|
+
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
10933
|
+
const padded = base64 + "===".slice((base64.length + 3) % 4);
|
|
10934
|
+
const payload = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
|
|
10935
|
+
return typeof payload.exp === "number" ? payload.exp : void 0;
|
|
10936
|
+
} catch {
|
|
10937
|
+
return void 0;
|
|
10938
|
+
}
|
|
10939
|
+
}
|
|
10891
10940
|
|
|
10892
10941
|
// src/agents/codex/link.ts
|
|
10893
10942
|
function codexCredentialLocator() {
|
|
@@ -10896,7 +10945,11 @@ function codexCredentialLocator() {
|
|
|
10896
10945
|
vendor: "OpenAI",
|
|
10897
10946
|
hint: "~/.codex/auth.json",
|
|
10898
10947
|
watchPaths: codexCredentialsPaths,
|
|
10899
|
-
extract: extractLocalCodexToken
|
|
10948
|
+
extract: extractLocalCodexToken,
|
|
10949
|
+
validate: (token) => {
|
|
10950
|
+
const result = validateLocalCodexToken(token.credential);
|
|
10951
|
+
return { status: result.status, reason: result.reason };
|
|
10952
|
+
}
|
|
10900
10953
|
};
|
|
10901
10954
|
}
|
|
10902
10955
|
function codexLoginLauncher() {
|
|
@@ -15907,6 +15960,7 @@ async function link(args2 = []) {
|
|
|
15907
15960
|
installSpin.stop(`${ctx.displayName} is installed`);
|
|
15908
15961
|
const existing = await ctx.locator.extract();
|
|
15909
15962
|
if (existing) {
|
|
15963
|
+
if (await refuseIfStale(ctx, paired, pluginId, existing)) return;
|
|
15910
15964
|
showInfo(`Found existing ${ctx.displayName} credentials at ${import_picocolors2.default.bold(existing.source)}.`);
|
|
15911
15965
|
await uploadAndSucceed(ctx, paired, pluginId, existing);
|
|
15912
15966
|
return;
|
|
@@ -15923,8 +15977,36 @@ async function link(args2 = []) {
|
|
|
15923
15977
|
console.log("");
|
|
15924
15978
|
const captured = await captureFreshCredentials(ctx);
|
|
15925
15979
|
console.log("");
|
|
15980
|
+
if (await refuseIfStale(ctx, paired, pluginId, captured)) return;
|
|
15926
15981
|
await uploadAndSucceed(ctx, paired, pluginId, captured);
|
|
15927
15982
|
}
|
|
15983
|
+
async function refuseIfStale(ctx, paired, pluginId, token) {
|
|
15984
|
+
const verdict = ctx.locator.validate?.(token);
|
|
15985
|
+
if (!verdict || verdict.status !== "expired") return false;
|
|
15986
|
+
const reason = verdict.reason ?? "Token expired";
|
|
15987
|
+
if (paired.pluginAuthToken) {
|
|
15988
|
+
await postLinkErrorSignal({
|
|
15989
|
+
agentId: ctx.locator.publicId,
|
|
15990
|
+
sessionId: paired.sessionId,
|
|
15991
|
+
pluginId,
|
|
15992
|
+
pluginAuthToken: paired.pluginAuthToken,
|
|
15993
|
+
code: "credentials_expired",
|
|
15994
|
+
reason
|
|
15995
|
+
});
|
|
15996
|
+
}
|
|
15997
|
+
showError(
|
|
15998
|
+
`Your local ${ctx.displayName} credentials at ${import_picocolors2.default.bold(ctx.locator.hint)} are already expired:
|
|
15999
|
+
${reason}
|
|
16000
|
+
|
|
16001
|
+
Uploading them would land a dead snapshot in the vault \u2014 every codespace bootstrapped from it would immediately return 401.
|
|
16002
|
+
|
|
16003
|
+
Run on your machine, then re-link:
|
|
16004
|
+
${import_picocolors2.default.cyan(`${ctx.binary} logout`)}
|
|
16005
|
+
${import_picocolors2.default.cyan(`${ctx.binary} login`)}
|
|
16006
|
+
${import_picocolors2.default.cyan(`codeam link ${ctx.locator.publicId}`)}`
|
|
16007
|
+
);
|
|
16008
|
+
process.exit(1);
|
|
16009
|
+
}
|
|
15928
16010
|
async function captureFreshCredentials(ctx) {
|
|
15929
16011
|
const isWin = ctx.runtime.os.id === "win32";
|
|
15930
16012
|
const watcher = import_chokidar.default.watch(ctx.locator.watchPaths(), {
|
|
@@ -20257,7 +20339,7 @@ function checkChokidar() {
|
|
|
20257
20339
|
}
|
|
20258
20340
|
async function doctor(args2 = []) {
|
|
20259
20341
|
const json = args2.includes("--json");
|
|
20260
|
-
const cliVersion = true ? "2.26.
|
|
20342
|
+
const cliVersion = true ? "2.26.16" : "0.0.0-dev";
|
|
20261
20343
|
const apiBase = resolveApiBaseUrl();
|
|
20262
20344
|
const diagnosticId = (0, import_node_crypto6.randomUUID)();
|
|
20263
20345
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -20456,7 +20538,7 @@ async function completion(args2) {
|
|
|
20456
20538
|
// src/commands/version.ts
|
|
20457
20539
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
20458
20540
|
function version2() {
|
|
20459
|
-
const v = true ? "2.26.
|
|
20541
|
+
const v = true ? "2.26.16" : "unknown";
|
|
20460
20542
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
20461
20543
|
}
|
|
20462
20544
|
|
|
@@ -20684,7 +20766,7 @@ function checkForUpdates() {
|
|
|
20684
20766
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
20685
20767
|
if (process.env.CI) return;
|
|
20686
20768
|
if (!process.stdout.isTTY) return;
|
|
20687
|
-
const current = true ? "2.26.
|
|
20769
|
+
const current = true ? "2.26.16" : null;
|
|
20688
20770
|
if (!current) return;
|
|
20689
20771
|
const cache = readCache();
|
|
20690
20772
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.26.
|
|
3
|
+
"version": "2.26.16",
|
|
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",
|