codeam-cli 2.22.1 → 2.23.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 +6 -0
- package/dist/index.js +234 -56
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.22.1] — 2026-05-25
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Payload.agentId — accept any string, not just the public enum (#187)
|
|
12
|
+
|
|
7
13
|
## [2.22.0] — 2026-05-25
|
|
8
14
|
|
|
9
15
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -441,7 +441,7 @@ var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
|
|
|
441
441
|
// package.json
|
|
442
442
|
var package_default = {
|
|
443
443
|
name: "codeam-cli",
|
|
444
|
-
version: "2.
|
|
444
|
+
version: "2.23.0",
|
|
445
445
|
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.",
|
|
446
446
|
type: "commonjs",
|
|
447
447
|
main: "dist/index.js",
|
|
@@ -734,6 +734,34 @@ async function postLinkCredential(input) {
|
|
|
734
734
|
};
|
|
735
735
|
}
|
|
736
736
|
}
|
|
737
|
+
async function postAiResult(input) {
|
|
738
|
+
const body = {
|
|
739
|
+
sessionId: input.sessionId,
|
|
740
|
+
pluginId: input.pluginId,
|
|
741
|
+
kind: input.kind,
|
|
742
|
+
summary: input.summary
|
|
743
|
+
};
|
|
744
|
+
if (input.turnId) body.turnId = input.turnId;
|
|
745
|
+
if (input.stats) body.stats = input.stats;
|
|
746
|
+
if (input.fileChangeId) body.fileChangeId = input.fileChangeId;
|
|
747
|
+
if (input.reasoning) body.reasoning = input.reasoning;
|
|
748
|
+
if (input.securityNote) body.securityNote = input.securityNote;
|
|
749
|
+
try {
|
|
750
|
+
await _transport.postJsonAuthed(
|
|
751
|
+
`${API_BASE}/api/plugin/ai-result`,
|
|
752
|
+
body,
|
|
753
|
+
input.pluginAuthToken
|
|
754
|
+
);
|
|
755
|
+
return { ok: true };
|
|
756
|
+
} catch (err) {
|
|
757
|
+
const e = err;
|
|
758
|
+
return {
|
|
759
|
+
ok: false,
|
|
760
|
+
status: typeof e.statusCode === "number" ? e.statusCode : 0,
|
|
761
|
+
message: e.message || "unknown"
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
}
|
|
737
765
|
async function _postJsonAuthed(url, body, pluginAuthToken) {
|
|
738
766
|
return new Promise((resolve5, reject) => {
|
|
739
767
|
const data = JSON.stringify(body);
|
|
@@ -5740,7 +5768,7 @@ function readAnonId() {
|
|
|
5740
5768
|
}
|
|
5741
5769
|
function superProperties() {
|
|
5742
5770
|
return {
|
|
5743
|
-
cliVersion: true ? "2.
|
|
5771
|
+
cliVersion: true ? "2.23.0" : "0.0.0-dev",
|
|
5744
5772
|
nodeVersion: process.version,
|
|
5745
5773
|
platform: process.platform,
|
|
5746
5774
|
arch: process.arch,
|
|
@@ -9099,6 +9127,59 @@ async function fetchClaudeQuota() {
|
|
|
9099
9127
|
});
|
|
9100
9128
|
}
|
|
9101
9129
|
|
|
9130
|
+
// src/services/spawn-and-capture.ts
|
|
9131
|
+
var import_child_process6 = require("child_process");
|
|
9132
|
+
async function spawnAndCapture(cmd, args2, opts = {}) {
|
|
9133
|
+
const timeoutMs = opts.timeoutMs ?? 6e4;
|
|
9134
|
+
return new Promise((resolve5) => {
|
|
9135
|
+
let settled = false;
|
|
9136
|
+
const settle = (value) => {
|
|
9137
|
+
if (settled) return;
|
|
9138
|
+
settled = true;
|
|
9139
|
+
resolve5(value);
|
|
9140
|
+
};
|
|
9141
|
+
let child;
|
|
9142
|
+
try {
|
|
9143
|
+
child = (0, import_child_process6.spawn)(cmd, [...args2], {
|
|
9144
|
+
cwd: opts.cwd,
|
|
9145
|
+
env: opts.env ?? process.env,
|
|
9146
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
9147
|
+
});
|
|
9148
|
+
} catch {
|
|
9149
|
+
settle(null);
|
|
9150
|
+
return;
|
|
9151
|
+
}
|
|
9152
|
+
let stdout = "";
|
|
9153
|
+
child.stdout?.on("data", (chunk) => {
|
|
9154
|
+
stdout += chunk.toString("utf8");
|
|
9155
|
+
});
|
|
9156
|
+
child.stderr?.on("data", (chunk) => {
|
|
9157
|
+
opts.onStderr?.(chunk.toString("utf8"));
|
|
9158
|
+
});
|
|
9159
|
+
const timer = setTimeout(() => {
|
|
9160
|
+
try {
|
|
9161
|
+
child.kill("SIGKILL");
|
|
9162
|
+
} catch {
|
|
9163
|
+
}
|
|
9164
|
+
settle(null);
|
|
9165
|
+
}, timeoutMs);
|
|
9166
|
+
timer.unref();
|
|
9167
|
+
child.on("error", () => {
|
|
9168
|
+
clearTimeout(timer);
|
|
9169
|
+
settle(null);
|
|
9170
|
+
});
|
|
9171
|
+
child.on("exit", (code) => {
|
|
9172
|
+
clearTimeout(timer);
|
|
9173
|
+
if (code !== 0) {
|
|
9174
|
+
settle(null);
|
|
9175
|
+
return;
|
|
9176
|
+
}
|
|
9177
|
+
const trimmed = stdout.trim();
|
|
9178
|
+
settle(trimmed.length > 0 ? trimmed : null);
|
|
9179
|
+
});
|
|
9180
|
+
});
|
|
9181
|
+
}
|
|
9182
|
+
|
|
9102
9183
|
// src/agents/claude/history.ts
|
|
9103
9184
|
var fs9 = __toESM(require("fs"));
|
|
9104
9185
|
var path12 = __toESM(require("path"));
|
|
@@ -9541,6 +9622,14 @@ var ClaudeRuntimeStrategy = class {
|
|
|
9541
9622
|
loginLauncher() {
|
|
9542
9623
|
return claudeLoginLauncher();
|
|
9543
9624
|
}
|
|
9625
|
+
async generateOneShot(prompt, opts) {
|
|
9626
|
+
const launch = buildClaudeLaunch(["-p", prompt], this.os);
|
|
9627
|
+
if (!launch) return null;
|
|
9628
|
+
return spawnAndCapture(launch.cmd, launch.args, {
|
|
9629
|
+
cwd: opts?.cwd,
|
|
9630
|
+
timeoutMs: opts?.timeoutMs
|
|
9631
|
+
});
|
|
9632
|
+
}
|
|
9544
9633
|
};
|
|
9545
9634
|
|
|
9546
9635
|
// src/agents/claude/deploy.ts
|
|
@@ -9549,12 +9638,12 @@ var os13 = __toESM(require("os"));
|
|
|
9549
9638
|
var path14 = __toESM(require("path"));
|
|
9550
9639
|
|
|
9551
9640
|
// src/agents/claude/credentials.ts
|
|
9552
|
-
var
|
|
9641
|
+
var import_child_process7 = require("child_process");
|
|
9553
9642
|
var fs10 = __toESM(require("fs"));
|
|
9554
9643
|
var os12 = __toESM(require("os"));
|
|
9555
9644
|
var path13 = __toESM(require("path"));
|
|
9556
9645
|
var import_util = require("util");
|
|
9557
|
-
var execFileP2 = (0, import_util.promisify)(
|
|
9646
|
+
var execFileP2 = (0, import_util.promisify)(import_child_process7.execFile);
|
|
9558
9647
|
async function detectLocalClaudeCredentials() {
|
|
9559
9648
|
const localClaudeDir = path13.join(os12.homedir(), ".claude");
|
|
9560
9649
|
const flat = path13.join(localClaudeDir, ".credentials.json");
|
|
@@ -10424,6 +10513,15 @@ var CodexRuntimeStrategy = class {
|
|
|
10424
10513
|
loginLauncher() {
|
|
10425
10514
|
return codexLoginLauncher();
|
|
10426
10515
|
}
|
|
10516
|
+
async generateOneShot(prompt, opts) {
|
|
10517
|
+
const binary = this.os.findInPath("codex");
|
|
10518
|
+
if (!binary) return null;
|
|
10519
|
+
const launch = this.os.buildLaunch(binary, ["exec", prompt]);
|
|
10520
|
+
return spawnAndCapture(launch.cmd, launch.args, {
|
|
10521
|
+
cwd: opts?.cwd,
|
|
10522
|
+
timeoutMs: opts?.timeoutMs
|
|
10523
|
+
});
|
|
10524
|
+
}
|
|
10427
10525
|
};
|
|
10428
10526
|
function resolveNpm(os26) {
|
|
10429
10527
|
return os26.id === "win32" ? "npm.cmd" : "npm";
|
|
@@ -12206,7 +12304,7 @@ var HistoryService = class _HistoryService {
|
|
|
12206
12304
|
};
|
|
12207
12305
|
|
|
12208
12306
|
// src/services/file-watcher.service.ts
|
|
12209
|
-
var
|
|
12307
|
+
var import_child_process8 = require("child_process");
|
|
12210
12308
|
var fs21 = __toESM(require("fs"));
|
|
12211
12309
|
var os22 = __toESM(require("os"));
|
|
12212
12310
|
var path25 = __toESM(require("path"));
|
|
@@ -12744,7 +12842,7 @@ async function _runGitImpl(cwd, args2, opts = {}) {
|
|
|
12744
12842
|
return new Promise((resolve5) => {
|
|
12745
12843
|
let proc;
|
|
12746
12844
|
try {
|
|
12747
|
-
proc = (0,
|
|
12845
|
+
proc = (0, import_child_process8.spawn)("git", args2, { cwd, env: process.env });
|
|
12748
12846
|
} catch {
|
|
12749
12847
|
resolve5(null);
|
|
12750
12848
|
return;
|
|
@@ -12776,7 +12874,7 @@ function _runGit(cwd, args2, opts = {}) {
|
|
|
12776
12874
|
var import_crypto2 = require("crypto");
|
|
12777
12875
|
|
|
12778
12876
|
// src/services/turn-files/git-changeset.ts
|
|
12779
|
-
var
|
|
12877
|
+
var import_child_process9 = require("child_process");
|
|
12780
12878
|
var path26 = __toESM(require("path"));
|
|
12781
12879
|
async function collectRepoChangeset(opts) {
|
|
12782
12880
|
const status2 = await runGit2(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
|
|
@@ -12859,7 +12957,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
12859
12957
|
return new Promise((resolve5) => {
|
|
12860
12958
|
let proc;
|
|
12861
12959
|
try {
|
|
12862
|
-
proc = (0,
|
|
12960
|
+
proc = (0, import_child_process9.spawn)("git", args2, { cwd, env: process.env });
|
|
12863
12961
|
} catch {
|
|
12864
12962
|
resolve5(null);
|
|
12865
12963
|
return;
|
|
@@ -13199,6 +13297,7 @@ var TurnFileAggregator = class {
|
|
|
13199
13297
|
sessionId: entry.sessionId,
|
|
13200
13298
|
pluginId: entry.pluginId,
|
|
13201
13299
|
turnId: entry.turnId,
|
|
13300
|
+
agentId: this.opts.agentId,
|
|
13202
13301
|
files: entry.files
|
|
13203
13302
|
});
|
|
13204
13303
|
try {
|
|
@@ -13711,13 +13810,13 @@ function fetchQuotaUsage(runtime, historySvc) {
|
|
|
13711
13810
|
}
|
|
13712
13811
|
|
|
13713
13812
|
// src/commands/start/keep-alive.ts
|
|
13714
|
-
var
|
|
13813
|
+
var import_child_process10 = require("child_process");
|
|
13715
13814
|
function buildKeepAlive(ctx) {
|
|
13716
13815
|
let timer = null;
|
|
13717
13816
|
async function setIdleTimeout(minutes) {
|
|
13718
13817
|
if (!ctx.inCodespace || !ctx.codespaceName) return;
|
|
13719
13818
|
await new Promise((resolve5) => {
|
|
13720
|
-
const proc = (0,
|
|
13819
|
+
const proc = (0, import_child_process10.spawn)(
|
|
13721
13820
|
"gh",
|
|
13722
13821
|
[
|
|
13723
13822
|
"api",
|
|
@@ -13758,7 +13857,7 @@ var fs27 = __toESM(require("fs"));
|
|
|
13758
13857
|
var os23 = __toESM(require("os"));
|
|
13759
13858
|
var path33 = __toESM(require("path"));
|
|
13760
13859
|
var import_crypto5 = require("crypto");
|
|
13761
|
-
var
|
|
13860
|
+
var import_child_process14 = require("child_process");
|
|
13762
13861
|
|
|
13763
13862
|
// src/lib/payload.ts
|
|
13764
13863
|
var import_zod2 = require("zod");
|
|
@@ -13823,7 +13922,27 @@ var startCommandSchema = import_zod2.z.object({
|
|
|
13823
13922
|
// a narrow enum) because the web sends internal ids ('claude')
|
|
13824
13923
|
// while the auto-link backend sends public ids ('claude_code'),
|
|
13825
13924
|
// and the consuming handlers normalize themselves.
|
|
13826
|
-
agentId: import_zod2.z.string().max(64).optional()
|
|
13925
|
+
agentId: import_zod2.z.string().max(64).optional(),
|
|
13926
|
+
// `request_ai_summary` / `request_ai_insight` — backend fires
|
|
13927
|
+
// these on turn-end (+ file selection) when LinkedAgent.
|
|
13928
|
+
// aiInsightsEnabled is true. The CLI spawns the agent in
|
|
13929
|
+
// headless one-shot mode (`claude -p "..."` / `codex exec`) and
|
|
13930
|
+
// POSTs the response back to /api/plugin/ai-result.
|
|
13931
|
+
//
|
|
13932
|
+
// `prompt` (declared above for start_task) carries the LLM prompt
|
|
13933
|
+
// the backend pre-rendered with the diff context inlined; the
|
|
13934
|
+
// agent receives it verbatim. `turnId` keys the summary,
|
|
13935
|
+
// `fileChangeId` keys the per-file insight, `stats` is echoed
|
|
13936
|
+
// unchanged on the result POST so the backend doesn't have to
|
|
13937
|
+
// recompute (numbers came from file_changes; the agent only
|
|
13938
|
+
// writes the narrative).
|
|
13939
|
+
turnId: import_zod2.z.string().max(128).optional(),
|
|
13940
|
+
fileChangeId: import_zod2.z.string().max(128).optional(),
|
|
13941
|
+
stats: import_zod2.z.object({
|
|
13942
|
+
added: import_zod2.z.number().int(),
|
|
13943
|
+
removed: import_zod2.z.number().int(),
|
|
13944
|
+
complexityShift: import_zod2.z.number().int()
|
|
13945
|
+
}).optional()
|
|
13827
13946
|
});
|
|
13828
13947
|
function parsePayload2(schema, raw) {
|
|
13829
13948
|
const result = schema.safeParse(raw);
|
|
@@ -13979,11 +14098,11 @@ async function writeProjectFile(rawPath, content) {
|
|
|
13979
14098
|
}
|
|
13980
14099
|
|
|
13981
14100
|
// src/services/project-ops.service.ts
|
|
13982
|
-
var
|
|
14101
|
+
var import_child_process11 = require("child_process");
|
|
13983
14102
|
var import_util2 = require("util");
|
|
13984
14103
|
var fs24 = __toESM(require("fs/promises"));
|
|
13985
14104
|
var path29 = __toESM(require("path"));
|
|
13986
|
-
var execFileP3 = (0, import_util2.promisify)(
|
|
14105
|
+
var execFileP3 = (0, import_util2.promisify)(import_child_process11.execFile);
|
|
13987
14106
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
13988
14107
|
"node_modules",
|
|
13989
14108
|
".git",
|
|
@@ -14323,7 +14442,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
14323
14442
|
}
|
|
14324
14443
|
|
|
14325
14444
|
// src/services/terminal-ops.service.ts
|
|
14326
|
-
var
|
|
14445
|
+
var import_child_process12 = require("child_process");
|
|
14327
14446
|
var import_crypto4 = require("crypto");
|
|
14328
14447
|
var import_path3 = __toESM(require("path"));
|
|
14329
14448
|
var MAX_CONCURRENT_SESSIONS = 4;
|
|
@@ -14445,7 +14564,7 @@ function createPythonSession(id, shell, cwd, env, cols, rows) {
|
|
|
14445
14564
|
}
|
|
14446
14565
|
let child;
|
|
14447
14566
|
try {
|
|
14448
|
-
child = (0,
|
|
14567
|
+
child = (0, import_child_process12.spawn)(python, ["-c", PYTHON_TERMINAL_HELPER, shell], {
|
|
14449
14568
|
cwd,
|
|
14450
14569
|
env: { ...env, COLUMNS: String(cols), LINES: String(rows) },
|
|
14451
14570
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -14580,7 +14699,7 @@ function closeAllTerminals() {
|
|
|
14580
14699
|
}
|
|
14581
14700
|
|
|
14582
14701
|
// src/services/apply-file-review.service.ts
|
|
14583
|
-
var
|
|
14702
|
+
var import_child_process13 = require("child_process");
|
|
14584
14703
|
var fs25 = __toESM(require("fs"));
|
|
14585
14704
|
var path31 = __toESM(require("path"));
|
|
14586
14705
|
async function applyFileReview(workingDir, filePath, action) {
|
|
@@ -14622,7 +14741,7 @@ function runGit3(cwd, args2) {
|
|
|
14622
14741
|
return new Promise((resolve5) => {
|
|
14623
14742
|
let proc;
|
|
14624
14743
|
try {
|
|
14625
|
-
proc = (0,
|
|
14744
|
+
proc = (0, import_child_process13.spawn)("git", args2, { cwd, env: process.env });
|
|
14626
14745
|
} catch (err) {
|
|
14627
14746
|
resolve5({ ok: false, code: -1, stdout: "", stderr: err.message });
|
|
14628
14747
|
return;
|
|
@@ -15153,7 +15272,7 @@ var sessionTerminated = (ctx) => {
|
|
|
15153
15272
|
} catch {
|
|
15154
15273
|
}
|
|
15155
15274
|
try {
|
|
15156
|
-
const proc = (0,
|
|
15275
|
+
const proc = (0, import_child_process14.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
15157
15276
|
detached: true,
|
|
15158
15277
|
stdio: "ignore"
|
|
15159
15278
|
});
|
|
@@ -15175,7 +15294,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
15175
15294
|
}
|
|
15176
15295
|
if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
|
|
15177
15296
|
try {
|
|
15178
|
-
const stopProc = (0,
|
|
15297
|
+
const stopProc = (0, import_child_process14.spawn)(
|
|
15179
15298
|
"bash",
|
|
15180
15299
|
["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
|
|
15181
15300
|
{ detached: true, stdio: "ignore" }
|
|
@@ -15185,7 +15304,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
15185
15304
|
}
|
|
15186
15305
|
}
|
|
15187
15306
|
try {
|
|
15188
|
-
const proc = (0,
|
|
15307
|
+
const proc = (0, import_child_process14.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
15189
15308
|
detached: true,
|
|
15190
15309
|
stdio: "ignore"
|
|
15191
15310
|
});
|
|
@@ -15367,6 +15486,62 @@ var requestLinkCredentialsH = async (ctx, _cmd, parsed) => {
|
|
|
15367
15486
|
log.trace("auto-link", `upload failed (${result.status}): ${result.message}`);
|
|
15368
15487
|
}
|
|
15369
15488
|
};
|
|
15489
|
+
var requestAiSummaryH = async (ctx, _cmd, parsed) => {
|
|
15490
|
+
if (!ctx.pluginAuthToken) return;
|
|
15491
|
+
if (typeof ctx.runtime.generateOneShot !== "function") return;
|
|
15492
|
+
if (!parsed.prompt || !parsed.turnId || !parsed.stats) {
|
|
15493
|
+
log.trace("ai-summary", "missing prompt/turnId/stats \u2014 skipping");
|
|
15494
|
+
return;
|
|
15495
|
+
}
|
|
15496
|
+
const text = await ctx.runtime.generateOneShot(parsed.prompt).catch((err) => {
|
|
15497
|
+
log.trace("ai-summary", "generateOneShot threw", err);
|
|
15498
|
+
return null;
|
|
15499
|
+
});
|
|
15500
|
+
if (!text) return;
|
|
15501
|
+
await postAiResult({
|
|
15502
|
+
sessionId: ctx.sessionId,
|
|
15503
|
+
pluginId: ctx.pluginId,
|
|
15504
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
15505
|
+
kind: "summary",
|
|
15506
|
+
turnId: parsed.turnId,
|
|
15507
|
+
summary: text,
|
|
15508
|
+
stats: parsed.stats
|
|
15509
|
+
});
|
|
15510
|
+
};
|
|
15511
|
+
var requestAiInsightH = async (ctx, _cmd, parsed) => {
|
|
15512
|
+
if (!ctx.pluginAuthToken) return;
|
|
15513
|
+
if (typeof ctx.runtime.generateOneShot !== "function") return;
|
|
15514
|
+
if (!parsed.prompt || !parsed.fileChangeId) {
|
|
15515
|
+
log.trace("ai-insight", "missing prompt/fileChangeId \u2014 skipping");
|
|
15516
|
+
return;
|
|
15517
|
+
}
|
|
15518
|
+
const text = await ctx.runtime.generateOneShot(parsed.prompt).catch((err) => {
|
|
15519
|
+
log.trace("ai-insight", "generateOneShot threw", err);
|
|
15520
|
+
return null;
|
|
15521
|
+
});
|
|
15522
|
+
if (!text) return;
|
|
15523
|
+
const { summary, reasoning, securityNote } = parseInsightText(text);
|
|
15524
|
+
await postAiResult({
|
|
15525
|
+
sessionId: ctx.sessionId,
|
|
15526
|
+
pluginId: ctx.pluginId,
|
|
15527
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
15528
|
+
kind: "insight",
|
|
15529
|
+
fileChangeId: parsed.fileChangeId,
|
|
15530
|
+
summary,
|
|
15531
|
+
reasoning,
|
|
15532
|
+
securityNote
|
|
15533
|
+
});
|
|
15534
|
+
};
|
|
15535
|
+
function parseInsightText(text) {
|
|
15536
|
+
const summaryMatch = text.match(/SUMMARY:\s*([\s\S]*?)(?=\n\s*(?:REASONING|SECURITY):|$)/i);
|
|
15537
|
+
const reasoningMatch = text.match(/REASONING:\s*([\s\S]*?)(?=\n\s*SECURITY:|$)/i);
|
|
15538
|
+
const securityMatch = text.match(/SECURITY:\s*([\s\S]*)/i);
|
|
15539
|
+
return {
|
|
15540
|
+
summary: (summaryMatch?.[1] ?? text).trim(),
|
|
15541
|
+
reasoning: (reasoningMatch?.[1] ?? text).trim(),
|
|
15542
|
+
securityNote: securityMatch?.[1]?.trim() || void 0
|
|
15543
|
+
};
|
|
15544
|
+
}
|
|
15370
15545
|
var handlers = {
|
|
15371
15546
|
start_task: startTask,
|
|
15372
15547
|
provide_input: provideInput,
|
|
@@ -15399,7 +15574,9 @@ var handlers = {
|
|
|
15399
15574
|
git_pull: gitPullH,
|
|
15400
15575
|
git_resolve: gitResolveH,
|
|
15401
15576
|
apply_file_review: applyFileReviewH,
|
|
15402
|
-
request_link_credentials: requestLinkCredentialsH
|
|
15577
|
+
request_link_credentials: requestLinkCredentialsH,
|
|
15578
|
+
request_ai_summary: requestAiSummaryH,
|
|
15579
|
+
request_ai_insight: requestAiInsightH
|
|
15403
15580
|
};
|
|
15404
15581
|
async function dispatchCommand(ctx, cmd) {
|
|
15405
15582
|
const parsed = parsePayload2(startCommandSchema, cmd.payload);
|
|
@@ -15494,6 +15671,7 @@ async function start(requestedAgent) {
|
|
|
15494
15671
|
sessionId: session.id,
|
|
15495
15672
|
pluginId,
|
|
15496
15673
|
pluginAuthToken: session.pluginAuthToken,
|
|
15674
|
+
agentId: runtime.meta.id,
|
|
15497
15675
|
dirtyTracker: dirtyTracker ?? void 0
|
|
15498
15676
|
}) : null;
|
|
15499
15677
|
let streamingEmitter = null;
|
|
@@ -15991,11 +16169,11 @@ async function logout() {
|
|
|
15991
16169
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
15992
16170
|
|
|
15993
16171
|
// src/services/providers/github-codespaces.ts
|
|
15994
|
-
var
|
|
16172
|
+
var import_child_process15 = require("child_process");
|
|
15995
16173
|
var import_util3 = require("util");
|
|
15996
16174
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
15997
16175
|
var path34 = __toESM(require("path"));
|
|
15998
|
-
var execFileP4 = (0, import_util3.promisify)(
|
|
16176
|
+
var execFileP4 = (0, import_util3.promisify)(import_child_process15.execFile);
|
|
15999
16177
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
16000
16178
|
function resetStdinForChild() {
|
|
16001
16179
|
if (process.stdin.isTTY) {
|
|
@@ -16039,7 +16217,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16039
16217
|
if (!isAuthed) {
|
|
16040
16218
|
resetStdinForChild();
|
|
16041
16219
|
await new Promise((resolve5, reject) => {
|
|
16042
|
-
const proc = (0,
|
|
16220
|
+
const proc = (0, import_child_process15.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
|
|
16043
16221
|
stdio: "inherit"
|
|
16044
16222
|
});
|
|
16045
16223
|
proc.on("exit", (code) => {
|
|
@@ -16073,7 +16251,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16073
16251
|
wt(noteLines.join("\n"), "One more permission needed");
|
|
16074
16252
|
resetStdinForChild();
|
|
16075
16253
|
const refreshCode = await new Promise((resolve5, reject) => {
|
|
16076
|
-
const proc = (0,
|
|
16254
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16077
16255
|
"gh",
|
|
16078
16256
|
["auth", "refresh", "-h", "github.com", "-s", "codespace"],
|
|
16079
16257
|
{ stdio: "inherit" }
|
|
@@ -16223,7 +16401,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16223
16401
|
O2.step(`Installing gh via ${installCmd.describe}\u2026`);
|
|
16224
16402
|
resetStdinForChild();
|
|
16225
16403
|
const ok = await new Promise((resolve5) => {
|
|
16226
|
-
const proc = (0,
|
|
16404
|
+
const proc = (0, import_child_process15.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
|
|
16227
16405
|
proc.on("exit", (code) => resolve5(code === 0));
|
|
16228
16406
|
proc.on("error", () => resolve5(false));
|
|
16229
16407
|
});
|
|
@@ -16250,7 +16428,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16250
16428
|
);
|
|
16251
16429
|
resetStdinForChild();
|
|
16252
16430
|
await new Promise((resolve5, reject) => {
|
|
16253
|
-
const proc = (0,
|
|
16431
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16254
16432
|
"gh",
|
|
16255
16433
|
["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
|
|
16256
16434
|
{ stdio: "inherit" }
|
|
@@ -16428,7 +16606,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16428
16606
|
async streamCommand(workspaceId, command2) {
|
|
16429
16607
|
resetStdinForChild();
|
|
16430
16608
|
return new Promise((resolve5, reject) => {
|
|
16431
|
-
const proc = (0,
|
|
16609
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16432
16610
|
"gh",
|
|
16433
16611
|
["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
|
|
16434
16612
|
{ stdio: "inherit" }
|
|
@@ -16455,11 +16633,11 @@ var GitHubCodespacesProvider = class {
|
|
|
16455
16633
|
`mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
|
|
16456
16634
|
];
|
|
16457
16635
|
await new Promise((resolve5, reject) => {
|
|
16458
|
-
const tar = (0,
|
|
16636
|
+
const tar = (0, import_child_process15.spawn)("tar", tarArgs, {
|
|
16459
16637
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16460
16638
|
env: tarEnv
|
|
16461
16639
|
});
|
|
16462
|
-
const ssh = (0,
|
|
16640
|
+
const ssh = (0, import_child_process15.spawn)("gh", sshArgs, {
|
|
16463
16641
|
stdio: [tar.stdout, "pipe", "pipe"]
|
|
16464
16642
|
});
|
|
16465
16643
|
let tarErr = "";
|
|
@@ -16493,7 +16671,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16493
16671
|
}
|
|
16494
16672
|
const cmd = parts.join(" && ");
|
|
16495
16673
|
await new Promise((resolve5, reject) => {
|
|
16496
|
-
const proc = (0,
|
|
16674
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16497
16675
|
"gh",
|
|
16498
16676
|
["codespace", "ssh", "-c", workspaceId, "--", cmd],
|
|
16499
16677
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -16551,11 +16729,11 @@ function shellQuote(s) {
|
|
|
16551
16729
|
}
|
|
16552
16730
|
|
|
16553
16731
|
// src/services/providers/gitpod.ts
|
|
16554
|
-
var
|
|
16732
|
+
var import_child_process16 = require("child_process");
|
|
16555
16733
|
var import_util4 = require("util");
|
|
16556
16734
|
var path35 = __toESM(require("path"));
|
|
16557
16735
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
16558
|
-
var execFileP5 = (0, import_util4.promisify)(
|
|
16736
|
+
var execFileP5 = (0, import_util4.promisify)(import_child_process16.execFile);
|
|
16559
16737
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
16560
16738
|
function resetStdinForChild2() {
|
|
16561
16739
|
if (process.stdin.isTTY) {
|
|
@@ -16595,7 +16773,7 @@ var GitpodProvider = class {
|
|
|
16595
16773
|
);
|
|
16596
16774
|
resetStdinForChild2();
|
|
16597
16775
|
await new Promise((resolve5, reject) => {
|
|
16598
|
-
const proc = (0,
|
|
16776
|
+
const proc = (0, import_child_process16.spawn)("gitpod", ["login"], { stdio: "inherit" });
|
|
16599
16777
|
proc.on("exit", (code) => {
|
|
16600
16778
|
if (code === 0) resolve5();
|
|
16601
16779
|
else reject(new Error("gitpod login failed."));
|
|
@@ -16747,7 +16925,7 @@ var GitpodProvider = class {
|
|
|
16747
16925
|
async streamCommand(workspaceId, command2) {
|
|
16748
16926
|
resetStdinForChild2();
|
|
16749
16927
|
return new Promise((resolve5, reject) => {
|
|
16750
|
-
const proc = (0,
|
|
16928
|
+
const proc = (0, import_child_process16.spawn)(
|
|
16751
16929
|
"gitpod",
|
|
16752
16930
|
["workspace", "ssh", workspaceId, "--", "-tt", command2],
|
|
16753
16931
|
{ stdio: "inherit" }
|
|
@@ -16767,11 +16945,11 @@ var GitpodProvider = class {
|
|
|
16767
16945
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
16768
16946
|
const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
|
|
16769
16947
|
await new Promise((resolve5, reject) => {
|
|
16770
|
-
const tar = (0,
|
|
16948
|
+
const tar = (0, import_child_process16.spawn)("tar", tarArgs, {
|
|
16771
16949
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16772
16950
|
env: tarEnv
|
|
16773
16951
|
});
|
|
16774
|
-
const ssh = (0,
|
|
16952
|
+
const ssh = (0, import_child_process16.spawn)(
|
|
16775
16953
|
"gitpod",
|
|
16776
16954
|
["workspace", "ssh", workspaceId, "--", remoteCmd],
|
|
16777
16955
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -16803,7 +16981,7 @@ var GitpodProvider = class {
|
|
|
16803
16981
|
}
|
|
16804
16982
|
const cmd = parts.join(" && ");
|
|
16805
16983
|
await new Promise((resolve5, reject) => {
|
|
16806
|
-
const proc = (0,
|
|
16984
|
+
const proc = (0, import_child_process16.spawn)(
|
|
16807
16985
|
"gitpod",
|
|
16808
16986
|
["workspace", "ssh", workspaceId, "--", cmd],
|
|
16809
16987
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -16827,10 +17005,10 @@ function shellQuote2(s) {
|
|
|
16827
17005
|
}
|
|
16828
17006
|
|
|
16829
17007
|
// src/services/providers/gitlab-workspaces.ts
|
|
16830
|
-
var
|
|
17008
|
+
var import_child_process17 = require("child_process");
|
|
16831
17009
|
var import_util5 = require("util");
|
|
16832
17010
|
var path36 = __toESM(require("path"));
|
|
16833
|
-
var execFileP6 = (0, import_util5.promisify)(
|
|
17011
|
+
var execFileP6 = (0, import_util5.promisify)(import_child_process17.execFile);
|
|
16834
17012
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
16835
17013
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
16836
17014
|
function resetStdinForChild3() {
|
|
@@ -16872,7 +17050,7 @@ var GitLabWorkspacesProvider = class {
|
|
|
16872
17050
|
);
|
|
16873
17051
|
resetStdinForChild3();
|
|
16874
17052
|
await new Promise((resolve5, reject) => {
|
|
16875
|
-
const proc = (0,
|
|
17053
|
+
const proc = (0, import_child_process17.spawn)(
|
|
16876
17054
|
"glab",
|
|
16877
17055
|
["auth", "login", "--scopes", "api,read_user,read_repository"],
|
|
16878
17056
|
{ stdio: "inherit" }
|
|
@@ -17044,7 +17222,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17044
17222
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
17045
17223
|
resetStdinForChild3();
|
|
17046
17224
|
return new Promise((resolve5, reject) => {
|
|
17047
|
-
const proc = (0,
|
|
17225
|
+
const proc = (0, import_child_process17.spawn)(
|
|
17048
17226
|
"ssh",
|
|
17049
17227
|
["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
|
|
17050
17228
|
{ stdio: "inherit" }
|
|
@@ -17065,8 +17243,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17065
17243
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
17066
17244
|
const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
|
|
17067
17245
|
await new Promise((resolve5, reject) => {
|
|
17068
|
-
const tar = (0,
|
|
17069
|
-
const ssh = (0,
|
|
17246
|
+
const tar = (0, import_child_process17.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
17247
|
+
const ssh = (0, import_child_process17.spawn)(
|
|
17070
17248
|
"ssh",
|
|
17071
17249
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
|
|
17072
17250
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -17096,7 +17274,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17096
17274
|
}
|
|
17097
17275
|
const cmd = parts.join(" && ");
|
|
17098
17276
|
await new Promise((resolve5, reject) => {
|
|
17099
|
-
const proc = (0,
|
|
17277
|
+
const proc = (0, import_child_process17.spawn)(
|
|
17100
17278
|
"ssh",
|
|
17101
17279
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
|
|
17102
17280
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -17155,10 +17333,10 @@ function shellQuote3(s) {
|
|
|
17155
17333
|
}
|
|
17156
17334
|
|
|
17157
17335
|
// src/services/providers/railway.ts
|
|
17158
|
-
var
|
|
17336
|
+
var import_child_process18 = require("child_process");
|
|
17159
17337
|
var import_util6 = require("util");
|
|
17160
17338
|
var path37 = __toESM(require("path"));
|
|
17161
|
-
var execFileP7 = (0, import_util6.promisify)(
|
|
17339
|
+
var execFileP7 = (0, import_util6.promisify)(import_child_process18.execFile);
|
|
17162
17340
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
17163
17341
|
function resetStdinForChild4() {
|
|
17164
17342
|
if (process.stdin.isTTY) {
|
|
@@ -17199,7 +17377,7 @@ var RailwayProvider = class {
|
|
|
17199
17377
|
);
|
|
17200
17378
|
resetStdinForChild4();
|
|
17201
17379
|
await new Promise((resolve5, reject) => {
|
|
17202
|
-
const proc = (0,
|
|
17380
|
+
const proc = (0, import_child_process18.spawn)("railway", ["login"], { stdio: "inherit" });
|
|
17203
17381
|
proc.on("exit", (code) => {
|
|
17204
17382
|
if (code === 0) resolve5();
|
|
17205
17383
|
else reject(new Error("railway login failed."));
|
|
@@ -17342,7 +17520,7 @@ var RailwayProvider = class {
|
|
|
17342
17520
|
}
|
|
17343
17521
|
resetStdinForChild4();
|
|
17344
17522
|
return new Promise((resolve5, reject) => {
|
|
17345
|
-
const proc = (0,
|
|
17523
|
+
const proc = (0, import_child_process18.spawn)(
|
|
17346
17524
|
"railway",
|
|
17347
17525
|
["shell", "--project", projectId, "--service", serviceId, "--command", command2],
|
|
17348
17526
|
{ stdio: "inherit" }
|
|
@@ -17366,8 +17544,8 @@ var RailwayProvider = class {
|
|
|
17366
17544
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
17367
17545
|
const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
|
|
17368
17546
|
await new Promise((resolve5, reject) => {
|
|
17369
|
-
const tar = (0,
|
|
17370
|
-
const sh = (0,
|
|
17547
|
+
const tar = (0, import_child_process18.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
17548
|
+
const sh = (0, import_child_process18.spawn)(
|
|
17371
17549
|
"railway",
|
|
17372
17550
|
["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
|
|
17373
17551
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -17400,7 +17578,7 @@ var RailwayProvider = class {
|
|
|
17400
17578
|
}
|
|
17401
17579
|
const cmd = parts.join(" && ");
|
|
17402
17580
|
await new Promise((resolve5, reject) => {
|
|
17403
|
-
const proc = (0,
|
|
17581
|
+
const proc = (0, import_child_process18.spawn)(
|
|
17404
17582
|
"railway",
|
|
17405
17583
|
["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
|
|
17406
17584
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -18105,7 +18283,7 @@ function checkChokidar() {
|
|
|
18105
18283
|
}
|
|
18106
18284
|
async function doctor(args2 = []) {
|
|
18107
18285
|
const json = args2.includes("--json");
|
|
18108
|
-
const cliVersion = true ? "2.
|
|
18286
|
+
const cliVersion = true ? "2.23.0" : "0.0.0-dev";
|
|
18109
18287
|
const apiBase = resolveApiBaseUrl();
|
|
18110
18288
|
const diagnosticId = (0, import_node_crypto5.randomUUID)();
|
|
18111
18289
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -18304,7 +18482,7 @@ async function completion(args2) {
|
|
|
18304
18482
|
// src/commands/version.ts
|
|
18305
18483
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
18306
18484
|
function version2() {
|
|
18307
|
-
const v = true ? "2.
|
|
18485
|
+
const v = true ? "2.23.0" : "unknown";
|
|
18308
18486
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
18309
18487
|
}
|
|
18310
18488
|
|
|
@@ -18532,7 +18710,7 @@ function checkForUpdates() {
|
|
|
18532
18710
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18533
18711
|
if (process.env.CI) return;
|
|
18534
18712
|
if (!process.stdout.isTTY) return;
|
|
18535
|
-
const current = true ? "2.
|
|
18713
|
+
const current = true ? "2.23.0" : null;
|
|
18536
18714
|
if (!current) return;
|
|
18537
18715
|
const cache = readCache();
|
|
18538
18716
|
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.
|
|
3
|
+
"version": "2.23.0",
|
|
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",
|