codeam-cli 2.65.2 → 2.65.4
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 +16 -0
- package/dist/index.js +841 -743
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -976,6 +976,12 @@ var PUBLIC_TO_INTERNAL = {
|
|
|
976
976
|
// MiniMax proxy). Its internal runtime is therefore `claude`.
|
|
977
977
|
[HOUSE_AGENT_ID]: "claude"
|
|
978
978
|
};
|
|
979
|
+
function isPublicToInternalKey(v) {
|
|
980
|
+
return Object.prototype.hasOwnProperty.call(PUBLIC_TO_INTERNAL, v);
|
|
981
|
+
}
|
|
982
|
+
function publicToInternal(publicId) {
|
|
983
|
+
return isPublicToInternalKey(publicId) ? PUBLIC_TO_INTERNAL[publicId] : null;
|
|
984
|
+
}
|
|
979
985
|
var TERMINAL_AGENT_PREFIX = "__terminal__:";
|
|
980
986
|
var AGENT_ID_ALIASES = {
|
|
981
987
|
claude_code: "claude",
|
|
@@ -3321,9 +3327,9 @@ var _default = makeConfig();
|
|
|
3321
3327
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
3322
3328
|
|
|
3323
3329
|
// src/commands/pair-auto.ts
|
|
3324
|
-
var
|
|
3325
|
-
var
|
|
3326
|
-
var
|
|
3330
|
+
var fs65 = __toESM(require("fs"));
|
|
3331
|
+
var os55 = __toESM(require("os"));
|
|
3332
|
+
var path70 = __toESM(require("path"));
|
|
3327
3333
|
var import_crypto4 = require("crypto");
|
|
3328
3334
|
|
|
3329
3335
|
// src/services/telemetry.service.ts
|
|
@@ -8073,7 +8079,7 @@ function readAnonId() {
|
|
|
8073
8079
|
}
|
|
8074
8080
|
function superProperties() {
|
|
8075
8081
|
return {
|
|
8076
|
-
cliVersion: true ? "2.65.
|
|
8082
|
+
cliVersion: true ? "2.65.4" : "0.0.0-dev",
|
|
8077
8083
|
nodeVersion: process.version,
|
|
8078
8084
|
platform: process.platform,
|
|
8079
8085
|
arch: process.arch,
|
|
@@ -8254,7 +8260,7 @@ var os4 = __toESM(require("os"));
|
|
|
8254
8260
|
// package.json
|
|
8255
8261
|
var package_default = {
|
|
8256
8262
|
name: "codeam-cli",
|
|
8257
|
-
version: "2.65.
|
|
8263
|
+
version: "2.65.4",
|
|
8258
8264
|
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.",
|
|
8259
8265
|
type: "commonjs",
|
|
8260
8266
|
main: "dist/index.js",
|
|
@@ -9706,7 +9712,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
9706
9712
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
9707
9713
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
9708
9714
|
// pair/reconnect). Older backends ignore the extra field.
|
|
9709
|
-
..."2.65.
|
|
9715
|
+
..."2.65.4" ? { ideVersion: "2.65.4" } : {}
|
|
9710
9716
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
9711
9717
|
}
|
|
9712
9718
|
/**
|
|
@@ -11098,9 +11104,9 @@ function closeAllTerminals() {
|
|
|
11098
11104
|
}
|
|
11099
11105
|
|
|
11100
11106
|
// src/commands/start/handlers.ts
|
|
11101
|
-
var
|
|
11102
|
-
var
|
|
11103
|
-
var
|
|
11107
|
+
var fs64 = __toESM(require("fs"));
|
|
11108
|
+
var os54 = __toESM(require("os"));
|
|
11109
|
+
var path69 = __toESM(require("path"));
|
|
11104
11110
|
var import_crypto3 = require("crypto");
|
|
11105
11111
|
var import_child_process26 = require("child_process");
|
|
11106
11112
|
|
|
@@ -11932,8 +11938,8 @@ function findGitRoot2(startDir) {
|
|
|
11932
11938
|
|
|
11933
11939
|
// src/commands/link.ts
|
|
11934
11940
|
var import_node_crypto8 = require("crypto");
|
|
11935
|
-
var
|
|
11936
|
-
var
|
|
11941
|
+
var fs33 = __toESM(require("fs"));
|
|
11942
|
+
var path38 = __toESM(require("path"));
|
|
11937
11943
|
var import_chokidar = __toESM(require("chokidar"));
|
|
11938
11944
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
11939
11945
|
|
|
@@ -15556,12 +15562,310 @@ var ClaudeDeployStrategy = class {
|
|
|
15556
15562
|
|
|
15557
15563
|
// src/agents/codex/runtime.ts
|
|
15558
15564
|
var import_node_child_process5 = require("child_process");
|
|
15559
|
-
var
|
|
15565
|
+
var path26 = __toESM(require("path"));
|
|
15560
15566
|
|
|
15561
15567
|
// src/agents/codex/history.ts
|
|
15562
15568
|
var import_node_fs3 = __toESM(require("fs"));
|
|
15563
15569
|
var import_node_path2 = __toESM(require("path"));
|
|
15564
15570
|
var import_node_os = __toESM(require("os"));
|
|
15571
|
+
|
|
15572
|
+
// src/agents/acp/squad-roster.ts
|
|
15573
|
+
var fs20 = __toESM(require("fs"));
|
|
15574
|
+
var os18 = __toESM(require("os"));
|
|
15575
|
+
var path23 = __toESM(require("path"));
|
|
15576
|
+
var PROMPT_MAX = 500;
|
|
15577
|
+
var REPLY_SUMMARY_MAX = 1e3;
|
|
15578
|
+
var PREAMBLE_MAX = 2e3;
|
|
15579
|
+
var BRIEFING_DEFAULT_MAX = 8e3;
|
|
15580
|
+
var GENERIC_SPECIALTY = "general implementation tasks";
|
|
15581
|
+
function clip(s, max) {
|
|
15582
|
+
return s.length > max ? s.slice(0, max) : s;
|
|
15583
|
+
}
|
|
15584
|
+
function defaultMember() {
|
|
15585
|
+
return {
|
|
15586
|
+
acpSessionId: null,
|
|
15587
|
+
provisioned: false,
|
|
15588
|
+
binaryVerified: false,
|
|
15589
|
+
lastTurnIndex: 0,
|
|
15590
|
+
contextTextFallback: false
|
|
15591
|
+
};
|
|
15592
|
+
}
|
|
15593
|
+
function journalPathFor(homeDir2, sessionId) {
|
|
15594
|
+
return path23.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
|
|
15595
|
+
}
|
|
15596
|
+
function loadJournal(journalPath) {
|
|
15597
|
+
try {
|
|
15598
|
+
const raw = JSON.parse(fs20.readFileSync(journalPath, "utf-8"));
|
|
15599
|
+
return Array.isArray(raw.turns) ? raw.turns : [];
|
|
15600
|
+
} catch {
|
|
15601
|
+
return [];
|
|
15602
|
+
}
|
|
15603
|
+
}
|
|
15604
|
+
var SquadState = class {
|
|
15605
|
+
/** Set by the caller after fetchSquadRoster; null until then. */
|
|
15606
|
+
roster = null;
|
|
15607
|
+
/**
|
|
15608
|
+
* Autonomous chained handoffs (P2-2, PRO). Seeded from the persisted
|
|
15609
|
+
* `SavedSession.squadAuto` at session start and rewritten by
|
|
15610
|
+
* `squad_configure`. Read-only to callers — mutate via {@link setAuto}, which
|
|
15611
|
+
* clamps the budget and re-arms the chain.
|
|
15612
|
+
*/
|
|
15613
|
+
autoConfig = { enabled: false, hopBudget: SQUAD_HOP_BUDGET_DEFAULT };
|
|
15614
|
+
/**
|
|
15615
|
+
* Hops left in the CURRENT chain. Reset to the budget on every USER-initiated
|
|
15616
|
+
* prompt (so a user turn always interrupts and re-arms) and decremented by
|
|
15617
|
+
* each self-accepted handoff.
|
|
15618
|
+
*/
|
|
15619
|
+
hopsLeft = 0;
|
|
15620
|
+
/** Lifetime handoff counters for `squad_stats` (in-memory, this process). */
|
|
15621
|
+
handoffCounters = { proposed: 0, accepted: 0, auto: 0 };
|
|
15622
|
+
journalPath;
|
|
15623
|
+
turns;
|
|
15624
|
+
members = /* @__PURE__ */ new Map();
|
|
15625
|
+
constructor(opts) {
|
|
15626
|
+
this.journalPath = journalPathFor(opts.homeDir ?? os18.homedir(), opts.sessionId);
|
|
15627
|
+
this.turns = loadJournal(this.journalPath);
|
|
15628
|
+
if (opts.auto) this.setAuto(opts.auto);
|
|
15629
|
+
}
|
|
15630
|
+
get auto() {
|
|
15631
|
+
return this.autoConfig;
|
|
15632
|
+
}
|
|
15633
|
+
/** Apply a new mode (clamping the budget) and re-arm the chain. */
|
|
15634
|
+
setAuto(value) {
|
|
15635
|
+
this.autoConfig = {
|
|
15636
|
+
enabled: value.enabled === true,
|
|
15637
|
+
hopBudget: clampHopBudget(value.hopBudget)
|
|
15638
|
+
};
|
|
15639
|
+
this.resetHops();
|
|
15640
|
+
return this.autoConfig;
|
|
15641
|
+
}
|
|
15642
|
+
hopsRemaining() {
|
|
15643
|
+
return this.hopsLeft;
|
|
15644
|
+
}
|
|
15645
|
+
/** Re-arm the chain — called at the start of every USER-initiated turn. */
|
|
15646
|
+
resetHops() {
|
|
15647
|
+
this.hopsLeft = this.autoConfig.enabled ? this.autoConfig.hopBudget : 0;
|
|
15648
|
+
}
|
|
15649
|
+
/** Spend one hop on a self-accepted handoff. */
|
|
15650
|
+
consumeHop() {
|
|
15651
|
+
if (this.hopsLeft > 0) this.hopsLeft -= 1;
|
|
15652
|
+
}
|
|
15653
|
+
countProposal(opts) {
|
|
15654
|
+
this.handoffCounters.proposed += 1;
|
|
15655
|
+
if (opts.auto) this.handoffCounters.auto += 1;
|
|
15656
|
+
}
|
|
15657
|
+
countAccepted() {
|
|
15658
|
+
this.handoffCounters.accepted += 1;
|
|
15659
|
+
}
|
|
15660
|
+
/**
|
|
15661
|
+
* Per-member activity for the `squad_stats` relay command, derived from the
|
|
15662
|
+
* journal (the same shared history the delta briefing reads) plus the
|
|
15663
|
+
* in-memory handoff counters. `filesTouched` counts DISTINCT paths — a member
|
|
15664
|
+
* that edited the same file across three turns touched ONE file.
|
|
15665
|
+
*/
|
|
15666
|
+
stats() {
|
|
15667
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
15668
|
+
for (const t2 of this.turns) {
|
|
15669
|
+
let row = byAgent.get(t2.agentId);
|
|
15670
|
+
if (!row) {
|
|
15671
|
+
row = { turns: 0, files: /* @__PURE__ */ new Set() };
|
|
15672
|
+
byAgent.set(t2.agentId, row);
|
|
15673
|
+
}
|
|
15674
|
+
row.turns += 1;
|
|
15675
|
+
for (const f of t2.filesTouched) row.files.add(f);
|
|
15676
|
+
}
|
|
15677
|
+
const members = [...byAgent.entries()].map(([agentId, row]) => ({
|
|
15678
|
+
agentId,
|
|
15679
|
+
turns: row.turns,
|
|
15680
|
+
filesTouched: row.files.size
|
|
15681
|
+
}));
|
|
15682
|
+
return { members, handoffs: { ...this.handoffCounters }, sinceTurn: 1 };
|
|
15683
|
+
}
|
|
15684
|
+
/** Returns (creating on first access) the mutable per-agent state. */
|
|
15685
|
+
member(agentId) {
|
|
15686
|
+
let m = this.members.get(agentId);
|
|
15687
|
+
if (!m) {
|
|
15688
|
+
m = defaultMember();
|
|
15689
|
+
this.members.set(agentId, m);
|
|
15690
|
+
}
|
|
15691
|
+
return m;
|
|
15692
|
+
}
|
|
15693
|
+
/** Appends a journal entry and persists (fire-and-forget durability). */
|
|
15694
|
+
recordTurn(entry) {
|
|
15695
|
+
const turn = {
|
|
15696
|
+
turn: this.turns.length + 1,
|
|
15697
|
+
agentId: entry.agentId,
|
|
15698
|
+
prompt: clip(entry.prompt, PROMPT_MAX),
|
|
15699
|
+
replySummary: clip(entry.replySummary, REPLY_SUMMARY_MAX),
|
|
15700
|
+
filesTouched: entry.filesTouched
|
|
15701
|
+
};
|
|
15702
|
+
this.turns.push(turn);
|
|
15703
|
+
this.persist();
|
|
15704
|
+
}
|
|
15705
|
+
turnCount() {
|
|
15706
|
+
return this.turns.length;
|
|
15707
|
+
}
|
|
15708
|
+
entriesSince(turnIndex) {
|
|
15709
|
+
return this.turns.filter((t2) => t2.turn > turnIndex);
|
|
15710
|
+
}
|
|
15711
|
+
persist() {
|
|
15712
|
+
try {
|
|
15713
|
+
fs20.mkdirSync(path23.dirname(this.journalPath), { recursive: true, mode: 448 });
|
|
15714
|
+
fs20.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
|
|
15715
|
+
} catch {
|
|
15716
|
+
}
|
|
15717
|
+
}
|
|
15718
|
+
};
|
|
15719
|
+
function specialtyFor(agentId) {
|
|
15720
|
+
return SQUAD_SPECIALTIES[agentId] ?? GENERIC_SPECIALTY;
|
|
15721
|
+
}
|
|
15722
|
+
var TEAM_PREAMBLE_MARKER = "[Team context]";
|
|
15723
|
+
var TEAM_PREAMBLE_LINES = [
|
|
15724
|
+
"[Team context] You are the active agent in a CodeAgent Mobile session where the user",
|
|
15725
|
+
"has a squad of agents and can pass work between them. Your available teammates:",
|
|
15726
|
+
"If a task clearly fits a teammate better than you, you MAY propose a handoff. The fence",
|
|
15727
|
+
`MUST be a three-backtick code block with the info string exactly ${HANDOFF_FENCE_TAG}`,
|
|
15728
|
+
"(never a single backtick, never bare text) with the JSON alone on its own line inside",
|
|
15729
|
+
"it, exactly like this:",
|
|
15730
|
+
"```" + HANDOFF_FENCE_TAG,
|
|
15731
|
+
'{"to":"<teammate id>","reason":"<one sentence>","prompt":"<the prompt they should run>"}',
|
|
15732
|
+
"```",
|
|
15733
|
+
'"to" MUST be one of the ids shown above, written EXACTLY as shown (e.g. "claude", never',
|
|
15734
|
+
'a display name like "Claude Code"). Propose at most one handoff per reply, only when',
|
|
15735
|
+
"genuinely better, and never announce the block in prose \u2014 the app renders it as a card",
|
|
15736
|
+
"the user can accept."
|
|
15737
|
+
];
|
|
15738
|
+
var TEAM_PREAMBLE_BULLET_RE = /^- .+ — best at: /;
|
|
15739
|
+
var BRIEFING_MARKER = "[Team update]";
|
|
15740
|
+
var BRIEFING_HEADER = "[Team update] While you were away, other agents worked on this session:";
|
|
15741
|
+
var BRIEFING_FOOTER = "Continue from the CURRENT state of the working tree.";
|
|
15742
|
+
function buildTeamPreamble(roster, currentAgent, opts) {
|
|
15743
|
+
const others = roster.agents.filter((a) => a.agentId !== currentAgent);
|
|
15744
|
+
if (others.length === 0) return null;
|
|
15745
|
+
const lines = [
|
|
15746
|
+
TEAM_PREAMBLE_LINES[0],
|
|
15747
|
+
TEAM_PREAMBLE_LINES[1],
|
|
15748
|
+
...others.map(
|
|
15749
|
+
(a) => `- ${a.displayName} (id: ${a.agentId}) \u2014 best at: ${specialtyFor(a.agentId)}`
|
|
15750
|
+
)
|
|
15751
|
+
];
|
|
15752
|
+
if (opts.handoffInstructions) {
|
|
15753
|
+
lines.push(...TEAM_PREAMBLE_LINES.slice(2));
|
|
15754
|
+
}
|
|
15755
|
+
return clip(lines.join("\n"), PREAMBLE_MAX);
|
|
15756
|
+
}
|
|
15757
|
+
function renderJournalEntry(e) {
|
|
15758
|
+
const filesClause = e.filesTouched.length > 0 ? ` (files: ${e.filesTouched.join(", ")})` : "";
|
|
15759
|
+
return `- turn ${e.turn} (${e.agentId}): ${e.prompt} \u2192 ${e.replySummary}${filesClause}`;
|
|
15760
|
+
}
|
|
15761
|
+
function buildDeltaBriefing(entries, maxChars = BRIEFING_DEFAULT_MAX) {
|
|
15762
|
+
if (entries.length === 0) return null;
|
|
15763
|
+
const header = BRIEFING_HEADER;
|
|
15764
|
+
const footer = BRIEFING_FOOTER;
|
|
15765
|
+
const envelope = header.length + 1 + footer.length + 1;
|
|
15766
|
+
const sorted = [...entries].sort((a, b) => a.turn - b.turn);
|
|
15767
|
+
const lines = [];
|
|
15768
|
+
let bodyLen = 0;
|
|
15769
|
+
for (let i = sorted.length - 1; i >= 0; i--) {
|
|
15770
|
+
const line = renderJournalEntry(sorted[i]);
|
|
15771
|
+
const addedLen = line.length + (lines.length > 0 ? 1 : 0);
|
|
15772
|
+
if (lines.length > 0 && envelope + bodyLen + addedLen > maxChars) break;
|
|
15773
|
+
lines.unshift(line);
|
|
15774
|
+
bodyLen += addedLen;
|
|
15775
|
+
}
|
|
15776
|
+
return [header, lines.join("\n"), footer].join("\n");
|
|
15777
|
+
}
|
|
15778
|
+
|
|
15779
|
+
// src/agents/acp/squad-context.ts
|
|
15780
|
+
var SQUAD_CONTEXT_URI = "codeam://squad-context";
|
|
15781
|
+
var HANDOFF_MARKER = "[Session handoff]";
|
|
15782
|
+
var HANDOFF_TERMINATOR = "--- End of handoff context ---";
|
|
15783
|
+
function buildSquadContextBlock(text) {
|
|
15784
|
+
return {
|
|
15785
|
+
type: "resource",
|
|
15786
|
+
resource: { uri: SQUAD_CONTEXT_URI, mimeType: "text/plain", text }
|
|
15787
|
+
};
|
|
15788
|
+
}
|
|
15789
|
+
function isSquadContextBlock(block) {
|
|
15790
|
+
return block.type === "resource" && block.resource.uri === SQUAD_CONTEXT_URI;
|
|
15791
|
+
}
|
|
15792
|
+
function isLeakedSquadContextText(text) {
|
|
15793
|
+
return text.trim().startsWith(SQUAD_CONTEXT_URI);
|
|
15794
|
+
}
|
|
15795
|
+
function looksLikeUnsupportedPromptShape(err) {
|
|
15796
|
+
const code = err?.code;
|
|
15797
|
+
if (code === -32602) return true;
|
|
15798
|
+
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
15799
|
+
if (/invalid[ _]params|-32602/i.test(message)) return true;
|
|
15800
|
+
return /\bresource\b/i.test(message) && /unsupported|not supported/i.test(message);
|
|
15801
|
+
}
|
|
15802
|
+
function skipWhile(lines, start2, keepGoing) {
|
|
15803
|
+
let i = start2;
|
|
15804
|
+
while (i < lines.length && keepGoing(lines[i])) i++;
|
|
15805
|
+
return i;
|
|
15806
|
+
}
|
|
15807
|
+
function endOfTeamPreamble(lines, start2) {
|
|
15808
|
+
if (lines[start2] !== TEAM_PREAMBLE_LINES[0]) return -1;
|
|
15809
|
+
if (lines[start2 + 1] !== TEAM_PREAMBLE_LINES[1]) return -1;
|
|
15810
|
+
return skipWhile(
|
|
15811
|
+
lines,
|
|
15812
|
+
start2 + 2,
|
|
15813
|
+
(line) => TEAM_PREAMBLE_BULLET_RE.test(line) || TEAM_PREAMBLE_LINES.includes(line)
|
|
15814
|
+
);
|
|
15815
|
+
}
|
|
15816
|
+
function endOfTerminatedBlock(lines, start2, terminator) {
|
|
15817
|
+
for (let i = start2; i < lines.length; i++) {
|
|
15818
|
+
if (lines[i].trimEnd() === terminator) return i + 1;
|
|
15819
|
+
}
|
|
15820
|
+
return -1;
|
|
15821
|
+
}
|
|
15822
|
+
function stripSquadContext(text) {
|
|
15823
|
+
if (!text.includes(HANDOFF_MARKER) && !text.includes(BRIEFING_MARKER) && !text.includes(TEAM_PREAMBLE_MARKER)) {
|
|
15824
|
+
return text;
|
|
15825
|
+
}
|
|
15826
|
+
const lines = text.split("\n");
|
|
15827
|
+
const kept = [];
|
|
15828
|
+
let i = 0;
|
|
15829
|
+
let stripped = false;
|
|
15830
|
+
while (i < lines.length) {
|
|
15831
|
+
const line = lines[i];
|
|
15832
|
+
if (line.startsWith(HANDOFF_MARKER)) {
|
|
15833
|
+
const end = endOfTerminatedBlock(lines, i, HANDOFF_TERMINATOR);
|
|
15834
|
+
if (end !== -1) {
|
|
15835
|
+
i = end;
|
|
15836
|
+
stripped = true;
|
|
15837
|
+
continue;
|
|
15838
|
+
}
|
|
15839
|
+
} else if (line.startsWith(BRIEFING_MARKER)) {
|
|
15840
|
+
const end = endOfTerminatedBlock(lines, i, BRIEFING_FOOTER);
|
|
15841
|
+
if (end !== -1) {
|
|
15842
|
+
i = end;
|
|
15843
|
+
stripped = true;
|
|
15844
|
+
continue;
|
|
15845
|
+
}
|
|
15846
|
+
} else if (line.startsWith(TEAM_PREAMBLE_MARKER)) {
|
|
15847
|
+
const end = endOfTeamPreamble(lines, i);
|
|
15848
|
+
if (end !== -1) {
|
|
15849
|
+
i = end;
|
|
15850
|
+
stripped = true;
|
|
15851
|
+
continue;
|
|
15852
|
+
}
|
|
15853
|
+
}
|
|
15854
|
+
kept.push(line);
|
|
15855
|
+
i++;
|
|
15856
|
+
}
|
|
15857
|
+
if (!stripped) return text;
|
|
15858
|
+
return kept.join("\n").trim();
|
|
15859
|
+
}
|
|
15860
|
+
|
|
15861
|
+
// src/agents/acp/agent-meta-blocks.ts
|
|
15862
|
+
var AGENT_META_BLOCK_MARKERS = ["<recommended_plugins>"];
|
|
15863
|
+
function isAgentMetaBlock(text) {
|
|
15864
|
+
const trimmed = text.trim();
|
|
15865
|
+
return AGENT_META_BLOCK_MARKERS.some((marker) => trimmed.startsWith(marker));
|
|
15866
|
+
}
|
|
15867
|
+
|
|
15868
|
+
// src/agents/codex/history.ts
|
|
15565
15869
|
function resolveHistoryDir2(_cwd, homeOverride) {
|
|
15566
15870
|
const home = homeOverride ?? import_node_os.default.homedir();
|
|
15567
15871
|
const sessionsRoot = import_node_path2.default.join(home, ".codex", "sessions");
|
|
@@ -15620,6 +15924,8 @@ function isSyntheticCodexTurn(role, text) {
|
|
|
15620
15924
|
if (trimmed.startsWith("<environment_context>")) return true;
|
|
15621
15925
|
if (trimmed.startsWith("<turn_aborted>")) return true;
|
|
15622
15926
|
if (/^(<<ccr:[^>]*>>\s*)+$/.test(trimmed)) return true;
|
|
15927
|
+
if (isLeakedSquadContextText(trimmed)) return true;
|
|
15928
|
+
if (isAgentMetaBlock(trimmed)) return true;
|
|
15623
15929
|
return false;
|
|
15624
15930
|
}
|
|
15625
15931
|
function parseHistoryFile2(filePath) {
|
|
@@ -15916,16 +16222,16 @@ function getCurrentUsage2(historyDir) {
|
|
|
15916
16222
|
var import_node_child_process4 = require("child_process");
|
|
15917
16223
|
|
|
15918
16224
|
// src/agents/codex/local-token.ts
|
|
15919
|
-
var
|
|
15920
|
-
var
|
|
15921
|
-
var
|
|
16225
|
+
var fs22 = __toESM(require("fs"));
|
|
16226
|
+
var os20 = __toESM(require("os"));
|
|
16227
|
+
var path25 = __toESM(require("path"));
|
|
15922
16228
|
function codexCredentialsPath() {
|
|
15923
|
-
return
|
|
16229
|
+
return path25.join(os20.homedir(), ".codex", "auth.json");
|
|
15924
16230
|
}
|
|
15925
16231
|
async function extractLocalCodexToken() {
|
|
15926
16232
|
const file = codexCredentialsPath();
|
|
15927
|
-
if (!
|
|
15928
|
-
const credential =
|
|
16233
|
+
if (!fs22.existsSync(file)) return null;
|
|
16234
|
+
const credential = fs22.readFileSync(file, "utf8").trim();
|
|
15929
16235
|
if (credential.length === 0) return null;
|
|
15930
16236
|
return { method: "oauth", credential, source: "flat-file" };
|
|
15931
16237
|
}
|
|
@@ -16148,7 +16454,7 @@ function augmentNpmGlobalBin(os67) {
|
|
|
16148
16454
|
if (result.status !== 0) return;
|
|
16149
16455
|
const prefix = result.stdout.toString().trim();
|
|
16150
16456
|
if (!prefix) return;
|
|
16151
|
-
const binDir = os67.id === "win32" ? prefix :
|
|
16457
|
+
const binDir = os67.id === "win32" ? prefix : path26.join(prefix, "bin");
|
|
16152
16458
|
os67.augmentPath([binDir]);
|
|
16153
16459
|
} catch {
|
|
16154
16460
|
}
|
|
@@ -16233,7 +16539,7 @@ var import_node_child_process9 = require("child_process");
|
|
|
16233
16539
|
// src/agents/coderabbit/installer.ts
|
|
16234
16540
|
var import_node_child_process7 = require("child_process");
|
|
16235
16541
|
var import_node_fs5 = require("fs");
|
|
16236
|
-
var
|
|
16542
|
+
var path28 = __toESM(require("path"));
|
|
16237
16543
|
|
|
16238
16544
|
// src/commands/host/os-packages.ts
|
|
16239
16545
|
var import_node_child_process6 = require("child_process");
|
|
@@ -16564,7 +16870,7 @@ function writeUnzipShim(os67, runner) {
|
|
|
16564
16870
|
const python = ["python3", "python"].find((p2) => runner.which(p2));
|
|
16565
16871
|
if (!python) return null;
|
|
16566
16872
|
const dir = os67.scratchPath("codeam-cr-prereq");
|
|
16567
|
-
const shim =
|
|
16873
|
+
const shim = path28.join(dir, "unzip");
|
|
16568
16874
|
const script = `#!/bin/sh
|
|
16569
16875
|
set -e
|
|
16570
16876
|
archive=""
|
|
@@ -16714,9 +17020,9 @@ async function ensureCoderabbitInstalled(os67, deps = {}) {
|
|
|
16714
17020
|
|
|
16715
17021
|
// src/agents/coderabbit/link.ts
|
|
16716
17022
|
var import_node_child_process8 = require("child_process");
|
|
16717
|
-
var
|
|
16718
|
-
var
|
|
16719
|
-
var
|
|
17023
|
+
var fs24 = __toESM(require("fs"));
|
|
17024
|
+
var os22 = __toESM(require("os"));
|
|
17025
|
+
var path29 = __toESM(require("path"));
|
|
16720
17026
|
|
|
16721
17027
|
// src/agents/strategy.ts
|
|
16722
17028
|
function validateNonEmptyCredential(token) {
|
|
@@ -16725,12 +17031,12 @@ function validateNonEmptyCredential(token) {
|
|
|
16725
17031
|
|
|
16726
17032
|
// src/agents/coderabbit/link.ts
|
|
16727
17033
|
function authPath() {
|
|
16728
|
-
return
|
|
17034
|
+
return path29.join(os22.homedir(), ".coderabbit", "auth.json");
|
|
16729
17035
|
}
|
|
16730
17036
|
async function extractLocalCoderabbitToken() {
|
|
16731
17037
|
const file = authPath();
|
|
16732
|
-
if (!
|
|
16733
|
-
const credential =
|
|
17038
|
+
if (!fs24.existsSync(file)) return null;
|
|
17039
|
+
const credential = fs24.readFileSync(file, "utf8").trim();
|
|
16734
17040
|
if (credential.length === 0) return null;
|
|
16735
17041
|
return { method: "oauth", credential, source: "flat-file" };
|
|
16736
17042
|
}
|
|
@@ -17074,39 +17380,39 @@ CodeRabbit review timed out after ${Math.round(
|
|
|
17074
17380
|
};
|
|
17075
17381
|
|
|
17076
17382
|
// src/agents/cursor/history.ts
|
|
17077
|
-
var
|
|
17078
|
-
var
|
|
17079
|
-
var
|
|
17383
|
+
var fs25 = __toESM(require("fs"));
|
|
17384
|
+
var os23 = __toESM(require("os"));
|
|
17385
|
+
var path30 = __toESM(require("path"));
|
|
17080
17386
|
var import_node_crypto5 = require("crypto");
|
|
17081
|
-
var HISTORY_ROOT =
|
|
17082
|
-
var CURSOR_HOME =
|
|
17387
|
+
var HISTORY_ROOT = path30.join(os23.homedir(), ".cursor", "projects");
|
|
17388
|
+
var CURSOR_HOME = path30.join(os23.homedir(), ".cursor");
|
|
17083
17389
|
var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
|
|
17084
17390
|
function acpSessionDir(sessionId) {
|
|
17085
|
-
return
|
|
17391
|
+
return path30.join(CURSOR_HOME, "acp-sessions", sessionId);
|
|
17086
17392
|
}
|
|
17087
17393
|
function nativeStoreDir(cwd, sessionId) {
|
|
17088
|
-
const chatsRoot =
|
|
17394
|
+
const chatsRoot = path30.join(CURSOR_HOME, "chats");
|
|
17089
17395
|
let buckets = [];
|
|
17090
17396
|
try {
|
|
17091
|
-
buckets =
|
|
17397
|
+
buckets = fs25.readdirSync(chatsRoot);
|
|
17092
17398
|
} catch {
|
|
17093
17399
|
}
|
|
17094
17400
|
for (const b of buckets) {
|
|
17095
|
-
const candidate =
|
|
17096
|
-
if (
|
|
17401
|
+
const candidate = path30.join(chatsRoot, b, sessionId);
|
|
17402
|
+
if (fs25.existsSync(path30.join(candidate, "store.db"))) return candidate;
|
|
17097
17403
|
}
|
|
17098
|
-
const computed =
|
|
17099
|
-
return
|
|
17404
|
+
const computed = path30.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
17405
|
+
return fs25.existsSync(computed) ? computed : null;
|
|
17100
17406
|
}
|
|
17101
17407
|
function copyStoreFiles(srcDir, dstDir) {
|
|
17102
|
-
|
|
17408
|
+
fs25.mkdirSync(dstDir, { recursive: true });
|
|
17103
17409
|
for (const f of STORE_FILES) {
|
|
17104
|
-
const dst =
|
|
17105
|
-
if (
|
|
17410
|
+
const dst = path30.join(dstDir, f);
|
|
17411
|
+
if (fs25.existsSync(dst)) fs25.rmSync(dst, { force: true });
|
|
17106
17412
|
}
|
|
17107
17413
|
for (const f of STORE_FILES) {
|
|
17108
|
-
const src =
|
|
17109
|
-
if (
|
|
17414
|
+
const src = path30.join(srcDir, f);
|
|
17415
|
+
if (fs25.existsSync(src)) fs25.copyFileSync(src, path30.join(dstDir, f));
|
|
17110
17416
|
}
|
|
17111
17417
|
}
|
|
17112
17418
|
function bridgeNativeToAcp(cwd, sessionId) {
|
|
@@ -17118,8 +17424,8 @@ function bridgeNativeToAcp(cwd, sessionId) {
|
|
|
17118
17424
|
}
|
|
17119
17425
|
const dst = acpSessionDir(sessionId);
|
|
17120
17426
|
copyStoreFiles(src, dst);
|
|
17121
|
-
|
|
17122
|
-
|
|
17427
|
+
fs25.writeFileSync(
|
|
17428
|
+
path30.join(dst, "meta.json"),
|
|
17123
17429
|
JSON.stringify({ schemaVersion: 1, cwd })
|
|
17124
17430
|
);
|
|
17125
17431
|
log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
|
|
@@ -17130,11 +17436,11 @@ function bridgeNativeToAcp(cwd, sessionId) {
|
|
|
17130
17436
|
function bridgeAcpToNative(cwd, sessionId) {
|
|
17131
17437
|
try {
|
|
17132
17438
|
const src = acpSessionDir(sessionId);
|
|
17133
|
-
if (!
|
|
17439
|
+
if (!fs25.existsSync(path30.join(src, "store.db"))) {
|
|
17134
17440
|
log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
|
|
17135
17441
|
return;
|
|
17136
17442
|
}
|
|
17137
|
-
const dst = nativeStoreDir(cwd, sessionId) ??
|
|
17443
|
+
const dst = nativeStoreDir(cwd, sessionId) ?? path30.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
|
|
17138
17444
|
copyStoreFiles(src, dst);
|
|
17139
17445
|
log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
|
|
17140
17446
|
} catch (err) {
|
|
@@ -17145,26 +17451,26 @@ function encodeCursorCwd(cwd) {
|
|
|
17145
17451
|
return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
|
|
17146
17452
|
}
|
|
17147
17453
|
function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
|
|
17148
|
-
const rel =
|
|
17149
|
-
const primary =
|
|
17150
|
-
if (
|
|
17454
|
+
const rel = path30.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
|
|
17455
|
+
const primary = path30.join(root, encodeCursorCwd(cwd), rel);
|
|
17456
|
+
if (fs25.existsSync(primary)) return primary;
|
|
17151
17457
|
let entries;
|
|
17152
17458
|
try {
|
|
17153
|
-
entries =
|
|
17459
|
+
entries = fs25.readdirSync(root, { withFileTypes: true });
|
|
17154
17460
|
} catch {
|
|
17155
17461
|
return null;
|
|
17156
17462
|
}
|
|
17157
17463
|
for (const e of entries) {
|
|
17158
17464
|
if (!e.isDirectory()) continue;
|
|
17159
|
-
const candidate =
|
|
17160
|
-
if (
|
|
17465
|
+
const candidate = path30.join(root, e.name, rel);
|
|
17466
|
+
if (fs25.existsSync(candidate)) return candidate;
|
|
17161
17467
|
}
|
|
17162
17468
|
return null;
|
|
17163
17469
|
}
|
|
17164
17470
|
function resolveHistoryDir3(cwd) {
|
|
17165
|
-
if (!
|
|
17166
|
-
const dir =
|
|
17167
|
-
return
|
|
17471
|
+
if (!fs25.existsSync(HISTORY_ROOT)) return null;
|
|
17472
|
+
const dir = path30.join(HISTORY_ROOT, encodeCursorCwd(cwd));
|
|
17473
|
+
return fs25.existsSync(dir) ? dir : null;
|
|
17168
17474
|
}
|
|
17169
17475
|
function extractText2(content) {
|
|
17170
17476
|
if (!Array.isArray(content)) return "";
|
|
@@ -17177,7 +17483,7 @@ function unwrapUserQuery(text) {
|
|
|
17177
17483
|
function parseHistoryFile3(filePath) {
|
|
17178
17484
|
let raw;
|
|
17179
17485
|
try {
|
|
17180
|
-
raw =
|
|
17486
|
+
raw = fs25.readFileSync(filePath, "utf8");
|
|
17181
17487
|
} catch {
|
|
17182
17488
|
return [];
|
|
17183
17489
|
}
|
|
@@ -17215,16 +17521,16 @@ function getCurrentUsage3(_historyDir) {
|
|
|
17215
17521
|
var import_node_child_process10 = require("child_process");
|
|
17216
17522
|
|
|
17217
17523
|
// src/agents/cursor/local-token.ts
|
|
17218
|
-
var
|
|
17219
|
-
var
|
|
17220
|
-
var
|
|
17524
|
+
var fs26 = __toESM(require("fs"));
|
|
17525
|
+
var os24 = __toESM(require("os"));
|
|
17526
|
+
var path31 = __toESM(require("path"));
|
|
17221
17527
|
function cursorCredentialsPath() {
|
|
17222
|
-
return
|
|
17528
|
+
return path31.join(os24.homedir(), ".cursor", "auth.json");
|
|
17223
17529
|
}
|
|
17224
17530
|
async function extractLocalCursorToken() {
|
|
17225
17531
|
const file = cursorCredentialsPath();
|
|
17226
|
-
if (!
|
|
17227
|
-
const credential =
|
|
17532
|
+
if (!fs26.existsSync(file)) return null;
|
|
17533
|
+
const credential = fs26.readFileSync(file, "utf8").trim();
|
|
17228
17534
|
if (credential.length === 0) return null;
|
|
17229
17535
|
return { method: "oauth", credential, source: "flat-file" };
|
|
17230
17536
|
}
|
|
@@ -17467,12 +17773,12 @@ var CursorRuntimeStrategy = class {
|
|
|
17467
17773
|
};
|
|
17468
17774
|
|
|
17469
17775
|
// src/agents/aider/history.ts
|
|
17470
|
-
var
|
|
17471
|
-
var
|
|
17776
|
+
var fs27 = __toESM(require("fs"));
|
|
17777
|
+
var path32 = __toESM(require("path"));
|
|
17472
17778
|
var AIDER_HISTORY_FILE = ".aider.chat.history.md";
|
|
17473
17779
|
function resolveHistoryDir4(cwd) {
|
|
17474
|
-
const candidate =
|
|
17475
|
-
return
|
|
17780
|
+
const candidate = path32.join(cwd, AIDER_HISTORY_FILE);
|
|
17781
|
+
return fs27.existsSync(candidate) ? cwd : null;
|
|
17476
17782
|
}
|
|
17477
17783
|
function parseHistoryFile4(_filePath) {
|
|
17478
17784
|
return [];
|
|
@@ -17485,10 +17791,10 @@ function getCurrentUsage4(_historyDir) {
|
|
|
17485
17791
|
var import_node_child_process12 = require("child_process");
|
|
17486
17792
|
|
|
17487
17793
|
// src/agents/aider/local-token.ts
|
|
17488
|
-
var
|
|
17489
|
-
var
|
|
17490
|
-
var
|
|
17491
|
-
var AIDER_CONF_FILE =
|
|
17794
|
+
var fs28 = __toESM(require("fs"));
|
|
17795
|
+
var os25 = __toESM(require("os"));
|
|
17796
|
+
var path33 = __toESM(require("path"));
|
|
17797
|
+
var AIDER_CONF_FILE = path33.join(os25.homedir(), ".aider.conf.yml");
|
|
17492
17798
|
var API_KEY_ENV_VARS = [
|
|
17493
17799
|
"ANTHROPIC_API_KEY",
|
|
17494
17800
|
"OPENAI_API_KEY",
|
|
@@ -17503,8 +17809,8 @@ async function extractLocalAiderToken() {
|
|
|
17503
17809
|
return { method: "api_key", credential: value.trim(), source: "flat-file" };
|
|
17504
17810
|
}
|
|
17505
17811
|
}
|
|
17506
|
-
if (
|
|
17507
|
-
const conf =
|
|
17812
|
+
if (fs28.existsSync(AIDER_CONF_FILE)) {
|
|
17813
|
+
const conf = fs28.readFileSync(AIDER_CONF_FILE, "utf8");
|
|
17508
17814
|
const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
|
|
17509
17815
|
if (match) {
|
|
17510
17816
|
return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
|
|
@@ -17880,19 +18186,19 @@ var import_node_crypto6 = require("crypto");
|
|
|
17880
18186
|
var import_node_child_process13 = require("child_process");
|
|
17881
18187
|
|
|
17882
18188
|
// src/agents/gemini/local-token.ts
|
|
17883
|
-
var
|
|
17884
|
-
var
|
|
17885
|
-
var
|
|
18189
|
+
var fs30 = __toESM(require("fs"));
|
|
18190
|
+
var os27 = __toESM(require("os"));
|
|
18191
|
+
var path35 = __toESM(require("path"));
|
|
17886
18192
|
function geminiCredentialsPath() {
|
|
17887
|
-
return
|
|
18193
|
+
return path35.join(os27.homedir(), ".gemini", "oauth_creds.json");
|
|
17888
18194
|
}
|
|
17889
18195
|
function geminiCredentialsPaths() {
|
|
17890
18196
|
return [geminiCredentialsPath()];
|
|
17891
18197
|
}
|
|
17892
18198
|
async function extractLocalGeminiToken() {
|
|
17893
18199
|
const file = geminiCredentialsPath();
|
|
17894
|
-
if (!
|
|
17895
|
-
const credential =
|
|
18200
|
+
if (!fs30.existsSync(file)) return null;
|
|
18201
|
+
const credential = fs30.readFileSync(file, "utf8").trim();
|
|
17896
18202
|
if (credential.length === 0) return null;
|
|
17897
18203
|
return { method: "oauth", credential, source: "flat-file" };
|
|
17898
18204
|
}
|
|
@@ -17948,20 +18254,20 @@ function geminiLoginLauncher() {
|
|
|
17948
18254
|
}
|
|
17949
18255
|
|
|
17950
18256
|
// src/agents/gemini/history.ts
|
|
17951
|
-
var
|
|
17952
|
-
var
|
|
17953
|
-
var
|
|
17954
|
-
var GEMINI_ROOT =
|
|
18257
|
+
var fs31 = __toESM(require("fs"));
|
|
18258
|
+
var os28 = __toESM(require("os"));
|
|
18259
|
+
var path36 = __toESM(require("path"));
|
|
18260
|
+
var GEMINI_ROOT = path36.join(os28.homedir(), ".gemini");
|
|
17955
18261
|
function projectNameForCwd(cwd, root) {
|
|
17956
18262
|
try {
|
|
17957
18263
|
const parsed = JSON.parse(
|
|
17958
|
-
|
|
18264
|
+
fs31.readFileSync(path36.join(root, "projects.json"), "utf8")
|
|
17959
18265
|
);
|
|
17960
18266
|
const map = parsed.projects;
|
|
17961
18267
|
if (map && typeof map === "object") {
|
|
17962
18268
|
if (typeof map[cwd] === "string") return map[cwd];
|
|
17963
18269
|
try {
|
|
17964
|
-
const rp =
|
|
18270
|
+
const rp = fs31.realpathSync(cwd);
|
|
17965
18271
|
if (typeof map[rp] === "string") return map[rp];
|
|
17966
18272
|
} catch {
|
|
17967
18273
|
}
|
|
@@ -17970,7 +18276,7 @@ function projectNameForCwd(cwd, root) {
|
|
|
17970
18276
|
} catch (err) {
|
|
17971
18277
|
log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
|
|
17972
18278
|
}
|
|
17973
|
-
return
|
|
18279
|
+
return path36.basename(cwd) || null;
|
|
17974
18280
|
}
|
|
17975
18281
|
function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
17976
18282
|
const name = projectNameForCwd(cwd, root);
|
|
@@ -17978,8 +18284,8 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
|
|
|
17978
18284
|
log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
|
|
17979
18285
|
return null;
|
|
17980
18286
|
}
|
|
17981
|
-
const dir =
|
|
17982
|
-
if (!
|
|
18287
|
+
const dir = path36.join(root, "tmp", name, "chats");
|
|
18288
|
+
if (!fs31.existsSync(dir)) {
|
|
17983
18289
|
log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
|
|
17984
18290
|
return null;
|
|
17985
18291
|
}
|
|
@@ -17991,7 +18297,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
17991
18297
|
if (!dir) return null;
|
|
17992
18298
|
let files;
|
|
17993
18299
|
try {
|
|
17994
|
-
files =
|
|
18300
|
+
files = fs31.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
17995
18301
|
} catch (err) {
|
|
17996
18302
|
log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
|
|
17997
18303
|
return null;
|
|
@@ -18003,12 +18309,12 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
18003
18309
|
const byName = files.find((f) => id8.length > 0 && f.includes(id8));
|
|
18004
18310
|
if (byName) {
|
|
18005
18311
|
log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
|
|
18006
|
-
return
|
|
18312
|
+
return path36.join(dir, byName);
|
|
18007
18313
|
}
|
|
18008
18314
|
for (const f of files) {
|
|
18009
|
-
const full =
|
|
18315
|
+
const full = path36.join(dir, f);
|
|
18010
18316
|
try {
|
|
18011
|
-
const firstLine =
|
|
18317
|
+
const firstLine = fs31.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
|
|
18012
18318
|
const hdr = JSON.parse(firstLine);
|
|
18013
18319
|
if (hdr.sessionId === sessionId) {
|
|
18014
18320
|
log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
|
|
@@ -18021,7 +18327,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
18021
18327
|
let newest = null;
|
|
18022
18328
|
for (const f of files) {
|
|
18023
18329
|
try {
|
|
18024
|
-
const mtime =
|
|
18330
|
+
const mtime = fs31.statSync(path36.join(dir, f)).mtimeMs;
|
|
18025
18331
|
if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
|
|
18026
18332
|
} catch {
|
|
18027
18333
|
}
|
|
@@ -18030,7 +18336,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
|
|
|
18030
18336
|
"gemini",
|
|
18031
18337
|
`resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
|
|
18032
18338
|
);
|
|
18033
|
-
return newest ?
|
|
18339
|
+
return newest ? path36.join(dir, newest.file) : null;
|
|
18034
18340
|
}
|
|
18035
18341
|
function extractGeminiText(content) {
|
|
18036
18342
|
const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
|
|
@@ -18058,7 +18364,7 @@ function isSyntheticGeminiTurn(text) {
|
|
|
18058
18364
|
function parseHistoryFile5(filePath) {
|
|
18059
18365
|
let raw;
|
|
18060
18366
|
try {
|
|
18061
|
-
raw =
|
|
18367
|
+
raw = fs31.readFileSync(filePath, "utf8");
|
|
18062
18368
|
} catch (err) {
|
|
18063
18369
|
log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
|
|
18064
18370
|
return [];
|
|
@@ -18099,7 +18405,7 @@ function parseHistoryFile5(filePath) {
|
|
|
18099
18405
|
}
|
|
18100
18406
|
log.trace(
|
|
18101
18407
|
"gemini",
|
|
18102
|
-
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${
|
|
18408
|
+
`parseHistoryFile \u2014 ${out2.length} turn(s) from ${path36.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
|
|
18103
18409
|
);
|
|
18104
18410
|
return out2;
|
|
18105
18411
|
}
|
|
@@ -18243,42 +18549,42 @@ var import_node_os3 = require("os");
|
|
|
18243
18549
|
var import_node_path4 = require("path");
|
|
18244
18550
|
|
|
18245
18551
|
// src/agents/kimi/history.ts
|
|
18246
|
-
var
|
|
18247
|
-
var
|
|
18248
|
-
var
|
|
18552
|
+
var fs32 = __toESM(require("fs"));
|
|
18553
|
+
var os29 = __toESM(require("os"));
|
|
18554
|
+
var path37 = __toESM(require("path"));
|
|
18249
18555
|
var import_node_crypto7 = require("crypto");
|
|
18250
18556
|
function kimiHome() {
|
|
18251
|
-
return process.env.KIMI_CODE_HOME ||
|
|
18557
|
+
return process.env.KIMI_CODE_HOME || path37.join(os29.homedir(), ".kimi-code");
|
|
18252
18558
|
}
|
|
18253
18559
|
function workDirKey(cwd) {
|
|
18254
18560
|
const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
|
|
18255
|
-
return `wd_${
|
|
18561
|
+
return `wd_${path37.basename(cwd)}_${hash}`;
|
|
18256
18562
|
}
|
|
18257
18563
|
function resolveHistoryDir6(cwd) {
|
|
18258
|
-
const dir =
|
|
18259
|
-
if (!
|
|
18564
|
+
const dir = path37.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18565
|
+
if (!fs32.existsSync(dir)) {
|
|
18260
18566
|
log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
|
|
18261
18567
|
return null;
|
|
18262
18568
|
}
|
|
18263
18569
|
return dir;
|
|
18264
18570
|
}
|
|
18265
|
-
var WIRE_REL =
|
|
18571
|
+
var WIRE_REL = path37.join("agents", "main", "wire.jsonl");
|
|
18266
18572
|
function resolveHistoryFile5(cwd, sessionId) {
|
|
18267
18573
|
const fromIndex = sessionDirFromIndex(sessionId);
|
|
18268
18574
|
if (fromIndex) {
|
|
18269
|
-
const p2 =
|
|
18270
|
-
if (
|
|
18575
|
+
const p2 = path37.join(fromIndex, WIRE_REL);
|
|
18576
|
+
if (fs32.existsSync(p2)) return p2;
|
|
18271
18577
|
}
|
|
18272
|
-
const bucket2 =
|
|
18273
|
-
const computed =
|
|
18274
|
-
if (
|
|
18578
|
+
const bucket2 = path37.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18579
|
+
const computed = path37.join(bucket2, sessionId, WIRE_REL);
|
|
18580
|
+
if (fs32.existsSync(computed)) return computed;
|
|
18275
18581
|
const scanned = scanBucketsForSession(sessionId);
|
|
18276
18582
|
if (scanned) return scanned;
|
|
18277
18583
|
return null;
|
|
18278
18584
|
}
|
|
18279
18585
|
function sessionDirFromIndex(sessionId) {
|
|
18280
18586
|
try {
|
|
18281
|
-
const raw =
|
|
18587
|
+
const raw = fs32.readFileSync(path37.join(kimiHome(), "session_index.jsonl"), "utf8");
|
|
18282
18588
|
for (const line of raw.split("\n")) {
|
|
18283
18589
|
if (!line.includes(sessionId)) continue;
|
|
18284
18590
|
try {
|
|
@@ -18294,22 +18600,22 @@ function sessionDirFromIndex(sessionId) {
|
|
|
18294
18600
|
return null;
|
|
18295
18601
|
}
|
|
18296
18602
|
function scanBucketsForSession(sessionId) {
|
|
18297
|
-
const sessionsRoot =
|
|
18603
|
+
const sessionsRoot = path37.join(kimiHome(), "sessions");
|
|
18298
18604
|
let buckets;
|
|
18299
18605
|
try {
|
|
18300
|
-
buckets =
|
|
18606
|
+
buckets = fs32.readdirSync(sessionsRoot, { withFileTypes: true });
|
|
18301
18607
|
} catch {
|
|
18302
18608
|
return null;
|
|
18303
18609
|
}
|
|
18304
18610
|
for (const b of buckets) {
|
|
18305
18611
|
if (!b.isDirectory()) continue;
|
|
18306
|
-
const candidate =
|
|
18307
|
-
if (
|
|
18612
|
+
const candidate = path37.join(sessionsRoot, b.name, sessionId, WIRE_REL);
|
|
18613
|
+
if (fs32.existsSync(candidate)) return candidate;
|
|
18308
18614
|
}
|
|
18309
18615
|
return null;
|
|
18310
18616
|
}
|
|
18311
18617
|
async function discoverSessionId2(cwd, opts) {
|
|
18312
|
-
const bucket2 =
|
|
18618
|
+
const bucket2 = path37.join(kimiHome(), "sessions", workDirKey(cwd));
|
|
18313
18619
|
const floor = opts.sinceMs - 2e3;
|
|
18314
18620
|
const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
|
|
18315
18621
|
for (; ; ) {
|
|
@@ -18322,7 +18628,7 @@ async function discoverSessionId2(cwd, opts) {
|
|
|
18322
18628
|
function newestSessionSince(bucket2, floorMs) {
|
|
18323
18629
|
let entries;
|
|
18324
18630
|
try {
|
|
18325
|
-
entries =
|
|
18631
|
+
entries = fs32.readdirSync(bucket2, { withFileTypes: true });
|
|
18326
18632
|
} catch {
|
|
18327
18633
|
return null;
|
|
18328
18634
|
}
|
|
@@ -18332,7 +18638,7 @@ function newestSessionSince(bucket2, floorMs) {
|
|
|
18332
18638
|
if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
|
|
18333
18639
|
let mtime;
|
|
18334
18640
|
try {
|
|
18335
|
-
mtime =
|
|
18641
|
+
mtime = fs32.statSync(path37.join(bucket2, e.name)).mtimeMs;
|
|
18336
18642
|
} catch {
|
|
18337
18643
|
continue;
|
|
18338
18644
|
}
|
|
@@ -18353,7 +18659,7 @@ function joinTextParts(parts) {
|
|
|
18353
18659
|
function parseHistoryFile6(filePath) {
|
|
18354
18660
|
let raw;
|
|
18355
18661
|
try {
|
|
18356
|
-
raw =
|
|
18662
|
+
raw = fs32.readFileSync(filePath, "utf8");
|
|
18357
18663
|
} catch {
|
|
18358
18664
|
return [];
|
|
18359
18665
|
}
|
|
@@ -18731,7 +19037,7 @@ function parseLinkArgs(args2) {
|
|
|
18731
19037
|
if (apiKeyFileArg) {
|
|
18732
19038
|
const filePath = apiKeyFileArg.slice("--api-key-file=".length);
|
|
18733
19039
|
try {
|
|
18734
|
-
apiKey =
|
|
19040
|
+
apiKey = fs33.readFileSync(path38.resolve(filePath), "utf8").trim();
|
|
18735
19041
|
} catch (err) {
|
|
18736
19042
|
throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
|
|
18737
19043
|
}
|
|
@@ -18858,7 +19164,7 @@ async function link(args2 = []) {
|
|
|
18858
19164
|
return;
|
|
18859
19165
|
}
|
|
18860
19166
|
if (parsed.tokenFile) {
|
|
18861
|
-
const credential =
|
|
19167
|
+
const credential = fs33.readFileSync(path38.resolve(parsed.tokenFile), "utf8").trim();
|
|
18862
19168
|
if (!credential) {
|
|
18863
19169
|
showError(`--token-file ${parsed.tokenFile} is empty.`);
|
|
18864
19170
|
process.exit(1);
|
|
@@ -19077,13 +19383,13 @@ async function linkDryRunPreflight(ctx) {
|
|
|
19077
19383
|
// src/agents/coderabbit/configure.ts
|
|
19078
19384
|
var import_node_child_process17 = require("child_process");
|
|
19079
19385
|
var import_node_fs6 = require("fs");
|
|
19080
|
-
var
|
|
19386
|
+
var path40 = __toESM(require("path"));
|
|
19081
19387
|
|
|
19082
19388
|
// src/agents/coderabbit/oauth.ts
|
|
19083
19389
|
var import_node_child_process16 = require("child_process");
|
|
19084
|
-
var
|
|
19085
|
-
var
|
|
19086
|
-
var
|
|
19390
|
+
var fs34 = __toESM(require("fs"));
|
|
19391
|
+
var os30 = __toESM(require("os"));
|
|
19392
|
+
var path39 = __toESM(require("path"));
|
|
19087
19393
|
function parseCoderabbitAuthEvent(line) {
|
|
19088
19394
|
const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
|
|
19089
19395
|
if (!l || l[0] !== "{") return null;
|
|
@@ -19132,8 +19438,8 @@ function resolvePython() {
|
|
|
19132
19438
|
function spawnCoderabbitLoginProc(cmd, args2) {
|
|
19133
19439
|
const python = resolvePython();
|
|
19134
19440
|
if (python) {
|
|
19135
|
-
const helper =
|
|
19136
|
-
|
|
19441
|
+
const helper = path39.join(os30.tmpdir(), "codeam-cr-pty.py");
|
|
19442
|
+
fs34.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
|
|
19137
19443
|
return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
|
|
19138
19444
|
stdio: ["pipe", "pipe", "pipe"],
|
|
19139
19445
|
env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
|
|
@@ -19244,7 +19550,7 @@ function runCoderabbitOAuthLogin(deps) {
|
|
|
19244
19550
|
});
|
|
19245
19551
|
}
|
|
19246
19552
|
function coderabbitDir(home) {
|
|
19247
|
-
return
|
|
19553
|
+
return path39.join(home ?? os30.homedir(), ".coderabbit");
|
|
19248
19554
|
}
|
|
19249
19555
|
var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
|
|
19250
19556
|
function snapshotCredentialDir(home) {
|
|
@@ -19252,14 +19558,14 @@ function snapshotCredentialDir(home) {
|
|
|
19252
19558
|
const snap = {};
|
|
19253
19559
|
let entries;
|
|
19254
19560
|
try {
|
|
19255
|
-
entries =
|
|
19561
|
+
entries = fs34.readdirSync(dir, { withFileTypes: true });
|
|
19256
19562
|
} catch {
|
|
19257
19563
|
return snap;
|
|
19258
19564
|
}
|
|
19259
19565
|
for (const e of entries) {
|
|
19260
19566
|
if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
|
|
19261
19567
|
try {
|
|
19262
|
-
const st3 =
|
|
19568
|
+
const st3 = fs34.statSync(path39.join(dir, e.name));
|
|
19263
19569
|
snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
|
|
19264
19570
|
} catch {
|
|
19265
19571
|
}
|
|
@@ -19277,7 +19583,7 @@ function diffCapturedCredential(before, home) {
|
|
|
19277
19583
|
}
|
|
19278
19584
|
if (!best) return null;
|
|
19279
19585
|
try {
|
|
19280
|
-
return { file: best.file, contents:
|
|
19586
|
+
return { file: best.file, contents: fs34.readFileSync(path39.join(dir, best.file), "utf8") };
|
|
19281
19587
|
} catch {
|
|
19282
19588
|
return null;
|
|
19283
19589
|
}
|
|
@@ -19354,7 +19660,7 @@ function collectChangedFiles(cwd) {
|
|
|
19354
19660
|
return [...byPath.values()];
|
|
19355
19661
|
}
|
|
19356
19662
|
function restoreCoderabbitOauthBlob(os67, value) {
|
|
19357
|
-
const dir =
|
|
19663
|
+
const dir = path40.join(os67.homeDir(), ".coderabbit");
|
|
19358
19664
|
(0, import_node_fs6.mkdirSync)(dir, { recursive: true });
|
|
19359
19665
|
let file = "auth.json";
|
|
19360
19666
|
let contents = value.trim();
|
|
@@ -19362,13 +19668,13 @@ function restoreCoderabbitOauthBlob(os67, value) {
|
|
|
19362
19668
|
try {
|
|
19363
19669
|
const parsed = JSON.parse(contents);
|
|
19364
19670
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
19365
|
-
file =
|
|
19671
|
+
file = path40.basename(parsed.file);
|
|
19366
19672
|
contents = parsed.contents;
|
|
19367
19673
|
}
|
|
19368
19674
|
} catch {
|
|
19369
19675
|
}
|
|
19370
19676
|
}
|
|
19371
|
-
(0, import_node_fs6.writeFileSync)(
|
|
19677
|
+
(0, import_node_fs6.writeFileSync)(path40.join(dir, file), contents, { mode: 384 });
|
|
19372
19678
|
}
|
|
19373
19679
|
function installFailureMessage(result) {
|
|
19374
19680
|
return result.error ?? "CodeRabbit CLI could not be installed";
|
|
@@ -19384,10 +19690,10 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
19384
19690
|
const home = os67.homeDir();
|
|
19385
19691
|
os67.augmentPath(
|
|
19386
19692
|
os67.id === "win32" ? [
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
] : [
|
|
19693
|
+
path40.join(home, ".local", "bin"),
|
|
19694
|
+
path40.join(process.env.APPDATA ?? path40.join(home, "AppData", "Roaming"), "npm"),
|
|
19695
|
+
path40.join(home, "scoop", "shims")
|
|
19696
|
+
] : [path40.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
19391
19697
|
);
|
|
19392
19698
|
const installed2 = os67.findInPath("coderabbit") !== null;
|
|
19393
19699
|
const base = () => ({
|
|
@@ -19696,9 +20002,9 @@ function defaultRunGh(args2) {
|
|
|
19696
20002
|
|
|
19697
20003
|
// src/commands/host-agent.ts
|
|
19698
20004
|
var import_node_child_process25 = require("child_process");
|
|
19699
|
-
var
|
|
19700
|
-
var
|
|
19701
|
-
var
|
|
20005
|
+
var os43 = __toESM(require("os"));
|
|
20006
|
+
var fs47 = __toESM(require("fs"));
|
|
20007
|
+
var path51 = __toESM(require("path"));
|
|
19702
20008
|
|
|
19703
20009
|
// src/integrations/manifest.ts
|
|
19704
20010
|
var import_node_fs8 = __toESM(require("fs"));
|
|
@@ -19822,12 +20128,12 @@ function persistOrClearSkillsFromPayload(skills) {
|
|
|
19822
20128
|
|
|
19823
20129
|
// src/commands/host/agent-install.ts
|
|
19824
20130
|
var import_child_process14 = require("child_process");
|
|
19825
|
-
var
|
|
20131
|
+
var os34 = __toESM(require("os"));
|
|
19826
20132
|
function runAgentInstallScript(script, opts = {}) {
|
|
19827
20133
|
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
19828
20134
|
const scope = opts.logScope ?? "agent-install";
|
|
19829
20135
|
return new Promise((resolve9) => {
|
|
19830
|
-
const home = process.env.HOME ||
|
|
20136
|
+
const home = process.env.HOME || os34.homedir();
|
|
19831
20137
|
const child = (0, import_child_process14.spawn)("sh", ["-c", script], {
|
|
19832
20138
|
env: { ...process.env, HOME: home },
|
|
19833
20139
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -19893,14 +20199,14 @@ function describeReason(reason) {
|
|
|
19893
20199
|
}
|
|
19894
20200
|
|
|
19895
20201
|
// src/commands/host/host-client.ts
|
|
19896
|
-
var
|
|
19897
|
-
var
|
|
19898
|
-
var
|
|
20202
|
+
var fs38 = __toESM(require("fs"));
|
|
20203
|
+
var os35 = __toESM(require("os"));
|
|
20204
|
+
var path43 = __toESM(require("path"));
|
|
19899
20205
|
var import_node_crypto9 = require("crypto");
|
|
19900
20206
|
function sampleCpuTimes() {
|
|
19901
20207
|
let idle = 0;
|
|
19902
20208
|
let total = 0;
|
|
19903
|
-
for (const cpu of
|
|
20209
|
+
for (const cpu of os35.cpus()) {
|
|
19904
20210
|
const t2 = cpu.times;
|
|
19905
20211
|
idle += t2.idle;
|
|
19906
20212
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -19919,8 +20225,8 @@ var MetricsCollector = class {
|
|
|
19919
20225
|
const prev = this.prevCpu;
|
|
19920
20226
|
this.prevCpu = current2;
|
|
19921
20227
|
if (!prev) {
|
|
19922
|
-
const cores =
|
|
19923
|
-
const proxy =
|
|
20228
|
+
const cores = os35.cpus().length || 1;
|
|
20229
|
+
const proxy = os35.loadavg()[0] / cores * 100;
|
|
19924
20230
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
19925
20231
|
}
|
|
19926
20232
|
const idleDelta = current2.idle - prev.idle;
|
|
@@ -19933,8 +20239,8 @@ var MetricsCollector = class {
|
|
|
19933
20239
|
collect() {
|
|
19934
20240
|
return {
|
|
19935
20241
|
cpuPct: this.cpuPct(),
|
|
19936
|
-
ramUsedMb: Math.round((
|
|
19937
|
-
ramTotalMb: Math.round(
|
|
20242
|
+
ramUsedMb: Math.round((os35.totalmem() - os35.freemem()) / 1048576),
|
|
20243
|
+
ramTotalMb: Math.round(os35.totalmem() / 1048576),
|
|
19938
20244
|
latencyMs: this.lastLatencyMs
|
|
19939
20245
|
};
|
|
19940
20246
|
}
|
|
@@ -19943,19 +20249,19 @@ function apiBase() {
|
|
|
19943
20249
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
19944
20250
|
}
|
|
19945
20251
|
function hostIdentityPath() {
|
|
19946
|
-
return
|
|
20252
|
+
return path43.join(os35.homedir(), ".codeam", "host-agent.json");
|
|
19947
20253
|
}
|
|
19948
20254
|
function collectOsInfo() {
|
|
19949
20255
|
return {
|
|
19950
|
-
distro:
|
|
19951
|
-
arch:
|
|
19952
|
-
kernel:
|
|
20256
|
+
distro: os35.platform(),
|
|
20257
|
+
arch: os35.arch(),
|
|
20258
|
+
kernel: os35.release(),
|
|
19953
20259
|
nodeVersion: process.versions.node
|
|
19954
20260
|
};
|
|
19955
20261
|
}
|
|
19956
20262
|
function loadHostIdentity() {
|
|
19957
20263
|
try {
|
|
19958
|
-
const raw =
|
|
20264
|
+
const raw = fs38.readFileSync(hostIdentityPath(), "utf8");
|
|
19959
20265
|
const parsed = JSON.parse(raw);
|
|
19960
20266
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
19961
20267
|
const p2 = parsed;
|
|
@@ -19974,8 +20280,8 @@ function loadHostIdentity() {
|
|
|
19974
20280
|
}
|
|
19975
20281
|
function saveHostIdentity(identity) {
|
|
19976
20282
|
const file = hostIdentityPath();
|
|
19977
|
-
|
|
19978
|
-
|
|
20283
|
+
fs38.mkdirSync(path43.dirname(file), { recursive: true, mode: 448 });
|
|
20284
|
+
fs38.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
19979
20285
|
encoding: "utf8",
|
|
19980
20286
|
mode: 384
|
|
19981
20287
|
});
|
|
@@ -20020,7 +20326,7 @@ function isTerminalEnrollError(err) {
|
|
|
20020
20326
|
}
|
|
20021
20327
|
function deleteHostIdentity() {
|
|
20022
20328
|
try {
|
|
20023
|
-
|
|
20329
|
+
fs38.rmSync(hostIdentityPath(), { force: true });
|
|
20024
20330
|
} catch {
|
|
20025
20331
|
}
|
|
20026
20332
|
}
|
|
@@ -20044,7 +20350,7 @@ async function postJson(pathname, body) {
|
|
|
20044
20350
|
function resolveHostLabel(label) {
|
|
20045
20351
|
const explicit = label?.trim();
|
|
20046
20352
|
const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
|
|
20047
|
-
const resolved = explicit || envLabel ||
|
|
20353
|
+
const resolved = explicit || envLabel || os35.hostname();
|
|
20048
20354
|
return resolved.slice(0, 80);
|
|
20049
20355
|
}
|
|
20050
20356
|
async function redeemEnrollToken(token, label) {
|
|
@@ -20155,17 +20461,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
20155
20461
|
}
|
|
20156
20462
|
|
|
20157
20463
|
// src/commands/host/workspace.ts
|
|
20158
|
-
var
|
|
20159
|
-
var
|
|
20160
|
-
var
|
|
20464
|
+
var fs39 = __toESM(require("fs"));
|
|
20465
|
+
var os36 = __toESM(require("os"));
|
|
20466
|
+
var path44 = __toESM(require("path"));
|
|
20161
20467
|
var import_node_child_process20 = require("child_process");
|
|
20162
20468
|
var import_node_util4 = require("util");
|
|
20163
20469
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process20.execFile);
|
|
20164
20470
|
function isAbsolutePathTarget(target) {
|
|
20165
|
-
return
|
|
20471
|
+
return path44.isAbsolute(target);
|
|
20166
20472
|
}
|
|
20167
20473
|
function selfHostedWorkspaceRoot() {
|
|
20168
|
-
return
|
|
20474
|
+
return path44.join(os36.homedir(), ".codeam", "self-hosted");
|
|
20169
20475
|
}
|
|
20170
20476
|
function nonInteractiveGitEnv() {
|
|
20171
20477
|
return {
|
|
@@ -20235,15 +20541,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
|
|
|
20235
20541
|
const isGitlab = provider === "gitlab";
|
|
20236
20542
|
if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
|
|
20237
20543
|
if (!cloneToken) return;
|
|
20238
|
-
const credFile =
|
|
20544
|
+
const credFile = path44.join(dest, ".git", "codeam-credentials");
|
|
20239
20545
|
const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
|
|
20240
20546
|
` : `https://x-access-token:${cloneToken}@github.com
|
|
20241
20547
|
`;
|
|
20242
|
-
|
|
20548
|
+
fs39.writeFileSync(credFile, credLine, { mode: 384 });
|
|
20243
20549
|
restrictToOwner(credFile);
|
|
20244
20550
|
const env = nonInteractiveGitEnv();
|
|
20245
20551
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
20246
|
-
const credFilePosix = credFile.split(
|
|
20552
|
+
const credFilePosix = credFile.split(path44.sep).join("/");
|
|
20247
20553
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
20248
20554
|
});
|
|
20249
20555
|
await git2([
|
|
@@ -20276,17 +20582,17 @@ function maskToken(text, cloneToken) {
|
|
|
20276
20582
|
}
|
|
20277
20583
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
|
|
20278
20584
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
20279
|
-
if (!
|
|
20585
|
+
if (!fs39.existsSync(repoOrPath)) {
|
|
20280
20586
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
20281
20587
|
}
|
|
20282
20588
|
return repoOrPath;
|
|
20283
20589
|
}
|
|
20284
|
-
const dest =
|
|
20285
|
-
if (
|
|
20590
|
+
const dest = path44.join(selfHostedWorkspaceRoot(), deployId);
|
|
20591
|
+
if (fs39.existsSync(path44.join(dest, ".git"))) {
|
|
20286
20592
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
|
|
20287
20593
|
return dest;
|
|
20288
20594
|
}
|
|
20289
|
-
|
|
20595
|
+
fs39.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
20290
20596
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
|
|
20291
20597
|
const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
|
|
20292
20598
|
try {
|
|
@@ -20304,9 +20610,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
|
|
|
20304
20610
|
}
|
|
20305
20611
|
|
|
20306
20612
|
// src/commands/host/agent-provisioning.ts
|
|
20307
|
-
var
|
|
20308
|
-
var
|
|
20309
|
-
var
|
|
20613
|
+
var fs40 = __toESM(require("fs"));
|
|
20614
|
+
var os37 = __toESM(require("os"));
|
|
20615
|
+
var path45 = __toESM(require("path"));
|
|
20310
20616
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
20311
20617
|
claude_code: "claude",
|
|
20312
20618
|
claude: "claude",
|
|
@@ -20323,22 +20629,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
20323
20629
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
20324
20630
|
}
|
|
20325
20631
|
function ensureDir(dir) {
|
|
20326
|
-
|
|
20632
|
+
fs40.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
20327
20633
|
}
|
|
20328
20634
|
function writeFile0600(filePath, contents) {
|
|
20329
|
-
ensureDir(
|
|
20330
|
-
|
|
20635
|
+
ensureDir(path45.dirname(filePath));
|
|
20636
|
+
fs40.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
20331
20637
|
restrictToOwner(filePath);
|
|
20332
20638
|
}
|
|
20333
20639
|
function rmIfExists(filePath) {
|
|
20334
20640
|
try {
|
|
20335
|
-
|
|
20641
|
+
fs40.rmSync(filePath, { force: true });
|
|
20336
20642
|
} catch {
|
|
20337
20643
|
}
|
|
20338
20644
|
}
|
|
20339
20645
|
var claudeProvisioner = {
|
|
20340
20646
|
write(auth, home) {
|
|
20341
|
-
const credentialsJson =
|
|
20647
|
+
const credentialsJson = path45.join(home, ".claude", ".credentials.json");
|
|
20342
20648
|
if (auth.kind === "api_key") {
|
|
20343
20649
|
rmIfExists(credentialsJson);
|
|
20344
20650
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -20350,8 +20656,8 @@ var claudeProvisioner = {
|
|
|
20350
20656
|
} else {
|
|
20351
20657
|
rmIfExists(credentialsJson);
|
|
20352
20658
|
}
|
|
20353
|
-
const claudeJson =
|
|
20354
|
-
if (!
|
|
20659
|
+
const claudeJson = path45.join(home, ".claude.json");
|
|
20660
|
+
if (!fs40.existsSync(claudeJson)) {
|
|
20355
20661
|
writeFile0600(
|
|
20356
20662
|
claudeJson,
|
|
20357
20663
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -20362,7 +20668,7 @@ var claudeProvisioner = {
|
|
|
20362
20668
|
};
|
|
20363
20669
|
var codexProvisioner = {
|
|
20364
20670
|
write(auth, home) {
|
|
20365
|
-
const authJson =
|
|
20671
|
+
const authJson = path45.join(home, ".codex", "auth.json");
|
|
20366
20672
|
if (auth.kind === "api_key") {
|
|
20367
20673
|
rmIfExists(authJson);
|
|
20368
20674
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -20373,8 +20679,8 @@ var codexProvisioner = {
|
|
|
20373
20679
|
};
|
|
20374
20680
|
var geminiProvisioner = {
|
|
20375
20681
|
write(auth, home) {
|
|
20376
|
-
const settingsJson =
|
|
20377
|
-
const oauthCreds =
|
|
20682
|
+
const settingsJson = path45.join(home, ".gemini", "settings.json");
|
|
20683
|
+
const oauthCreds = path45.join(home, ".gemini", "oauth_creds.json");
|
|
20378
20684
|
if (auth.kind === "api_key") {
|
|
20379
20685
|
rmIfExists(oauthCreds);
|
|
20380
20686
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -20387,7 +20693,7 @@ var geminiProvisioner = {
|
|
|
20387
20693
|
};
|
|
20388
20694
|
var cursorProvisioner = {
|
|
20389
20695
|
write(auth, home) {
|
|
20390
|
-
const authJson =
|
|
20696
|
+
const authJson = path45.join(home, ".config", "cursor", "auth.json");
|
|
20391
20697
|
if (auth.kind === "api_key") {
|
|
20392
20698
|
rmIfExists(authJson);
|
|
20393
20699
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -20429,22 +20735,22 @@ max_context_size = 262144
|
|
|
20429
20735
|
var kimiProvisioner = {
|
|
20430
20736
|
write(auth, home) {
|
|
20431
20737
|
const credentialsFiles = [
|
|
20432
|
-
|
|
20433
|
-
|
|
20738
|
+
path45.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
20739
|
+
path45.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
20434
20740
|
];
|
|
20435
20741
|
if (auth.kind === "api_key") {
|
|
20436
20742
|
credentialsFiles.forEach(rmIfExists);
|
|
20437
20743
|
return { KIMI_API_KEY: auth.value };
|
|
20438
20744
|
}
|
|
20439
20745
|
credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
|
|
20440
|
-
writeFile0600(
|
|
20746
|
+
writeFile0600(path45.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
|
|
20441
20747
|
return {};
|
|
20442
20748
|
}
|
|
20443
20749
|
};
|
|
20444
20750
|
var coderabbitProvisioner = {
|
|
20445
20751
|
write(auth, home) {
|
|
20446
|
-
const dir =
|
|
20447
|
-
const authJson =
|
|
20752
|
+
const dir = path45.join(home, ".coderabbit");
|
|
20753
|
+
const authJson = path45.join(dir, "auth.json");
|
|
20448
20754
|
if (auth.kind === "api_key") {
|
|
20449
20755
|
rmIfExists(authJson);
|
|
20450
20756
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -20456,13 +20762,13 @@ var coderabbitProvisioner = {
|
|
|
20456
20762
|
try {
|
|
20457
20763
|
const parsed = JSON.parse(value);
|
|
20458
20764
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
20459
|
-
file =
|
|
20765
|
+
file = path45.basename(parsed.file);
|
|
20460
20766
|
contents = parsed.contents;
|
|
20461
20767
|
}
|
|
20462
20768
|
} catch {
|
|
20463
20769
|
}
|
|
20464
20770
|
}
|
|
20465
|
-
writeFile0600(
|
|
20771
|
+
writeFile0600(path45.join(dir, file), contents);
|
|
20466
20772
|
return {};
|
|
20467
20773
|
}
|
|
20468
20774
|
};
|
|
@@ -20490,7 +20796,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
20490
20796
|
this.agentId = agentId;
|
|
20491
20797
|
}
|
|
20492
20798
|
};
|
|
20493
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
20799
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os37.homedir()) {
|
|
20494
20800
|
const internal = toInternalAgentId(publicAgentId);
|
|
20495
20801
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
20496
20802
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -20500,11 +20806,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os36.homedir(
|
|
|
20500
20806
|
|
|
20501
20807
|
// src/commands/host/git-tooling.ts
|
|
20502
20808
|
var import_node_child_process21 = require("child_process");
|
|
20503
|
-
var
|
|
20504
|
-
var
|
|
20505
|
-
var
|
|
20809
|
+
var fs41 = __toESM(require("fs"));
|
|
20810
|
+
var os38 = __toESM(require("os"));
|
|
20811
|
+
var path46 = __toESM(require("path"));
|
|
20506
20812
|
function codeamBinDir() {
|
|
20507
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
20813
|
+
return process.env.CODEAM_BIN_DIR ?? path46.join(os38.homedir(), ".codeam", "bin");
|
|
20508
20814
|
}
|
|
20509
20815
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
20510
20816
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -20536,7 +20842,7 @@ async function download(url2, dest) {
|
|
|
20536
20842
|
const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
|
|
20537
20843
|
if (!res.ok || !res.body) return false;
|
|
20538
20844
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
20539
|
-
|
|
20845
|
+
fs41.writeFileSync(dest, buf);
|
|
20540
20846
|
return true;
|
|
20541
20847
|
} catch {
|
|
20542
20848
|
return false;
|
|
@@ -20559,8 +20865,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
20559
20865
|
const version3 = await resolveVersionFn(token);
|
|
20560
20866
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
20561
20867
|
const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
20562
|
-
const tmpRoot =
|
|
20563
|
-
const archive =
|
|
20868
|
+
const tmpRoot = fs41.mkdtempSync(path46.join(os38.tmpdir(), "codeam-gh-"));
|
|
20869
|
+
const archive = path46.join(tmpRoot, `${asset}.${ext}`);
|
|
20564
20870
|
if (!await downloadFn(url2, archive)) {
|
|
20565
20871
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
20566
20872
|
return null;
|
|
@@ -20570,16 +20876,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
20570
20876
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
20571
20877
|
return null;
|
|
20572
20878
|
}
|
|
20573
|
-
const extractedBin =
|
|
20574
|
-
if (!
|
|
20879
|
+
const extractedBin = path46.join(tmpRoot, asset, "bin", binaryName);
|
|
20880
|
+
if (!fs41.existsSync(extractedBin)) {
|
|
20575
20881
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
20576
20882
|
return null;
|
|
20577
20883
|
}
|
|
20578
20884
|
const binDir = codeamBinDir();
|
|
20579
|
-
|
|
20580
|
-
const target =
|
|
20581
|
-
|
|
20582
|
-
|
|
20885
|
+
fs41.mkdirSync(binDir, { recursive: true });
|
|
20886
|
+
const target = path46.join(binDir, binaryName);
|
|
20887
|
+
fs41.copyFileSync(extractedBin, target);
|
|
20888
|
+
fs41.chmodSync(target, 493);
|
|
20583
20889
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
20584
20890
|
return target;
|
|
20585
20891
|
} catch (e) {
|
|
@@ -20639,8 +20945,8 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
20639
20945
|
const version3 = await resolveLatestGlabVersion();
|
|
20640
20946
|
const asset = `glab_${version3}_${osToken}_${arch2}`;
|
|
20641
20947
|
const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
|
|
20642
|
-
const tmpRoot =
|
|
20643
|
-
const archive =
|
|
20948
|
+
const tmpRoot = fs41.mkdtempSync(path46.join(os38.tmpdir(), "codeam-glab-"));
|
|
20949
|
+
const archive = path46.join(tmpRoot, `${asset}.${ext}`);
|
|
20644
20950
|
if (!await downloadFn(url2, archive)) {
|
|
20645
20951
|
log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
|
|
20646
20952
|
return null;
|
|
@@ -20651,20 +20957,20 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
20651
20957
|
return null;
|
|
20652
20958
|
}
|
|
20653
20959
|
const candidates = [
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20960
|
+
path46.join(tmpRoot, "bin", binaryName),
|
|
20961
|
+
path46.join(tmpRoot, asset, "bin", binaryName),
|
|
20962
|
+
path46.join(tmpRoot, binaryName)
|
|
20657
20963
|
];
|
|
20658
|
-
const extractedBin = candidates.find((c2) =>
|
|
20964
|
+
const extractedBin = candidates.find((c2) => fs41.existsSync(c2));
|
|
20659
20965
|
if (!extractedBin) {
|
|
20660
20966
|
log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
|
|
20661
20967
|
return null;
|
|
20662
20968
|
}
|
|
20663
20969
|
const binDir = codeamBinDir();
|
|
20664
|
-
|
|
20665
|
-
const target =
|
|
20666
|
-
|
|
20667
|
-
|
|
20970
|
+
fs41.mkdirSync(binDir, { recursive: true });
|
|
20971
|
+
const target = path46.join(binDir, binaryName);
|
|
20972
|
+
fs41.copyFileSync(extractedBin, target);
|
|
20973
|
+
fs41.chmodSync(target, 493);
|
|
20668
20974
|
log.info("host-agent", `glab installed to ${target} (v${version3})`);
|
|
20669
20975
|
return target;
|
|
20670
20976
|
} catch (e) {
|
|
@@ -20861,24 +21167,24 @@ var HeadroomStatsReporter = class {
|
|
|
20861
21167
|
};
|
|
20862
21168
|
|
|
20863
21169
|
// src/commands/host/headroom-bootstrap.ts
|
|
20864
|
-
var
|
|
20865
|
-
var
|
|
20866
|
-
var
|
|
21170
|
+
var fs43 = __toESM(require("fs"));
|
|
21171
|
+
var path48 = __toESM(require("path"));
|
|
21172
|
+
var os40 = __toESM(require("os"));
|
|
20867
21173
|
|
|
20868
21174
|
// src/commands/host/headroom-config.ts
|
|
20869
|
-
var
|
|
20870
|
-
var
|
|
20871
|
-
var
|
|
21175
|
+
var fs42 = __toESM(require("fs"));
|
|
21176
|
+
var os39 = __toESM(require("os"));
|
|
21177
|
+
var path47 = __toESM(require("path"));
|
|
20872
21178
|
function headroomConfigPath() {
|
|
20873
|
-
return
|
|
21179
|
+
return path47.join(os39.homedir(), ".codeam", "headroom-config.json");
|
|
20874
21180
|
}
|
|
20875
21181
|
function persistHeadroomConfig(config) {
|
|
20876
21182
|
try {
|
|
20877
21183
|
const file = headroomConfigPath();
|
|
20878
|
-
|
|
21184
|
+
fs42.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
|
|
20879
21185
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
20880
|
-
|
|
20881
|
-
|
|
21186
|
+
fs42.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
21187
|
+
fs42.renameSync(tmp, file);
|
|
20882
21188
|
restrictToOwner(file);
|
|
20883
21189
|
} catch (err) {
|
|
20884
21190
|
log.warn(
|
|
@@ -20888,21 +21194,21 @@ function persistHeadroomConfig(config) {
|
|
|
20888
21194
|
}
|
|
20889
21195
|
}
|
|
20890
21196
|
function agentSettingsPath(kind) {
|
|
20891
|
-
const home =
|
|
20892
|
-
if (kind === "claude") return
|
|
20893
|
-
if (kind === "codex") return
|
|
20894
|
-
if (kind === "copilot") return
|
|
21197
|
+
const home = os39.homedir();
|
|
21198
|
+
if (kind === "claude") return path47.join(home, ".claude", "settings.json");
|
|
21199
|
+
if (kind === "codex") return path47.join(home, ".codex", "auth.json");
|
|
21200
|
+
if (kind === "copilot") return path47.join(home, ".config", "github-copilot", "hosts.json");
|
|
20895
21201
|
return null;
|
|
20896
21202
|
}
|
|
20897
21203
|
function backupAgentHeadroomConfig(kind) {
|
|
20898
21204
|
const src = agentSettingsPath(kind);
|
|
20899
21205
|
if (!src) return;
|
|
20900
21206
|
try {
|
|
20901
|
-
if (!
|
|
20902
|
-
const dest =
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
21207
|
+
if (!fs42.existsSync(src)) return;
|
|
21208
|
+
const dest = path47.join(os39.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
21209
|
+
fs42.mkdirSync(path47.dirname(dest), { recursive: true, mode: 448 });
|
|
21210
|
+
fs42.copyFileSync(src, dest);
|
|
21211
|
+
fs42.chmodSync(dest, 384);
|
|
20906
21212
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
20907
21213
|
} catch (err) {
|
|
20908
21214
|
log.warn(
|
|
@@ -20914,12 +21220,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
20914
21220
|
function restoreAgentHeadroomConfig(kind) {
|
|
20915
21221
|
const dest = agentSettingsPath(kind);
|
|
20916
21222
|
if (!dest) return false;
|
|
20917
|
-
const src =
|
|
20918
|
-
if (!
|
|
21223
|
+
const src = path47.join(os39.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
21224
|
+
if (!fs42.existsSync(src)) return false;
|
|
20919
21225
|
try {
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
21226
|
+
fs42.mkdirSync(path47.dirname(dest), { recursive: true, mode: 448 });
|
|
21227
|
+
fs42.copyFileSync(src, dest);
|
|
21228
|
+
fs42.chmodSync(dest, 384);
|
|
20923
21229
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
20924
21230
|
return true;
|
|
20925
21231
|
} catch (err) {
|
|
@@ -20932,7 +21238,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
20932
21238
|
}
|
|
20933
21239
|
function readHeadroomChildEnv() {
|
|
20934
21240
|
try {
|
|
20935
|
-
const raw =
|
|
21241
|
+
const raw = fs42.readFileSync(headroomConfigPath(), "utf8");
|
|
20936
21242
|
const parsed = JSON.parse(raw);
|
|
20937
21243
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
20938
21244
|
const o = parsed;
|
|
@@ -20968,49 +21274,49 @@ function bundledClaudeBinDir() {
|
|
|
20968
21274
|
const roots = /* @__PURE__ */ new Set();
|
|
20969
21275
|
let dir = __dirname;
|
|
20970
21276
|
for (let i = 0; i < 6; i++) {
|
|
20971
|
-
roots.add(
|
|
20972
|
-
const parent =
|
|
21277
|
+
roots.add(path48.join(dir, "node_modules"));
|
|
21278
|
+
const parent = path48.dirname(dir);
|
|
20973
21279
|
if (parent === dir) break;
|
|
20974
21280
|
dir = parent;
|
|
20975
21281
|
}
|
|
20976
21282
|
try {
|
|
20977
21283
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
20978
|
-
const marker = `${
|
|
21284
|
+
const marker = `${path48.sep}@anthropic-ai${path48.sep}`;
|
|
20979
21285
|
const idx = main2.lastIndexOf(marker);
|
|
20980
21286
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
20981
21287
|
} catch {
|
|
20982
21288
|
}
|
|
20983
21289
|
for (const nm of roots) {
|
|
20984
|
-
const atAnthropic =
|
|
21290
|
+
const atAnthropic = path48.join(nm, "@anthropic-ai");
|
|
20985
21291
|
let entries;
|
|
20986
21292
|
try {
|
|
20987
|
-
entries =
|
|
21293
|
+
entries = fs43.readdirSync(atAnthropic);
|
|
20988
21294
|
} catch {
|
|
20989
21295
|
continue;
|
|
20990
21296
|
}
|
|
20991
21297
|
for (const entry of entries) {
|
|
20992
21298
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
20993
|
-
const bin =
|
|
20994
|
-
if (
|
|
21299
|
+
const bin = path48.join(atAnthropic, entry, "claude");
|
|
21300
|
+
if (fs43.existsSync(bin)) return path48.dirname(bin);
|
|
20995
21301
|
}
|
|
20996
21302
|
}
|
|
20997
21303
|
return null;
|
|
20998
21304
|
}
|
|
20999
21305
|
async function getFreeDiskBytes(dir) {
|
|
21000
21306
|
try {
|
|
21001
|
-
const s = await
|
|
21307
|
+
const s = await fs43.promises.statfs(dir);
|
|
21002
21308
|
return s.bsize * s.bavail;
|
|
21003
21309
|
} catch {
|
|
21004
21310
|
return null;
|
|
21005
21311
|
}
|
|
21006
21312
|
}
|
|
21007
21313
|
function headroomModelsCached() {
|
|
21008
|
-
const hubDir = process.env.HUGGINGFACE_HUB_CACHE ||
|
|
21009
|
-
process.env.HF_HOME ||
|
|
21314
|
+
const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path48.join(
|
|
21315
|
+
process.env.HF_HOME || path48.join(os40.homedir(), ".cache", "huggingface"),
|
|
21010
21316
|
"hub"
|
|
21011
21317
|
);
|
|
21012
21318
|
return HEADROOM_MODELS.every(
|
|
21013
|
-
(m) =>
|
|
21319
|
+
(m) => fs43.existsSync(path48.join(hubDir, `models--${m.repo.replace("/", "--")}`))
|
|
21014
21320
|
);
|
|
21015
21321
|
}
|
|
21016
21322
|
async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
|
|
@@ -21079,7 +21385,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
21079
21385
|
if (initKind === "claude") {
|
|
21080
21386
|
const claudeDir = bundledClaudeBinDir();
|
|
21081
21387
|
if (claudeDir) {
|
|
21082
|
-
initEnv.PATH = `${claudeDir}${
|
|
21388
|
+
initEnv.PATH = `${claudeDir}${path48.delimiter}${process.env["PATH"] ?? ""}`;
|
|
21083
21389
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
21084
21390
|
} else {
|
|
21085
21391
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -21116,19 +21422,19 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
21116
21422
|
}
|
|
21117
21423
|
|
|
21118
21424
|
// src/commands/host/house-proxy-config.ts
|
|
21119
|
-
var
|
|
21120
|
-
var
|
|
21121
|
-
var
|
|
21425
|
+
var fs44 = __toESM(require("fs"));
|
|
21426
|
+
var os41 = __toESM(require("os"));
|
|
21427
|
+
var path49 = __toESM(require("path"));
|
|
21122
21428
|
function houseProxyConfigPath() {
|
|
21123
|
-
return
|
|
21429
|
+
return path49.join(os41.homedir(), ".codeam", "house-proxy.json");
|
|
21124
21430
|
}
|
|
21125
21431
|
function persistHouseProxyConfig(config) {
|
|
21126
21432
|
try {
|
|
21127
21433
|
const file = houseProxyConfigPath();
|
|
21128
|
-
|
|
21434
|
+
fs44.mkdirSync(path49.dirname(file), { recursive: true, mode: 448 });
|
|
21129
21435
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
21130
|
-
|
|
21131
|
-
|
|
21436
|
+
fs44.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
21437
|
+
fs44.renameSync(tmp, file);
|
|
21132
21438
|
restrictToOwner(file);
|
|
21133
21439
|
} catch (err) {
|
|
21134
21440
|
log.warn(
|
|
@@ -21139,13 +21445,13 @@ function persistHouseProxyConfig(config) {
|
|
|
21139
21445
|
}
|
|
21140
21446
|
function clearHouseProxyConfig() {
|
|
21141
21447
|
try {
|
|
21142
|
-
|
|
21448
|
+
fs44.rmSync(houseProxyConfigPath(), { force: true });
|
|
21143
21449
|
} catch {
|
|
21144
21450
|
}
|
|
21145
21451
|
}
|
|
21146
21452
|
function readHouseProxyChildEnv() {
|
|
21147
21453
|
try {
|
|
21148
|
-
const raw =
|
|
21454
|
+
const raw = fs44.readFileSync(houseProxyConfigPath(), "utf8");
|
|
21149
21455
|
const parsed = JSON.parse(raw);
|
|
21150
21456
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
21151
21457
|
const o = parsed;
|
|
@@ -21178,9 +21484,9 @@ function readHouseProxyChildEnv() {
|
|
|
21178
21484
|
var import_node_child_process23 = require("child_process");
|
|
21179
21485
|
|
|
21180
21486
|
// src/lib/updateNotifier.ts
|
|
21181
|
-
var
|
|
21182
|
-
var
|
|
21183
|
-
var
|
|
21487
|
+
var fs45 = __toESM(require("fs"));
|
|
21488
|
+
var os42 = __toESM(require("os"));
|
|
21489
|
+
var path50 = __toESM(require("path"));
|
|
21184
21490
|
var https6 = __toESM(require("https"));
|
|
21185
21491
|
var import_node_child_process22 = require("child_process");
|
|
21186
21492
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -21189,12 +21495,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
21189
21495
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
21190
21496
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
21191
21497
|
function cachePath() {
|
|
21192
|
-
const dir =
|
|
21193
|
-
return
|
|
21498
|
+
const dir = path50.join(os42.homedir(), ".codeam");
|
|
21499
|
+
return path50.join(dir, "update-check.json");
|
|
21194
21500
|
}
|
|
21195
21501
|
function readCache() {
|
|
21196
21502
|
try {
|
|
21197
|
-
const raw =
|
|
21503
|
+
const raw = fs45.readFileSync(cachePath(), "utf8");
|
|
21198
21504
|
const parsed = JSON.parse(raw);
|
|
21199
21505
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
21200
21506
|
return parsed;
|
|
@@ -21205,10 +21511,10 @@ function readCache() {
|
|
|
21205
21511
|
function writeCache(cache) {
|
|
21206
21512
|
try {
|
|
21207
21513
|
const file = cachePath();
|
|
21208
|
-
|
|
21514
|
+
fs45.mkdirSync(path50.dirname(file), { recursive: true });
|
|
21209
21515
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
21210
|
-
|
|
21211
|
-
|
|
21516
|
+
fs45.writeFileSync(tmp, JSON.stringify(cache));
|
|
21517
|
+
fs45.renameSync(tmp, file);
|
|
21212
21518
|
} catch {
|
|
21213
21519
|
}
|
|
21214
21520
|
}
|
|
@@ -21282,8 +21588,8 @@ function isLinkedInstall() {
|
|
|
21282
21588
|
timeout: 2e3
|
|
21283
21589
|
}).trim();
|
|
21284
21590
|
if (!root) return false;
|
|
21285
|
-
const pkgPath =
|
|
21286
|
-
return
|
|
21591
|
+
const pkgPath = path50.join(root, PKG_NAME);
|
|
21592
|
+
return fs45.lstatSync(pkgPath).isSymbolicLink();
|
|
21287
21593
|
} catch {
|
|
21288
21594
|
return false;
|
|
21289
21595
|
}
|
|
@@ -21319,7 +21625,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
21319
21625
|
return;
|
|
21320
21626
|
}
|
|
21321
21627
|
try {
|
|
21322
|
-
|
|
21628
|
+
fs45.unlinkSync(cachePath());
|
|
21323
21629
|
} catch {
|
|
21324
21630
|
}
|
|
21325
21631
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -21335,7 +21641,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
21335
21641
|
if (process.env.NODE_ENV === "test") return;
|
|
21336
21642
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21337
21643
|
if (process.env.CI) return;
|
|
21338
|
-
const current2 = true ? "2.65.
|
|
21644
|
+
const current2 = true ? "2.65.4" : null;
|
|
21339
21645
|
if (!current2) return;
|
|
21340
21646
|
const cache = readCache();
|
|
21341
21647
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21352,7 +21658,7 @@ function checkForUpdates() {
|
|
|
21352
21658
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
21353
21659
|
if (process.env.CI) return;
|
|
21354
21660
|
if (!process.stdout.isTTY) return;
|
|
21355
|
-
const current2 = true ? "2.65.
|
|
21661
|
+
const current2 = true ? "2.65.4" : null;
|
|
21356
21662
|
if (!current2) return;
|
|
21357
21663
|
const cache = readCache();
|
|
21358
21664
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -21372,7 +21678,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
21372
21678
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
21373
21679
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
21374
21680
|
function currentCliVersion() {
|
|
21375
|
-
return true ? "2.65.
|
|
21681
|
+
return true ? "2.65.4" : null;
|
|
21376
21682
|
}
|
|
21377
21683
|
function runCmd(cmd, args2, timeoutMs) {
|
|
21378
21684
|
return new Promise((resolve9) => {
|
|
@@ -21439,7 +21745,7 @@ async function runSelfUpdate() {
|
|
|
21439
21745
|
|
|
21440
21746
|
// src/commands/host/teardown.ts
|
|
21441
21747
|
var import_node_child_process24 = require("child_process");
|
|
21442
|
-
var
|
|
21748
|
+
var fs46 = __toESM(require("fs"));
|
|
21443
21749
|
var defaultDisableService = () => {
|
|
21444
21750
|
try {
|
|
21445
21751
|
(0, import_node_child_process24.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
@@ -21448,7 +21754,7 @@ var defaultDisableService = () => {
|
|
|
21448
21754
|
};
|
|
21449
21755
|
var defaultTeardownHeadroom = () => {
|
|
21450
21756
|
try {
|
|
21451
|
-
const kind = JSON.parse(
|
|
21757
|
+
const kind = JSON.parse(fs46.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
21452
21758
|
if (kind) {
|
|
21453
21759
|
(0, import_node_child_process24.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
21454
21760
|
}
|
|
@@ -21516,8 +21822,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
21516
21822
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
21517
21823
|
try {
|
|
21518
21824
|
const file = headroomConfigPath();
|
|
21519
|
-
if (!
|
|
21520
|
-
const cfg = JSON.parse(
|
|
21825
|
+
if (!fs47.existsSync(file)) return null;
|
|
21826
|
+
const cfg = JSON.parse(fs47.readFileSync(file, "utf8"));
|
|
21521
21827
|
if (!cfg?.enabled) return null;
|
|
21522
21828
|
const agent = cfg.agent ?? "claude";
|
|
21523
21829
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -22104,13 +22410,13 @@ var HostAgentSupervisor = class {
|
|
|
22104
22410
|
const relay = this.relay;
|
|
22105
22411
|
if (!relay) return;
|
|
22106
22412
|
const raw = cmd.payload?.path;
|
|
22107
|
-
const target = typeof raw === "string" && raw.trim() ?
|
|
22413
|
+
const target = typeof raw === "string" && raw.trim() ? path51.resolve(raw.trim()) : os43.homedir();
|
|
22108
22414
|
try {
|
|
22109
|
-
const dirents = await
|
|
22415
|
+
const dirents = await fs47.promises.readdir(target, { withFileTypes: true });
|
|
22110
22416
|
const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
|
|
22111
22417
|
(a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
|
|
22112
22418
|
);
|
|
22113
|
-
const parent =
|
|
22419
|
+
const parent = path51.dirname(target);
|
|
22114
22420
|
await relay.sendResult(cmd.id, "completed", {
|
|
22115
22421
|
path: target,
|
|
22116
22422
|
// null at the filesystem root so the UI can hide the ".." affordance.
|
|
@@ -22343,14 +22649,14 @@ var HostAgentSupervisor = class {
|
|
|
22343
22649
|
API_TIMEOUT_MS: "3000000",
|
|
22344
22650
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
22345
22651
|
};
|
|
22346
|
-
const houseConfigDir =
|
|
22347
|
-
|
|
22652
|
+
const houseConfigDir = path51.join(
|
|
22653
|
+
os43.homedir(),
|
|
22348
22654
|
".codeam",
|
|
22349
22655
|
"house-claude",
|
|
22350
22656
|
payload.deployId
|
|
22351
22657
|
);
|
|
22352
22658
|
try {
|
|
22353
|
-
|
|
22659
|
+
fs47.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
22354
22660
|
} catch {
|
|
22355
22661
|
}
|
|
22356
22662
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -22376,7 +22682,7 @@ var HostAgentSupervisor = class {
|
|
|
22376
22682
|
report("installing", "installing agent CLI");
|
|
22377
22683
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
22378
22684
|
}
|
|
22379
|
-
const home = process.env.HOME ||
|
|
22685
|
+
const home = process.env.HOME || os43.homedir();
|
|
22380
22686
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
22381
22687
|
if (payload.cloneToken) {
|
|
22382
22688
|
try {
|
|
@@ -22384,13 +22690,13 @@ var HostAgentSupervisor = class {
|
|
|
22384
22690
|
if ((payload.repoProvider ?? "github") === "gitlab") {
|
|
22385
22691
|
const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
|
|
22386
22692
|
if (glabCmd) {
|
|
22387
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
22693
|
+
childEnv.PATH = `${codeamBinDir()}${path51.delimiter}${childEnv.PATH}`;
|
|
22388
22694
|
await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
|
|
22389
22695
|
}
|
|
22390
22696
|
} else {
|
|
22391
22697
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
22392
22698
|
if (ghCmd) {
|
|
22393
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
22699
|
+
childEnv.PATH = `${codeamBinDir()}${path51.delimiter}${childEnv.PATH}`;
|
|
22394
22700
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
22395
22701
|
}
|
|
22396
22702
|
}
|
|
@@ -22410,7 +22716,7 @@ var HostAgentSupervisor = class {
|
|
|
22410
22716
|
}
|
|
22411
22717
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
22412
22718
|
report("headroom", "setting up Headroom proxy");
|
|
22413
|
-
const freeBytes = await this.getFreeDisk(
|
|
22719
|
+
const freeBytes = await this.getFreeDisk(os43.homedir());
|
|
22414
22720
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
22415
22721
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
22416
22722
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -22469,9 +22775,9 @@ var HostAgentSupervisor = class {
|
|
|
22469
22775
|
);
|
|
22470
22776
|
if (!payload.suppressOnboardingWelcome) {
|
|
22471
22777
|
try {
|
|
22472
|
-
const cfgDir = childEnv.CLAUDE_CONFIG_DIR ||
|
|
22473
|
-
const projectDir =
|
|
22474
|
-
const hasPriorConversation =
|
|
22778
|
+
const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path51.join(os43.homedir(), ".claude");
|
|
22779
|
+
const projectDir = path51.join(cfgDir, "projects", encodeCwd(cwd));
|
|
22780
|
+
const hasPriorConversation = fs47.existsSync(projectDir) && fs47.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
|
|
22475
22781
|
if (hasPriorConversation) {
|
|
22476
22782
|
childEnv.CODEAM_RESUME_LATEST = "1";
|
|
22477
22783
|
log.info(
|
|
@@ -22570,7 +22876,7 @@ var HostAgentSupervisor = class {
|
|
|
22570
22876
|
if (this.children.size > 0) return;
|
|
22571
22877
|
const session = getActiveSession();
|
|
22572
22878
|
if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
|
|
22573
|
-
const cwd = session.cwd &&
|
|
22879
|
+
const cwd = session.cwd && fs47.existsSync(session.cwd) ? session.cwd : process.cwd();
|
|
22574
22880
|
const proc = this.resumeSpawner(
|
|
22575
22881
|
{ ...readHeadroomChildEnv(), ...readHouseProxyChildEnv() },
|
|
22576
22882
|
cwd
|
|
@@ -22667,12 +22973,12 @@ var HostAgentSupervisor = class {
|
|
|
22667
22973
|
this.children.delete(deployId);
|
|
22668
22974
|
}
|
|
22669
22975
|
const dirs = [
|
|
22670
|
-
|
|
22671
|
-
|
|
22976
|
+
path51.join(selfHostedWorkspaceRoot(), deployId),
|
|
22977
|
+
path51.join(os43.homedir(), ".codeam", "house-claude", deployId)
|
|
22672
22978
|
];
|
|
22673
22979
|
for (const dir of dirs) {
|
|
22674
22980
|
try {
|
|
22675
|
-
|
|
22981
|
+
fs47.rmSync(dir, { recursive: true, force: true });
|
|
22676
22982
|
} catch (err) {
|
|
22677
22983
|
log.warn(
|
|
22678
22984
|
"host-agent",
|
|
@@ -22809,9 +23115,9 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
22809
23115
|
}
|
|
22810
23116
|
|
|
22811
23117
|
// src/services/headroom/budget-relaunch.ts
|
|
22812
|
-
var
|
|
22813
|
-
var
|
|
22814
|
-
var
|
|
23118
|
+
var fs48 = __toESM(require("fs"));
|
|
23119
|
+
var os44 = __toESM(require("os"));
|
|
23120
|
+
var path52 = __toESM(require("path"));
|
|
22815
23121
|
var import_child_process15 = require("child_process");
|
|
22816
23122
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
22817
23123
|
const rawArgs = manifest.proxy_args ?? [];
|
|
@@ -22845,7 +23151,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
22845
23151
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
22846
23152
|
}
|
|
22847
23153
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
22848
|
-
const deployDir =
|
|
23154
|
+
const deployDir = path52.join(homeDir2, ".headroom", "deploy");
|
|
22849
23155
|
let profiles;
|
|
22850
23156
|
try {
|
|
22851
23157
|
profiles = deps.readDir(deployDir);
|
|
@@ -22854,7 +23160,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
22854
23160
|
}
|
|
22855
23161
|
const results = [];
|
|
22856
23162
|
for (const profile of profiles) {
|
|
22857
|
-
const manifestPath =
|
|
23163
|
+
const manifestPath = path52.join(deployDir, profile, "manifest.json");
|
|
22858
23164
|
let raw;
|
|
22859
23165
|
try {
|
|
22860
23166
|
raw = deps.readJson(manifestPath);
|
|
@@ -22886,8 +23192,8 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
22886
23192
|
}
|
|
22887
23193
|
function writeManifestReal(manifestPath, manifest) {
|
|
22888
23194
|
const tmp = manifestPath + ".codeam.tmp";
|
|
22889
|
-
|
|
22890
|
-
|
|
23195
|
+
fs48.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
23196
|
+
fs48.renameSync(tmp, manifestPath);
|
|
22891
23197
|
}
|
|
22892
23198
|
function restartDeploymentReal(profile) {
|
|
22893
23199
|
try {
|
|
@@ -22922,11 +23228,11 @@ function spawnProxyReal2(_budget) {
|
|
|
22922
23228
|
);
|
|
22923
23229
|
}
|
|
22924
23230
|
function makeRealApplyBudgetDeps() {
|
|
22925
|
-
const homeDir2 =
|
|
23231
|
+
const homeDir2 = os44.homedir();
|
|
22926
23232
|
return {
|
|
22927
23233
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
22928
|
-
readDir: (dir) =>
|
|
22929
|
-
readJson: (filePath) => JSON.parse(
|
|
23234
|
+
readDir: (dir) => fs48.readdirSync(dir),
|
|
23235
|
+
readJson: (filePath) => JSON.parse(fs48.readFileSync(filePath, "utf8"))
|
|
22930
23236
|
}),
|
|
22931
23237
|
writeManifest: writeManifestReal,
|
|
22932
23238
|
restartDeployment: restartDeploymentReal,
|
|
@@ -23059,47 +23365,47 @@ async function readUsageReport(deps = {}) {
|
|
|
23059
23365
|
}
|
|
23060
23366
|
|
|
23061
23367
|
// src/agents/acp/guardrail-config.ts
|
|
23062
|
-
var
|
|
23063
|
-
var
|
|
23064
|
-
var
|
|
23368
|
+
var fs49 = __toESM(require("fs"));
|
|
23369
|
+
var path53 = __toESM(require("path"));
|
|
23370
|
+
var os45 = __toESM(require("os"));
|
|
23065
23371
|
var current = null;
|
|
23066
|
-
function guardrailConfigPath(homeDir2 =
|
|
23067
|
-
return
|
|
23372
|
+
function guardrailConfigPath(homeDir2 = os45.homedir()) {
|
|
23373
|
+
return path53.join(homeDir2, ".codeam", "guardrails.json");
|
|
23068
23374
|
}
|
|
23069
|
-
function loadGuardrailPolicy(homeDir2 =
|
|
23375
|
+
function loadGuardrailPolicy(homeDir2 = os45.homedir()) {
|
|
23070
23376
|
try {
|
|
23071
|
-
current = normalizeGuardrailPolicy(JSON.parse(
|
|
23377
|
+
current = normalizeGuardrailPolicy(JSON.parse(fs49.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
|
|
23072
23378
|
} catch {
|
|
23073
23379
|
current = { ...DEFAULT_GUARDRAIL_POLICY };
|
|
23074
23380
|
}
|
|
23075
23381
|
return current;
|
|
23076
23382
|
}
|
|
23077
|
-
function getGuardrailPolicy(homeDir2 =
|
|
23383
|
+
function getGuardrailPolicy(homeDir2 = os45.homedir()) {
|
|
23078
23384
|
return current ?? loadGuardrailPolicy(homeDir2);
|
|
23079
23385
|
}
|
|
23080
|
-
function setGuardrailPolicy(raw, homeDir2 =
|
|
23386
|
+
function setGuardrailPolicy(raw, homeDir2 = os45.homedir()) {
|
|
23081
23387
|
const next = normalizeGuardrailPolicy(raw);
|
|
23082
23388
|
current = next;
|
|
23083
23389
|
try {
|
|
23084
23390
|
const p2 = guardrailConfigPath(homeDir2);
|
|
23085
|
-
|
|
23086
|
-
|
|
23391
|
+
fs49.mkdirSync(path53.dirname(p2), { recursive: true });
|
|
23392
|
+
fs49.writeFileSync(p2, JSON.stringify(next, null, 2));
|
|
23087
23393
|
} catch {
|
|
23088
23394
|
}
|
|
23089
23395
|
return next;
|
|
23090
23396
|
}
|
|
23091
23397
|
|
|
23092
23398
|
// src/services/preview/port-registry.ts
|
|
23093
|
-
var
|
|
23094
|
-
var
|
|
23095
|
-
var
|
|
23399
|
+
var fs50 = __toESM(require("fs"));
|
|
23400
|
+
var os46 = __toESM(require("os"));
|
|
23401
|
+
var path54 = __toESM(require("path"));
|
|
23096
23402
|
var import_child_process16 = require("child_process");
|
|
23097
23403
|
function registryPath() {
|
|
23098
|
-
return
|
|
23404
|
+
return path54.join(os46.homedir(), ".codeam", "preview-ports.json");
|
|
23099
23405
|
}
|
|
23100
23406
|
function readRegistry() {
|
|
23101
23407
|
try {
|
|
23102
|
-
const raw =
|
|
23408
|
+
const raw = fs50.readFileSync(registryPath(), "utf8");
|
|
23103
23409
|
const parsed = JSON.parse(raw);
|
|
23104
23410
|
if (parsed && typeof parsed === "object") return parsed;
|
|
23105
23411
|
} catch {
|
|
@@ -23109,10 +23415,10 @@ function readRegistry() {
|
|
|
23109
23415
|
function writeRegistry(reg) {
|
|
23110
23416
|
try {
|
|
23111
23417
|
const file = registryPath();
|
|
23112
|
-
|
|
23418
|
+
fs50.mkdirSync(path54.dirname(file), { recursive: true });
|
|
23113
23419
|
const tmp = `${file}.tmp`;
|
|
23114
|
-
|
|
23115
|
-
|
|
23420
|
+
fs50.writeFileSync(tmp, JSON.stringify(reg), "utf8");
|
|
23421
|
+
fs50.renameSync(tmp, file);
|
|
23116
23422
|
} catch (err) {
|
|
23117
23423
|
log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
23118
23424
|
}
|
|
@@ -23178,7 +23484,7 @@ function reclaimOwnOrphanPort(port) {
|
|
|
23178
23484
|
|
|
23179
23485
|
// src/services/preview/host-allow.ts
|
|
23180
23486
|
var import_fs2 = require("fs");
|
|
23181
|
-
var
|
|
23487
|
+
var path55 = __toESM(require("path"));
|
|
23182
23488
|
var NEXT_ALLOWED_ORIGINS = [
|
|
23183
23489
|
"*.trycloudflare.com",
|
|
23184
23490
|
"*.preview.codeagent-mobile.com",
|
|
@@ -23198,7 +23504,7 @@ var MARKER_DIR = ".codeam";
|
|
|
23198
23504
|
var MARKER_FILE = "preview-host-allow.json";
|
|
23199
23505
|
var ORIG_INFIX = ".codeam-orig";
|
|
23200
23506
|
function markerPath(cwd) {
|
|
23201
|
-
return
|
|
23507
|
+
return path55.join(cwd, MARKER_DIR, MARKER_FILE);
|
|
23202
23508
|
}
|
|
23203
23509
|
async function fileExists(p2) {
|
|
23204
23510
|
try {
|
|
@@ -23211,13 +23517,13 @@ async function fileExists(p2) {
|
|
|
23211
23517
|
async function findConfigFile(cwd, framework) {
|
|
23212
23518
|
const base = CONFIG_BASENAMES[framework];
|
|
23213
23519
|
for (const ext of CONFIG_EXTS) {
|
|
23214
|
-
if (await fileExists(
|
|
23520
|
+
if (await fileExists(path55.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
|
|
23215
23521
|
}
|
|
23216
23522
|
return null;
|
|
23217
23523
|
}
|
|
23218
23524
|
async function dependsOn(cwd, pkgName) {
|
|
23219
23525
|
try {
|
|
23220
|
-
const raw = await import_fs2.promises.readFile(
|
|
23526
|
+
const raw = await import_fs2.promises.readFile(path55.join(cwd, "package.json"), "utf8");
|
|
23221
23527
|
const pkg = JSON.parse(raw);
|
|
23222
23528
|
return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
|
|
23223
23529
|
} catch {
|
|
@@ -23225,11 +23531,11 @@ async function dependsOn(cwd, pkgName) {
|
|
|
23225
23531
|
}
|
|
23226
23532
|
}
|
|
23227
23533
|
async function isEsmConfig(cwd, configFile) {
|
|
23228
|
-
const ext =
|
|
23534
|
+
const ext = path55.extname(configFile);
|
|
23229
23535
|
if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
|
|
23230
23536
|
if (ext === ".cjs") return false;
|
|
23231
23537
|
try {
|
|
23232
|
-
const raw = await import_fs2.promises.readFile(
|
|
23538
|
+
const raw = await import_fs2.promises.readFile(path55.join(cwd, "package.json"), "utf8");
|
|
23233
23539
|
return JSON.parse(raw).type === "module";
|
|
23234
23540
|
} catch {
|
|
23235
23541
|
return false;
|
|
@@ -23312,7 +23618,7 @@ function shimFor(framework, origBasename, esm) {
|
|
|
23312
23618
|
return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
|
|
23313
23619
|
}
|
|
23314
23620
|
async function writeMarker(cwd, marker) {
|
|
23315
|
-
await import_fs2.promises.mkdir(
|
|
23621
|
+
await import_fs2.promises.mkdir(path55.join(cwd, MARKER_DIR), { recursive: true });
|
|
23316
23622
|
await import_fs2.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
|
|
23317
23623
|
}
|
|
23318
23624
|
async function readMarker(cwd) {
|
|
@@ -23327,9 +23633,9 @@ async function restorePreviewHostAllow(cwd) {
|
|
|
23327
23633
|
const marker = await readMarker(cwd);
|
|
23328
23634
|
if (!marker) return;
|
|
23329
23635
|
try {
|
|
23330
|
-
const configAbs =
|
|
23636
|
+
const configAbs = path55.join(cwd, marker.configFile);
|
|
23331
23637
|
if (marker.backupFile) {
|
|
23332
|
-
const backupAbs =
|
|
23638
|
+
const backupAbs = path55.join(cwd, marker.backupFile);
|
|
23333
23639
|
if (await fileExists(backupAbs)) {
|
|
23334
23640
|
await import_fs2.promises.rm(configAbs, { force: true });
|
|
23335
23641
|
await import_fs2.promises.rename(backupAbs, configAbs);
|
|
@@ -23362,16 +23668,16 @@ async function applyPreviewHostAllow(cwd) {
|
|
|
23362
23668
|
}
|
|
23363
23669
|
if (!framework) return;
|
|
23364
23670
|
if (existing) {
|
|
23365
|
-
const ext =
|
|
23671
|
+
const ext = path55.extname(existing);
|
|
23366
23672
|
const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
|
|
23367
23673
|
const esm = await isEsmConfig(cwd, existing);
|
|
23368
|
-
await import_fs2.promises.rename(
|
|
23369
|
-
await import_fs2.promises.writeFile(
|
|
23674
|
+
await import_fs2.promises.rename(path55.join(cwd, existing), path55.join(cwd, origBasename));
|
|
23675
|
+
await import_fs2.promises.writeFile(path55.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
|
|
23370
23676
|
await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
|
|
23371
23677
|
log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
|
|
23372
23678
|
} else {
|
|
23373
23679
|
const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
|
|
23374
|
-
await import_fs2.promises.writeFile(
|
|
23680
|
+
await import_fs2.promises.writeFile(path55.join(cwd, configFile), shimFor(framework, null, true), "utf8");
|
|
23375
23681
|
await writeMarker(cwd, { framework, configFile, backupFile: null });
|
|
23376
23682
|
log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
|
|
23377
23683
|
}
|
|
@@ -24053,19 +24359,19 @@ function activePreviewSessionIds() {
|
|
|
24053
24359
|
|
|
24054
24360
|
// src/services/preview/start-orchestrator.ts
|
|
24055
24361
|
var import_child_process21 = require("child_process");
|
|
24056
|
-
var
|
|
24057
|
-
var
|
|
24362
|
+
var fs58 = __toESM(require("fs"));
|
|
24363
|
+
var path62 = __toESM(require("path"));
|
|
24058
24364
|
var import_which2 = __toESM(require("which"));
|
|
24059
24365
|
|
|
24060
24366
|
// src/services/project-env/index.ts
|
|
24061
24367
|
var import_fs6 = require("fs");
|
|
24062
|
-
var
|
|
24368
|
+
var path61 = __toESM(require("path"));
|
|
24063
24369
|
|
|
24064
24370
|
// src/beads/project-key.ts
|
|
24065
24371
|
var import_child_process20 = require("child_process");
|
|
24066
24372
|
var crypto2 = __toESM(require("crypto"));
|
|
24067
|
-
var
|
|
24068
|
-
var
|
|
24373
|
+
var fs56 = __toESM(require("fs"));
|
|
24374
|
+
var path60 = __toESM(require("path"));
|
|
24069
24375
|
function normalizeOrigin(raw) {
|
|
24070
24376
|
const trimmed = raw.trim();
|
|
24071
24377
|
if (!trimmed) return null;
|
|
@@ -24091,17 +24397,17 @@ function normalizeOrigin(raw) {
|
|
|
24091
24397
|
return `${host2}/${pathPart}`;
|
|
24092
24398
|
}
|
|
24093
24399
|
function findRepoRoot(cwd) {
|
|
24094
|
-
let dir =
|
|
24400
|
+
let dir = path60.resolve(cwd);
|
|
24095
24401
|
const seen = /* @__PURE__ */ new Set();
|
|
24096
24402
|
for (let i = 0; i < 256; i++) {
|
|
24097
24403
|
if (seen.has(dir)) return null;
|
|
24098
24404
|
seen.add(dir);
|
|
24099
24405
|
try {
|
|
24100
|
-
const stat3 =
|
|
24406
|
+
const stat3 = fs56.statSync(path60.join(dir, ".git"), { throwIfNoEntry: false });
|
|
24101
24407
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
24102
24408
|
} catch {
|
|
24103
24409
|
}
|
|
24104
|
-
const parent =
|
|
24410
|
+
const parent = path60.dirname(dir);
|
|
24105
24411
|
if (parent === dir) return null;
|
|
24106
24412
|
dir = parent;
|
|
24107
24413
|
}
|
|
@@ -24112,7 +24418,7 @@ var _execSeam2 = {
|
|
|
24112
24418
|
const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
|
|
24113
24419
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
24114
24420
|
},
|
|
24115
|
-
realpath: (p2) =>
|
|
24421
|
+
realpath: (p2) => fs56.realpathSync(p2)
|
|
24116
24422
|
};
|
|
24117
24423
|
function readOrigin(cwd) {
|
|
24118
24424
|
try {
|
|
@@ -24141,7 +24447,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
24141
24447
|
} catch {
|
|
24142
24448
|
}
|
|
24143
24449
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
24144
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
24450
|
+
return { projectKey: `path:${hash}`, projectLabel: path60.basename(real) || "project" };
|
|
24145
24451
|
}
|
|
24146
24452
|
|
|
24147
24453
|
// src/services/project-env/index.ts
|
|
@@ -24154,7 +24460,7 @@ async function readIfExists(p2) {
|
|
|
24154
24460
|
}
|
|
24155
24461
|
async function syncProjectEnvUp(cwd, ctx) {
|
|
24156
24462
|
if (!ctx.pluginAuthToken) return;
|
|
24157
|
-
const content = await readIfExists(
|
|
24463
|
+
const content = await readIfExists(path61.join(cwd, ".env"));
|
|
24158
24464
|
if (content == null) return;
|
|
24159
24465
|
try {
|
|
24160
24466
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -24176,7 +24482,7 @@ async function syncProjectEnvUp(cwd, ctx) {
|
|
|
24176
24482
|
}
|
|
24177
24483
|
async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
24178
24484
|
if (!ctx.pluginAuthToken) return false;
|
|
24179
|
-
const envPath =
|
|
24485
|
+
const envPath = path61.join(cwd, ".env");
|
|
24180
24486
|
if (await readIfExists(envPath) != null) return false;
|
|
24181
24487
|
try {
|
|
24182
24488
|
const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
|
|
@@ -24187,7 +24493,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
|
|
|
24187
24493
|
projectKey
|
|
24188
24494
|
});
|
|
24189
24495
|
if (!stored) return false;
|
|
24190
|
-
const tmp =
|
|
24496
|
+
const tmp = path61.join(cwd, ".env.codeam-restore.tmp");
|
|
24191
24497
|
await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
|
|
24192
24498
|
await import_fs6.promises.rename(tmp, envPath);
|
|
24193
24499
|
log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
|
|
@@ -24264,8 +24570,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
24264
24570
|
if (args2.length === 0) return detection;
|
|
24265
24571
|
const binName = args2[0];
|
|
24266
24572
|
if (binName.startsWith("-")) return detection;
|
|
24267
|
-
const binPath =
|
|
24268
|
-
if (!
|
|
24573
|
+
const binPath = path62.join(cwd, "node_modules", ".bin", binName);
|
|
24574
|
+
if (!fs58.existsSync(binPath)) return detection;
|
|
24269
24575
|
return {
|
|
24270
24576
|
...detection,
|
|
24271
24577
|
command: binPath,
|
|
@@ -24638,9 +24944,9 @@ async function establishTunnel(ctx, dev) {
|
|
|
24638
24944
|
|
|
24639
24945
|
// src/beads/bd-adapter.ts
|
|
24640
24946
|
var import_child_process22 = require("child_process");
|
|
24641
|
-
var
|
|
24642
|
-
var
|
|
24643
|
-
var
|
|
24947
|
+
var fs59 = __toESM(require("fs"));
|
|
24948
|
+
var os48 = __toESM(require("os"));
|
|
24949
|
+
var path63 = __toESM(require("path"));
|
|
24644
24950
|
var BD_PACKAGE = "@beads/bd";
|
|
24645
24951
|
function resolveBundledBdBinary() {
|
|
24646
24952
|
return _resolveSeam.resolveBundled();
|
|
@@ -24652,11 +24958,11 @@ function _defaultResolveBundled() {
|
|
|
24652
24958
|
} catch {
|
|
24653
24959
|
return null;
|
|
24654
24960
|
}
|
|
24655
|
-
const binDir =
|
|
24961
|
+
const binDir = path63.join(path63.dirname(pkgJsonPath), "bin");
|
|
24656
24962
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
24657
|
-
const binaryPath =
|
|
24963
|
+
const binaryPath = path63.join(binDir, binaryName);
|
|
24658
24964
|
try {
|
|
24659
|
-
|
|
24965
|
+
fs59.accessSync(binaryPath, fs59.constants.F_OK);
|
|
24660
24966
|
return binaryPath;
|
|
24661
24967
|
} catch {
|
|
24662
24968
|
return null;
|
|
@@ -24666,13 +24972,13 @@ function resolveBdOnPath() {
|
|
|
24666
24972
|
return _resolveSeam.resolveOnPath();
|
|
24667
24973
|
}
|
|
24668
24974
|
function _defaultResolveOnPath() {
|
|
24669
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
24975
|
+
const dirs = (process.env.PATH ?? "").split(path63.delimiter).filter(Boolean);
|
|
24670
24976
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
24671
24977
|
for (const dir of dirs) {
|
|
24672
24978
|
for (const candidate of candidates) {
|
|
24673
|
-
const full =
|
|
24979
|
+
const full = path63.join(dir, candidate);
|
|
24674
24980
|
try {
|
|
24675
|
-
|
|
24981
|
+
fs59.accessSync(full, fs59.constants.F_OK);
|
|
24676
24982
|
return full;
|
|
24677
24983
|
} catch {
|
|
24678
24984
|
}
|
|
@@ -24757,7 +25063,7 @@ var BdAdapter = class {
|
|
|
24757
25063
|
const env = { ...process.env };
|
|
24758
25064
|
if (!env.HOME) {
|
|
24759
25065
|
try {
|
|
24760
|
-
const home =
|
|
25066
|
+
const home = os48.homedir();
|
|
24761
25067
|
if (home) env.HOME = home;
|
|
24762
25068
|
} catch {
|
|
24763
25069
|
}
|
|
@@ -24849,9 +25155,9 @@ function coerceIssue(row, projectKey) {
|
|
|
24849
25155
|
|
|
24850
25156
|
// src/beads/provisioner.ts
|
|
24851
25157
|
var import_child_process25 = require("child_process");
|
|
24852
|
-
var
|
|
24853
|
-
var
|
|
24854
|
-
var
|
|
25158
|
+
var fs61 = __toESM(require("fs"));
|
|
25159
|
+
var os50 = __toESM(require("os"));
|
|
25160
|
+
var path65 = __toESM(require("path"));
|
|
24855
25161
|
|
|
24856
25162
|
// src/beads/install-bd.ts
|
|
24857
25163
|
var import_child_process23 = require("child_process");
|
|
@@ -24916,9 +25222,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
24916
25222
|
|
|
24917
25223
|
// src/beads/install-dolt.ts
|
|
24918
25224
|
var import_child_process24 = require("child_process");
|
|
24919
|
-
var
|
|
24920
|
-
var
|
|
24921
|
-
var
|
|
25225
|
+
var fs60 = __toESM(require("fs"));
|
|
25226
|
+
var os49 = __toESM(require("os"));
|
|
25227
|
+
var path64 = __toESM(require("path"));
|
|
24922
25228
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
24923
25229
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
24924
25230
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -25007,14 +25313,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
25007
25313
|
return result;
|
|
25008
25314
|
}
|
|
25009
25315
|
var _doltPathSeam = {
|
|
25010
|
-
homedir: () =>
|
|
25316
|
+
homedir: () => os49.homedir(),
|
|
25011
25317
|
getPath: () => process.env.PATH ?? "",
|
|
25012
25318
|
setPath: (p2) => {
|
|
25013
25319
|
process.env.PATH = p2;
|
|
25014
25320
|
},
|
|
25015
25321
|
exists: (p2) => {
|
|
25016
25322
|
try {
|
|
25017
|
-
|
|
25323
|
+
fs60.accessSync(p2, fs60.constants.F_OK);
|
|
25018
25324
|
return true;
|
|
25019
25325
|
} catch {
|
|
25020
25326
|
return false;
|
|
@@ -25025,7 +25331,7 @@ function doltBinaryNames(platform3) {
|
|
|
25025
25331
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
25026
25332
|
}
|
|
25027
25333
|
function knownDoltDirs(platform3) {
|
|
25028
|
-
const P3 = platform3 === "win32" ?
|
|
25334
|
+
const P3 = platform3 === "win32" ? path64.win32 : path64.posix;
|
|
25029
25335
|
const home = _doltPathSeam.homedir();
|
|
25030
25336
|
if (platform3 === "win32") {
|
|
25031
25337
|
return [
|
|
@@ -25041,7 +25347,7 @@ function knownDoltDirs(platform3) {
|
|
|
25041
25347
|
].filter(Boolean);
|
|
25042
25348
|
}
|
|
25043
25349
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
25044
|
-
const P3 = platform3 === "win32" ?
|
|
25350
|
+
const P3 = platform3 === "win32" ? path64.win32 : path64.posix;
|
|
25045
25351
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
25046
25352
|
const names = doltBinaryNames(platform3);
|
|
25047
25353
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -25218,17 +25524,17 @@ var _provisionSeam = {
|
|
|
25218
25524
|
};
|
|
25219
25525
|
var _linkSeam = {
|
|
25220
25526
|
platform: () => process.platform,
|
|
25221
|
-
homedir: () =>
|
|
25527
|
+
homedir: () => os50.homedir(),
|
|
25222
25528
|
isWritableDir: (dir) => {
|
|
25223
25529
|
try {
|
|
25224
|
-
|
|
25530
|
+
fs61.accessSync(dir, fs61.constants.W_OK);
|
|
25225
25531
|
return true;
|
|
25226
25532
|
} catch {
|
|
25227
25533
|
return false;
|
|
25228
25534
|
}
|
|
25229
25535
|
},
|
|
25230
25536
|
ensureDir: (dir) => {
|
|
25231
|
-
|
|
25537
|
+
fs61.mkdirSync(dir, { recursive: true });
|
|
25232
25538
|
},
|
|
25233
25539
|
/**
|
|
25234
25540
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -25249,9 +25555,9 @@ var _linkSeam = {
|
|
|
25249
25555
|
* which `linkBdOntoPath` creates if missing.
|
|
25250
25556
|
*/
|
|
25251
25557
|
cliBinDir: () => {
|
|
25252
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
25558
|
+
const pathDirs = (process.env.PATH ?? "").split(path65.delimiter).filter(Boolean);
|
|
25253
25559
|
const home = _linkSeam.homedir();
|
|
25254
|
-
const localBin = home ?
|
|
25560
|
+
const localBin = home ? path65.join(home, ".local", "bin") : null;
|
|
25255
25561
|
if (localBin) {
|
|
25256
25562
|
try {
|
|
25257
25563
|
_linkSeam.ensureDir(localBin);
|
|
@@ -25261,16 +25567,16 @@ var _linkSeam = {
|
|
|
25261
25567
|
const candidates = [];
|
|
25262
25568
|
if (localBin) candidates.push(localBin);
|
|
25263
25569
|
try {
|
|
25264
|
-
candidates.push(
|
|
25570
|
+
candidates.push(path65.dirname(process.execPath));
|
|
25265
25571
|
} catch {
|
|
25266
25572
|
}
|
|
25267
25573
|
candidates.push("/usr/local/bin");
|
|
25268
25574
|
const entry = process.argv[1];
|
|
25269
25575
|
if (entry) {
|
|
25270
25576
|
try {
|
|
25271
|
-
candidates.push(
|
|
25577
|
+
candidates.push(path65.dirname(fs61.realpathSync(entry)));
|
|
25272
25578
|
} catch {
|
|
25273
|
-
candidates.push(
|
|
25579
|
+
candidates.push(path65.dirname(entry));
|
|
25274
25580
|
}
|
|
25275
25581
|
}
|
|
25276
25582
|
const onPathWritable = candidates.find(
|
|
@@ -25282,20 +25588,20 @@ var _linkSeam = {
|
|
|
25282
25588
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
25283
25589
|
readlink: (linkPath) => {
|
|
25284
25590
|
try {
|
|
25285
|
-
return
|
|
25591
|
+
return fs61.readlinkSync(linkPath);
|
|
25286
25592
|
} catch {
|
|
25287
25593
|
return null;
|
|
25288
25594
|
}
|
|
25289
25595
|
},
|
|
25290
|
-
unlink: (linkPath) =>
|
|
25291
|
-
symlink: (target, linkPath) =>
|
|
25596
|
+
unlink: (linkPath) => fs61.unlinkSync(linkPath),
|
|
25597
|
+
symlink: (target, linkPath) => fs61.symlinkSync(target, linkPath)
|
|
25292
25598
|
};
|
|
25293
25599
|
function linkBdOntoPath(binaryPath) {
|
|
25294
25600
|
if (_linkSeam.platform() === "win32") return;
|
|
25295
25601
|
const binDir = _linkSeam.cliBinDir();
|
|
25296
25602
|
if (!binDir) return;
|
|
25297
25603
|
_linkSeam.ensureDir(binDir);
|
|
25298
|
-
const linkPath =
|
|
25604
|
+
const linkPath = path65.join(binDir, "bd");
|
|
25299
25605
|
if (linkPath === binaryPath) return;
|
|
25300
25606
|
const current2 = _linkSeam.readlink(linkPath);
|
|
25301
25607
|
if (current2 === binaryPath) return;
|
|
@@ -25490,7 +25796,7 @@ function dedupeRecipes(agents) {
|
|
|
25490
25796
|
|
|
25491
25797
|
// src/beads/watcher.ts
|
|
25492
25798
|
var crypto4 = __toESM(require("crypto"));
|
|
25493
|
-
var
|
|
25799
|
+
var path66 = __toESM(require("path"));
|
|
25494
25800
|
var API_BASE6 = resolveApiBaseUrl();
|
|
25495
25801
|
var DEBOUNCE_MS2 = 400;
|
|
25496
25802
|
var ZERO_SUMMARY = {
|
|
@@ -25514,7 +25820,7 @@ var BeadsWatcher = class {
|
|
|
25514
25820
|
constructor(opts) {
|
|
25515
25821
|
this.opts = opts;
|
|
25516
25822
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
25517
|
-
this.feedPath = opts.feedPath ??
|
|
25823
|
+
this.feedPath = opts.feedPath ?? path66.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
25518
25824
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
25519
25825
|
}
|
|
25520
25826
|
opts;
|
|
@@ -26013,8 +26319,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
26013
26319
|
function saveFilesTemp(files) {
|
|
26014
26320
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
26015
26321
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
26016
|
-
const tmpPath =
|
|
26017
|
-
|
|
26322
|
+
const tmpPath = path69.join(os54.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
26323
|
+
fs64.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
26018
26324
|
pendingAttachmentFiles.add(tmpPath);
|
|
26019
26325
|
return tmpPath;
|
|
26020
26326
|
});
|
|
@@ -26232,10 +26538,10 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
26232
26538
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
26233
26539
|
};
|
|
26234
26540
|
var envReadH = async (ctx, cmd) => {
|
|
26235
|
-
const envPath =
|
|
26541
|
+
const envPath = path69.join(process.cwd(), ".env");
|
|
26236
26542
|
await restoreProjectEnvIfMissing(process.cwd(), ctx);
|
|
26237
26543
|
try {
|
|
26238
|
-
const raw = await
|
|
26544
|
+
const raw = await fs64.promises.readFile(envPath, "utf8");
|
|
26239
26545
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
26240
26546
|
exists: true,
|
|
26241
26547
|
vars: parseDotenv(raw)
|
|
@@ -26266,15 +26572,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
26266
26572
|
}
|
|
26267
26573
|
seen.add(v.key);
|
|
26268
26574
|
}
|
|
26269
|
-
const envPath =
|
|
26270
|
-
const tmpPath =
|
|
26575
|
+
const envPath = path69.join(process.cwd(), ".env");
|
|
26576
|
+
const tmpPath = path69.join(process.cwd(), ".env.codeam.tmp");
|
|
26271
26577
|
try {
|
|
26272
|
-
await
|
|
26273
|
-
await
|
|
26578
|
+
await fs64.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
26579
|
+
await fs64.promises.rename(tmpPath, envPath);
|
|
26274
26580
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
26275
26581
|
void syncProjectEnvUp(process.cwd(), ctx);
|
|
26276
26582
|
} catch (err) {
|
|
26277
|
-
await
|
|
26583
|
+
await fs64.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
26278
26584
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
26279
26585
|
}
|
|
26280
26586
|
};
|
|
@@ -26323,7 +26629,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
26323
26629
|
let configuredAgent = rawAgentId;
|
|
26324
26630
|
if (!configuredAgent) {
|
|
26325
26631
|
try {
|
|
26326
|
-
const raw = JSON.parse(
|
|
26632
|
+
const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
|
|
26327
26633
|
configuredAgent = raw.agent ?? "";
|
|
26328
26634
|
} catch {
|
|
26329
26635
|
}
|
|
@@ -26357,7 +26663,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
26357
26663
|
persist: persistHeadroomConfig,
|
|
26358
26664
|
readEnabled: () => {
|
|
26359
26665
|
try {
|
|
26360
|
-
const raw = JSON.parse(
|
|
26666
|
+
const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
|
|
26361
26667
|
return raw.enabled === true;
|
|
26362
26668
|
} catch {
|
|
26363
26669
|
return false;
|
|
@@ -26679,7 +26985,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
26679
26985
|
}
|
|
26680
26986
|
let headroomActive = false;
|
|
26681
26987
|
try {
|
|
26682
|
-
const raw = JSON.parse(
|
|
26988
|
+
const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
|
|
26683
26989
|
headroomActive = raw.enabled === true;
|
|
26684
26990
|
} catch {
|
|
26685
26991
|
}
|
|
@@ -26689,7 +26995,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
26689
26995
|
}
|
|
26690
26996
|
let existingConfig = { enabled: true };
|
|
26691
26997
|
try {
|
|
26692
|
-
existingConfig = JSON.parse(
|
|
26998
|
+
existingConfig = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
|
|
26693
26999
|
} catch {
|
|
26694
27000
|
}
|
|
26695
27001
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -26802,9 +27108,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
26802
27108
|
function buildNpmInstallInvocation(opts) {
|
|
26803
27109
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
26804
27110
|
const execPath = opts?.execPath ?? process.execPath;
|
|
26805
|
-
const exists2 = opts?.existsSync ??
|
|
27111
|
+
const exists2 = opts?.existsSync ?? fs64.existsSync;
|
|
26806
27112
|
const platform3 = opts?.platform ?? process.platform;
|
|
26807
|
-
const p2 = platform3 === "win32" ?
|
|
27113
|
+
const p2 = platform3 === "win32" ? path69.win32 : path69.posix;
|
|
26808
27114
|
const normalized = entryScript.split(/[\\/]/).join("/");
|
|
26809
27115
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
26810
27116
|
const markerIdx = normalized.indexOf(marker);
|
|
@@ -26826,7 +27132,7 @@ function isPermissionError(stderr) {
|
|
|
26826
27132
|
function resolveGlobalNodeModulesDir(opts) {
|
|
26827
27133
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
26828
27134
|
const platform3 = opts?.platform ?? process.platform;
|
|
26829
|
-
const p2 = platform3 === "win32" ?
|
|
27135
|
+
const p2 = platform3 === "win32" ? path69.win32 : path69.posix;
|
|
26830
27136
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
26831
27137
|
const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
|
|
26832
27138
|
if (markerIdx <= 0) return null;
|
|
@@ -26836,9 +27142,9 @@ function resolveGlobalNodeModulesDir(opts) {
|
|
|
26836
27142
|
var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
|
|
26837
27143
|
function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
26838
27144
|
if (!nodeModulesDir) return 0;
|
|
26839
|
-
const readdirSync15 = deps?.readdirSync ??
|
|
26840
|
-
const statSync17 = deps?.statSync ??
|
|
26841
|
-
const rmSync9 = deps?.rmSync ??
|
|
27145
|
+
const readdirSync15 = deps?.readdirSync ?? fs64.readdirSync;
|
|
27146
|
+
const statSync17 = deps?.statSync ?? fs64.statSync;
|
|
27147
|
+
const rmSync9 = deps?.rmSync ?? fs64.rmSync;
|
|
26842
27148
|
let removed = 0;
|
|
26843
27149
|
let entries;
|
|
26844
27150
|
try {
|
|
@@ -26848,7 +27154,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
|
|
|
26848
27154
|
}
|
|
26849
27155
|
for (const name of entries) {
|
|
26850
27156
|
if (!/^\.codeam-cli-/.test(name)) continue;
|
|
26851
|
-
const full =
|
|
27157
|
+
const full = path69.join(nodeModulesDir, name);
|
|
26852
27158
|
try {
|
|
26853
27159
|
const st3 = statSync17(full);
|
|
26854
27160
|
if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
|
|
@@ -27728,7 +28034,7 @@ function resolveTokenValue(args2) {
|
|
|
27728
28034
|
if (fileFlag) {
|
|
27729
28035
|
const path92 = fileFlag.slice("--token-file=".length);
|
|
27730
28036
|
try {
|
|
27731
|
-
const content =
|
|
28037
|
+
const content = fs65.readFileSync(path92, "utf8").trim();
|
|
27732
28038
|
if (content.length === 0) fail(`--token-file ${path92} is empty`);
|
|
27733
28039
|
rmIfExistsQuiet(path92);
|
|
27734
28040
|
return content;
|
|
@@ -27759,7 +28065,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
27759
28065
|
pluginId,
|
|
27760
28066
|
ideName: "codeam-cli (codespace)",
|
|
27761
28067
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
27762
|
-
hostname:
|
|
28068
|
+
hostname: os55.hostname(),
|
|
27763
28069
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
27764
28070
|
// Current git branch of the codespace's working directory, so the
|
|
27765
28071
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -27820,7 +28126,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
27820
28126
|
}
|
|
27821
28127
|
}
|
|
27822
28128
|
function pairAutoLockPath() {
|
|
27823
|
-
return
|
|
28129
|
+
return path70.join(os55.homedir(), ".codeam", "pair-auto.lock");
|
|
27824
28130
|
}
|
|
27825
28131
|
function isLivePairAuto(pid) {
|
|
27826
28132
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -27830,7 +28136,7 @@ function isLivePairAuto(pid) {
|
|
|
27830
28136
|
if (e.code !== "EPERM") return false;
|
|
27831
28137
|
}
|
|
27832
28138
|
try {
|
|
27833
|
-
return
|
|
28139
|
+
return fs65.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
27834
28140
|
} catch {
|
|
27835
28141
|
return true;
|
|
27836
28142
|
}
|
|
@@ -27840,24 +28146,24 @@ function isLiveCodeam(pid) {
|
|
|
27840
28146
|
}
|
|
27841
28147
|
function daemonLockPath(sessionId) {
|
|
27842
28148
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
27843
|
-
return
|
|
28149
|
+
return path70.join(os55.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
27844
28150
|
}
|
|
27845
28151
|
function acquireDaemonLock(sessionId) {
|
|
27846
28152
|
const lockPath = daemonLockPath(sessionId);
|
|
27847
28153
|
try {
|
|
27848
|
-
|
|
28154
|
+
fs65.mkdirSync(path70.dirname(lockPath), { recursive: true });
|
|
27849
28155
|
try {
|
|
27850
|
-
|
|
28156
|
+
fs65.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
27851
28157
|
} catch (e) {
|
|
27852
28158
|
if (e.code !== "EEXIST") throw e;
|
|
27853
|
-
const holder = Number(
|
|
28159
|
+
const holder = Number(fs65.readFileSync(lockPath, "utf8").trim());
|
|
27854
28160
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
27855
|
-
|
|
28161
|
+
fs65.writeFileSync(lockPath, String(process.pid));
|
|
27856
28162
|
}
|
|
27857
28163
|
const release3 = () => {
|
|
27858
28164
|
try {
|
|
27859
|
-
if (
|
|
27860
|
-
|
|
28165
|
+
if (fs65.existsSync(lockPath) && Number(fs65.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
28166
|
+
fs65.unlinkSync(lockPath);
|
|
27861
28167
|
}
|
|
27862
28168
|
} catch {
|
|
27863
28169
|
}
|
|
@@ -27879,19 +28185,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
27879
28185
|
function acquireSingletonLock() {
|
|
27880
28186
|
const lockPath = pairAutoLockPath();
|
|
27881
28187
|
try {
|
|
27882
|
-
|
|
28188
|
+
fs65.mkdirSync(path70.dirname(lockPath), { recursive: true });
|
|
27883
28189
|
try {
|
|
27884
|
-
|
|
28190
|
+
fs65.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
27885
28191
|
} catch (e) {
|
|
27886
28192
|
if (e.code !== "EEXIST") throw e;
|
|
27887
|
-
const holder = Number(
|
|
28193
|
+
const holder = Number(fs65.readFileSync(lockPath, "utf8").trim());
|
|
27888
28194
|
if (isLivePairAuto(holder)) return false;
|
|
27889
|
-
|
|
28195
|
+
fs65.writeFileSync(lockPath, String(process.pid));
|
|
27890
28196
|
}
|
|
27891
28197
|
process.once("exit", () => {
|
|
27892
28198
|
try {
|
|
27893
|
-
if (
|
|
27894
|
-
|
|
28199
|
+
if (fs65.existsSync(lockPath) && Number(fs65.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
28200
|
+
fs65.unlinkSync(lockPath);
|
|
27895
28201
|
}
|
|
27896
28202
|
} catch {
|
|
27897
28203
|
}
|
|
@@ -28343,7 +28649,7 @@ var AgentService = class _AgentService {
|
|
|
28343
28649
|
};
|
|
28344
28650
|
|
|
28345
28651
|
// src/agents/acp/adapters.ts
|
|
28346
|
-
var
|
|
28652
|
+
var path71 = __toESM(require("path"));
|
|
28347
28653
|
|
|
28348
28654
|
// src/agents/kimi/installer.ts
|
|
28349
28655
|
var import_node_child_process27 = require("child_process");
|
|
@@ -28463,13 +28769,13 @@ function resolveBin(pkgName, binName) {
|
|
|
28463
28769
|
try {
|
|
28464
28770
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
28465
28771
|
const manifest = require_(`${pkgName}/package.json`);
|
|
28466
|
-
const pkgDir =
|
|
28772
|
+
const pkgDir = path71.dirname(manifestPath);
|
|
28467
28773
|
const bin = manifest.bin;
|
|
28468
28774
|
if (!bin) return null;
|
|
28469
|
-
if (typeof bin === "string") return
|
|
28775
|
+
if (typeof bin === "string") return path71.resolve(pkgDir, bin);
|
|
28470
28776
|
const target = binName ?? Object.keys(bin)[0];
|
|
28471
28777
|
if (!target || !bin[target]) return null;
|
|
28472
|
-
return
|
|
28778
|
+
return path71.resolve(pkgDir, bin[target]);
|
|
28473
28779
|
} catch {
|
|
28474
28780
|
return null;
|
|
28475
28781
|
}
|
|
@@ -28658,286 +28964,6 @@ var os56 = __toESM(require("os"));
|
|
|
28658
28964
|
var https7 = __toESM(require("https"));
|
|
28659
28965
|
var http6 = __toESM(require("http"));
|
|
28660
28966
|
var import_zod2 = require("zod");
|
|
28661
|
-
|
|
28662
|
-
// src/agents/acp/squad-roster.ts
|
|
28663
|
-
var fs65 = __toESM(require("fs"));
|
|
28664
|
-
var os55 = __toESM(require("os"));
|
|
28665
|
-
var path71 = __toESM(require("path"));
|
|
28666
|
-
var PROMPT_MAX = 500;
|
|
28667
|
-
var REPLY_SUMMARY_MAX = 1e3;
|
|
28668
|
-
var PREAMBLE_MAX = 2e3;
|
|
28669
|
-
var BRIEFING_DEFAULT_MAX = 8e3;
|
|
28670
|
-
var GENERIC_SPECIALTY = "general implementation tasks";
|
|
28671
|
-
function clip(s, max) {
|
|
28672
|
-
return s.length > max ? s.slice(0, max) : s;
|
|
28673
|
-
}
|
|
28674
|
-
function defaultMember() {
|
|
28675
|
-
return {
|
|
28676
|
-
acpSessionId: null,
|
|
28677
|
-
provisioned: false,
|
|
28678
|
-
binaryVerified: false,
|
|
28679
|
-
lastTurnIndex: 0,
|
|
28680
|
-
contextTextFallback: false
|
|
28681
|
-
};
|
|
28682
|
-
}
|
|
28683
|
-
function journalPathFor(homeDir2, sessionId) {
|
|
28684
|
-
return path71.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
|
|
28685
|
-
}
|
|
28686
|
-
function loadJournal(journalPath) {
|
|
28687
|
-
try {
|
|
28688
|
-
const raw = JSON.parse(fs65.readFileSync(journalPath, "utf-8"));
|
|
28689
|
-
return Array.isArray(raw.turns) ? raw.turns : [];
|
|
28690
|
-
} catch {
|
|
28691
|
-
return [];
|
|
28692
|
-
}
|
|
28693
|
-
}
|
|
28694
|
-
var SquadState = class {
|
|
28695
|
-
/** Set by the caller after fetchSquadRoster; null until then. */
|
|
28696
|
-
roster = null;
|
|
28697
|
-
/**
|
|
28698
|
-
* Autonomous chained handoffs (P2-2, PRO). Seeded from the persisted
|
|
28699
|
-
* `SavedSession.squadAuto` at session start and rewritten by
|
|
28700
|
-
* `squad_configure`. Read-only to callers — mutate via {@link setAuto}, which
|
|
28701
|
-
* clamps the budget and re-arms the chain.
|
|
28702
|
-
*/
|
|
28703
|
-
autoConfig = { enabled: false, hopBudget: SQUAD_HOP_BUDGET_DEFAULT };
|
|
28704
|
-
/**
|
|
28705
|
-
* Hops left in the CURRENT chain. Reset to the budget on every USER-initiated
|
|
28706
|
-
* prompt (so a user turn always interrupts and re-arms) and decremented by
|
|
28707
|
-
* each self-accepted handoff.
|
|
28708
|
-
*/
|
|
28709
|
-
hopsLeft = 0;
|
|
28710
|
-
/** Lifetime handoff counters for `squad_stats` (in-memory, this process). */
|
|
28711
|
-
handoffCounters = { proposed: 0, accepted: 0, auto: 0 };
|
|
28712
|
-
journalPath;
|
|
28713
|
-
turns;
|
|
28714
|
-
members = /* @__PURE__ */ new Map();
|
|
28715
|
-
constructor(opts) {
|
|
28716
|
-
this.journalPath = journalPathFor(opts.homeDir ?? os55.homedir(), opts.sessionId);
|
|
28717
|
-
this.turns = loadJournal(this.journalPath);
|
|
28718
|
-
if (opts.auto) this.setAuto(opts.auto);
|
|
28719
|
-
}
|
|
28720
|
-
get auto() {
|
|
28721
|
-
return this.autoConfig;
|
|
28722
|
-
}
|
|
28723
|
-
/** Apply a new mode (clamping the budget) and re-arm the chain. */
|
|
28724
|
-
setAuto(value) {
|
|
28725
|
-
this.autoConfig = {
|
|
28726
|
-
enabled: value.enabled === true,
|
|
28727
|
-
hopBudget: clampHopBudget(value.hopBudget)
|
|
28728
|
-
};
|
|
28729
|
-
this.resetHops();
|
|
28730
|
-
return this.autoConfig;
|
|
28731
|
-
}
|
|
28732
|
-
hopsRemaining() {
|
|
28733
|
-
return this.hopsLeft;
|
|
28734
|
-
}
|
|
28735
|
-
/** Re-arm the chain — called at the start of every USER-initiated turn. */
|
|
28736
|
-
resetHops() {
|
|
28737
|
-
this.hopsLeft = this.autoConfig.enabled ? this.autoConfig.hopBudget : 0;
|
|
28738
|
-
}
|
|
28739
|
-
/** Spend one hop on a self-accepted handoff. */
|
|
28740
|
-
consumeHop() {
|
|
28741
|
-
if (this.hopsLeft > 0) this.hopsLeft -= 1;
|
|
28742
|
-
}
|
|
28743
|
-
countProposal(opts) {
|
|
28744
|
-
this.handoffCounters.proposed += 1;
|
|
28745
|
-
if (opts.auto) this.handoffCounters.auto += 1;
|
|
28746
|
-
}
|
|
28747
|
-
countAccepted() {
|
|
28748
|
-
this.handoffCounters.accepted += 1;
|
|
28749
|
-
}
|
|
28750
|
-
/**
|
|
28751
|
-
* Per-member activity for the `squad_stats` relay command, derived from the
|
|
28752
|
-
* journal (the same shared history the delta briefing reads) plus the
|
|
28753
|
-
* in-memory handoff counters. `filesTouched` counts DISTINCT paths — a member
|
|
28754
|
-
* that edited the same file across three turns touched ONE file.
|
|
28755
|
-
*/
|
|
28756
|
-
stats() {
|
|
28757
|
-
const byAgent = /* @__PURE__ */ new Map();
|
|
28758
|
-
for (const t2 of this.turns) {
|
|
28759
|
-
let row = byAgent.get(t2.agentId);
|
|
28760
|
-
if (!row) {
|
|
28761
|
-
row = { turns: 0, files: /* @__PURE__ */ new Set() };
|
|
28762
|
-
byAgent.set(t2.agentId, row);
|
|
28763
|
-
}
|
|
28764
|
-
row.turns += 1;
|
|
28765
|
-
for (const f of t2.filesTouched) row.files.add(f);
|
|
28766
|
-
}
|
|
28767
|
-
const members = [...byAgent.entries()].map(([agentId, row]) => ({
|
|
28768
|
-
agentId,
|
|
28769
|
-
turns: row.turns,
|
|
28770
|
-
filesTouched: row.files.size
|
|
28771
|
-
}));
|
|
28772
|
-
return { members, handoffs: { ...this.handoffCounters }, sinceTurn: 1 };
|
|
28773
|
-
}
|
|
28774
|
-
/** Returns (creating on first access) the mutable per-agent state. */
|
|
28775
|
-
member(agentId) {
|
|
28776
|
-
let m = this.members.get(agentId);
|
|
28777
|
-
if (!m) {
|
|
28778
|
-
m = defaultMember();
|
|
28779
|
-
this.members.set(agentId, m);
|
|
28780
|
-
}
|
|
28781
|
-
return m;
|
|
28782
|
-
}
|
|
28783
|
-
/** Appends a journal entry and persists (fire-and-forget durability). */
|
|
28784
|
-
recordTurn(entry) {
|
|
28785
|
-
const turn = {
|
|
28786
|
-
turn: this.turns.length + 1,
|
|
28787
|
-
agentId: entry.agentId,
|
|
28788
|
-
prompt: clip(entry.prompt, PROMPT_MAX),
|
|
28789
|
-
replySummary: clip(entry.replySummary, REPLY_SUMMARY_MAX),
|
|
28790
|
-
filesTouched: entry.filesTouched
|
|
28791
|
-
};
|
|
28792
|
-
this.turns.push(turn);
|
|
28793
|
-
this.persist();
|
|
28794
|
-
}
|
|
28795
|
-
turnCount() {
|
|
28796
|
-
return this.turns.length;
|
|
28797
|
-
}
|
|
28798
|
-
entriesSince(turnIndex) {
|
|
28799
|
-
return this.turns.filter((t2) => t2.turn > turnIndex);
|
|
28800
|
-
}
|
|
28801
|
-
persist() {
|
|
28802
|
-
try {
|
|
28803
|
-
fs65.mkdirSync(path71.dirname(this.journalPath), { recursive: true, mode: 448 });
|
|
28804
|
-
fs65.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
|
|
28805
|
-
} catch {
|
|
28806
|
-
}
|
|
28807
|
-
}
|
|
28808
|
-
};
|
|
28809
|
-
function specialtyFor(agentId) {
|
|
28810
|
-
return SQUAD_SPECIALTIES[agentId] ?? GENERIC_SPECIALTY;
|
|
28811
|
-
}
|
|
28812
|
-
var TEAM_PREAMBLE_MARKER = "[Team context]";
|
|
28813
|
-
var TEAM_PREAMBLE_LINES = [
|
|
28814
|
-
"[Team context] You are the active agent in a CodeAgent Mobile session where the user",
|
|
28815
|
-
"has a squad of agents and can pass work between them. Your available teammates:",
|
|
28816
|
-
"If a task clearly fits a teammate better than you, you MAY propose a handoff by ending",
|
|
28817
|
-
`your reply with a fenced code block tagged ${HANDOFF_FENCE_TAG} containing ONE JSON object:`,
|
|
28818
|
-
'{"to":"<teammate id>","reason":"<one sentence>","prompt":"<the prompt they should run>"}',
|
|
28819
|
-
"Propose at most one handoff per reply, only when genuinely better, and never announce",
|
|
28820
|
-
"the block in prose \u2014 the app renders it as a card the user can accept."
|
|
28821
|
-
];
|
|
28822
|
-
var TEAM_PREAMBLE_BULLET_RE = /^- .+ — best at: /;
|
|
28823
|
-
var BRIEFING_MARKER = "[Team update]";
|
|
28824
|
-
var BRIEFING_HEADER = "[Team update] While you were away, other agents worked on this session:";
|
|
28825
|
-
var BRIEFING_FOOTER = "Continue from the CURRENT state of the working tree.";
|
|
28826
|
-
function buildTeamPreamble(roster, currentAgent, opts) {
|
|
28827
|
-
const others = roster.agents.filter((a) => a.agentId !== currentAgent);
|
|
28828
|
-
if (others.length === 0) return null;
|
|
28829
|
-
const lines = [
|
|
28830
|
-
TEAM_PREAMBLE_LINES[0],
|
|
28831
|
-
TEAM_PREAMBLE_LINES[1],
|
|
28832
|
-
...others.map((a) => `- ${a.displayName} \u2014 best at: ${specialtyFor(a.agentId)}`)
|
|
28833
|
-
];
|
|
28834
|
-
if (opts.handoffInstructions) {
|
|
28835
|
-
lines.push(...TEAM_PREAMBLE_LINES.slice(2));
|
|
28836
|
-
}
|
|
28837
|
-
return clip(lines.join("\n"), PREAMBLE_MAX);
|
|
28838
|
-
}
|
|
28839
|
-
function renderJournalEntry(e) {
|
|
28840
|
-
const filesClause = e.filesTouched.length > 0 ? ` (files: ${e.filesTouched.join(", ")})` : "";
|
|
28841
|
-
return `- turn ${e.turn} (${e.agentId}): ${e.prompt} \u2192 ${e.replySummary}${filesClause}`;
|
|
28842
|
-
}
|
|
28843
|
-
function buildDeltaBriefing(entries, maxChars = BRIEFING_DEFAULT_MAX) {
|
|
28844
|
-
if (entries.length === 0) return null;
|
|
28845
|
-
const header = BRIEFING_HEADER;
|
|
28846
|
-
const footer = BRIEFING_FOOTER;
|
|
28847
|
-
const envelope = header.length + 1 + footer.length + 1;
|
|
28848
|
-
const sorted = [...entries].sort((a, b) => a.turn - b.turn);
|
|
28849
|
-
const lines = [];
|
|
28850
|
-
let bodyLen = 0;
|
|
28851
|
-
for (let i = sorted.length - 1; i >= 0; i--) {
|
|
28852
|
-
const line = renderJournalEntry(sorted[i]);
|
|
28853
|
-
const addedLen = line.length + (lines.length > 0 ? 1 : 0);
|
|
28854
|
-
if (lines.length > 0 && envelope + bodyLen + addedLen > maxChars) break;
|
|
28855
|
-
lines.unshift(line);
|
|
28856
|
-
bodyLen += addedLen;
|
|
28857
|
-
}
|
|
28858
|
-
return [header, lines.join("\n"), footer].join("\n");
|
|
28859
|
-
}
|
|
28860
|
-
|
|
28861
|
-
// src/agents/acp/squad-context.ts
|
|
28862
|
-
var SQUAD_CONTEXT_URI = "codeam://squad-context";
|
|
28863
|
-
var HANDOFF_MARKER = "[Session handoff]";
|
|
28864
|
-
var HANDOFF_TERMINATOR = "--- End of handoff context ---";
|
|
28865
|
-
function buildSquadContextBlock(text) {
|
|
28866
|
-
return {
|
|
28867
|
-
type: "resource",
|
|
28868
|
-
resource: { uri: SQUAD_CONTEXT_URI, mimeType: "text/plain", text }
|
|
28869
|
-
};
|
|
28870
|
-
}
|
|
28871
|
-
function isSquadContextBlock(block) {
|
|
28872
|
-
return block.type === "resource" && block.resource.uri === SQUAD_CONTEXT_URI;
|
|
28873
|
-
}
|
|
28874
|
-
function looksLikeUnsupportedPromptShape(err) {
|
|
28875
|
-
const code = err?.code;
|
|
28876
|
-
if (code === -32602) return true;
|
|
28877
|
-
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
28878
|
-
if (/invalid[ _]params|-32602/i.test(message)) return true;
|
|
28879
|
-
return /\bresource\b/i.test(message) && /unsupported|not supported/i.test(message);
|
|
28880
|
-
}
|
|
28881
|
-
function skipWhile(lines, start2, keepGoing) {
|
|
28882
|
-
let i = start2;
|
|
28883
|
-
while (i < lines.length && keepGoing(lines[i])) i++;
|
|
28884
|
-
return i;
|
|
28885
|
-
}
|
|
28886
|
-
function endOfTeamPreamble(lines, start2) {
|
|
28887
|
-
if (lines[start2] !== TEAM_PREAMBLE_LINES[0]) return -1;
|
|
28888
|
-
if (lines[start2 + 1] !== TEAM_PREAMBLE_LINES[1]) return -1;
|
|
28889
|
-
return skipWhile(
|
|
28890
|
-
lines,
|
|
28891
|
-
start2 + 2,
|
|
28892
|
-
(line) => TEAM_PREAMBLE_BULLET_RE.test(line) || TEAM_PREAMBLE_LINES.includes(line)
|
|
28893
|
-
);
|
|
28894
|
-
}
|
|
28895
|
-
function endOfTerminatedBlock(lines, start2, terminator) {
|
|
28896
|
-
for (let i = start2; i < lines.length; i++) {
|
|
28897
|
-
if (lines[i].trimEnd() === terminator) return i + 1;
|
|
28898
|
-
}
|
|
28899
|
-
return -1;
|
|
28900
|
-
}
|
|
28901
|
-
function stripSquadContext(text) {
|
|
28902
|
-
if (!text.includes(HANDOFF_MARKER) && !text.includes(BRIEFING_MARKER) && !text.includes(TEAM_PREAMBLE_MARKER)) {
|
|
28903
|
-
return text;
|
|
28904
|
-
}
|
|
28905
|
-
const lines = text.split("\n");
|
|
28906
|
-
const kept = [];
|
|
28907
|
-
let i = 0;
|
|
28908
|
-
let stripped = false;
|
|
28909
|
-
while (i < lines.length) {
|
|
28910
|
-
const line = lines[i];
|
|
28911
|
-
if (line.startsWith(HANDOFF_MARKER)) {
|
|
28912
|
-
const end = endOfTerminatedBlock(lines, i, HANDOFF_TERMINATOR);
|
|
28913
|
-
if (end !== -1) {
|
|
28914
|
-
i = end;
|
|
28915
|
-
stripped = true;
|
|
28916
|
-
continue;
|
|
28917
|
-
}
|
|
28918
|
-
} else if (line.startsWith(BRIEFING_MARKER)) {
|
|
28919
|
-
const end = endOfTerminatedBlock(lines, i, BRIEFING_FOOTER);
|
|
28920
|
-
if (end !== -1) {
|
|
28921
|
-
i = end;
|
|
28922
|
-
stripped = true;
|
|
28923
|
-
continue;
|
|
28924
|
-
}
|
|
28925
|
-
} else if (line.startsWith(TEAM_PREAMBLE_MARKER)) {
|
|
28926
|
-
const end = endOfTeamPreamble(lines, i);
|
|
28927
|
-
if (end !== -1) {
|
|
28928
|
-
i = end;
|
|
28929
|
-
stripped = true;
|
|
28930
|
-
continue;
|
|
28931
|
-
}
|
|
28932
|
-
}
|
|
28933
|
-
kept.push(line);
|
|
28934
|
-
i++;
|
|
28935
|
-
}
|
|
28936
|
-
if (!stripped) return text;
|
|
28937
|
-
return kept.join("\n").trim();
|
|
28938
|
-
}
|
|
28939
|
-
|
|
28940
|
-
// src/services/history.service.ts
|
|
28941
28967
|
var historyRecordSchema = import_zod2.z.object({
|
|
28942
28968
|
type: import_zod2.z.string().optional(),
|
|
28943
28969
|
timestamp: import_zod2.z.union([import_zod2.z.string(), import_zod2.z.number()]).optional(),
|
|
@@ -28960,6 +28986,7 @@ var CONVERSATION_BATCH_SIZE = 30;
|
|
|
28960
28986
|
function scrubSquadContext(messages) {
|
|
28961
28987
|
const out2 = [];
|
|
28962
28988
|
for (const m of messages) {
|
|
28989
|
+
if (isLeakedSquadContextText(m.text) || isAgentMetaBlock(m.text)) continue;
|
|
28963
28990
|
const text = stripSquadContext(m.text);
|
|
28964
28991
|
if (text === m.text) {
|
|
28965
28992
|
out2.push(m);
|
|
@@ -28991,7 +29018,11 @@ function parseJsonl(filePath) {
|
|
|
28991
29018
|
}
|
|
28992
29019
|
const result = historyRecordSchema.safeParse(parsedJson);
|
|
28993
29020
|
if (!result.success) {
|
|
28994
|
-
log.warn(
|
|
29021
|
+
log.warn(
|
|
29022
|
+
"history:parseJsonl",
|
|
29023
|
+
`record failed schema validation in ${filePath}`,
|
|
29024
|
+
result.error.issues
|
|
29025
|
+
);
|
|
28995
29026
|
continue;
|
|
28996
29027
|
}
|
|
28997
29028
|
const record2 = result.data;
|
|
@@ -29256,7 +29287,14 @@ var HistoryService = class _HistoryService {
|
|
|
29256
29287
|
const inputTokens = (lastUsage["input_tokens"] ?? lastUsage["prompt_tokens"] ?? 0) + (lastUsage["cache_read_input_tokens"] ?? 0) + (lastUsage["cache_creation_input_tokens"] ?? 0);
|
|
29257
29288
|
const outputTokens = lastUsage["output_tokens"] ?? lastUsage["completion_tokens"] ?? 0;
|
|
29258
29289
|
const percent = Math.min(100, Math.round(inputTokens / total * 100));
|
|
29259
|
-
return {
|
|
29290
|
+
return {
|
|
29291
|
+
used: inputTokens,
|
|
29292
|
+
total,
|
|
29293
|
+
percent,
|
|
29294
|
+
model: lastModel,
|
|
29295
|
+
outputTokens,
|
|
29296
|
+
cacheReadTokens: lastUsage["cache_read_input_tokens"] ?? 0
|
|
29297
|
+
};
|
|
29260
29298
|
}
|
|
29261
29299
|
/**
|
|
29262
29300
|
* Estimate the API cost for the current month in the current project directory.
|
|
@@ -29429,7 +29467,9 @@ var HistoryService = class _HistoryService {
|
|
|
29429
29467
|
ok = await post("/api/sessions/conversation", body, this.pluginAuthToken);
|
|
29430
29468
|
}
|
|
29431
29469
|
if (!ok) {
|
|
29432
|
-
throw new Error(
|
|
29470
|
+
throw new Error(
|
|
29471
|
+
`Failed to upload conversation batch ${i + 1}/${totalBatches} after all retries`
|
|
29472
|
+
);
|
|
29433
29473
|
}
|
|
29434
29474
|
}
|
|
29435
29475
|
const last = messages[messages.length - 1];
|
|
@@ -35339,6 +35379,9 @@ var REASON_MAX = 1e3;
|
|
|
35339
35379
|
var PROMPT_MAX2 = 8e3;
|
|
35340
35380
|
var FENCE_OPEN = "```" + HANDOFF_FENCE_TAG;
|
|
35341
35381
|
var FENCE_RE = new RegExp("```" + HANDOFF_FENCE_TAG + "\\s*\\n([\\s\\S]*?)\\n?```", "g");
|
|
35382
|
+
var DEGENERATE_LINE_RE = new RegExp(
|
|
35383
|
+
"^[ \\t]*(`{0,2})[ \\t]*" + HANDOFF_FENCE_TAG + "[ \\t]+(\\{.*\\})[ \\t]*\\1[ \\t]*\\r?$"
|
|
35384
|
+
);
|
|
35342
35385
|
var OUTER_FENCE_RE = /(`{4,})[\s\S]*?\1/g;
|
|
35343
35386
|
var outerFencePlaceholder = (i) => `@@HANDOFF_MASK_${i}@@`;
|
|
35344
35387
|
function maskOuterFences(text) {
|
|
@@ -35351,62 +35394,117 @@ function maskOuterFences(text) {
|
|
|
35351
35394
|
const restore = (s) => spans.reduce((acc, span, i) => acc.split(outerFencePlaceholder(i)).join(span), s);
|
|
35352
35395
|
return { masked, restore };
|
|
35353
35396
|
}
|
|
35354
|
-
function
|
|
35397
|
+
function parseProposalShape(raw) {
|
|
35355
35398
|
let parsed;
|
|
35356
35399
|
try {
|
|
35357
35400
|
parsed = JSON.parse(raw);
|
|
35358
35401
|
} catch {
|
|
35359
|
-
log.debug("handoffProtocol", "dropped proposal: malformed JSON");
|
|
35360
|
-
return null;
|
|
35361
|
-
}
|
|
35362
|
-
if (typeof parsed !== "object" || parsed === null) {
|
|
35363
|
-
log.debug("handoffProtocol", "dropped proposal: not a JSON object");
|
|
35364
35402
|
return null;
|
|
35365
35403
|
}
|
|
35404
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
35366
35405
|
const { to, reason, prompt } = parsed;
|
|
35367
|
-
if (typeof to !== "string" || to.length === 0)
|
|
35368
|
-
|
|
35406
|
+
if (typeof to !== "string" || to.length === 0) return null;
|
|
35407
|
+
if (typeof reason !== "string" || reason.length === 0 || reason.length > REASON_MAX) {
|
|
35369
35408
|
return null;
|
|
35370
35409
|
}
|
|
35371
|
-
if (
|
|
35372
|
-
log.debug("handoffProtocol", `dropped proposal: unknown target "${to}"`);
|
|
35410
|
+
if (typeof prompt !== "string" || prompt.length === 0 || prompt.length > PROMPT_MAX2) {
|
|
35373
35411
|
return null;
|
|
35374
35412
|
}
|
|
35375
|
-
|
|
35376
|
-
|
|
35413
|
+
return { to, reason, prompt };
|
|
35414
|
+
}
|
|
35415
|
+
function resolveHandoffTarget(raw, validTargets) {
|
|
35416
|
+
const trimmed = (raw ?? "").trim();
|
|
35417
|
+
if (!trimmed) return null;
|
|
35418
|
+
const lower = trimmed.toLowerCase();
|
|
35419
|
+
for (const target of validTargets) {
|
|
35420
|
+
if (target.toLowerCase() === lower) return target;
|
|
35421
|
+
}
|
|
35422
|
+
const viaAlias = normalizeAgentId(trimmed);
|
|
35423
|
+
if (viaAlias && validTargets.has(viaAlias)) return viaAlias;
|
|
35424
|
+
const viaPublic = publicToInternal(lower);
|
|
35425
|
+
if (viaPublic && validTargets.has(viaPublic)) return viaPublic;
|
|
35426
|
+
for (const meta of Object.values(AGENT_REGISTRY)) {
|
|
35427
|
+
if (meta.displayName.toLowerCase() === lower && validTargets.has(meta.id)) {
|
|
35428
|
+
return meta.id;
|
|
35429
|
+
}
|
|
35430
|
+
}
|
|
35431
|
+
return null;
|
|
35432
|
+
}
|
|
35433
|
+
function parseProposal(raw, currentAgent, validTargets) {
|
|
35434
|
+
const shape = parseProposalShape(raw);
|
|
35435
|
+
if (!shape) {
|
|
35436
|
+
log.debug("handoffProtocol", "dropped proposal: malformed JSON or invalid shape");
|
|
35377
35437
|
return null;
|
|
35378
35438
|
}
|
|
35379
|
-
|
|
35380
|
-
|
|
35439
|
+
const to = resolveHandoffTarget(shape.to, validTargets);
|
|
35440
|
+
if (!to) {
|
|
35441
|
+
log.debug("handoffProtocol", `dropped proposal: unknown target "${shape.to}"`);
|
|
35381
35442
|
return null;
|
|
35382
35443
|
}
|
|
35383
|
-
if (
|
|
35384
|
-
log.debug("handoffProtocol",
|
|
35444
|
+
if (to === currentAgent) {
|
|
35445
|
+
log.debug("handoffProtocol", "dropped proposal: target is the current agent");
|
|
35385
35446
|
return null;
|
|
35386
35447
|
}
|
|
35387
|
-
return { to, reason, prompt };
|
|
35448
|
+
return { to, reason: shape.reason, prompt: shape.prompt };
|
|
35449
|
+
}
|
|
35450
|
+
function collapseSeams(s) {
|
|
35451
|
+
return s.replace(/(?:\r?\n){3,}/g, "\n\n").trim();
|
|
35388
35452
|
}
|
|
35389
35453
|
function stripFences(masked) {
|
|
35390
|
-
|
|
35391
|
-
|
|
35454
|
+
return collapseSeams(masked.replace(FENCE_RE, ""));
|
|
35455
|
+
}
|
|
35456
|
+
function lastNonBlankLine(masked) {
|
|
35457
|
+
const parts = masked.split("\n");
|
|
35458
|
+
const starts = [];
|
|
35459
|
+
let offset = 0;
|
|
35460
|
+
for (const p2 of parts) {
|
|
35461
|
+
starts.push(offset);
|
|
35462
|
+
offset += p2.length + 1;
|
|
35463
|
+
}
|
|
35464
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
35465
|
+
if (parts[i].trim().length > 0) return { line: parts[i], start: starts[i] };
|
|
35466
|
+
}
|
|
35467
|
+
return null;
|
|
35468
|
+
}
|
|
35469
|
+
function trailingDegenerateMatch(masked) {
|
|
35470
|
+
const last = lastNonBlankLine(masked);
|
|
35471
|
+
if (!last) return null;
|
|
35472
|
+
const match = last.line.match(DEGENERATE_LINE_RE);
|
|
35473
|
+
return match ? { match, start: last.start } : null;
|
|
35392
35474
|
}
|
|
35393
35475
|
function extractHandoffProposal(text, currentAgent, validTargets) {
|
|
35394
35476
|
const { masked, restore } = maskOuterFences(text);
|
|
35395
35477
|
const matches = [...masked.matchAll(FENCE_RE)];
|
|
35396
|
-
if (matches.length
|
|
35478
|
+
if (matches.length > 0) {
|
|
35479
|
+
const last = matches[matches.length - 1];
|
|
35480
|
+
const proposal = parseProposal(last[1].trim(), currentAgent, validTargets);
|
|
35481
|
+
const cleanText = restore(stripFences(masked));
|
|
35482
|
+
return { cleanText, proposal };
|
|
35483
|
+
}
|
|
35484
|
+
const degenerate = trailingDegenerateMatch(masked);
|
|
35485
|
+
if (degenerate) {
|
|
35486
|
+
const proposal = parseProposal(degenerate.match[2].trim(), currentAgent, validTargets);
|
|
35487
|
+
if (proposal) {
|
|
35488
|
+
const { start: start2 } = degenerate;
|
|
35489
|
+
const stripped = masked.slice(0, start2) + masked.slice(start2 + degenerate.match[0].length);
|
|
35490
|
+
return { cleanText: restore(collapseSeams(stripped)), proposal };
|
|
35491
|
+
}
|
|
35397
35492
|
return { cleanText: text, proposal: null };
|
|
35398
35493
|
}
|
|
35399
|
-
|
|
35400
|
-
const proposal = parseProposal(last[1].trim(), currentAgent, validTargets);
|
|
35401
|
-
const cleanText = restore(stripFences(masked));
|
|
35402
|
-
return { cleanText, proposal };
|
|
35494
|
+
return { cleanText: text, proposal: null };
|
|
35403
35495
|
}
|
|
35404
35496
|
function stripHandoffFences(text) {
|
|
35405
35497
|
const { masked, restore } = maskOuterFences(text);
|
|
35406
|
-
if (masked.search(FENCE_RE)
|
|
35407
|
-
return
|
|
35498
|
+
if (masked.search(FENCE_RE) !== -1) {
|
|
35499
|
+
return restore(stripFences(masked));
|
|
35500
|
+
}
|
|
35501
|
+
const degenerate = trailingDegenerateMatch(masked);
|
|
35502
|
+
if (degenerate && parseProposalShape(degenerate.match[2].trim())) {
|
|
35503
|
+
const { start: start2 } = degenerate;
|
|
35504
|
+
const stripped = masked.slice(0, start2) + masked.slice(start2 + degenerate.match[0].length);
|
|
35505
|
+
return restore(collapseSeams(stripped));
|
|
35408
35506
|
}
|
|
35409
|
-
return
|
|
35507
|
+
return text;
|
|
35410
35508
|
}
|
|
35411
35509
|
function handoffFenceStartMasked(text) {
|
|
35412
35510
|
const { masked } = maskOuterFences(text);
|
|
@@ -44473,7 +44571,7 @@ function checkChokidar() {
|
|
|
44473
44571
|
}
|
|
44474
44572
|
async function doctor(args2 = []) {
|
|
44475
44573
|
const json = args2.includes("--json");
|
|
44476
|
-
const cliVersion = true ? "2.65.
|
|
44574
|
+
const cliVersion = true ? "2.65.4" : "0.0.0-dev";
|
|
44477
44575
|
const apiBase2 = resolveApiBaseUrl();
|
|
44478
44576
|
const diagnosticId = (0, import_node_crypto13.randomUUID)();
|
|
44479
44577
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -44864,7 +44962,7 @@ async function mcpRun(args2) {
|
|
|
44864
44962
|
// src/commands/version.ts
|
|
44865
44963
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
44866
44964
|
function version2() {
|
|
44867
|
-
const v = true ? "2.65.
|
|
44965
|
+
const v = true ? "2.65.4" : "unknown";
|
|
44868
44966
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
44869
44967
|
}
|
|
44870
44968
|
|