codeam-cli 2.61.43 → 2.61.45
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 +161 -8
- package/package.json +2 -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.61.44] — 2026-07-25
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **shared:** Resend integration — api_key (send-only comms), excluded from From-Conversation
|
|
12
|
+
|
|
13
|
+
## [2.61.43] — 2026-07-25
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **shared:** Discord comms integration — OAuth bot-invite, guildId discriminator
|
|
18
|
+
|
|
7
19
|
## [2.61.42] — 2026-07-25
|
|
8
20
|
|
|
9
21
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
@@ -86,6 +89,67 @@ var require_src = __commonJS({
|
|
|
86
89
|
}
|
|
87
90
|
});
|
|
88
91
|
|
|
92
|
+
// src/integrations/http-relay.ts
|
|
93
|
+
var http_relay_exports = {};
|
|
94
|
+
__export(http_relay_exports, {
|
|
95
|
+
buildHttpHeaders: () => buildHttpHeaders,
|
|
96
|
+
runHttpRelay: () => runHttpRelay
|
|
97
|
+
});
|
|
98
|
+
function buildHttpHeaders(httpHeaders, token) {
|
|
99
|
+
const headers = {};
|
|
100
|
+
for (const [name, template] of Object.entries(httpHeaders ?? {})) {
|
|
101
|
+
headers[name] = template.replace(/\{(\w+)\}/g, (_m, field) => {
|
|
102
|
+
const v = token[field];
|
|
103
|
+
return typeof v === "string" ? v : "";
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return headers;
|
|
107
|
+
}
|
|
108
|
+
async function runHttpRelay(delivery, client3, id) {
|
|
109
|
+
if (!delivery.httpUrl) throw new Error("runHttpRelay called without delivery.httpUrl");
|
|
110
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
111
|
+
const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
112
|
+
const token = await client3.getToken(id);
|
|
113
|
+
const httpTransport = new StreamableHTTPClientTransport(new URL(delivery.httpUrl), {
|
|
114
|
+
requestInit: { headers: buildHttpHeaders(delivery.httpHeaders, token) }
|
|
115
|
+
});
|
|
116
|
+
const stdioTransport = new StdioServerTransport();
|
|
117
|
+
await new Promise((resolve8, reject) => {
|
|
118
|
+
let done = false;
|
|
119
|
+
const finish = (err) => {
|
|
120
|
+
if (done) return;
|
|
121
|
+
done = true;
|
|
122
|
+
void httpTransport.close().catch(() => void 0);
|
|
123
|
+
void stdioTransport.close().catch(() => void 0);
|
|
124
|
+
if (err) reject(err);
|
|
125
|
+
else resolve8();
|
|
126
|
+
};
|
|
127
|
+
stdioTransport.onmessage = (msg) => {
|
|
128
|
+
void httpTransport.send(msg).catch((e) => {
|
|
129
|
+
process.stderr.write(`[mcp-run http] send\u2192remote failed: ${String(e)}
|
|
130
|
+
`);
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
httpTransport.onmessage = (msg) => {
|
|
134
|
+
void stdioTransport.send(msg).catch(() => void 0);
|
|
135
|
+
};
|
|
136
|
+
stdioTransport.onclose = () => finish();
|
|
137
|
+
httpTransport.onclose = () => finish();
|
|
138
|
+
stdioTransport.onerror = (e) => process.stderr.write(`[mcp-run http] stdio: ${String(e)}
|
|
139
|
+
`);
|
|
140
|
+
httpTransport.onerror = (e) => process.stderr.write(`[mcp-run http] http: ${String(e)}
|
|
141
|
+
`);
|
|
142
|
+
Promise.all([httpTransport.start(), stdioTransport.start()]).catch(
|
|
143
|
+
(e) => finish(e instanceof Error ? e : new Error(String(e)))
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
var init_http_relay = __esm({
|
|
148
|
+
"src/integrations/http-relay.ts"() {
|
|
149
|
+
"use strict";
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
89
153
|
// src/commands/start.ts
|
|
90
154
|
var import_picocolors4 = __toESM(require("picocolors"));
|
|
91
155
|
|
|
@@ -815,6 +879,83 @@ var INTEGRATION_REGISTRY = {
|
|
|
815
879
|
}
|
|
816
880
|
}
|
|
817
881
|
},
|
|
882
|
+
resend: {
|
|
883
|
+
id: "resend",
|
|
884
|
+
name: "Resend",
|
|
885
|
+
icon: "resend",
|
|
886
|
+
category: "comms",
|
|
887
|
+
// LIVE — api_key (like Azure DevOps): the user pastes a Resend API key
|
|
888
|
+
// (`re_…`); Resend has NO OAuth, so there's no OAuth app / GSM secret /
|
|
889
|
+
// config-gated 503 — a backend VALIDATOR proves the key against the Resend
|
|
890
|
+
// API and vaults it. ⚠️ SEND-ONLY email → `sendOnly: true` keeps it OUT of
|
|
891
|
+
// From-Conversation (comms conversation sources need readable threads; Resend
|
|
892
|
+
// has none) while still being a linkable comms tool the agent uses via MCP.
|
|
893
|
+
enabled: true,
|
|
894
|
+
sendOnly: true,
|
|
895
|
+
auth: {
|
|
896
|
+
kind: "api_key",
|
|
897
|
+
fields: [
|
|
898
|
+
{
|
|
899
|
+
key: "accessToken",
|
|
900
|
+
label: "API Key",
|
|
901
|
+
placeholder: "re_xxxxxxxxxxxxxxxx",
|
|
902
|
+
secret: true,
|
|
903
|
+
help: 'Create in Resend \u2192 API Keys (https://resend.com/api-keys). "Sending access" is enough.'
|
|
904
|
+
}
|
|
905
|
+
]
|
|
906
|
+
},
|
|
907
|
+
delivery: {
|
|
908
|
+
mcp: {
|
|
909
|
+
// The OFFICIAL resend-mcp (Node) in BYO-token mode: the API key is fed
|
|
910
|
+
// via RESEND_API_KEY (env only, never argv). Version PINNED; bump only
|
|
911
|
+
// after re-verifying headless. Tools: send email + contacts/broadcasts/
|
|
912
|
+
// domains.
|
|
913
|
+
command: "npx",
|
|
914
|
+
args: ["-y", "resend-mcp@2.6.1"],
|
|
915
|
+
envMapping: {
|
|
916
|
+
RESEND_API_KEY: "accessToken"
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
posthog: {
|
|
922
|
+
id: "posthog",
|
|
923
|
+
name: "PostHog",
|
|
924
|
+
icon: "posthog",
|
|
925
|
+
category: "observability",
|
|
926
|
+
// LIVE — api_key: the user pastes a PostHog Personal API Key (phx_…, created
|
|
927
|
+
// with the "MCP Server" preset). PostHog's MCP is HOSTED-ONLY
|
|
928
|
+
// (mcp.posthog.com) over HTTP, and its stdio bridge (mcp-remote) forces its
|
|
929
|
+
// own browser OAuth — incompatible with our headless broker. So delivery
|
|
930
|
+
// uses the shim's HTTP transport: it relays to the hosted MCP with the key
|
|
931
|
+
// as a Bearer header (exactly Cursor's {url, headers} config). No OAuth, no
|
|
932
|
+
// GSM secret; a backend VALIDATOR proves the key + vaults it.
|
|
933
|
+
enabled: true,
|
|
934
|
+
auth: {
|
|
935
|
+
kind: "api_key",
|
|
936
|
+
fields: [
|
|
937
|
+
{
|
|
938
|
+
key: "accessToken",
|
|
939
|
+
label: "Personal API Key",
|
|
940
|
+
placeholder: "phx_xxxxxxxxxxxxxxxx",
|
|
941
|
+
secret: true,
|
|
942
|
+
help: 'PostHog \u2192 Settings \u2192 Personal API keys \u2192 create with the "MCP Server" preset (scopes it to a project).'
|
|
943
|
+
}
|
|
944
|
+
]
|
|
945
|
+
},
|
|
946
|
+
delivery: {
|
|
947
|
+
mcp: {
|
|
948
|
+
// HTTP transport (not a spawned stdio server) — the shim relays to
|
|
949
|
+
// PostHog's hosted MCP with the key as a Bearer header. The key stays
|
|
950
|
+
// server-side of the shim, never on argv.
|
|
951
|
+
command: "",
|
|
952
|
+
args: [],
|
|
953
|
+
envMapping: {},
|
|
954
|
+
httpUrl: "https://mcp.posthog.com/mcp",
|
|
955
|
+
httpHeaders: { Authorization: "Bearer {accessToken}" }
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
},
|
|
818
959
|
notion: {
|
|
819
960
|
id: "notion",
|
|
820
961
|
name: "Notion",
|
|
@@ -6383,7 +6524,7 @@ function readAnonId() {
|
|
|
6383
6524
|
}
|
|
6384
6525
|
function superProperties() {
|
|
6385
6526
|
return {
|
|
6386
|
-
cliVersion: true ? "2.61.
|
|
6527
|
+
cliVersion: true ? "2.61.45" : "0.0.0-dev",
|
|
6387
6528
|
nodeVersion: process.version,
|
|
6388
6529
|
platform: process.platform,
|
|
6389
6530
|
arch: process.arch,
|
|
@@ -6564,7 +6705,7 @@ var os4 = __toESM(require("os"));
|
|
|
6564
6705
|
// package.json
|
|
6565
6706
|
var package_default = {
|
|
6566
6707
|
name: "codeam-cli",
|
|
6567
|
-
version: "2.61.
|
|
6708
|
+
version: "2.61.45",
|
|
6568
6709
|
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.",
|
|
6569
6710
|
type: "commonjs",
|
|
6570
6711
|
main: "dist/index.js",
|
|
@@ -6640,6 +6781,7 @@ var package_default = {
|
|
|
6640
6781
|
"@agentclientprotocol/codex-acp": "1.1.4",
|
|
6641
6782
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
6642
6783
|
"@clack/prompts": "^1.2.0",
|
|
6784
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
6643
6785
|
chokidar: "^3.6.0",
|
|
6644
6786
|
ignore: "^7.0.6",
|
|
6645
6787
|
picocolors: "^1.1.0",
|
|
@@ -7735,7 +7877,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
7735
7877
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7736
7878
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7737
7879
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7738
|
-
..."2.61.
|
|
7880
|
+
..."2.61.45" ? { ideVersion: "2.61.45" } : {}
|
|
7739
7881
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7740
7882
|
}
|
|
7741
7883
|
/**
|
|
@@ -18720,7 +18862,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
18720
18862
|
if (process.env.NODE_ENV === "test") return;
|
|
18721
18863
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18722
18864
|
if (process.env.CI) return;
|
|
18723
|
-
const current = true ? "2.61.
|
|
18865
|
+
const current = true ? "2.61.45" : null;
|
|
18724
18866
|
if (!current) return;
|
|
18725
18867
|
const cache = readCache();
|
|
18726
18868
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18737,7 +18879,7 @@ function checkForUpdates() {
|
|
|
18737
18879
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18738
18880
|
if (process.env.CI) return;
|
|
18739
18881
|
if (!process.stdout.isTTY) return;
|
|
18740
|
-
const current = true ? "2.61.
|
|
18882
|
+
const current = true ? "2.61.45" : null;
|
|
18741
18883
|
if (!current) return;
|
|
18742
18884
|
const cache = readCache();
|
|
18743
18885
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18757,7 +18899,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
18757
18899
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
18758
18900
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
18759
18901
|
function currentCliVersion() {
|
|
18760
|
-
return true ? "2.61.
|
|
18902
|
+
return true ? "2.61.45" : null;
|
|
18761
18903
|
}
|
|
18762
18904
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18763
18905
|
return new Promise((resolve8) => {
|
|
@@ -38883,7 +39025,7 @@ function checkChokidar() {
|
|
|
38883
39025
|
}
|
|
38884
39026
|
async function doctor(args2 = []) {
|
|
38885
39027
|
const json = args2.includes("--json");
|
|
38886
|
-
const cliVersion = true ? "2.61.
|
|
39028
|
+
const cliVersion = true ? "2.61.45" : "0.0.0-dev";
|
|
38887
39029
|
const apiBase2 = resolveApiBaseUrl();
|
|
38888
39030
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
38889
39031
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -39367,6 +39509,17 @@ async function mcpRun(args2) {
|
|
|
39367
39509
|
`);
|
|
39368
39510
|
process.exit(1);
|
|
39369
39511
|
}
|
|
39512
|
+
if (delivery.httpUrl) {
|
|
39513
|
+
const httpClient = new IntegrationTokenClient({
|
|
39514
|
+
sessionId,
|
|
39515
|
+
pluginId,
|
|
39516
|
+
pluginAuthToken,
|
|
39517
|
+
pollSecret: process.env.CODEAM_MCP_POLL_SECRET
|
|
39518
|
+
});
|
|
39519
|
+
const { runHttpRelay: runHttpRelay2 } = await Promise.resolve().then(() => (init_http_relay(), http_relay_exports));
|
|
39520
|
+
await runHttpRelay2(delivery, httpClient, id);
|
|
39521
|
+
return;
|
|
39522
|
+
}
|
|
39370
39523
|
ensureCommand(delivery.command);
|
|
39371
39524
|
const launcher = resolveLauncherPath(delivery.command);
|
|
39372
39525
|
const client3 = new IntegrationTokenClient({
|
|
@@ -39394,7 +39547,7 @@ async function mcpRun(args2) {
|
|
|
39394
39547
|
// src/commands/version.ts
|
|
39395
39548
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
39396
39549
|
function version2() {
|
|
39397
|
-
const v = true ? "2.61.
|
|
39550
|
+
const v = true ? "2.61.45" : "unknown";
|
|
39398
39551
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
39399
39552
|
}
|
|
39400
39553
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.61.
|
|
3
|
+
"version": "2.61.45",
|
|
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",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"@agentclientprotocol/codex-acp": "1.1.4",
|
|
77
77
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
78
78
|
"@clack/prompts": "^1.2.0",
|
|
79
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
79
80
|
"chokidar": "^3.6.0",
|
|
80
81
|
"ignore": "^7.0.6",
|
|
81
82
|
"picocolors": "^1.1.0",
|