@codeam/shared 2.54.0
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 +5 -0
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/index.d.mts +1117 -0
- package/dist/index.d.ts +1117 -0
- package/dist/index.js +700 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +631 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +50 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AGENT_REGISTRY: () => AGENT_REGISTRY,
|
|
24
|
+
DEFAULT_API_BASE_URL: () => DEFAULT_API_BASE_URL,
|
|
25
|
+
DEV_API_BASE_URL: () => DEV_API_BASE_URL,
|
|
26
|
+
HEADROOM_BACKEND_ENV: () => HEADROOM_BACKEND_ENV,
|
|
27
|
+
HEADROOM_EXTRAS_BY_SURFACE: () => HEADROOM_EXTRAS_BY_SURFACE,
|
|
28
|
+
HEADROOM_MODELS: () => HEADROOM_MODELS,
|
|
29
|
+
HEADROOM_PIP_COMPANIONS: () => HEADROOM_PIP_COMPANIONS,
|
|
30
|
+
HEADROOM_PROXY_PORT: () => HEADROOM_PROXY_PORT,
|
|
31
|
+
HEARTBEAT_INTERVAL_MS_DEFAULT: () => HEARTBEAT_INTERVAL_MS_DEFAULT,
|
|
32
|
+
HOUSE_AGENT_ID: () => HOUSE_AGENT_ID,
|
|
33
|
+
HOUSE_AGENT_NAME: () => HOUSE_AGENT_NAME,
|
|
34
|
+
HOUSE_AGENT_PROVIDER: () => HOUSE_AGENT_PROVIDER,
|
|
35
|
+
HOUSE_AGENT_SUBTITLE: () => HOUSE_AGENT_SUBTITLE,
|
|
36
|
+
HOUSE_AGENT_VENDOR: () => HOUSE_AGENT_VENDOR,
|
|
37
|
+
INTERNAL_TO_PUBLIC: () => INTERNAL_TO_PUBLIC,
|
|
38
|
+
LINKED_AGENT_IDS: () => LINKED_AGENT_IDS,
|
|
39
|
+
MODEL_CONTEXT_WINDOW: () => MODEL_CONTEXT_WINDOW,
|
|
40
|
+
MODEL_PRICING: () => MODEL_PRICING,
|
|
41
|
+
OBSERVER_BRIDGE_PORT: () => OBSERVER_BRIDGE_PORT,
|
|
42
|
+
PREVIEW_DETECT_PROMPT: () => PREVIEW_DETECT_PROMPT,
|
|
43
|
+
PROTOCOL_VERSION: () => PROTOCOL_VERSION,
|
|
44
|
+
PUBLIC_TO_INTERNAL: () => PUBLIC_TO_INTERNAL,
|
|
45
|
+
SSE_SOCKET_TIMEOUT_MS: () => SSE_SOCKET_TIMEOUT_MS,
|
|
46
|
+
TERMINAL_AGENT_PREFIX: () => TERMINAL_AGENT_PREFIX,
|
|
47
|
+
USER_EVENTS: () => USER_EVENTS,
|
|
48
|
+
getAgent: () => getAgent,
|
|
49
|
+
getContextWindow: () => getContextWindow,
|
|
50
|
+
getEnabledAgents: () => getEnabledAgents,
|
|
51
|
+
getPricing: () => getPricing,
|
|
52
|
+
headroomKindFor: () => headroomKindFor,
|
|
53
|
+
headroomModelPredownloadScript: () => headroomModelPredownloadScript,
|
|
54
|
+
headroomPipPackage: () => headroomPipPackage,
|
|
55
|
+
headroomSnapshotDownloadLine: () => headroomSnapshotDownloadLine,
|
|
56
|
+
internalToPublic: () => internalToPublic,
|
|
57
|
+
isHeadroomWrappable: () => isHeadroomWrappable,
|
|
58
|
+
isKnownAgentId: () => isKnownAgentId,
|
|
59
|
+
isKnownModel: () => isKnownModel,
|
|
60
|
+
isLinkedAgentId: () => isLinkedAgentId,
|
|
61
|
+
normalizeAgentId: () => normalizeAgentId,
|
|
62
|
+
publicToInternal: () => publicToInternal,
|
|
63
|
+
renderToLines: () => renderToLines,
|
|
64
|
+
resolveApiBaseUrl: () => resolveApiBaseUrl,
|
|
65
|
+
toRemoteCommand: () => toRemoteCommand
|
|
66
|
+
});
|
|
67
|
+
module.exports = __toCommonJS(index_exports);
|
|
68
|
+
|
|
69
|
+
// src/protocol/constants.ts
|
|
70
|
+
var PROTOCOL_VERSION = "2.0.0";
|
|
71
|
+
var OBSERVER_BRIDGE_PORT = 47832;
|
|
72
|
+
var HEARTBEAT_INTERVAL_MS_DEFAULT = 3e4;
|
|
73
|
+
var SSE_SOCKET_TIMEOUT_MS = 35e3;
|
|
74
|
+
|
|
75
|
+
// src/protocol/renderToLines.ts
|
|
76
|
+
function renderToLines(raw) {
|
|
77
|
+
const screen = [""];
|
|
78
|
+
let row = 0;
|
|
79
|
+
let col = 0;
|
|
80
|
+
function ensureRow() {
|
|
81
|
+
while (screen.length <= row) screen.push("");
|
|
82
|
+
}
|
|
83
|
+
function writeChar(ch) {
|
|
84
|
+
ensureRow();
|
|
85
|
+
if (col < screen[row].length) {
|
|
86
|
+
screen[row] = screen[row].slice(0, col) + ch + screen[row].slice(col + 1);
|
|
87
|
+
} else {
|
|
88
|
+
while (screen[row].length < col) screen[row] += " ";
|
|
89
|
+
screen[row] += ch;
|
|
90
|
+
}
|
|
91
|
+
col++;
|
|
92
|
+
}
|
|
93
|
+
let i = 0;
|
|
94
|
+
while (i < raw.length) {
|
|
95
|
+
const ch = raw[i];
|
|
96
|
+
if (ch === "\x1B") {
|
|
97
|
+
i++;
|
|
98
|
+
if (i >= raw.length) break;
|
|
99
|
+
if (raw[i] === "[") {
|
|
100
|
+
i++;
|
|
101
|
+
let param = "";
|
|
102
|
+
while (i < raw.length && !/[@-~]/.test(raw[i])) param += raw[i++];
|
|
103
|
+
const cmd = raw[i] ?? "";
|
|
104
|
+
const n = parseInt(param) || 1;
|
|
105
|
+
if (cmd === "A") {
|
|
106
|
+
row = Math.max(0, row - n);
|
|
107
|
+
} else if (cmd === "B") {
|
|
108
|
+
row += n;
|
|
109
|
+
ensureRow();
|
|
110
|
+
} else if (cmd === "C") {
|
|
111
|
+
col += n;
|
|
112
|
+
} else if (cmd === "D") {
|
|
113
|
+
col = Math.max(0, col - n);
|
|
114
|
+
} else if (cmd === "G") {
|
|
115
|
+
col = Math.max(0, n - 1);
|
|
116
|
+
} else if (cmd === "H" || cmd === "f") {
|
|
117
|
+
const p = param.split(";");
|
|
118
|
+
row = Math.max(0, (parseInt(p[0] ?? "1") || 1) - 1);
|
|
119
|
+
col = Math.max(0, (parseInt(p[1] ?? "1") || 1) - 1);
|
|
120
|
+
ensureRow();
|
|
121
|
+
} else if (cmd === "J") {
|
|
122
|
+
if (param === "2" || param === "3") {
|
|
123
|
+
screen.length = 1;
|
|
124
|
+
screen[0] = "";
|
|
125
|
+
row = 0;
|
|
126
|
+
col = 0;
|
|
127
|
+
} else if (param === "1") {
|
|
128
|
+
for (let r = 0; r < row; r++) screen[r] = "";
|
|
129
|
+
screen[row] = " ".repeat(col) + screen[row].slice(col);
|
|
130
|
+
} else {
|
|
131
|
+
screen[row] = screen[row].slice(0, col);
|
|
132
|
+
screen.splice(row + 1);
|
|
133
|
+
}
|
|
134
|
+
} else if (cmd === "K") {
|
|
135
|
+
ensureRow();
|
|
136
|
+
if (param === "" || param === "0") screen[row] = screen[row].slice(0, col);
|
|
137
|
+
else if (param === "1") screen[row] = " ".repeat(col) + screen[row].slice(col);
|
|
138
|
+
else if (param === "2") screen[row] = "";
|
|
139
|
+
} else if (cmd === "h" && (param === "?1049" || param === "?47")) {
|
|
140
|
+
screen.length = 1;
|
|
141
|
+
screen[0] = "";
|
|
142
|
+
row = 0;
|
|
143
|
+
col = 0;
|
|
144
|
+
} else if (cmd === "l" && (param === "?1049" || param === "?47")) {
|
|
145
|
+
screen.length = 1;
|
|
146
|
+
screen[0] = "";
|
|
147
|
+
row = 0;
|
|
148
|
+
col = 0;
|
|
149
|
+
}
|
|
150
|
+
} else if (raw[i] === "]") {
|
|
151
|
+
i++;
|
|
152
|
+
while (i < raw.length) {
|
|
153
|
+
if (raw[i] === "\x07") break;
|
|
154
|
+
if (raw[i] === "\x1B" && i + 1 < raw.length && raw[i + 1] === "\\") {
|
|
155
|
+
i++;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else if (ch === "\r") {
|
|
162
|
+
if (i + 1 < raw.length && raw[i + 1] === "\n") {
|
|
163
|
+
row++;
|
|
164
|
+
col = 0;
|
|
165
|
+
ensureRow();
|
|
166
|
+
i++;
|
|
167
|
+
} else {
|
|
168
|
+
col = 0;
|
|
169
|
+
}
|
|
170
|
+
} else if (ch === "\n") {
|
|
171
|
+
row++;
|
|
172
|
+
col = 0;
|
|
173
|
+
ensureRow();
|
|
174
|
+
} else if (ch >= " " || ch === " ") {
|
|
175
|
+
writeChar(ch);
|
|
176
|
+
}
|
|
177
|
+
i++;
|
|
178
|
+
}
|
|
179
|
+
return screen;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/protocol/remote-command.ts
|
|
183
|
+
var import_zod = require("zod");
|
|
184
|
+
var remoteCommandSchema = import_zod.z.object({
|
|
185
|
+
id: import_zod.z.string(),
|
|
186
|
+
sessionId: import_zod.z.string(),
|
|
187
|
+
pluginId: import_zod.z.string(),
|
|
188
|
+
type: import_zod.z.string(),
|
|
189
|
+
// The backend may omit `payload` (or send null) for payload-less commands;
|
|
190
|
+
// clients have always normalized that to `{}` — keep that behavior here.
|
|
191
|
+
payload: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).nullish(),
|
|
192
|
+
status: import_zod.z.string(),
|
|
193
|
+
createdAt: import_zod.z.number()
|
|
194
|
+
});
|
|
195
|
+
function toRemoteCommand(raw) {
|
|
196
|
+
const parsed = remoteCommandSchema.safeParse(raw);
|
|
197
|
+
if (!parsed.success) return null;
|
|
198
|
+
const { payload, ...rest } = parsed.data;
|
|
199
|
+
return { ...rest, payload: payload ?? {} };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/models/pricing.ts
|
|
203
|
+
var MODEL_PRICING = {
|
|
204
|
+
// ── Anthropic / Claude ────────────────────────────────────
|
|
205
|
+
// The 4.x rows below cover the model ids actually emitted by the CLI
|
|
206
|
+
// (apps/cli/src/agents/claude/runtime.ts listModels) and the JetBrains
|
|
207
|
+
// fallback catalog (RemoteCommandRouter.kt). Prices are copied from the
|
|
208
|
+
// same-family base rows (claude-opus-4 / claude-sonnet-4 /
|
|
209
|
+
// claude-3-5-haiku) until distinct published rates land.
|
|
210
|
+
"claude-opus-4-7": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
211
|
+
"claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
212
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
213
|
+
// Haiku-tier prices copied from claude-3-5-haiku (closest same-tier
|
|
214
|
+
// sibling in this table) — previously this id matched NO row and was
|
|
215
|
+
// silently billed at sonnet rates via the unknown-model fallback.
|
|
216
|
+
"claude-haiku-4-5": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
217
|
+
"claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
218
|
+
"claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
|
219
|
+
"claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
220
|
+
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
|
221
|
+
"claude-3-haiku": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 },
|
|
222
|
+
// ── Codex / OpenAI ────────────────────────────────────────
|
|
223
|
+
// Phase 2 placeholder pricing: 0 across the board until OpenAI publishes
|
|
224
|
+
// confirmed rates for the GPT-5.x catalog. Sync from
|
|
225
|
+
// developers.openai.com/pricing when available.
|
|
226
|
+
"gpt-5.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
227
|
+
"gpt-5.4": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
228
|
+
"gpt-5.4-mini": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
229
|
+
"gpt-5.3-codex": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
230
|
+
"gpt-5.2": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
231
|
+
"codex-auto-review": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }
|
|
232
|
+
};
|
|
233
|
+
var MODEL_CONTEXT_WINDOW = {
|
|
234
|
+
// ── Anthropic / Claude ────────────────────────────────────
|
|
235
|
+
"claude-opus-4-7": 1e6,
|
|
236
|
+
"claude-opus-4-6": 1e6,
|
|
237
|
+
"claude-sonnet-4-6": 1e6,
|
|
238
|
+
"claude-haiku-4-5": 2e5,
|
|
239
|
+
"claude-opus-4": 1e6,
|
|
240
|
+
"claude-sonnet-4": 1e6,
|
|
241
|
+
"claude-3-5-sonnet": 2e5,
|
|
242
|
+
"claude-3-5-haiku": 2e5,
|
|
243
|
+
"claude-3-haiku": 2e5,
|
|
244
|
+
// ── Codex / OpenAI ────────────────────────────────────────
|
|
245
|
+
"gpt-5.5": 272e3,
|
|
246
|
+
"gpt-5.4": 272e3,
|
|
247
|
+
"gpt-5.4-mini": 272e3,
|
|
248
|
+
"gpt-5.3-codex": 272e3,
|
|
249
|
+
"gpt-5.2": 272e3,
|
|
250
|
+
"codex-auto-review": 272e3
|
|
251
|
+
};
|
|
252
|
+
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
253
|
+
function longestPrefixMatch(table, model) {
|
|
254
|
+
let best;
|
|
255
|
+
let bestLen = -1;
|
|
256
|
+
for (const [prefix, value] of Object.entries(table)) {
|
|
257
|
+
if (prefix.length > bestLen && model.startsWith(prefix)) {
|
|
258
|
+
best = value;
|
|
259
|
+
bestLen = prefix.length;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return best;
|
|
263
|
+
}
|
|
264
|
+
function isKnownModel(model) {
|
|
265
|
+
return longestPrefixMatch(MODEL_PRICING, model) !== void 0;
|
|
266
|
+
}
|
|
267
|
+
function getPricing(model) {
|
|
268
|
+
return longestPrefixMatch(MODEL_PRICING, model) ?? MODEL_PRICING["claude-sonnet-4"];
|
|
269
|
+
}
|
|
270
|
+
function getContextWindow(model) {
|
|
271
|
+
if (!model) return DEFAULT_CONTEXT_WINDOW;
|
|
272
|
+
return longestPrefixMatch(MODEL_CONTEXT_WINDOW, model) ?? DEFAULT_CONTEXT_WINDOW;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/agents/registry.ts
|
|
276
|
+
var AGENT_REGISTRY = {
|
|
277
|
+
claude: {
|
|
278
|
+
id: "claude",
|
|
279
|
+
displayName: "Claude Code",
|
|
280
|
+
binaryName: "claude",
|
|
281
|
+
enabled: true,
|
|
282
|
+
// Mirrors the backend registry (codeagent-mobile
|
|
283
|
+
// apps/api-v2/src/codespaces/agent.ts — authoritative for auth
|
|
284
|
+
// capabilities). `setup_token` is the bare `sk-ant-oat01-…` from
|
|
285
|
+
// `claude setup-token` → delivered via CLAUDE_CODE_OAUTH_TOKEN.
|
|
286
|
+
supportedAuthKinds: ["setup_token", "oauth_token", "api_key"],
|
|
287
|
+
preferredAuthKind: "setup_token",
|
|
288
|
+
headroomWrappable: true,
|
|
289
|
+
headroomKind: "claude",
|
|
290
|
+
// npm adapter `@agentclientprotocol/claude-agent-acp`.
|
|
291
|
+
acp: true
|
|
292
|
+
},
|
|
293
|
+
codex: {
|
|
294
|
+
id: "codex",
|
|
295
|
+
displayName: "Codex CLI",
|
|
296
|
+
binaryName: "codex",
|
|
297
|
+
enabled: true,
|
|
298
|
+
supportedAuthKinds: ["oauth_token", "api_key"],
|
|
299
|
+
preferredAuthKind: "oauth_token",
|
|
300
|
+
headroomWrappable: true,
|
|
301
|
+
headroomKind: "codex",
|
|
302
|
+
// npm adapter `@agentclientprotocol/codex-acp`.
|
|
303
|
+
acp: true,
|
|
304
|
+
// OAuth device-code flow; the user_code on the OpenAI page IS a real
|
|
305
|
+
// human-typed code — surfaces render it (with a copy affordance).
|
|
306
|
+
deviceFlow: true,
|
|
307
|
+
showsUserCode: true
|
|
308
|
+
},
|
|
309
|
+
copilot: {
|
|
310
|
+
id: "copilot",
|
|
311
|
+
displayName: "GitHub Copilot CLI",
|
|
312
|
+
binaryName: "gh",
|
|
313
|
+
enabled: false,
|
|
314
|
+
supportedAuthKinds: ["oauth_token"],
|
|
315
|
+
preferredAuthKind: "oauth_token",
|
|
316
|
+
// `headroom init --global copilot` exists even though the agent is
|
|
317
|
+
// still disabled here (no runtime builder yet).
|
|
318
|
+
headroomWrappable: true,
|
|
319
|
+
headroomKind: "copilot",
|
|
320
|
+
acp: false
|
|
321
|
+
},
|
|
322
|
+
coderabbit: {
|
|
323
|
+
id: "coderabbit",
|
|
324
|
+
displayName: "CodeRabbit",
|
|
325
|
+
binaryName: "coderabbit",
|
|
326
|
+
enabled: true,
|
|
327
|
+
// Backend registry is authoritative: CodeRabbit links via a real
|
|
328
|
+
// API key only (no OAuth flow exists in api-v2).
|
|
329
|
+
supportedAuthKinds: ["api_key"],
|
|
330
|
+
preferredAuthKind: "api_key",
|
|
331
|
+
headroomWrappable: false,
|
|
332
|
+
// Legacy PTY runtime — no ACP adapter registered.
|
|
333
|
+
acp: false
|
|
334
|
+
},
|
|
335
|
+
cursor: {
|
|
336
|
+
id: "cursor",
|
|
337
|
+
displayName: "Cursor Agent",
|
|
338
|
+
binaryName: "cursor-agent",
|
|
339
|
+
enabled: true,
|
|
340
|
+
// Backend registry is authoritative: since the Cursor OAuth
|
|
341
|
+
// device-flow shipped, new links are oauth_token only (the login
|
|
342
|
+
// blob written to ~/.config/cursor/auth.json). Legacy vaulted
|
|
343
|
+
// api_key rows may still exist server-side, but the link surface
|
|
344
|
+
// no longer offers api_key.
|
|
345
|
+
supportedAuthKinds: ["oauth_token"],
|
|
346
|
+
preferredAuthKind: "oauth_token",
|
|
347
|
+
// `headroom wrap cursor` is "manual/print-only" (IDE settings; the
|
|
348
|
+
// headless cursor-agent CLI has no base-URL override) — runs native.
|
|
349
|
+
headroomWrappable: false,
|
|
350
|
+
// Native ACP server: `cursor-agent acp`.
|
|
351
|
+
acp: true,
|
|
352
|
+
// Reverse-engineered device/poll flow; `userCode` is the secret PKCE
|
|
353
|
+
// verifier echoed back on poll — NEVER human-facing.
|
|
354
|
+
deviceFlow: true,
|
|
355
|
+
showsUserCode: false
|
|
356
|
+
},
|
|
357
|
+
aider: {
|
|
358
|
+
id: "aider",
|
|
359
|
+
displayName: "Aider",
|
|
360
|
+
binaryName: "aider",
|
|
361
|
+
enabled: true,
|
|
362
|
+
// Aider is OAuth-less — auth is via ANTHROPIC_API_KEY / OPENAI_API_KEY
|
|
363
|
+
// / etc. env vars or `~/.aider.conf.yml`. The link flow surfaces
|
|
364
|
+
// this via the existing --api-key escape hatch in commands/link.ts.
|
|
365
|
+
supportedAuthKinds: ["api_key"],
|
|
366
|
+
preferredAuthKind: "api_key",
|
|
367
|
+
headroomWrappable: false,
|
|
368
|
+
// Legacy PTY runtime — no ACP adapter registered.
|
|
369
|
+
acp: false
|
|
370
|
+
},
|
|
371
|
+
gemini: {
|
|
372
|
+
id: "gemini",
|
|
373
|
+
displayName: "Gemini CLI",
|
|
374
|
+
binaryName: "gemini",
|
|
375
|
+
enabled: true,
|
|
376
|
+
// OAuth via `gemini auth login` (captured by `codeam link gemini`
|
|
377
|
+
// from ~/.gemini/oauth_creds.json) AND GEMINI_API_KEY are both
|
|
378
|
+
// accepted by the backend's GeminiProvisioningStrategy and propagated
|
|
379
|
+
// into codespace deploys.
|
|
380
|
+
supportedAuthKinds: ["oauth_token", "api_key"],
|
|
381
|
+
preferredAuthKind: "oauth_token",
|
|
382
|
+
// Not listed by `headroom wrap --help` — runs native.
|
|
383
|
+
headroomWrappable: false,
|
|
384
|
+
// Native ACP server: `gemini --skip-trust --acp`.
|
|
385
|
+
acp: true
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
function getEnabledAgents() {
|
|
389
|
+
return Object.values(AGENT_REGISTRY).filter((m) => m.enabled);
|
|
390
|
+
}
|
|
391
|
+
function getAgent(id) {
|
|
392
|
+
const meta = AGENT_REGISTRY[id];
|
|
393
|
+
if (!meta) throw new Error(`Unknown agent id: ${id}`);
|
|
394
|
+
return meta;
|
|
395
|
+
}
|
|
396
|
+
function isKnownAgentId(id) {
|
|
397
|
+
return id in AGENT_REGISTRY;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/agents/identity.ts
|
|
401
|
+
var HOUSE_AGENT_ID = "house-codeagent-cloud";
|
|
402
|
+
var HOUSE_AGENT_PROVIDER = "codeagent_cloud";
|
|
403
|
+
var HOUSE_AGENT_NAME = "CodeAgent Cloud";
|
|
404
|
+
var HOUSE_AGENT_VENDOR = "CodeAgent";
|
|
405
|
+
var HOUSE_AGENT_SUBTITLE = "Included \u2014 no setup";
|
|
406
|
+
var LINKED_AGENT_IDS = [
|
|
407
|
+
"claude_code",
|
|
408
|
+
"codex",
|
|
409
|
+
"cursor",
|
|
410
|
+
"aider",
|
|
411
|
+
"coderabbit",
|
|
412
|
+
"gemini",
|
|
413
|
+
HOUSE_AGENT_ID
|
|
414
|
+
];
|
|
415
|
+
function isLinkedAgentId(value) {
|
|
416
|
+
return LINKED_AGENT_IDS.includes(value);
|
|
417
|
+
}
|
|
418
|
+
var PUBLIC_TO_INTERNAL = {
|
|
419
|
+
claude_code: "claude",
|
|
420
|
+
// CLI-side extra: self-hosted deploy payloads may carry the internal id.
|
|
421
|
+
claude: "claude",
|
|
422
|
+
codex: "codex",
|
|
423
|
+
// CLI-side extra: copilot has no public LinkedAgentId (backend doesn't
|
|
424
|
+
// expose it) but the self-hosted path accepts it.
|
|
425
|
+
copilot: "copilot",
|
|
426
|
+
cursor: "cursor",
|
|
427
|
+
aider: "aider",
|
|
428
|
+
coderabbit: "coderabbit",
|
|
429
|
+
gemini: "gemini",
|
|
430
|
+
// The house agent runs Claude Code under the hood (pointed at the
|
|
431
|
+
// MiniMax proxy). Its internal runtime is therefore `claude`.
|
|
432
|
+
[HOUSE_AGENT_ID]: "claude"
|
|
433
|
+
};
|
|
434
|
+
var INTERNAL_TO_PUBLIC = {
|
|
435
|
+
claude: "claude_code",
|
|
436
|
+
codex: "codex",
|
|
437
|
+
cursor: "cursor",
|
|
438
|
+
aider: "aider",
|
|
439
|
+
coderabbit: "coderabbit",
|
|
440
|
+
gemini: "gemini"
|
|
441
|
+
};
|
|
442
|
+
function isPublicToInternalKey(v) {
|
|
443
|
+
return Object.prototype.hasOwnProperty.call(PUBLIC_TO_INTERNAL, v);
|
|
444
|
+
}
|
|
445
|
+
function publicToInternal(publicId) {
|
|
446
|
+
return isPublicToInternalKey(publicId) ? PUBLIC_TO_INTERNAL[publicId] : null;
|
|
447
|
+
}
|
|
448
|
+
function internalToPublic(internal) {
|
|
449
|
+
return INTERNAL_TO_PUBLIC[internal] ?? null;
|
|
450
|
+
}
|
|
451
|
+
var TERMINAL_AGENT_PREFIX = "__terminal__:";
|
|
452
|
+
var AGENT_ID_ALIASES = {
|
|
453
|
+
claude_code: "claude",
|
|
454
|
+
"claude-code": "claude",
|
|
455
|
+
"anthropic.claude-code": "claude",
|
|
456
|
+
"anthropics.claude": "claude",
|
|
457
|
+
"anthropic.claude-ce": "claude",
|
|
458
|
+
"anthropic.claude": "claude",
|
|
459
|
+
"com.anthropic.claudecode": "claude",
|
|
460
|
+
"com.anthropic.claude": "claude",
|
|
461
|
+
"openai.chatgpt": "codex",
|
|
462
|
+
"coderabbitai.coderabbit-vscode": "coderabbit"
|
|
463
|
+
};
|
|
464
|
+
function normalizeAgentId(raw) {
|
|
465
|
+
const value = (raw ?? "").trim().toLowerCase();
|
|
466
|
+
if (!value) return null;
|
|
467
|
+
if (isKnownAgentId(value)) return value;
|
|
468
|
+
const unprefixed = value.startsWith(TERMINAL_AGENT_PREFIX) ? value.slice(TERMINAL_AGENT_PREFIX.length) : value;
|
|
469
|
+
if (isKnownAgentId(unprefixed)) return unprefixed;
|
|
470
|
+
return AGENT_ID_ALIASES[unprefixed] ?? null;
|
|
471
|
+
}
|
|
472
|
+
function headroomKindFor(agentId) {
|
|
473
|
+
const normalized = (agentId ?? "").toLowerCase().replace(/[_-]/g, "");
|
|
474
|
+
if (!normalized) return null;
|
|
475
|
+
for (const meta of Object.values(AGENT_REGISTRY)) {
|
|
476
|
+
if (meta.headroomKind !== void 0 && normalized.startsWith(meta.id)) {
|
|
477
|
+
return meta.headroomKind;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
function isHeadroomWrappable(agentId) {
|
|
483
|
+
return headroomKindFor(agentId) !== null;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// src/api-url.ts
|
|
487
|
+
var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
|
|
488
|
+
var DEV_API_BASE_URL = "https://dev-api.codeagent-mobile.com";
|
|
489
|
+
function resolveApiBaseUrl() {
|
|
490
|
+
const env = globalThis.process?.env;
|
|
491
|
+
const explicit = env?.CODEAM_API_URL?.trim();
|
|
492
|
+
if (explicit) return explicit;
|
|
493
|
+
const testFlag = env?.CODEAM_TEST_MODE?.trim();
|
|
494
|
+
if (testFlag === "1" || testFlag?.toLowerCase() === "true") return DEV_API_BASE_URL;
|
|
495
|
+
return DEFAULT_API_BASE_URL;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// src/headroom/manifest.ts
|
|
499
|
+
var HEADROOM_PROXY_PORT = 8787;
|
|
500
|
+
var HEADROOM_BACKEND_ENV = {
|
|
501
|
+
HEADROOM_KOMPRESS_BACKEND: "onnx_cpu"
|
|
502
|
+
};
|
|
503
|
+
var HEADROOM_PIP_COMPANIONS = [
|
|
504
|
+
"fastapi",
|
|
505
|
+
"uvicorn",
|
|
506
|
+
"httpx[http2]",
|
|
507
|
+
"websockets",
|
|
508
|
+
"zstandard"
|
|
509
|
+
];
|
|
510
|
+
var HEADROOM_EXTRAS_BY_SURFACE = {
|
|
511
|
+
codespace: ["proxy", "code"],
|
|
512
|
+
selfHosted: ["proxy", "code"],
|
|
513
|
+
onDemand: ["proxy", "code", "image"]
|
|
514
|
+
};
|
|
515
|
+
function headroomPipPackage(extras) {
|
|
516
|
+
return `headroom-ai[${extras.join(",")}]`;
|
|
517
|
+
}
|
|
518
|
+
var HEADROOM_MODELS = [
|
|
519
|
+
{
|
|
520
|
+
repo: "chopratejas/kompress-v2-base",
|
|
521
|
+
allowPatterns: ["*.json", "onnx/*.onnx", "kompress-int8-wo.onnx"]
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
repo: "answerdotai/ModernBERT-base",
|
|
525
|
+
allowPatterns: ["*.json", "tokenizer*", "*.txt", "vocab*", "merges*"]
|
|
526
|
+
}
|
|
527
|
+
];
|
|
528
|
+
function headroomSnapshotDownloadLine(model, opts = {}) {
|
|
529
|
+
const sep = opts.spaceAfterComma ? ", " : ",";
|
|
530
|
+
const patterns = model.allowPatterns.map((p) => `"${p}"`).join(sep);
|
|
531
|
+
return `snapshot_download("${model.repo}", allow_patterns=[${patterns}])`;
|
|
532
|
+
}
|
|
533
|
+
function headroomModelPredownloadScript(opts = {}) {
|
|
534
|
+
return [
|
|
535
|
+
"from huggingface_hub import snapshot_download",
|
|
536
|
+
...HEADROOM_MODELS.map((m) => headroomSnapshotDownloadLine(m, opts))
|
|
537
|
+
].join("\n");
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// src/types/events.ts
|
|
541
|
+
var USER_EVENTS = {
|
|
542
|
+
PAIRED_SESSION_STATUS: "paired_session_status",
|
|
543
|
+
PAIRED_SESSION_ADDED: "paired_session_added",
|
|
544
|
+
PAIRED_SESSION_REMOVED: "paired_session_removed",
|
|
545
|
+
PAIRED_SESSION_BRANCH_CHANGED: "paired_session_branch_changed",
|
|
546
|
+
SHARED_WITH_ME_ADDED: "shared_with_me_added",
|
|
547
|
+
SHARED_WITH_ME_REVOKED: "shared_with_me_revoked",
|
|
548
|
+
USAGE_CHANGED: "usage_changed",
|
|
549
|
+
TASK_DONE: "task_done",
|
|
550
|
+
HUNK_PENDING_REVIEW_ADDED: "hunk_pending_review_added",
|
|
551
|
+
HUNK_REVIEW_RESOLVED: "hunk_review_resolved",
|
|
552
|
+
FILE_CHANGED: "file_changed",
|
|
553
|
+
FILES_BATCH_CHANGED: "files_batch_changed",
|
|
554
|
+
AGENT_STREAMING_CHUNK: "agent_streaming_chunk",
|
|
555
|
+
AGENT_AWAITING_ANSWER: "agent_awaiting_answer",
|
|
556
|
+
AWAITING_INPUT_ADDED: "awaiting_input_added",
|
|
557
|
+
AGENT_ANSWER_RESOLVED: "agent_answer_resolved",
|
|
558
|
+
TEMPLATE_ADDED: "template_added",
|
|
559
|
+
TEMPLATE_REMOVED: "template_removed",
|
|
560
|
+
TEMPLATE_UPDATED: "template_updated",
|
|
561
|
+
AGENT_TASK_DISPATCHED: "agent_task_dispatched",
|
|
562
|
+
AGENT_TASK_COMPLETED: "agent_task_completed",
|
|
563
|
+
LINKED_AGENT_ADDED: "linked_agent_added",
|
|
564
|
+
QUOTA_REACHED: "quota_reached",
|
|
565
|
+
LINKED_AGENT_LINK_FAILED: "linked_agent_link_failed",
|
|
566
|
+
CODESPACE_AGENT_INSTALLED: "codespace_agent_installed",
|
|
567
|
+
AGENT_CREDENTIALS_REFRESHED: "agent_credentials_refreshed",
|
|
568
|
+
CREDENTIAL_INVALID: "credential_invalid",
|
|
569
|
+
CODESPACE_WAKING: "codespace_waking",
|
|
570
|
+
CODESPACE_BILLING_BLOCKED: "codespace_billing_blocked",
|
|
571
|
+
COST_SAVING_UPDATED: "cost_saving_updated",
|
|
572
|
+
COMMAND_COMPLETED: "command_completed",
|
|
573
|
+
AI_SUMMARY_PENDING: "ai_summary_pending",
|
|
574
|
+
AI_SUMMARY_READY: "ai_summary_ready",
|
|
575
|
+
AI_INSIGHT_PENDING: "ai_insight_pending",
|
|
576
|
+
AI_INSIGHT_READY: "ai_insight_ready",
|
|
577
|
+
PUSH_TOKEN_INVALIDATED: "push_token_invalidated",
|
|
578
|
+
PREVIEW_DETECTION_PENDING: "preview_detection_pending",
|
|
579
|
+
PREVIEW_DETECTION_READY: "preview_detection_ready",
|
|
580
|
+
PREVIEW_STARTING: "preview_starting",
|
|
581
|
+
PREVIEW_READY: "preview_ready",
|
|
582
|
+
PREVIEW_STOPPED: "preview_stopped",
|
|
583
|
+
PREVIEW_ERROR: "preview_error",
|
|
584
|
+
PREVIEW_PROGRESS: "preview_progress",
|
|
585
|
+
BEADS_STATE_CHANGED: "beads_state_changed",
|
|
586
|
+
BEADS_PROVISIONING: "beads_provisioning",
|
|
587
|
+
BEADS_TEAM_MEMORY_CHANGED: "beads_team_memory_changed",
|
|
588
|
+
AUDIT_EVENT_ADDED: "audit_event_added",
|
|
589
|
+
SELF_HOSTED_HOST_ADDED: "self_hosted_host_added",
|
|
590
|
+
SELF_HOSTED_HOST_STATUS: "self_hosted_host_status",
|
|
591
|
+
SELF_HOSTED_HOST_REMOVED: "self_hosted_host_removed",
|
|
592
|
+
SELF_HOSTED_HOST_TELEMETRY: "self_hosted_host_telemetry",
|
|
593
|
+
SELF_HOSTED_HOST_METRICS: "self_hosted_host_metrics",
|
|
594
|
+
SELF_HOSTED_HOST_SESSIONS: "self_hosted_host_sessions",
|
|
595
|
+
SELF_HOSTED_DEPLOY_PROGRESS: "self_hosted_deploy_progress",
|
|
596
|
+
REFERRAL_REWARD_EARNED: "referral_reward_earned",
|
|
597
|
+
HEADROOM_PROGRESS: "headroom_progress",
|
|
598
|
+
HEADROOM_STATUS: "headroom_status",
|
|
599
|
+
BEADS_STATUS: "beads_status",
|
|
600
|
+
LINKED_AGENT_HEADROOM_BUDGET_UPDATED: "linked_agent_headroom_budget_updated",
|
|
601
|
+
CLI_UPDATE_AVAILABLE: "cli_update_available",
|
|
602
|
+
AGENT_INSTALL_PROGRESS: "agent_install_progress",
|
|
603
|
+
AGENT_INSTALL_FAILED: "agent_install_failed",
|
|
604
|
+
CLI_UPDATE_PROGRESS: "cli_update_progress",
|
|
605
|
+
CLI_UPDATE_FAILED: "cli_update_failed"
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
// src/preview-prompts.ts
|
|
609
|
+
var PREVIEW_DETECT_PROMPT = `
|
|
610
|
+
Analyze the project in the current working directory and return how to start
|
|
611
|
+
its development server for in-app preview.
|
|
612
|
+
|
|
613
|
+
Read package.json, Procfile, Dockerfile, docker-compose.yml, manage.py, app.json,
|
|
614
|
+
mix.exs, Cargo.toml, go.mod, requirements.txt, Gemfile, and any other framework
|
|
615
|
+
markers you find at depth <= 2.
|
|
616
|
+
|
|
617
|
+
Return ONLY a JSON object on stdout (no prose, no markdown fences):
|
|
618
|
+
|
|
619
|
+
{
|
|
620
|
+
"framework": "<name, or 'unsupported'>",
|
|
621
|
+
"command": "<executable>",
|
|
622
|
+
"args": ["..."],
|
|
623
|
+
"port": <number>,
|
|
624
|
+
"ready_pattern": "<regex matching the server-ready stdout line>",
|
|
625
|
+
"env": { "HOST": "0.0.0.0" },
|
|
626
|
+
"setup_commands": [{ "cmd": "<executable>", "args": ["..."] }],
|
|
627
|
+
"notes": "<one-line caveat or null>"
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
Rules:
|
|
631
|
+
- Pick the script the developer would run locally to see the app (typically "dev", "start", "serve").
|
|
632
|
+
- Prefer binding to 0.0.0.0 \u2014 most frameworks default to localhost which the tunnel cannot reach.
|
|
633
|
+
- For Expo: framework="Expo", command="npx", args=["expo","start","--tunnel"], port=8081, notes="Scan QR with Expo Go".
|
|
634
|
+
- If no dev server applies (CLI library, lambda, batch script): {"framework":"unsupported","notes":"<reason>"}.
|
|
635
|
+
|
|
636
|
+
CRITICAL \u2014 setup_commands:
|
|
637
|
+
- DO NOT include an install command (npm install, pnpm install, yarn install,
|
|
638
|
+
yarn, bun install) in setup_commands. A lockfile-aware pre-flight installer
|
|
639
|
+
runs BEFORE setup_commands and picks the correct package manager from the
|
|
640
|
+
lockfile present (pnpm-lock.yaml -> pnpm, yarn.lock -> yarn, bun.lockb -> bun,
|
|
641
|
+
else npm). Emitting an install here either duplicates that work or, worse,
|
|
642
|
+
uses the WRONG package manager on top of node_modules just populated by the
|
|
643
|
+
pre-flight, which crashes (e.g. npm errors with "Cannot read properties of
|
|
644
|
+
null (reading 'matches')" when run over pnpm's .pnpm/ layout).
|
|
645
|
+
- ONLY include setup_commands for genuinely non-install work the project needs
|
|
646
|
+
before its dev server can boot: prisma generate, codegen, prebuild scripts,
|
|
647
|
+
database migrations against a local SQLite, etc.
|
|
648
|
+
- Each setup_commands entry MUST be an object {"cmd": "...", "args": ["..."]} \u2014
|
|
649
|
+
e.g. {"cmd": "npx", "args": ["prisma", "generate"]}. NOT a bare string.
|
|
650
|
+
- For most projects, setup_commands should be an empty array [].
|
|
651
|
+
|
|
652
|
+
OUTPUT JSON ONLY. NO MARKDOWN. NO COMMENTARY.
|
|
653
|
+
`.trim();
|
|
654
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
655
|
+
0 && (module.exports = {
|
|
656
|
+
AGENT_REGISTRY,
|
|
657
|
+
DEFAULT_API_BASE_URL,
|
|
658
|
+
DEV_API_BASE_URL,
|
|
659
|
+
HEADROOM_BACKEND_ENV,
|
|
660
|
+
HEADROOM_EXTRAS_BY_SURFACE,
|
|
661
|
+
HEADROOM_MODELS,
|
|
662
|
+
HEADROOM_PIP_COMPANIONS,
|
|
663
|
+
HEADROOM_PROXY_PORT,
|
|
664
|
+
HEARTBEAT_INTERVAL_MS_DEFAULT,
|
|
665
|
+
HOUSE_AGENT_ID,
|
|
666
|
+
HOUSE_AGENT_NAME,
|
|
667
|
+
HOUSE_AGENT_PROVIDER,
|
|
668
|
+
HOUSE_AGENT_SUBTITLE,
|
|
669
|
+
HOUSE_AGENT_VENDOR,
|
|
670
|
+
INTERNAL_TO_PUBLIC,
|
|
671
|
+
LINKED_AGENT_IDS,
|
|
672
|
+
MODEL_CONTEXT_WINDOW,
|
|
673
|
+
MODEL_PRICING,
|
|
674
|
+
OBSERVER_BRIDGE_PORT,
|
|
675
|
+
PREVIEW_DETECT_PROMPT,
|
|
676
|
+
PROTOCOL_VERSION,
|
|
677
|
+
PUBLIC_TO_INTERNAL,
|
|
678
|
+
SSE_SOCKET_TIMEOUT_MS,
|
|
679
|
+
TERMINAL_AGENT_PREFIX,
|
|
680
|
+
USER_EVENTS,
|
|
681
|
+
getAgent,
|
|
682
|
+
getContextWindow,
|
|
683
|
+
getEnabledAgents,
|
|
684
|
+
getPricing,
|
|
685
|
+
headroomKindFor,
|
|
686
|
+
headroomModelPredownloadScript,
|
|
687
|
+
headroomPipPackage,
|
|
688
|
+
headroomSnapshotDownloadLine,
|
|
689
|
+
internalToPublic,
|
|
690
|
+
isHeadroomWrappable,
|
|
691
|
+
isKnownAgentId,
|
|
692
|
+
isKnownModel,
|
|
693
|
+
isLinkedAgentId,
|
|
694
|
+
normalizeAgentId,
|
|
695
|
+
publicToInternal,
|
|
696
|
+
renderToLines,
|
|
697
|
+
resolveApiBaseUrl,
|
|
698
|
+
toRemoteCommand
|
|
699
|
+
});
|
|
700
|
+
//# sourceMappingURL=index.js.map
|