codeam-cli 2.22.1 → 2.23.1
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 +241 -56
- package/package.json +1 -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.23.0] — 2026-05-25
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **cli:** AI insights — generateOneShot + handlers (PR 2 of 6) (#188)
|
|
12
|
+
|
|
13
|
+
## [2.22.1] — 2026-05-25
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **cli:** Payload.agentId — accept any string, not just the public enum (#187)
|
|
18
|
+
|
|
7
19
|
## [2.22.0] — 2026-05-25
|
|
8
20
|
|
|
9
21
|
### 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.1",
|
|
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.1" : "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,34 @@ 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
|
-
|
|
13925
|
+
//
|
|
13926
|
+
// `.nullable()` — the web's session page passes the literal value
|
|
13927
|
+
// `null` when no agent has been selected yet for the session
|
|
13928
|
+
// (`currentAgentId` is null before sessionAgents populates).
|
|
13929
|
+
// Without nullable() zod rejects the whole payload, the dispatcher
|
|
13930
|
+
// logs "Ignoring malformed list_models payload" and the model
|
|
13931
|
+
// picker / context never load.
|
|
13932
|
+
agentId: import_zod2.z.string().max(64).nullable().optional(),
|
|
13933
|
+
// `request_ai_summary` / `request_ai_insight` — backend fires
|
|
13934
|
+
// these on turn-end (+ file selection) when LinkedAgent.
|
|
13935
|
+
// aiInsightsEnabled is true. The CLI spawns the agent in
|
|
13936
|
+
// headless one-shot mode (`claude -p "..."` / `codex exec`) and
|
|
13937
|
+
// POSTs the response back to /api/plugin/ai-result.
|
|
13938
|
+
//
|
|
13939
|
+
// `prompt` (declared above for start_task) carries the LLM prompt
|
|
13940
|
+
// the backend pre-rendered with the diff context inlined; the
|
|
13941
|
+
// agent receives it verbatim. `turnId` keys the summary,
|
|
13942
|
+
// `fileChangeId` keys the per-file insight, `stats` is echoed
|
|
13943
|
+
// unchanged on the result POST so the backend doesn't have to
|
|
13944
|
+
// recompute (numbers came from file_changes; the agent only
|
|
13945
|
+
// writes the narrative).
|
|
13946
|
+
turnId: import_zod2.z.string().max(128).optional(),
|
|
13947
|
+
fileChangeId: import_zod2.z.string().max(128).optional(),
|
|
13948
|
+
stats: import_zod2.z.object({
|
|
13949
|
+
added: import_zod2.z.number().int(),
|
|
13950
|
+
removed: import_zod2.z.number().int(),
|
|
13951
|
+
complexityShift: import_zod2.z.number().int()
|
|
13952
|
+
}).optional()
|
|
13827
13953
|
});
|
|
13828
13954
|
function parsePayload2(schema, raw) {
|
|
13829
13955
|
const result = schema.safeParse(raw);
|
|
@@ -13979,11 +14105,11 @@ async function writeProjectFile(rawPath, content) {
|
|
|
13979
14105
|
}
|
|
13980
14106
|
|
|
13981
14107
|
// src/services/project-ops.service.ts
|
|
13982
|
-
var
|
|
14108
|
+
var import_child_process11 = require("child_process");
|
|
13983
14109
|
var import_util2 = require("util");
|
|
13984
14110
|
var fs24 = __toESM(require("fs/promises"));
|
|
13985
14111
|
var path29 = __toESM(require("path"));
|
|
13986
|
-
var execFileP3 = (0, import_util2.promisify)(
|
|
14112
|
+
var execFileP3 = (0, import_util2.promisify)(import_child_process11.execFile);
|
|
13987
14113
|
var PROJECT_IGNORE = /* @__PURE__ */ new Set([
|
|
13988
14114
|
"node_modules",
|
|
13989
14115
|
".git",
|
|
@@ -14323,7 +14449,7 @@ async function jsSearchFiles(opts, cwd, cap) {
|
|
|
14323
14449
|
}
|
|
14324
14450
|
|
|
14325
14451
|
// src/services/terminal-ops.service.ts
|
|
14326
|
-
var
|
|
14452
|
+
var import_child_process12 = require("child_process");
|
|
14327
14453
|
var import_crypto4 = require("crypto");
|
|
14328
14454
|
var import_path3 = __toESM(require("path"));
|
|
14329
14455
|
var MAX_CONCURRENT_SESSIONS = 4;
|
|
@@ -14445,7 +14571,7 @@ function createPythonSession(id, shell, cwd, env, cols, rows) {
|
|
|
14445
14571
|
}
|
|
14446
14572
|
let child;
|
|
14447
14573
|
try {
|
|
14448
|
-
child = (0,
|
|
14574
|
+
child = (0, import_child_process12.spawn)(python, ["-c", PYTHON_TERMINAL_HELPER, shell], {
|
|
14449
14575
|
cwd,
|
|
14450
14576
|
env: { ...env, COLUMNS: String(cols), LINES: String(rows) },
|
|
14451
14577
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -14580,7 +14706,7 @@ function closeAllTerminals() {
|
|
|
14580
14706
|
}
|
|
14581
14707
|
|
|
14582
14708
|
// src/services/apply-file-review.service.ts
|
|
14583
|
-
var
|
|
14709
|
+
var import_child_process13 = require("child_process");
|
|
14584
14710
|
var fs25 = __toESM(require("fs"));
|
|
14585
14711
|
var path31 = __toESM(require("path"));
|
|
14586
14712
|
async function applyFileReview(workingDir, filePath, action) {
|
|
@@ -14622,7 +14748,7 @@ function runGit3(cwd, args2) {
|
|
|
14622
14748
|
return new Promise((resolve5) => {
|
|
14623
14749
|
let proc;
|
|
14624
14750
|
try {
|
|
14625
|
-
proc = (0,
|
|
14751
|
+
proc = (0, import_child_process13.spawn)("git", args2, { cwd, env: process.env });
|
|
14626
14752
|
} catch (err) {
|
|
14627
14753
|
resolve5({ ok: false, code: -1, stdout: "", stderr: err.message });
|
|
14628
14754
|
return;
|
|
@@ -15153,7 +15279,7 @@ var sessionTerminated = (ctx) => {
|
|
|
15153
15279
|
} catch {
|
|
15154
15280
|
}
|
|
15155
15281
|
try {
|
|
15156
|
-
const proc = (0,
|
|
15282
|
+
const proc = (0, import_child_process14.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
15157
15283
|
detached: true,
|
|
15158
15284
|
stdio: "ignore"
|
|
15159
15285
|
});
|
|
@@ -15175,7 +15301,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
15175
15301
|
}
|
|
15176
15302
|
if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
|
|
15177
15303
|
try {
|
|
15178
|
-
const stopProc = (0,
|
|
15304
|
+
const stopProc = (0, import_child_process14.spawn)(
|
|
15179
15305
|
"bash",
|
|
15180
15306
|
["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
|
|
15181
15307
|
{ detached: true, stdio: "ignore" }
|
|
@@ -15185,7 +15311,7 @@ var shutdownSession = async (ctx, cmd) => {
|
|
|
15185
15311
|
}
|
|
15186
15312
|
}
|
|
15187
15313
|
try {
|
|
15188
|
-
const proc = (0,
|
|
15314
|
+
const proc = (0, import_child_process14.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
|
|
15189
15315
|
detached: true,
|
|
15190
15316
|
stdio: "ignore"
|
|
15191
15317
|
});
|
|
@@ -15367,6 +15493,62 @@ var requestLinkCredentialsH = async (ctx, _cmd, parsed) => {
|
|
|
15367
15493
|
log.trace("auto-link", `upload failed (${result.status}): ${result.message}`);
|
|
15368
15494
|
}
|
|
15369
15495
|
};
|
|
15496
|
+
var requestAiSummaryH = async (ctx, _cmd, parsed) => {
|
|
15497
|
+
if (!ctx.pluginAuthToken) return;
|
|
15498
|
+
if (typeof ctx.runtime.generateOneShot !== "function") return;
|
|
15499
|
+
if (!parsed.prompt || !parsed.turnId || !parsed.stats) {
|
|
15500
|
+
log.trace("ai-summary", "missing prompt/turnId/stats \u2014 skipping");
|
|
15501
|
+
return;
|
|
15502
|
+
}
|
|
15503
|
+
const text = await ctx.runtime.generateOneShot(parsed.prompt).catch((err) => {
|
|
15504
|
+
log.trace("ai-summary", "generateOneShot threw", err);
|
|
15505
|
+
return null;
|
|
15506
|
+
});
|
|
15507
|
+
if (!text) return;
|
|
15508
|
+
await postAiResult({
|
|
15509
|
+
sessionId: ctx.sessionId,
|
|
15510
|
+
pluginId: ctx.pluginId,
|
|
15511
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
15512
|
+
kind: "summary",
|
|
15513
|
+
turnId: parsed.turnId,
|
|
15514
|
+
summary: text,
|
|
15515
|
+
stats: parsed.stats
|
|
15516
|
+
});
|
|
15517
|
+
};
|
|
15518
|
+
var requestAiInsightH = async (ctx, _cmd, parsed) => {
|
|
15519
|
+
if (!ctx.pluginAuthToken) return;
|
|
15520
|
+
if (typeof ctx.runtime.generateOneShot !== "function") return;
|
|
15521
|
+
if (!parsed.prompt || !parsed.fileChangeId) {
|
|
15522
|
+
log.trace("ai-insight", "missing prompt/fileChangeId \u2014 skipping");
|
|
15523
|
+
return;
|
|
15524
|
+
}
|
|
15525
|
+
const text = await ctx.runtime.generateOneShot(parsed.prompt).catch((err) => {
|
|
15526
|
+
log.trace("ai-insight", "generateOneShot threw", err);
|
|
15527
|
+
return null;
|
|
15528
|
+
});
|
|
15529
|
+
if (!text) return;
|
|
15530
|
+
const { summary, reasoning, securityNote } = parseInsightText(text);
|
|
15531
|
+
await postAiResult({
|
|
15532
|
+
sessionId: ctx.sessionId,
|
|
15533
|
+
pluginId: ctx.pluginId,
|
|
15534
|
+
pluginAuthToken: ctx.pluginAuthToken,
|
|
15535
|
+
kind: "insight",
|
|
15536
|
+
fileChangeId: parsed.fileChangeId,
|
|
15537
|
+
summary,
|
|
15538
|
+
reasoning,
|
|
15539
|
+
securityNote
|
|
15540
|
+
});
|
|
15541
|
+
};
|
|
15542
|
+
function parseInsightText(text) {
|
|
15543
|
+
const summaryMatch = text.match(/SUMMARY:\s*([\s\S]*?)(?=\n\s*(?:REASONING|SECURITY):|$)/i);
|
|
15544
|
+
const reasoningMatch = text.match(/REASONING:\s*([\s\S]*?)(?=\n\s*SECURITY:|$)/i);
|
|
15545
|
+
const securityMatch = text.match(/SECURITY:\s*([\s\S]*)/i);
|
|
15546
|
+
return {
|
|
15547
|
+
summary: (summaryMatch?.[1] ?? text).trim(),
|
|
15548
|
+
reasoning: (reasoningMatch?.[1] ?? text).trim(),
|
|
15549
|
+
securityNote: securityMatch?.[1]?.trim() || void 0
|
|
15550
|
+
};
|
|
15551
|
+
}
|
|
15370
15552
|
var handlers = {
|
|
15371
15553
|
start_task: startTask,
|
|
15372
15554
|
provide_input: provideInput,
|
|
@@ -15399,7 +15581,9 @@ var handlers = {
|
|
|
15399
15581
|
git_pull: gitPullH,
|
|
15400
15582
|
git_resolve: gitResolveH,
|
|
15401
15583
|
apply_file_review: applyFileReviewH,
|
|
15402
|
-
request_link_credentials: requestLinkCredentialsH
|
|
15584
|
+
request_link_credentials: requestLinkCredentialsH,
|
|
15585
|
+
request_ai_summary: requestAiSummaryH,
|
|
15586
|
+
request_ai_insight: requestAiInsightH
|
|
15403
15587
|
};
|
|
15404
15588
|
async function dispatchCommand(ctx, cmd) {
|
|
15405
15589
|
const parsed = parsePayload2(startCommandSchema, cmd.payload);
|
|
@@ -15494,6 +15678,7 @@ async function start(requestedAgent) {
|
|
|
15494
15678
|
sessionId: session.id,
|
|
15495
15679
|
pluginId,
|
|
15496
15680
|
pluginAuthToken: session.pluginAuthToken,
|
|
15681
|
+
agentId: runtime.meta.id,
|
|
15497
15682
|
dirtyTracker: dirtyTracker ?? void 0
|
|
15498
15683
|
}) : null;
|
|
15499
15684
|
let streamingEmitter = null;
|
|
@@ -15991,11 +16176,11 @@ async function logout() {
|
|
|
15991
16176
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
15992
16177
|
|
|
15993
16178
|
// src/services/providers/github-codespaces.ts
|
|
15994
|
-
var
|
|
16179
|
+
var import_child_process15 = require("child_process");
|
|
15995
16180
|
var import_util3 = require("util");
|
|
15996
16181
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
15997
16182
|
var path34 = __toESM(require("path"));
|
|
15998
|
-
var execFileP4 = (0, import_util3.promisify)(
|
|
16183
|
+
var execFileP4 = (0, import_util3.promisify)(import_child_process15.execFile);
|
|
15999
16184
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
16000
16185
|
function resetStdinForChild() {
|
|
16001
16186
|
if (process.stdin.isTTY) {
|
|
@@ -16039,7 +16224,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16039
16224
|
if (!isAuthed) {
|
|
16040
16225
|
resetStdinForChild();
|
|
16041
16226
|
await new Promise((resolve5, reject) => {
|
|
16042
|
-
const proc = (0,
|
|
16227
|
+
const proc = (0, import_child_process15.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
|
|
16043
16228
|
stdio: "inherit"
|
|
16044
16229
|
});
|
|
16045
16230
|
proc.on("exit", (code) => {
|
|
@@ -16073,7 +16258,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16073
16258
|
wt(noteLines.join("\n"), "One more permission needed");
|
|
16074
16259
|
resetStdinForChild();
|
|
16075
16260
|
const refreshCode = await new Promise((resolve5, reject) => {
|
|
16076
|
-
const proc = (0,
|
|
16261
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16077
16262
|
"gh",
|
|
16078
16263
|
["auth", "refresh", "-h", "github.com", "-s", "codespace"],
|
|
16079
16264
|
{ stdio: "inherit" }
|
|
@@ -16223,7 +16408,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16223
16408
|
O2.step(`Installing gh via ${installCmd.describe}\u2026`);
|
|
16224
16409
|
resetStdinForChild();
|
|
16225
16410
|
const ok = await new Promise((resolve5) => {
|
|
16226
|
-
const proc = (0,
|
|
16411
|
+
const proc = (0, import_child_process15.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
|
|
16227
16412
|
proc.on("exit", (code) => resolve5(code === 0));
|
|
16228
16413
|
proc.on("error", () => resolve5(false));
|
|
16229
16414
|
});
|
|
@@ -16250,7 +16435,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16250
16435
|
);
|
|
16251
16436
|
resetStdinForChild();
|
|
16252
16437
|
await new Promise((resolve5, reject) => {
|
|
16253
|
-
const proc = (0,
|
|
16438
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16254
16439
|
"gh",
|
|
16255
16440
|
["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
|
|
16256
16441
|
{ stdio: "inherit" }
|
|
@@ -16428,7 +16613,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16428
16613
|
async streamCommand(workspaceId, command2) {
|
|
16429
16614
|
resetStdinForChild();
|
|
16430
16615
|
return new Promise((resolve5, reject) => {
|
|
16431
|
-
const proc = (0,
|
|
16616
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16432
16617
|
"gh",
|
|
16433
16618
|
["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
|
|
16434
16619
|
{ stdio: "inherit" }
|
|
@@ -16455,11 +16640,11 @@ var GitHubCodespacesProvider = class {
|
|
|
16455
16640
|
`mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
|
|
16456
16641
|
];
|
|
16457
16642
|
await new Promise((resolve5, reject) => {
|
|
16458
|
-
const tar = (0,
|
|
16643
|
+
const tar = (0, import_child_process15.spawn)("tar", tarArgs, {
|
|
16459
16644
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16460
16645
|
env: tarEnv
|
|
16461
16646
|
});
|
|
16462
|
-
const ssh = (0,
|
|
16647
|
+
const ssh = (0, import_child_process15.spawn)("gh", sshArgs, {
|
|
16463
16648
|
stdio: [tar.stdout, "pipe", "pipe"]
|
|
16464
16649
|
});
|
|
16465
16650
|
let tarErr = "";
|
|
@@ -16493,7 +16678,7 @@ var GitHubCodespacesProvider = class {
|
|
|
16493
16678
|
}
|
|
16494
16679
|
const cmd = parts.join(" && ");
|
|
16495
16680
|
await new Promise((resolve5, reject) => {
|
|
16496
|
-
const proc = (0,
|
|
16681
|
+
const proc = (0, import_child_process15.spawn)(
|
|
16497
16682
|
"gh",
|
|
16498
16683
|
["codespace", "ssh", "-c", workspaceId, "--", cmd],
|
|
16499
16684
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -16551,11 +16736,11 @@ function shellQuote(s) {
|
|
|
16551
16736
|
}
|
|
16552
16737
|
|
|
16553
16738
|
// src/services/providers/gitpod.ts
|
|
16554
|
-
var
|
|
16739
|
+
var import_child_process16 = require("child_process");
|
|
16555
16740
|
var import_util4 = require("util");
|
|
16556
16741
|
var path35 = __toESM(require("path"));
|
|
16557
16742
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
16558
|
-
var execFileP5 = (0, import_util4.promisify)(
|
|
16743
|
+
var execFileP5 = (0, import_util4.promisify)(import_child_process16.execFile);
|
|
16559
16744
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
16560
16745
|
function resetStdinForChild2() {
|
|
16561
16746
|
if (process.stdin.isTTY) {
|
|
@@ -16595,7 +16780,7 @@ var GitpodProvider = class {
|
|
|
16595
16780
|
);
|
|
16596
16781
|
resetStdinForChild2();
|
|
16597
16782
|
await new Promise((resolve5, reject) => {
|
|
16598
|
-
const proc = (0,
|
|
16783
|
+
const proc = (0, import_child_process16.spawn)("gitpod", ["login"], { stdio: "inherit" });
|
|
16599
16784
|
proc.on("exit", (code) => {
|
|
16600
16785
|
if (code === 0) resolve5();
|
|
16601
16786
|
else reject(new Error("gitpod login failed."));
|
|
@@ -16747,7 +16932,7 @@ var GitpodProvider = class {
|
|
|
16747
16932
|
async streamCommand(workspaceId, command2) {
|
|
16748
16933
|
resetStdinForChild2();
|
|
16749
16934
|
return new Promise((resolve5, reject) => {
|
|
16750
|
-
const proc = (0,
|
|
16935
|
+
const proc = (0, import_child_process16.spawn)(
|
|
16751
16936
|
"gitpod",
|
|
16752
16937
|
["workspace", "ssh", workspaceId, "--", "-tt", command2],
|
|
16753
16938
|
{ stdio: "inherit" }
|
|
@@ -16767,11 +16952,11 @@ var GitpodProvider = class {
|
|
|
16767
16952
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
16768
16953
|
const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
|
|
16769
16954
|
await new Promise((resolve5, reject) => {
|
|
16770
|
-
const tar = (0,
|
|
16955
|
+
const tar = (0, import_child_process16.spawn)("tar", tarArgs, {
|
|
16771
16956
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16772
16957
|
env: tarEnv
|
|
16773
16958
|
});
|
|
16774
|
-
const ssh = (0,
|
|
16959
|
+
const ssh = (0, import_child_process16.spawn)(
|
|
16775
16960
|
"gitpod",
|
|
16776
16961
|
["workspace", "ssh", workspaceId, "--", remoteCmd],
|
|
16777
16962
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -16803,7 +16988,7 @@ var GitpodProvider = class {
|
|
|
16803
16988
|
}
|
|
16804
16989
|
const cmd = parts.join(" && ");
|
|
16805
16990
|
await new Promise((resolve5, reject) => {
|
|
16806
|
-
const proc = (0,
|
|
16991
|
+
const proc = (0, import_child_process16.spawn)(
|
|
16807
16992
|
"gitpod",
|
|
16808
16993
|
["workspace", "ssh", workspaceId, "--", cmd],
|
|
16809
16994
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -16827,10 +17012,10 @@ function shellQuote2(s) {
|
|
|
16827
17012
|
}
|
|
16828
17013
|
|
|
16829
17014
|
// src/services/providers/gitlab-workspaces.ts
|
|
16830
|
-
var
|
|
17015
|
+
var import_child_process17 = require("child_process");
|
|
16831
17016
|
var import_util5 = require("util");
|
|
16832
17017
|
var path36 = __toESM(require("path"));
|
|
16833
|
-
var execFileP6 = (0, import_util5.promisify)(
|
|
17018
|
+
var execFileP6 = (0, import_util5.promisify)(import_child_process17.execFile);
|
|
16834
17019
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
16835
17020
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
16836
17021
|
function resetStdinForChild3() {
|
|
@@ -16872,7 +17057,7 @@ var GitLabWorkspacesProvider = class {
|
|
|
16872
17057
|
);
|
|
16873
17058
|
resetStdinForChild3();
|
|
16874
17059
|
await new Promise((resolve5, reject) => {
|
|
16875
|
-
const proc = (0,
|
|
17060
|
+
const proc = (0, import_child_process17.spawn)(
|
|
16876
17061
|
"glab",
|
|
16877
17062
|
["auth", "login", "--scopes", "api,read_user,read_repository"],
|
|
16878
17063
|
{ stdio: "inherit" }
|
|
@@ -17044,7 +17229,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17044
17229
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
17045
17230
|
resetStdinForChild3();
|
|
17046
17231
|
return new Promise((resolve5, reject) => {
|
|
17047
|
-
const proc = (0,
|
|
17232
|
+
const proc = (0, import_child_process17.spawn)(
|
|
17048
17233
|
"ssh",
|
|
17049
17234
|
["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
|
|
17050
17235
|
{ stdio: "inherit" }
|
|
@@ -17065,8 +17250,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17065
17250
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
17066
17251
|
const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
|
|
17067
17252
|
await new Promise((resolve5, reject) => {
|
|
17068
|
-
const tar = (0,
|
|
17069
|
-
const ssh = (0,
|
|
17253
|
+
const tar = (0, import_child_process17.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
17254
|
+
const ssh = (0, import_child_process17.spawn)(
|
|
17070
17255
|
"ssh",
|
|
17071
17256
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
|
|
17072
17257
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -17096,7 +17281,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
17096
17281
|
}
|
|
17097
17282
|
const cmd = parts.join(" && ");
|
|
17098
17283
|
await new Promise((resolve5, reject) => {
|
|
17099
|
-
const proc = (0,
|
|
17284
|
+
const proc = (0, import_child_process17.spawn)(
|
|
17100
17285
|
"ssh",
|
|
17101
17286
|
["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
|
|
17102
17287
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -17155,10 +17340,10 @@ function shellQuote3(s) {
|
|
|
17155
17340
|
}
|
|
17156
17341
|
|
|
17157
17342
|
// src/services/providers/railway.ts
|
|
17158
|
-
var
|
|
17343
|
+
var import_child_process18 = require("child_process");
|
|
17159
17344
|
var import_util6 = require("util");
|
|
17160
17345
|
var path37 = __toESM(require("path"));
|
|
17161
|
-
var execFileP7 = (0, import_util6.promisify)(
|
|
17346
|
+
var execFileP7 = (0, import_util6.promisify)(import_child_process18.execFile);
|
|
17162
17347
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
17163
17348
|
function resetStdinForChild4() {
|
|
17164
17349
|
if (process.stdin.isTTY) {
|
|
@@ -17199,7 +17384,7 @@ var RailwayProvider = class {
|
|
|
17199
17384
|
);
|
|
17200
17385
|
resetStdinForChild4();
|
|
17201
17386
|
await new Promise((resolve5, reject) => {
|
|
17202
|
-
const proc = (0,
|
|
17387
|
+
const proc = (0, import_child_process18.spawn)("railway", ["login"], { stdio: "inherit" });
|
|
17203
17388
|
proc.on("exit", (code) => {
|
|
17204
17389
|
if (code === 0) resolve5();
|
|
17205
17390
|
else reject(new Error("railway login failed."));
|
|
@@ -17342,7 +17527,7 @@ var RailwayProvider = class {
|
|
|
17342
17527
|
}
|
|
17343
17528
|
resetStdinForChild4();
|
|
17344
17529
|
return new Promise((resolve5, reject) => {
|
|
17345
|
-
const proc = (0,
|
|
17530
|
+
const proc = (0, import_child_process18.spawn)(
|
|
17346
17531
|
"railway",
|
|
17347
17532
|
["shell", "--project", projectId, "--service", serviceId, "--command", command2],
|
|
17348
17533
|
{ stdio: "inherit" }
|
|
@@ -17366,8 +17551,8 @@ var RailwayProvider = class {
|
|
|
17366
17551
|
const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
|
|
17367
17552
|
const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
|
|
17368
17553
|
await new Promise((resolve5, reject) => {
|
|
17369
|
-
const tar = (0,
|
|
17370
|
-
const sh = (0,
|
|
17554
|
+
const tar = (0, import_child_process18.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
|
|
17555
|
+
const sh = (0, import_child_process18.spawn)(
|
|
17371
17556
|
"railway",
|
|
17372
17557
|
["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
|
|
17373
17558
|
{ stdio: [tar.stdout, "pipe", "pipe"] }
|
|
@@ -17400,7 +17585,7 @@ var RailwayProvider = class {
|
|
|
17400
17585
|
}
|
|
17401
17586
|
const cmd = parts.join(" && ");
|
|
17402
17587
|
await new Promise((resolve5, reject) => {
|
|
17403
|
-
const proc = (0,
|
|
17588
|
+
const proc = (0, import_child_process18.spawn)(
|
|
17404
17589
|
"railway",
|
|
17405
17590
|
["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
|
|
17406
17591
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -18105,7 +18290,7 @@ function checkChokidar() {
|
|
|
18105
18290
|
}
|
|
18106
18291
|
async function doctor(args2 = []) {
|
|
18107
18292
|
const json = args2.includes("--json");
|
|
18108
|
-
const cliVersion = true ? "2.
|
|
18293
|
+
const cliVersion = true ? "2.23.1" : "0.0.0-dev";
|
|
18109
18294
|
const apiBase = resolveApiBaseUrl();
|
|
18110
18295
|
const diagnosticId = (0, import_node_crypto5.randomUUID)();
|
|
18111
18296
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -18304,7 +18489,7 @@ async function completion(args2) {
|
|
|
18304
18489
|
// src/commands/version.ts
|
|
18305
18490
|
var import_picocolors13 = __toESM(require("picocolors"));
|
|
18306
18491
|
function version2() {
|
|
18307
|
-
const v = true ? "2.
|
|
18492
|
+
const v = true ? "2.23.1" : "unknown";
|
|
18308
18493
|
console.log(`${import_picocolors13.default.bold("codeam-cli")} ${import_picocolors13.default.cyan(v)}`);
|
|
18309
18494
|
}
|
|
18310
18495
|
|
|
@@ -18532,7 +18717,7 @@ function checkForUpdates() {
|
|
|
18532
18717
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18533
18718
|
if (process.env.CI) return;
|
|
18534
18719
|
if (!process.stdout.isTTY) return;
|
|
18535
|
-
const current = true ? "2.
|
|
18720
|
+
const current = true ? "2.23.1" : null;
|
|
18536
18721
|
if (!current) return;
|
|
18537
18722
|
const cache = readCache();
|
|
18538
18723
|
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.1",
|
|
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",
|