codeam-cli 2.61.22 → 2.61.24
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 +23 -0
- package/dist/index.js +742 -472
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -806,6 +806,91 @@ function isKnownIntegrationId(id) {
|
|
|
806
806
|
return id in INTEGRATION_REGISTRY;
|
|
807
807
|
}
|
|
808
808
|
|
|
809
|
+
// ../../packages/shared/src/skills/registry.ts
|
|
810
|
+
var CODE_REVIEW_BODY = `Use this skill when reviewing a pull request. It defines what a high-signal
|
|
811
|
+
review looks like so your inline comments are worth the author's time.
|
|
812
|
+
|
|
813
|
+
## Review priorities (in order)
|
|
814
|
+
1. **Correctness** \u2014 does the change do what the PR says, and only that? Trace the
|
|
815
|
+
changed paths for logic errors, off-by-one, null/undefined, wrong branch, and
|
|
816
|
+
inverted conditions. State a concrete failure scenario (inputs \u2192 wrong output)
|
|
817
|
+
for anything you flag as a bug.
|
|
818
|
+
2. **Security** \u2014 untrusted input reaching a sink (SQL, shell, path, HTML), secrets
|
|
819
|
+
in code/logs, authz gaps, credentials passed via argv instead of env.
|
|
820
|
+
3. **Tests** \u2014 does the change carry tests that would fail without it? Missing
|
|
821
|
+
coverage on a bug-prone path is a finding.
|
|
822
|
+
4. **Clarity / reuse** \u2014 duplicated logic, a simpler existing helper, a name that
|
|
823
|
+
misleads. Only raise these when they materially affect maintainability.
|
|
824
|
+
|
|
825
|
+
## Comment discipline
|
|
826
|
+
- One finding per comment, anchored to the exact line.
|
|
827
|
+
- Lead with severity: **blocker**, **should-fix**, or **nit**.
|
|
828
|
+
- Say WHY (the failure or risk), not just WHAT. Propose the fix when it is short.
|
|
829
|
+
- Do NOT restate the diff, praise trivially, or nitpick style a formatter owns.
|
|
830
|
+
- If the PR is correct and well-tested, say so plainly and approve \u2014 a clean review
|
|
831
|
+
is a valid outcome, not a failure to find something.
|
|
832
|
+
|
|
833
|
+
## Scope
|
|
834
|
+
Review only what the diff changes and its direct blast radius. Do not demand
|
|
835
|
+
unrelated refactors.`;
|
|
836
|
+
var CODE_REVIEW_INSTRUCTION = `When reviewing this PR, prioritize correctness first, then security, then test
|
|
837
|
+
coverage, then clarity/reuse. One finding per inline comment, anchored to the exact
|
|
838
|
+
line, each led by a severity tag (blocker/should-fix/nit) and a concrete reason
|
|
839
|
+
(the failure scenario or risk), not a restatement of the diff. If the change is
|
|
840
|
+
correct and well-tested, approve and say so \u2014 finding nothing is a valid outcome.
|
|
841
|
+
Review only the diff and its direct blast radius; do not demand unrelated refactors.`;
|
|
842
|
+
var RESOLVE_CONFLICTS_BODY = `Use this skill when resolving merge conflicts on a pull request. The goal is a
|
|
843
|
+
merge that preserves BOTH sides' intent, not one that just makes the file compile.
|
|
844
|
+
|
|
845
|
+
## Method
|
|
846
|
+
1. Understand each conflict hunk before editing: what did HEAD change, what did the
|
|
847
|
+
base branch change, and WHY. Read the surrounding function, not just the markers.
|
|
848
|
+
2. Prefer a union of intents. Drop a side only when the two changes are genuinely
|
|
849
|
+
mutually exclusive \u2014 and when you do, keep the side that matches the PR's purpose.
|
|
850
|
+
3. Never leave a conflict marker (\`<<<<<<<\`, \`=======\`, \`>>>>>>>\`) behind. Grep for
|
|
851
|
+
them before committing.
|
|
852
|
+
4. After resolving, the code must build and its tests must pass. Run them. A merge
|
|
853
|
+
that resolves markers but breaks the build is not done.
|
|
854
|
+
5. For lockfiles/generated files, regenerate rather than hand-merge.
|
|
855
|
+
|
|
856
|
+
## Commit
|
|
857
|
+
One commit that explains what was reconciled and any intent you had to choose
|
|
858
|
+
between. Then push the branch.`;
|
|
859
|
+
var RESOLVE_CONFLICTS_INSTRUCTION = `When resolving these merge conflicts, preserve both sides' intent \u2014 read each hunk's
|
|
860
|
+
surrounding code to understand what HEAD and the base branch each changed and why,
|
|
861
|
+
and prefer a union of intents; drop a side only when the two are mutually exclusive,
|
|
862
|
+
keeping the side that matches the PR's purpose. Leave no conflict markers behind
|
|
863
|
+
(grep for them). Regenerate lockfiles rather than hand-merging them. The result must
|
|
864
|
+
build and pass tests \u2014 run them \u2014 before you commit and push.`;
|
|
865
|
+
var SKILL_REGISTRY = {
|
|
866
|
+
"code-review": {
|
|
867
|
+
id: "code-review",
|
|
868
|
+
name: "Code Review",
|
|
869
|
+
description: `High-signal PR review: prioritize correctness \u2192 security \u2192 tests \u2192 clarity, one anchored finding per comment.`,
|
|
870
|
+
source: "curated",
|
|
871
|
+
delivery: {
|
|
872
|
+
skillFile: { body: CODE_REVIEW_BODY },
|
|
873
|
+
instruction: { body: CODE_REVIEW_INSTRUCTION }
|
|
874
|
+
}
|
|
875
|
+
},
|
|
876
|
+
"resolve-conflicts": {
|
|
877
|
+
id: "resolve-conflicts",
|
|
878
|
+
name: "Resolve Conflicts",
|
|
879
|
+
description: `Merge-conflict resolution that preserves both sides' intent, leaves no markers, and keeps the build green.`,
|
|
880
|
+
source: "curated",
|
|
881
|
+
delivery: {
|
|
882
|
+
skillFile: { body: RESOLVE_CONFLICTS_BODY },
|
|
883
|
+
instruction: { body: RESOLVE_CONFLICTS_INSTRUCTION }
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
function isSkillId(id) {
|
|
888
|
+
return Object.prototype.hasOwnProperty.call(SKILL_REGISTRY, id);
|
|
889
|
+
}
|
|
890
|
+
function getSkillDefinition(id) {
|
|
891
|
+
return isSkillId(id) ? SKILL_REGISTRY[id] : null;
|
|
892
|
+
}
|
|
893
|
+
|
|
809
894
|
// ../../packages/shared/src/api-url.ts
|
|
810
895
|
var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
|
|
811
896
|
var DEV_API_BASE_URL = "https://dev-api.codeagent-mobile.com";
|
|
@@ -1130,11 +1215,11 @@ function quiet(fn) {
|
|
|
1130
1215
|
log.debug(TAG, "ignored sync error", err);
|
|
1131
1216
|
}
|
|
1132
1217
|
}
|
|
1133
|
-
function rmIfExistsQuiet(
|
|
1218
|
+
function rmIfExistsQuiet(path78) {
|
|
1134
1219
|
try {
|
|
1135
|
-
fs2.rmSync(
|
|
1220
|
+
fs2.rmSync(path78, { force: true });
|
|
1136
1221
|
} catch (err) {
|
|
1137
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
1222
|
+
log.debug(TAG, `rmIfExists failed for ${path78}`, err);
|
|
1138
1223
|
}
|
|
1139
1224
|
}
|
|
1140
1225
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -1280,9 +1365,9 @@ var _default = makeConfig();
|
|
|
1280
1365
|
var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
|
|
1281
1366
|
|
|
1282
1367
|
// src/commands/pair-auto.ts
|
|
1283
|
-
var
|
|
1284
|
-
var
|
|
1285
|
-
var
|
|
1368
|
+
var fs58 = __toESM(require("fs"));
|
|
1369
|
+
var os48 = __toESM(require("os"));
|
|
1370
|
+
var path62 = __toESM(require("path"));
|
|
1286
1371
|
var import_crypto4 = require("crypto");
|
|
1287
1372
|
|
|
1288
1373
|
// src/services/telemetry.service.ts
|
|
@@ -1318,8 +1403,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
1318
1403
|
return decodedFile;
|
|
1319
1404
|
};
|
|
1320
1405
|
}
|
|
1321
|
-
function normalizeWindowsPath(
|
|
1322
|
-
return
|
|
1406
|
+
function normalizeWindowsPath(path78) {
|
|
1407
|
+
return path78.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
1323
1408
|
}
|
|
1324
1409
|
|
|
1325
1410
|
// ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
|
|
@@ -3799,9 +3884,9 @@ async function addSourceContext(frames) {
|
|
|
3799
3884
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
3800
3885
|
return frames;
|
|
3801
3886
|
}
|
|
3802
|
-
function getContextLinesFromFile(
|
|
3887
|
+
function getContextLinesFromFile(path78, ranges, output) {
|
|
3803
3888
|
return new Promise((resolve8) => {
|
|
3804
|
-
const stream = (0, import_node_fs.createReadStream)(
|
|
3889
|
+
const stream = (0, import_node_fs.createReadStream)(path78);
|
|
3805
3890
|
const lineReaded = (0, import_node_readline.createInterface)({
|
|
3806
3891
|
input: stream
|
|
3807
3892
|
});
|
|
@@ -3816,7 +3901,7 @@ function getContextLinesFromFile(path76, ranges, output) {
|
|
|
3816
3901
|
let rangeStart = range[0];
|
|
3817
3902
|
let rangeEnd = range[1];
|
|
3818
3903
|
function onStreamError() {
|
|
3819
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
3904
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path78, 1);
|
|
3820
3905
|
lineReaded.close();
|
|
3821
3906
|
lineReaded.removeAllListeners();
|
|
3822
3907
|
destroyStreamAndResolve();
|
|
@@ -3877,8 +3962,8 @@ function clearLineContext(frame) {
|
|
|
3877
3962
|
delete frame.context_line;
|
|
3878
3963
|
delete frame.post_context;
|
|
3879
3964
|
}
|
|
3880
|
-
function shouldSkipContextLinesForFile(
|
|
3881
|
-
return
|
|
3965
|
+
function shouldSkipContextLinesForFile(path78) {
|
|
3966
|
+
return path78.startsWith("node:") || path78.endsWith(".min.js") || path78.endsWith(".min.cjs") || path78.endsWith(".min.mjs") || path78.startsWith("data:");
|
|
3882
3967
|
}
|
|
3883
3968
|
function shouldSkipContextLinesForFrame(frame) {
|
|
3884
3969
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
@@ -6032,7 +6117,7 @@ function readAnonId() {
|
|
|
6032
6117
|
}
|
|
6033
6118
|
function superProperties() {
|
|
6034
6119
|
return {
|
|
6035
|
-
cliVersion: true ? "2.61.
|
|
6120
|
+
cliVersion: true ? "2.61.24" : "0.0.0-dev",
|
|
6036
6121
|
nodeVersion: process.version,
|
|
6037
6122
|
platform: process.platform,
|
|
6038
6123
|
arch: process.arch,
|
|
@@ -6213,7 +6298,7 @@ var os4 = __toESM(require("os"));
|
|
|
6213
6298
|
// package.json
|
|
6214
6299
|
var package_default = {
|
|
6215
6300
|
name: "codeam-cli",
|
|
6216
|
-
version: "2.61.
|
|
6301
|
+
version: "2.61.24",
|
|
6217
6302
|
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.",
|
|
6218
6303
|
type: "commonjs",
|
|
6219
6304
|
main: "dist/index.js",
|
|
@@ -6290,7 +6375,7 @@ var package_default = {
|
|
|
6290
6375
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
6291
6376
|
"@clack/prompts": "^1.2.0",
|
|
6292
6377
|
chokidar: "^3.6.0",
|
|
6293
|
-
ignore: "^
|
|
6378
|
+
ignore: "^7.0.6",
|
|
6294
6379
|
picocolors: "^1.1.0",
|
|
6295
6380
|
"qrcode-terminal": "^0.12.0",
|
|
6296
6381
|
which: "^6.0.0",
|
|
@@ -6309,8 +6394,9 @@ var package_default = {
|
|
|
6309
6394
|
"@vitest/coverage-v8": "^4.1.7",
|
|
6310
6395
|
"node-pty": "^1.1.0",
|
|
6311
6396
|
tsup: "^8.0.0",
|
|
6312
|
-
typescript: "^
|
|
6313
|
-
vitest: "^4.1.5"
|
|
6397
|
+
typescript: "^7.0.2",
|
|
6398
|
+
vitest: "^4.1.5",
|
|
6399
|
+
yaml: "^2.9.0"
|
|
6314
6400
|
}
|
|
6315
6401
|
};
|
|
6316
6402
|
|
|
@@ -7377,7 +7463,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
7377
7463
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
7378
7464
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
7379
7465
|
// pair/reconnect). Older backends ignore the extra field.
|
|
7380
|
-
..."2.61.
|
|
7466
|
+
..."2.61.24" ? { ideVersion: "2.61.24" } : {}
|
|
7381
7467
|
}).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
|
|
7382
7468
|
}
|
|
7383
7469
|
/**
|
|
@@ -8751,9 +8837,9 @@ function closeAllTerminals() {
|
|
|
8751
8837
|
}
|
|
8752
8838
|
|
|
8753
8839
|
// src/commands/start/handlers.ts
|
|
8754
|
-
var
|
|
8755
|
-
var
|
|
8756
|
-
var
|
|
8840
|
+
var fs57 = __toESM(require("fs"));
|
|
8841
|
+
var os47 = __toESM(require("os"));
|
|
8842
|
+
var path61 = __toESM(require("path"));
|
|
8757
8843
|
var import_crypto3 = require("crypto");
|
|
8758
8844
|
var import_child_process24 = require("child_process");
|
|
8759
8845
|
|
|
@@ -8831,7 +8917,12 @@ var startCommandSchema = import_zod.z.object({
|
|
|
8831
8917
|
// Restore the caller's already-vaulted CodeRabbit credential onto this
|
|
8832
8918
|
// session (no re-login) — fetches from the backend + installs + writes it.
|
|
8833
8919
|
"provision",
|
|
8834
|
-
"review"
|
|
8920
|
+
"review",
|
|
8921
|
+
// `skills_configure` — attach/detach a curated Agent Skill on a RUNNING
|
|
8922
|
+
// session (Claude hot-reloads ~/.claude/skills/), or list what's installed.
|
|
8923
|
+
"add",
|
|
8924
|
+
"remove",
|
|
8925
|
+
"list"
|
|
8835
8926
|
]).optional(),
|
|
8836
8927
|
// `headroom_configure` — savings ingest URL delivered from the session
|
|
8837
8928
|
// when enabling Headroom on-demand. Bounded to 2048 chars.
|
|
@@ -8938,7 +9029,11 @@ var startCommandSchema = import_zod.z.object({
|
|
|
8938
9029
|
key: import_zod.z.string().min(1).max(256),
|
|
8939
9030
|
value: import_zod.z.string().max(32768)
|
|
8940
9031
|
})
|
|
8941
|
-
).max(512).optional()
|
|
9032
|
+
).max(512).optional(),
|
|
9033
|
+
// `skills_configure` — the curated `SkillId` to add/remove. `list` (and a
|
|
9034
|
+
// malformed/unknown id on add/remove) sends no `skillId` or an invalid one;
|
|
9035
|
+
// `configureSkill` itself validates against the shared registry.
|
|
9036
|
+
skillId: import_zod.z.string().min(1).max(128).optional()
|
|
8942
9037
|
});
|
|
8943
9038
|
function parsePayload2(schema, raw) {
|
|
8944
9039
|
const result = schema.safeParse(raw);
|
|
@@ -12224,10 +12319,10 @@ function buildForPlatform(platform3) {
|
|
|
12224
12319
|
var import_node_crypto4 = require("crypto");
|
|
12225
12320
|
|
|
12226
12321
|
// src/agents/claude/resolver.ts
|
|
12227
|
-
function buildClaudeLaunch(extraArgs = [],
|
|
12228
|
-
const found =
|
|
12322
|
+
function buildClaudeLaunch(extraArgs = [], os57 = createOsStrategy()) {
|
|
12323
|
+
const found = os57.findInPath("claude") ?? os57.findInPath("claude-code");
|
|
12229
12324
|
if (!found) return null;
|
|
12230
|
-
return
|
|
12325
|
+
return os57.buildLaunch(found, extraArgs);
|
|
12231
12326
|
}
|
|
12232
12327
|
|
|
12233
12328
|
// src/agents/claude/installer.ts
|
|
@@ -12817,8 +12912,8 @@ var ClaudeRuntimeStrategy = class {
|
|
|
12817
12912
|
meta = getAgent("claude");
|
|
12818
12913
|
mode = "interactive";
|
|
12819
12914
|
os;
|
|
12820
|
-
constructor(
|
|
12821
|
-
this.os =
|
|
12915
|
+
constructor(os57) {
|
|
12916
|
+
this.os = os57;
|
|
12822
12917
|
}
|
|
12823
12918
|
/**
|
|
12824
12919
|
* Claude Code's react-ink TUI enables bracketed-paste mode at
|
|
@@ -13598,8 +13693,8 @@ function codexCredentialLocator() {
|
|
|
13598
13693
|
function codexLoginLauncher() {
|
|
13599
13694
|
return {
|
|
13600
13695
|
async ensureInstalled() {
|
|
13601
|
-
const
|
|
13602
|
-
return
|
|
13696
|
+
const os57 = createOsStrategy();
|
|
13697
|
+
return os57.findInPath("codex") !== null;
|
|
13603
13698
|
},
|
|
13604
13699
|
launch() {
|
|
13605
13700
|
return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
|
|
@@ -13622,8 +13717,8 @@ var CodexRuntimeStrategy = class {
|
|
|
13622
13717
|
meta = getAgent("codex");
|
|
13623
13718
|
mode = "interactive";
|
|
13624
13719
|
os;
|
|
13625
|
-
constructor(
|
|
13626
|
-
this.os =
|
|
13720
|
+
constructor(os57) {
|
|
13721
|
+
this.os = os57;
|
|
13627
13722
|
}
|
|
13628
13723
|
async prepareLaunch() {
|
|
13629
13724
|
let binary = this.os.findInPath("codex");
|
|
@@ -13732,12 +13827,12 @@ var CodexRuntimeStrategy = class {
|
|
|
13732
13827
|
});
|
|
13733
13828
|
}
|
|
13734
13829
|
};
|
|
13735
|
-
function resolveNpm(
|
|
13736
|
-
return
|
|
13830
|
+
function resolveNpm(os57) {
|
|
13831
|
+
return os57.id === "win32" ? "npm.cmd" : "npm";
|
|
13737
13832
|
}
|
|
13738
|
-
async function installCodexViaNpm(
|
|
13833
|
+
async function installCodexViaNpm(os57) {
|
|
13739
13834
|
return new Promise((resolve8, reject) => {
|
|
13740
|
-
const proc = (0, import_node_child_process5.spawn)(resolveNpm(
|
|
13835
|
+
const proc = (0, import_node_child_process5.spawn)(resolveNpm(os57), ["install", "-g", "@openai/codex"], {
|
|
13741
13836
|
stdio: "inherit"
|
|
13742
13837
|
});
|
|
13743
13838
|
proc.on("close", (code) => {
|
|
@@ -13754,16 +13849,16 @@ async function installCodexViaNpm(os53) {
|
|
|
13754
13849
|
});
|
|
13755
13850
|
});
|
|
13756
13851
|
}
|
|
13757
|
-
function augmentNpmGlobalBin(
|
|
13852
|
+
function augmentNpmGlobalBin(os57) {
|
|
13758
13853
|
try {
|
|
13759
|
-
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(
|
|
13854
|
+
const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os57), ["prefix", "-g"], {
|
|
13760
13855
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13761
13856
|
});
|
|
13762
13857
|
if (result.status !== 0) return;
|
|
13763
13858
|
const prefix = result.stdout.toString().trim();
|
|
13764
13859
|
if (!prefix) return;
|
|
13765
|
-
const binDir =
|
|
13766
|
-
|
|
13860
|
+
const binDir = os57.id === "win32" ? prefix : path24.join(prefix, "bin");
|
|
13861
|
+
os57.augmentPath([binDir]);
|
|
13767
13862
|
} catch {
|
|
13768
13863
|
}
|
|
13769
13864
|
}
|
|
@@ -13847,9 +13942,9 @@ var import_node_child_process8 = require("child_process");
|
|
|
13847
13942
|
// src/agents/coderabbit/installer.ts
|
|
13848
13943
|
var import_node_child_process6 = require("child_process");
|
|
13849
13944
|
var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
|
|
13850
|
-
async function ensureCoderabbitInstalled(
|
|
13851
|
-
if (
|
|
13852
|
-
if (
|
|
13945
|
+
async function ensureCoderabbitInstalled(os57) {
|
|
13946
|
+
if (os57.findInPath("coderabbit")) return true;
|
|
13947
|
+
if (os57.id === "win32") {
|
|
13853
13948
|
console.error(
|
|
13854
13949
|
"\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
|
|
13855
13950
|
);
|
|
@@ -13882,8 +13977,8 @@ async function ensureCoderabbitInstalled(os53) {
|
|
|
13882
13977
|
proc.on("error", () => finish(false));
|
|
13883
13978
|
});
|
|
13884
13979
|
if (!ok) return false;
|
|
13885
|
-
|
|
13886
|
-
return
|
|
13980
|
+
os57.augmentPath([`${os57.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
|
|
13981
|
+
return os57.findInPath("coderabbit") !== null;
|
|
13887
13982
|
}
|
|
13888
13983
|
|
|
13889
13984
|
// src/agents/coderabbit/link.ts
|
|
@@ -13918,10 +14013,10 @@ function coderabbitCredentialLocator() {
|
|
|
13918
14013
|
validate: validateNonEmptyCredential
|
|
13919
14014
|
};
|
|
13920
14015
|
}
|
|
13921
|
-
function coderabbitLoginLauncher(
|
|
14016
|
+
function coderabbitLoginLauncher(os57) {
|
|
13922
14017
|
return {
|
|
13923
14018
|
async ensureInstalled() {
|
|
13924
|
-
return ensureCoderabbitInstalled(
|
|
14019
|
+
return ensureCoderabbitInstalled(os57);
|
|
13925
14020
|
},
|
|
13926
14021
|
launch() {
|
|
13927
14022
|
return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -13977,8 +14072,8 @@ function pickLine(obj) {
|
|
|
13977
14072
|
function toHunk(raw, groupSeverity) {
|
|
13978
14073
|
if (!raw || typeof raw !== "object") return null;
|
|
13979
14074
|
const o = raw;
|
|
13980
|
-
const
|
|
13981
|
-
if (!
|
|
14075
|
+
const path78 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
14076
|
+
if (!path78) return null;
|
|
13982
14077
|
const message = asString(
|
|
13983
14078
|
pick(o, [
|
|
13984
14079
|
"comment",
|
|
@@ -13995,7 +14090,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
13995
14090
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
13996
14091
|
const locObj = pick(o, ["location"]) ?? o;
|
|
13997
14092
|
return {
|
|
13998
|
-
path:
|
|
14093
|
+
path: path78.trim(),
|
|
13999
14094
|
line: pickLine(o) ?? pickLine(locObj),
|
|
14000
14095
|
severity,
|
|
14001
14096
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -14078,10 +14173,10 @@ function parsePlain(stdout) {
|
|
|
14078
14173
|
for (const line of stdout.split(/\r?\n/)) {
|
|
14079
14174
|
const m = line.match(HUNK_LINE_RE);
|
|
14080
14175
|
if (!m) continue;
|
|
14081
|
-
const [,
|
|
14082
|
-
if (!
|
|
14176
|
+
const [, path78, lineNo, sevToken, message] = m;
|
|
14177
|
+
if (!path78 || !lineNo || !message) continue;
|
|
14083
14178
|
hunks.push({
|
|
14084
|
-
path:
|
|
14179
|
+
path: path78.trim(),
|
|
14085
14180
|
line: Number(lineNo),
|
|
14086
14181
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
14087
14182
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -14141,8 +14236,8 @@ var CoderabbitRuntimeStrategy = class {
|
|
|
14141
14236
|
meta = getAgent("coderabbit");
|
|
14142
14237
|
mode = "batch";
|
|
14143
14238
|
os;
|
|
14144
|
-
constructor(
|
|
14145
|
-
this.os =
|
|
14239
|
+
constructor(os57) {
|
|
14240
|
+
this.os = os57;
|
|
14146
14241
|
}
|
|
14147
14242
|
getDefaultArgs() {
|
|
14148
14243
|
return ["review", "--agent"];
|
|
@@ -14413,10 +14508,10 @@ function cursorCredentialLocator() {
|
|
|
14413
14508
|
validate: validateNonEmptyCredential
|
|
14414
14509
|
};
|
|
14415
14510
|
}
|
|
14416
|
-
function cursorLoginLauncher(
|
|
14511
|
+
function cursorLoginLauncher(os57) {
|
|
14417
14512
|
return {
|
|
14418
14513
|
async ensureInstalled() {
|
|
14419
|
-
if (
|
|
14514
|
+
if (os57.findInPath("cursor-agent")) return true;
|
|
14420
14515
|
console.error(
|
|
14421
14516
|
"\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
|
|
14422
14517
|
);
|
|
@@ -14480,8 +14575,8 @@ var CursorRuntimeStrategy = class {
|
|
|
14480
14575
|
meta = getAgent("cursor");
|
|
14481
14576
|
mode = "interactive";
|
|
14482
14577
|
os;
|
|
14483
|
-
constructor(
|
|
14484
|
-
this.os =
|
|
14578
|
+
constructor(os57) {
|
|
14579
|
+
this.os = os57;
|
|
14485
14580
|
}
|
|
14486
14581
|
async prepareLaunch() {
|
|
14487
14582
|
const binary = this.os.findInPath("cursor-agent");
|
|
@@ -14697,10 +14792,10 @@ function aiderCredentialLocator() {
|
|
|
14697
14792
|
validate: validateNonEmptyCredential
|
|
14698
14793
|
};
|
|
14699
14794
|
}
|
|
14700
|
-
function aiderLoginLauncher(
|
|
14795
|
+
function aiderLoginLauncher(os57) {
|
|
14701
14796
|
return {
|
|
14702
14797
|
async ensureInstalled() {
|
|
14703
|
-
if (
|
|
14798
|
+
if (os57.findInPath("aider")) return true;
|
|
14704
14799
|
console.error(
|
|
14705
14800
|
"\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
|
|
14706
14801
|
);
|
|
@@ -14710,7 +14805,7 @@ function aiderLoginLauncher(os53) {
|
|
|
14710
14805
|
console.error(
|
|
14711
14806
|
"\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
|
|
14712
14807
|
);
|
|
14713
|
-
return (0, import_node_child_process11.spawn)(
|
|
14808
|
+
return (0, import_node_child_process11.spawn)(os57.id === "win32" ? "cmd.exe" : "sh", os57.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
|
|
14714
14809
|
stdio: "ignore"
|
|
14715
14810
|
});
|
|
14716
14811
|
}
|
|
@@ -14782,8 +14877,8 @@ var AiderRuntimeStrategy = class {
|
|
|
14782
14877
|
meta = getAgent("aider");
|
|
14783
14878
|
mode = "interactive";
|
|
14784
14879
|
os;
|
|
14785
|
-
constructor(
|
|
14786
|
-
this.os =
|
|
14880
|
+
constructor(os57) {
|
|
14881
|
+
this.os = os57;
|
|
14787
14882
|
}
|
|
14788
14883
|
async prepareLaunch() {
|
|
14789
14884
|
const binary = this.os.findInPath("aider");
|
|
@@ -14915,8 +15010,8 @@ function geminiCredentialLocator() {
|
|
|
14915
15010
|
function geminiLoginLauncher() {
|
|
14916
15011
|
return {
|
|
14917
15012
|
async ensureInstalled() {
|
|
14918
|
-
const
|
|
14919
|
-
return
|
|
15013
|
+
const os57 = createOsStrategy();
|
|
15014
|
+
return os57.findInPath("gemini") !== null;
|
|
14920
15015
|
},
|
|
14921
15016
|
launch() {
|
|
14922
15017
|
return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
|
|
@@ -15106,8 +15201,8 @@ var GeminiRuntimeStrategy = class {
|
|
|
15106
15201
|
meta = getAgent("gemini");
|
|
15107
15202
|
mode = "interactive";
|
|
15108
15203
|
os;
|
|
15109
|
-
constructor(
|
|
15110
|
-
this.os =
|
|
15204
|
+
constructor(os57) {
|
|
15205
|
+
this.os = os57;
|
|
15111
15206
|
}
|
|
15112
15207
|
async prepareLaunch() {
|
|
15113
15208
|
const binary = this.os.findInPath("gemini");
|
|
@@ -15398,8 +15493,8 @@ var KimiRuntimeStrategy = class {
|
|
|
15398
15493
|
meta = getAgent("kimi");
|
|
15399
15494
|
mode = "interactive";
|
|
15400
15495
|
os;
|
|
15401
|
-
constructor(
|
|
15402
|
-
this.os =
|
|
15496
|
+
constructor(os57) {
|
|
15497
|
+
this.os = os57;
|
|
15403
15498
|
}
|
|
15404
15499
|
async prepareLaunch() {
|
|
15405
15500
|
const binary = this.os.findInPath("kimi");
|
|
@@ -15512,19 +15607,19 @@ var KimiRuntimeStrategy = class {
|
|
|
15512
15607
|
|
|
15513
15608
|
// src/agents/registry.ts
|
|
15514
15609
|
var runtimeBuilders = {
|
|
15515
|
-
claude: (
|
|
15516
|
-
codex: (
|
|
15517
|
-
coderabbit: (
|
|
15518
|
-
cursor: (
|
|
15519
|
-
aider: (
|
|
15520
|
-
gemini: (
|
|
15521
|
-
kimi: (
|
|
15610
|
+
claude: (os57) => new ClaudeRuntimeStrategy(os57),
|
|
15611
|
+
codex: (os57) => new CodexRuntimeStrategy(os57),
|
|
15612
|
+
coderabbit: (os57) => new CoderabbitRuntimeStrategy(os57),
|
|
15613
|
+
cursor: (os57) => new CursorRuntimeStrategy(os57),
|
|
15614
|
+
aider: (os57) => new AiderRuntimeStrategy(os57),
|
|
15615
|
+
gemini: (os57) => new GeminiRuntimeStrategy(os57),
|
|
15616
|
+
kimi: (os57) => new KimiRuntimeStrategy(os57)
|
|
15522
15617
|
};
|
|
15523
15618
|
var deployBuilders = {
|
|
15524
15619
|
claude: () => new ClaudeDeployStrategy(),
|
|
15525
15620
|
codex: () => new CodexDeployStrategy()
|
|
15526
15621
|
};
|
|
15527
|
-
function createAgentStrategy(agent,
|
|
15622
|
+
function createAgentStrategy(agent, os57 = createOsStrategy()) {
|
|
15528
15623
|
if (!AGENT_REGISTRY[agent]?.enabled) {
|
|
15529
15624
|
throw new Error(
|
|
15530
15625
|
`Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
|
|
@@ -15534,10 +15629,10 @@ function createAgentStrategy(agent, os53 = createOsStrategy()) {
|
|
|
15534
15629
|
if (!build) {
|
|
15535
15630
|
throw new Error(`No runtime strategy registered for agent "${agent}"`);
|
|
15536
15631
|
}
|
|
15537
|
-
return build(
|
|
15632
|
+
return build(os57);
|
|
15538
15633
|
}
|
|
15539
|
-
function createInteractiveAgentStrategy(agent,
|
|
15540
|
-
const s = createAgentStrategy(agent,
|
|
15634
|
+
function createInteractiveAgentStrategy(agent, os57 = createOsStrategy()) {
|
|
15635
|
+
const s = createAgentStrategy(agent, os57);
|
|
15541
15636
|
if (s.mode !== "interactive") {
|
|
15542
15637
|
throw new Error(
|
|
15543
15638
|
`Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
|
|
@@ -16234,26 +16329,26 @@ function restoreCoderabbitOauthBlob(value) {
|
|
|
16234
16329
|
(0, import_node_fs5.writeFileSync)(path36.join(dir, file), contents, { mode: 384 });
|
|
16235
16330
|
}
|
|
16236
16331
|
async function configureCoderabbit(input, deps = {}) {
|
|
16237
|
-
const
|
|
16332
|
+
const os57 = deps.os ?? createOsStrategy();
|
|
16238
16333
|
const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
|
|
16239
16334
|
const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
|
|
16240
16335
|
const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
|
|
16241
16336
|
const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
|
|
16242
16337
|
const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
|
|
16243
16338
|
const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
|
|
16244
|
-
const home =
|
|
16245
|
-
|
|
16246
|
-
|
|
16339
|
+
const home = os57.homeDir();
|
|
16340
|
+
os57.augmentPath(
|
|
16341
|
+
os57.id === "win32" ? [
|
|
16247
16342
|
path36.join(home, ".local", "bin"),
|
|
16248
16343
|
path36.join(process.env.APPDATA ?? path36.join(home, "AppData", "Roaming"), "npm"),
|
|
16249
16344
|
path36.join(home, "scoop", "shims")
|
|
16250
16345
|
] : [path36.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
|
|
16251
16346
|
);
|
|
16252
|
-
const installed2 =
|
|
16347
|
+
const installed2 = os57.findInPath("coderabbit") !== null;
|
|
16253
16348
|
const base = () => ({
|
|
16254
16349
|
action: input.action,
|
|
16255
16350
|
supported: true,
|
|
16256
|
-
installed:
|
|
16351
|
+
installed: os57.findInPath("coderabbit") !== null,
|
|
16257
16352
|
loggedIn: false
|
|
16258
16353
|
});
|
|
16259
16354
|
if (input.action === "status") {
|
|
@@ -16267,7 +16362,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
16267
16362
|
const key = (input.apiKey ?? "").trim();
|
|
16268
16363
|
if (!key) return { ...res2, error: "No API key provided" };
|
|
16269
16364
|
if (!res2.installed) {
|
|
16270
|
-
const ok = await ensureInstalled(
|
|
16365
|
+
const ok = await ensureInstalled(os57);
|
|
16271
16366
|
res2.installed = ok;
|
|
16272
16367
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
16273
16368
|
}
|
|
@@ -16291,7 +16386,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
16291
16386
|
}
|
|
16292
16387
|
if (!res2.installed) {
|
|
16293
16388
|
deps.onEvent?.({ kind: "installing" });
|
|
16294
|
-
const ok = await ensureInstalled(
|
|
16389
|
+
const ok = await ensureInstalled(os57);
|
|
16295
16390
|
res2.installed = ok;
|
|
16296
16391
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
16297
16392
|
}
|
|
@@ -16321,7 +16416,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
16321
16416
|
const res2 = base();
|
|
16322
16417
|
if (!installed2) {
|
|
16323
16418
|
deps.onEvent?.({ kind: "installing" });
|
|
16324
|
-
const ok = await ensureInstalled(
|
|
16419
|
+
const ok = await ensureInstalled(os57);
|
|
16325
16420
|
res2.installed = ok;
|
|
16326
16421
|
if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
|
|
16327
16422
|
}
|
|
@@ -16361,7 +16456,7 @@ async function configureCoderabbit(input, deps = {}) {
|
|
|
16361
16456
|
}
|
|
16362
16457
|
const res = base();
|
|
16363
16458
|
if (!res.installed) {
|
|
16364
|
-
const ok = await ensureInstalled(
|
|
16459
|
+
const ok = await ensureInstalled(os57);
|
|
16365
16460
|
res.installed = ok;
|
|
16366
16461
|
if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
|
|
16367
16462
|
}
|
|
@@ -16545,9 +16640,9 @@ function defaultRunGh(args2) {
|
|
|
16545
16640
|
|
|
16546
16641
|
// src/commands/host-agent.ts
|
|
16547
16642
|
var import_node_child_process24 = require("child_process");
|
|
16548
|
-
var
|
|
16549
|
-
var
|
|
16550
|
-
var
|
|
16643
|
+
var os37 = __toESM(require("os"));
|
|
16644
|
+
var fs43 = __toESM(require("fs"));
|
|
16645
|
+
var path46 = __toESM(require("path"));
|
|
16551
16646
|
|
|
16552
16647
|
// src/integrations/manifest.ts
|
|
16553
16648
|
var import_node_fs7 = __toESM(require("fs"));
|
|
@@ -16622,14 +16717,84 @@ function clearIntegrationsManifest() {
|
|
|
16622
16717
|
}
|
|
16623
16718
|
}
|
|
16624
16719
|
|
|
16720
|
+
// src/skills/manifest.ts
|
|
16721
|
+
var import_node_fs8 = __toESM(require("fs"));
|
|
16722
|
+
var import_node_os7 = __toESM(require("os"));
|
|
16723
|
+
var import_node_path6 = __toESM(require("path"));
|
|
16724
|
+
function skillsManifestPath() {
|
|
16725
|
+
return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "skills.json");
|
|
16726
|
+
}
|
|
16727
|
+
function readSkillsManifest() {
|
|
16728
|
+
try {
|
|
16729
|
+
const raw = JSON.parse(import_node_fs8.default.readFileSync(skillsManifestPath(), "utf8"));
|
|
16730
|
+
if (!Array.isArray(raw?.skills)) return null;
|
|
16731
|
+
raw.skills = raw.skills.filter(
|
|
16732
|
+
(s) => Boolean(s) && typeof s === "object" && typeof s.id === "string"
|
|
16733
|
+
);
|
|
16734
|
+
return raw;
|
|
16735
|
+
} catch {
|
|
16736
|
+
return null;
|
|
16737
|
+
}
|
|
16738
|
+
}
|
|
16739
|
+
function persistSkillsManifest(m) {
|
|
16740
|
+
try {
|
|
16741
|
+
const file = skillsManifestPath();
|
|
16742
|
+
import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true, mode: 448 });
|
|
16743
|
+
const tmp = `${file}.tmp-${process.pid}`;
|
|
16744
|
+
import_node_fs8.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
|
|
16745
|
+
import_node_fs8.default.renameSync(tmp, file);
|
|
16746
|
+
restrictToOwner(file);
|
|
16747
|
+
} catch (err) {
|
|
16748
|
+
log.warn(
|
|
16749
|
+
"skills",
|
|
16750
|
+
`failed to persist skills manifest (best-effort): ${err instanceof Error ? err.message : String(err)}`
|
|
16751
|
+
);
|
|
16752
|
+
}
|
|
16753
|
+
}
|
|
16754
|
+
function clearSkillsManifest() {
|
|
16755
|
+
try {
|
|
16756
|
+
import_node_fs8.default.rmSync(skillsManifestPath(), { force: true });
|
|
16757
|
+
} catch {
|
|
16758
|
+
}
|
|
16759
|
+
}
|
|
16760
|
+
|
|
16761
|
+
// src/skills/persist-from-payload.ts
|
|
16762
|
+
function persistOrClearSkillsFromPayload(skills) {
|
|
16763
|
+
if (skills && skills.length > 0) persistSkillsManifest({ skills });
|
|
16764
|
+
else clearSkillsManifest();
|
|
16765
|
+
}
|
|
16766
|
+
|
|
16767
|
+
// src/lib/process-guards.ts
|
|
16768
|
+
var installed = false;
|
|
16769
|
+
function installRelayCrashGuards() {
|
|
16770
|
+
if (installed) return;
|
|
16771
|
+
installed = true;
|
|
16772
|
+
process.on("unhandledRejection", (reason) => {
|
|
16773
|
+
log.error("process", `unhandledRejection \u2014 relay kept alive \u2014 ${describeReason(reason)}`);
|
|
16774
|
+
});
|
|
16775
|
+
process.on("uncaughtException", (err) => {
|
|
16776
|
+
log.error("process", `uncaughtException \u2014 relay kept alive \u2014 ${describeReason(err)}`);
|
|
16777
|
+
});
|
|
16778
|
+
}
|
|
16779
|
+
function describeReason(reason) {
|
|
16780
|
+
if (reason instanceof Error) {
|
|
16781
|
+
return reason.stack ?? `${reason.name}: ${reason.message}`;
|
|
16782
|
+
}
|
|
16783
|
+
try {
|
|
16784
|
+
return typeof reason === "string" ? reason : JSON.stringify(reason);
|
|
16785
|
+
} catch {
|
|
16786
|
+
return String(reason);
|
|
16787
|
+
}
|
|
16788
|
+
}
|
|
16789
|
+
|
|
16625
16790
|
// src/commands/host/host-client.ts
|
|
16626
|
-
var
|
|
16627
|
-
var
|
|
16628
|
-
var
|
|
16791
|
+
var fs35 = __toESM(require("fs"));
|
|
16792
|
+
var os31 = __toESM(require("os"));
|
|
16793
|
+
var path39 = __toESM(require("path"));
|
|
16629
16794
|
function sampleCpuTimes() {
|
|
16630
16795
|
let idle = 0;
|
|
16631
16796
|
let total = 0;
|
|
16632
|
-
for (const cpu of
|
|
16797
|
+
for (const cpu of os31.cpus()) {
|
|
16633
16798
|
const t2 = cpu.times;
|
|
16634
16799
|
idle += t2.idle;
|
|
16635
16800
|
total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
|
|
@@ -16648,8 +16813,8 @@ var MetricsCollector = class {
|
|
|
16648
16813
|
const prev = this.prevCpu;
|
|
16649
16814
|
this.prevCpu = current;
|
|
16650
16815
|
if (!prev) {
|
|
16651
|
-
const cores =
|
|
16652
|
-
const proxy =
|
|
16816
|
+
const cores = os31.cpus().length || 1;
|
|
16817
|
+
const proxy = os31.loadavg()[0] / cores * 100;
|
|
16653
16818
|
return Math.min(100, Math.max(0, Math.round(proxy)));
|
|
16654
16819
|
}
|
|
16655
16820
|
const idleDelta = current.idle - prev.idle;
|
|
@@ -16662,8 +16827,8 @@ var MetricsCollector = class {
|
|
|
16662
16827
|
collect() {
|
|
16663
16828
|
return {
|
|
16664
16829
|
cpuPct: this.cpuPct(),
|
|
16665
|
-
ramUsedMb: Math.round((
|
|
16666
|
-
ramTotalMb: Math.round(
|
|
16830
|
+
ramUsedMb: Math.round((os31.totalmem() - os31.freemem()) / 1048576),
|
|
16831
|
+
ramTotalMb: Math.round(os31.totalmem() / 1048576),
|
|
16667
16832
|
latencyMs: this.lastLatencyMs
|
|
16668
16833
|
};
|
|
16669
16834
|
}
|
|
@@ -16672,19 +16837,19 @@ function apiBase() {
|
|
|
16672
16837
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
16673
16838
|
}
|
|
16674
16839
|
function hostIdentityPath() {
|
|
16675
|
-
return
|
|
16840
|
+
return path39.join(os31.homedir(), ".codeam", "host-agent.json");
|
|
16676
16841
|
}
|
|
16677
16842
|
function collectOsInfo() {
|
|
16678
16843
|
return {
|
|
16679
|
-
distro:
|
|
16680
|
-
arch:
|
|
16681
|
-
kernel:
|
|
16844
|
+
distro: os31.platform(),
|
|
16845
|
+
arch: os31.arch(),
|
|
16846
|
+
kernel: os31.release(),
|
|
16682
16847
|
nodeVersion: process.versions.node
|
|
16683
16848
|
};
|
|
16684
16849
|
}
|
|
16685
16850
|
function loadHostIdentity() {
|
|
16686
16851
|
try {
|
|
16687
|
-
const raw =
|
|
16852
|
+
const raw = fs35.readFileSync(hostIdentityPath(), "utf8");
|
|
16688
16853
|
const parsed = JSON.parse(raw);
|
|
16689
16854
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
|
|
16690
16855
|
const p2 = parsed;
|
|
@@ -16697,8 +16862,8 @@ function loadHostIdentity() {
|
|
|
16697
16862
|
}
|
|
16698
16863
|
function saveHostIdentity(identity) {
|
|
16699
16864
|
const file = hostIdentityPath();
|
|
16700
|
-
|
|
16701
|
-
|
|
16865
|
+
fs35.mkdirSync(path39.dirname(file), { recursive: true, mode: 448 });
|
|
16866
|
+
fs35.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
16702
16867
|
encoding: "utf8",
|
|
16703
16868
|
mode: 384
|
|
16704
16869
|
});
|
|
@@ -16743,7 +16908,7 @@ function isTerminalEnrollError(err) {
|
|
|
16743
16908
|
}
|
|
16744
16909
|
function deleteHostIdentity() {
|
|
16745
16910
|
try {
|
|
16746
|
-
|
|
16911
|
+
fs35.rmSync(hostIdentityPath(), { force: true });
|
|
16747
16912
|
} catch {
|
|
16748
16913
|
}
|
|
16749
16914
|
}
|
|
@@ -16767,7 +16932,7 @@ async function postJson(pathname, body) {
|
|
|
16767
16932
|
function resolveHostLabel(label) {
|
|
16768
16933
|
const explicit = label?.trim();
|
|
16769
16934
|
const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
|
|
16770
|
-
const resolved = explicit || envLabel ||
|
|
16935
|
+
const resolved = explicit || envLabel || os31.hostname();
|
|
16771
16936
|
return resolved.slice(0, 80);
|
|
16772
16937
|
}
|
|
16773
16938
|
async function redeemEnrollToken(token, label) {
|
|
@@ -16872,17 +17037,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
|
|
|
16872
17037
|
}
|
|
16873
17038
|
|
|
16874
17039
|
// src/commands/host/workspace.ts
|
|
16875
|
-
var
|
|
16876
|
-
var
|
|
16877
|
-
var
|
|
17040
|
+
var fs36 = __toESM(require("fs"));
|
|
17041
|
+
var os32 = __toESM(require("os"));
|
|
17042
|
+
var path40 = __toESM(require("path"));
|
|
16878
17043
|
var import_node_child_process18 = require("child_process");
|
|
16879
17044
|
var import_node_util4 = require("util");
|
|
16880
17045
|
var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process18.execFile);
|
|
16881
17046
|
function isAbsolutePathTarget(target) {
|
|
16882
|
-
return
|
|
17047
|
+
return path40.isAbsolute(target);
|
|
16883
17048
|
}
|
|
16884
17049
|
function selfHostedWorkspaceRoot() {
|
|
16885
|
-
return
|
|
17050
|
+
return path40.join(os32.homedir(), ".codeam", "self-hosted");
|
|
16886
17051
|
}
|
|
16887
17052
|
function nonInteractiveGitEnv() {
|
|
16888
17053
|
return {
|
|
@@ -16935,13 +17100,13 @@ async function fetchGithubIdentity(token) {
|
|
|
16935
17100
|
async function configureGitCredentials(dest, repoRef, cloneToken) {
|
|
16936
17101
|
const gh = githubOwnerRepo(repoRef.trim());
|
|
16937
17102
|
if (!gh || !cloneToken) return;
|
|
16938
|
-
const credFile =
|
|
16939
|
-
|
|
17103
|
+
const credFile = path40.join(dest, ".git", "codeam-credentials");
|
|
17104
|
+
fs36.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
|
|
16940
17105
|
`, { mode: 384 });
|
|
16941
17106
|
restrictToOwner(credFile);
|
|
16942
17107
|
const env = nonInteractiveGitEnv();
|
|
16943
17108
|
const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
16944
|
-
const credFilePosix = credFile.split(
|
|
17109
|
+
const credFilePosix = credFile.split(path40.sep).join("/");
|
|
16945
17110
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
16946
17111
|
});
|
|
16947
17112
|
await git2([
|
|
@@ -16977,17 +17142,17 @@ function maskToken(text, cloneToken) {
|
|
|
16977
17142
|
}
|
|
16978
17143
|
async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
16979
17144
|
if (isAbsolutePathTarget(repoOrPath)) {
|
|
16980
|
-
if (!
|
|
17145
|
+
if (!fs36.existsSync(repoOrPath)) {
|
|
16981
17146
|
throw new Error(`deploy target path does not exist: ${repoOrPath}`);
|
|
16982
17147
|
}
|
|
16983
17148
|
return repoOrPath;
|
|
16984
17149
|
}
|
|
16985
|
-
const dest =
|
|
16986
|
-
if (
|
|
17150
|
+
const dest = path40.join(selfHostedWorkspaceRoot(), deployId);
|
|
17151
|
+
if (fs36.existsSync(path40.join(dest, ".git"))) {
|
|
16987
17152
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
|
|
16988
17153
|
return dest;
|
|
16989
17154
|
}
|
|
16990
|
-
|
|
17155
|
+
fs36.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
|
|
16991
17156
|
const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
|
|
16992
17157
|
try {
|
|
16993
17158
|
await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
|
|
@@ -17004,9 +17169,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
|
|
|
17004
17169
|
}
|
|
17005
17170
|
|
|
17006
17171
|
// src/commands/host/agent-provisioning.ts
|
|
17007
|
-
var
|
|
17008
|
-
var
|
|
17009
|
-
var
|
|
17172
|
+
var fs37 = __toESM(require("fs"));
|
|
17173
|
+
var os33 = __toESM(require("os"));
|
|
17174
|
+
var path41 = __toESM(require("path"));
|
|
17010
17175
|
var PUBLIC_TO_INTERNAL_AGENT = {
|
|
17011
17176
|
claude_code: "claude",
|
|
17012
17177
|
claude: "claude",
|
|
@@ -17022,22 +17187,22 @@ function toInternalAgentId(publicAgentId) {
|
|
|
17022
17187
|
return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
|
|
17023
17188
|
}
|
|
17024
17189
|
function ensureDir(dir) {
|
|
17025
|
-
|
|
17190
|
+
fs37.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
17026
17191
|
}
|
|
17027
17192
|
function writeFile0600(filePath, contents) {
|
|
17028
|
-
ensureDir(
|
|
17029
|
-
|
|
17193
|
+
ensureDir(path41.dirname(filePath));
|
|
17194
|
+
fs37.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
|
|
17030
17195
|
restrictToOwner(filePath);
|
|
17031
17196
|
}
|
|
17032
17197
|
function rmIfExists(filePath) {
|
|
17033
17198
|
try {
|
|
17034
|
-
|
|
17199
|
+
fs37.rmSync(filePath, { force: true });
|
|
17035
17200
|
} catch {
|
|
17036
17201
|
}
|
|
17037
17202
|
}
|
|
17038
17203
|
var claudeProvisioner = {
|
|
17039
17204
|
write(auth, home) {
|
|
17040
|
-
const credentialsJson =
|
|
17205
|
+
const credentialsJson = path41.join(home, ".claude", ".credentials.json");
|
|
17041
17206
|
if (auth.kind === "api_key") {
|
|
17042
17207
|
rmIfExists(credentialsJson);
|
|
17043
17208
|
return { ANTHROPIC_API_KEY: auth.value };
|
|
@@ -17049,8 +17214,8 @@ var claudeProvisioner = {
|
|
|
17049
17214
|
} else {
|
|
17050
17215
|
rmIfExists(credentialsJson);
|
|
17051
17216
|
}
|
|
17052
|
-
const claudeJson =
|
|
17053
|
-
if (!
|
|
17217
|
+
const claudeJson = path41.join(home, ".claude.json");
|
|
17218
|
+
if (!fs37.existsSync(claudeJson)) {
|
|
17054
17219
|
writeFile0600(
|
|
17055
17220
|
claudeJson,
|
|
17056
17221
|
JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
|
|
@@ -17061,7 +17226,7 @@ var claudeProvisioner = {
|
|
|
17061
17226
|
};
|
|
17062
17227
|
var codexProvisioner = {
|
|
17063
17228
|
write(auth, home) {
|
|
17064
|
-
const authJson =
|
|
17229
|
+
const authJson = path41.join(home, ".codex", "auth.json");
|
|
17065
17230
|
if (auth.kind === "api_key") {
|
|
17066
17231
|
rmIfExists(authJson);
|
|
17067
17232
|
return { OPENAI_API_KEY: auth.value };
|
|
@@ -17072,8 +17237,8 @@ var codexProvisioner = {
|
|
|
17072
17237
|
};
|
|
17073
17238
|
var geminiProvisioner = {
|
|
17074
17239
|
write(auth, home) {
|
|
17075
|
-
const settingsJson =
|
|
17076
|
-
const oauthCreds =
|
|
17240
|
+
const settingsJson = path41.join(home, ".gemini", "settings.json");
|
|
17241
|
+
const oauthCreds = path41.join(home, ".gemini", "oauth_creds.json");
|
|
17077
17242
|
if (auth.kind === "api_key") {
|
|
17078
17243
|
rmIfExists(oauthCreds);
|
|
17079
17244
|
writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
|
|
@@ -17086,7 +17251,7 @@ var geminiProvisioner = {
|
|
|
17086
17251
|
};
|
|
17087
17252
|
var cursorProvisioner = {
|
|
17088
17253
|
write(auth, home) {
|
|
17089
|
-
const authJson =
|
|
17254
|
+
const authJson = path41.join(home, ".config", "cursor", "auth.json");
|
|
17090
17255
|
if (auth.kind === "api_key") {
|
|
17091
17256
|
rmIfExists(authJson);
|
|
17092
17257
|
return { CURSOR_API_KEY: auth.value };
|
|
@@ -17128,22 +17293,22 @@ max_context_size = 262144
|
|
|
17128
17293
|
var kimiProvisioner = {
|
|
17129
17294
|
write(auth, home) {
|
|
17130
17295
|
const credentialsFiles = [
|
|
17131
|
-
|
|
17132
|
-
|
|
17296
|
+
path41.join(home, ".kimi", "credentials", "kimi-code.json"),
|
|
17297
|
+
path41.join(home, ".kimi-code", "credentials", "kimi-code.json")
|
|
17133
17298
|
];
|
|
17134
17299
|
if (auth.kind === "api_key") {
|
|
17135
17300
|
credentialsFiles.forEach(rmIfExists);
|
|
17136
17301
|
return { KIMI_API_KEY: auth.value };
|
|
17137
17302
|
}
|
|
17138
17303
|
credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
|
|
17139
|
-
writeFile0600(
|
|
17304
|
+
writeFile0600(path41.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
|
|
17140
17305
|
return {};
|
|
17141
17306
|
}
|
|
17142
17307
|
};
|
|
17143
17308
|
var coderabbitProvisioner = {
|
|
17144
17309
|
write(auth, home) {
|
|
17145
|
-
const dir =
|
|
17146
|
-
const authJson =
|
|
17310
|
+
const dir = path41.join(home, ".coderabbit");
|
|
17311
|
+
const authJson = path41.join(dir, "auth.json");
|
|
17147
17312
|
if (auth.kind === "api_key") {
|
|
17148
17313
|
rmIfExists(authJson);
|
|
17149
17314
|
return { CODERABBIT_API_KEY: auth.value };
|
|
@@ -17155,13 +17320,13 @@ var coderabbitProvisioner = {
|
|
|
17155
17320
|
try {
|
|
17156
17321
|
const parsed = JSON.parse(value);
|
|
17157
17322
|
if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
|
|
17158
|
-
file =
|
|
17323
|
+
file = path41.basename(parsed.file);
|
|
17159
17324
|
contents = parsed.contents;
|
|
17160
17325
|
}
|
|
17161
17326
|
} catch {
|
|
17162
17327
|
}
|
|
17163
17328
|
}
|
|
17164
|
-
writeFile0600(
|
|
17329
|
+
writeFile0600(path41.join(dir, file), contents);
|
|
17165
17330
|
return {};
|
|
17166
17331
|
}
|
|
17167
17332
|
};
|
|
@@ -17181,7 +17346,7 @@ var UnsupportedAgentError = class extends Error {
|
|
|
17181
17346
|
this.agentId = agentId;
|
|
17182
17347
|
}
|
|
17183
17348
|
};
|
|
17184
|
-
function provisionAgentCredentials(publicAgentId, auth, homeDir2 =
|
|
17349
|
+
function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os33.homedir()) {
|
|
17185
17350
|
const internal = toInternalAgentId(publicAgentId);
|
|
17186
17351
|
if (!internal) throw new UnsupportedAgentError(publicAgentId);
|
|
17187
17352
|
const provisioner = PROVISIONERS[internal];
|
|
@@ -17191,11 +17356,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os32.homedir(
|
|
|
17191
17356
|
|
|
17192
17357
|
// src/commands/host/git-tooling.ts
|
|
17193
17358
|
var import_node_child_process19 = require("child_process");
|
|
17194
|
-
var
|
|
17195
|
-
var
|
|
17196
|
-
var
|
|
17359
|
+
var fs38 = __toESM(require("fs"));
|
|
17360
|
+
var os34 = __toESM(require("os"));
|
|
17361
|
+
var path42 = __toESM(require("path"));
|
|
17197
17362
|
function codeamBinDir() {
|
|
17198
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
17363
|
+
return process.env.CODEAM_BIN_DIR ?? path42.join(os34.homedir(), ".codeam", "bin");
|
|
17199
17364
|
}
|
|
17200
17365
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
17201
17366
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -17227,7 +17392,7 @@ async function download(url2, dest) {
|
|
|
17227
17392
|
const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
|
|
17228
17393
|
if (!res.ok || !res.body) return false;
|
|
17229
17394
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
17230
|
-
|
|
17395
|
+
fs38.writeFileSync(dest, buf);
|
|
17231
17396
|
return true;
|
|
17232
17397
|
} catch {
|
|
17233
17398
|
return false;
|
|
@@ -17250,8 +17415,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
17250
17415
|
const version3 = await resolveVersionFn(token);
|
|
17251
17416
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
17252
17417
|
const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
17253
|
-
const tmpRoot =
|
|
17254
|
-
const archive =
|
|
17418
|
+
const tmpRoot = fs38.mkdtempSync(path42.join(os34.tmpdir(), "codeam-gh-"));
|
|
17419
|
+
const archive = path42.join(tmpRoot, `${asset}.${ext}`);
|
|
17255
17420
|
if (!await downloadFn(url2, archive)) {
|
|
17256
17421
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
17257
17422
|
return null;
|
|
@@ -17261,16 +17426,16 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
17261
17426
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
17262
17427
|
return null;
|
|
17263
17428
|
}
|
|
17264
|
-
const extractedBin =
|
|
17265
|
-
if (!
|
|
17429
|
+
const extractedBin = path42.join(tmpRoot, asset, "bin", binaryName);
|
|
17430
|
+
if (!fs38.existsSync(extractedBin)) {
|
|
17266
17431
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
17267
17432
|
return null;
|
|
17268
17433
|
}
|
|
17269
17434
|
const binDir = codeamBinDir();
|
|
17270
|
-
|
|
17271
|
-
const target =
|
|
17272
|
-
|
|
17273
|
-
|
|
17435
|
+
fs38.mkdirSync(binDir, { recursive: true });
|
|
17436
|
+
const target = path42.join(binDir, binaryName);
|
|
17437
|
+
fs38.copyFileSync(extractedBin, target);
|
|
17438
|
+
fs38.chmodSync(target, 493);
|
|
17274
17439
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
17275
17440
|
return target;
|
|
17276
17441
|
} catch (e) {
|
|
@@ -17757,23 +17922,23 @@ async function ensureModernPython(runner) {
|
|
|
17757
17922
|
}
|
|
17758
17923
|
|
|
17759
17924
|
// src/commands/host/headroom-bootstrap.ts
|
|
17760
|
-
var
|
|
17761
|
-
var
|
|
17925
|
+
var fs40 = __toESM(require("fs"));
|
|
17926
|
+
var path44 = __toESM(require("path"));
|
|
17762
17927
|
|
|
17763
17928
|
// src/commands/host/headroom-config.ts
|
|
17764
|
-
var
|
|
17765
|
-
var
|
|
17766
|
-
var
|
|
17929
|
+
var fs39 = __toESM(require("fs"));
|
|
17930
|
+
var os35 = __toESM(require("os"));
|
|
17931
|
+
var path43 = __toESM(require("path"));
|
|
17767
17932
|
function headroomConfigPath() {
|
|
17768
|
-
return
|
|
17933
|
+
return path43.join(os35.homedir(), ".codeam", "headroom-config.json");
|
|
17769
17934
|
}
|
|
17770
17935
|
function persistHeadroomConfig(config) {
|
|
17771
17936
|
try {
|
|
17772
17937
|
const file = headroomConfigPath();
|
|
17773
|
-
|
|
17938
|
+
fs39.mkdirSync(path43.dirname(file), { recursive: true, mode: 448 });
|
|
17774
17939
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
17775
|
-
|
|
17776
|
-
|
|
17940
|
+
fs39.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
|
|
17941
|
+
fs39.renameSync(tmp, file);
|
|
17777
17942
|
restrictToOwner(file);
|
|
17778
17943
|
} catch (err) {
|
|
17779
17944
|
log.warn(
|
|
@@ -17783,21 +17948,21 @@ function persistHeadroomConfig(config) {
|
|
|
17783
17948
|
}
|
|
17784
17949
|
}
|
|
17785
17950
|
function agentSettingsPath(kind) {
|
|
17786
|
-
const home =
|
|
17787
|
-
if (kind === "claude") return
|
|
17788
|
-
if (kind === "codex") return
|
|
17789
|
-
if (kind === "copilot") return
|
|
17951
|
+
const home = os35.homedir();
|
|
17952
|
+
if (kind === "claude") return path43.join(home, ".claude", "settings.json");
|
|
17953
|
+
if (kind === "codex") return path43.join(home, ".codex", "auth.json");
|
|
17954
|
+
if (kind === "copilot") return path43.join(home, ".config", "github-copilot", "hosts.json");
|
|
17790
17955
|
return null;
|
|
17791
17956
|
}
|
|
17792
17957
|
function backupAgentHeadroomConfig(kind) {
|
|
17793
17958
|
const src = agentSettingsPath(kind);
|
|
17794
17959
|
if (!src) return;
|
|
17795
17960
|
try {
|
|
17796
|
-
if (!
|
|
17797
|
-
const dest =
|
|
17798
|
-
|
|
17799
|
-
|
|
17800
|
-
|
|
17961
|
+
if (!fs39.existsSync(src)) return;
|
|
17962
|
+
const dest = path43.join(os35.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
17963
|
+
fs39.mkdirSync(path43.dirname(dest), { recursive: true, mode: 448 });
|
|
17964
|
+
fs39.copyFileSync(src, dest);
|
|
17965
|
+
fs39.chmodSync(dest, 384);
|
|
17801
17966
|
log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
|
|
17802
17967
|
} catch (err) {
|
|
17803
17968
|
log.warn(
|
|
@@ -17809,12 +17974,12 @@ function backupAgentHeadroomConfig(kind) {
|
|
|
17809
17974
|
function restoreAgentHeadroomConfig(kind) {
|
|
17810
17975
|
const dest = agentSettingsPath(kind);
|
|
17811
17976
|
if (!dest) return false;
|
|
17812
|
-
const src =
|
|
17813
|
-
if (!
|
|
17977
|
+
const src = path43.join(os35.homedir(), ".codeam", `headroom-backup-${kind}.json`);
|
|
17978
|
+
if (!fs39.existsSync(src)) return false;
|
|
17814
17979
|
try {
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17980
|
+
fs39.mkdirSync(path43.dirname(dest), { recursive: true, mode: 448 });
|
|
17981
|
+
fs39.copyFileSync(src, dest);
|
|
17982
|
+
fs39.chmodSync(dest, 384);
|
|
17818
17983
|
log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
|
|
17819
17984
|
return true;
|
|
17820
17985
|
} catch (err) {
|
|
@@ -17827,7 +17992,7 @@ function restoreAgentHeadroomConfig(kind) {
|
|
|
17827
17992
|
}
|
|
17828
17993
|
function readHeadroomChildEnv() {
|
|
17829
17994
|
try {
|
|
17830
|
-
const raw =
|
|
17995
|
+
const raw = fs39.readFileSync(headroomConfigPath(), "utf8");
|
|
17831
17996
|
const parsed = JSON.parse(raw);
|
|
17832
17997
|
if (typeof parsed !== "object" || parsed === null) return {};
|
|
17833
17998
|
const o = parsed;
|
|
@@ -17863,37 +18028,37 @@ function bundledClaudeBinDir() {
|
|
|
17863
18028
|
const roots = /* @__PURE__ */ new Set();
|
|
17864
18029
|
let dir = __dirname;
|
|
17865
18030
|
for (let i = 0; i < 6; i++) {
|
|
17866
|
-
roots.add(
|
|
17867
|
-
const parent =
|
|
18031
|
+
roots.add(path44.join(dir, "node_modules"));
|
|
18032
|
+
const parent = path44.dirname(dir);
|
|
17868
18033
|
if (parent === dir) break;
|
|
17869
18034
|
dir = parent;
|
|
17870
18035
|
}
|
|
17871
18036
|
try {
|
|
17872
18037
|
const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
17873
|
-
const marker = `${
|
|
18038
|
+
const marker = `${path44.sep}@anthropic-ai${path44.sep}`;
|
|
17874
18039
|
const idx = main2.lastIndexOf(marker);
|
|
17875
18040
|
if (idx !== -1) roots.add(main2.slice(0, idx));
|
|
17876
18041
|
} catch {
|
|
17877
18042
|
}
|
|
17878
18043
|
for (const nm of roots) {
|
|
17879
|
-
const atAnthropic =
|
|
18044
|
+
const atAnthropic = path44.join(nm, "@anthropic-ai");
|
|
17880
18045
|
let entries;
|
|
17881
18046
|
try {
|
|
17882
|
-
entries =
|
|
18047
|
+
entries = fs40.readdirSync(atAnthropic);
|
|
17883
18048
|
} catch {
|
|
17884
18049
|
continue;
|
|
17885
18050
|
}
|
|
17886
18051
|
for (const entry of entries) {
|
|
17887
18052
|
if (!entry.startsWith("claude-agent-sdk-")) continue;
|
|
17888
|
-
const bin =
|
|
17889
|
-
if (
|
|
18053
|
+
const bin = path44.join(atAnthropic, entry, "claude");
|
|
18054
|
+
if (fs40.existsSync(bin)) return path44.dirname(bin);
|
|
17890
18055
|
}
|
|
17891
18056
|
}
|
|
17892
18057
|
return null;
|
|
17893
18058
|
}
|
|
17894
18059
|
async function getFreeDiskBytes(dir) {
|
|
17895
18060
|
try {
|
|
17896
|
-
const s = await
|
|
18061
|
+
const s = await fs40.promises.statfs(dir);
|
|
17897
18062
|
return s.bsize * s.bavail;
|
|
17898
18063
|
} catch {
|
|
17899
18064
|
return null;
|
|
@@ -17955,7 +18120,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17955
18120
|
if (initKind === "claude") {
|
|
17956
18121
|
const claudeDir = bundledClaudeBinDir();
|
|
17957
18122
|
if (claudeDir) {
|
|
17958
|
-
initEnv.PATH = `${claudeDir}${
|
|
18123
|
+
initEnv.PATH = `${claudeDir}${path44.delimiter}${process.env["PATH"] ?? ""}`;
|
|
17959
18124
|
log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
|
|
17960
18125
|
} else {
|
|
17961
18126
|
log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
|
|
@@ -17990,9 +18155,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
|
|
|
17990
18155
|
var import_node_child_process22 = require("child_process");
|
|
17991
18156
|
|
|
17992
18157
|
// src/lib/updateNotifier.ts
|
|
17993
|
-
var
|
|
17994
|
-
var
|
|
17995
|
-
var
|
|
18158
|
+
var fs41 = __toESM(require("fs"));
|
|
18159
|
+
var os36 = __toESM(require("os"));
|
|
18160
|
+
var path45 = __toESM(require("path"));
|
|
17996
18161
|
var https6 = __toESM(require("https"));
|
|
17997
18162
|
var import_node_child_process21 = require("child_process");
|
|
17998
18163
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -18001,12 +18166,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
18001
18166
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
18002
18167
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
18003
18168
|
function cachePath() {
|
|
18004
|
-
const dir =
|
|
18005
|
-
return
|
|
18169
|
+
const dir = path45.join(os36.homedir(), ".codeam");
|
|
18170
|
+
return path45.join(dir, "update-check.json");
|
|
18006
18171
|
}
|
|
18007
18172
|
function readCache() {
|
|
18008
18173
|
try {
|
|
18009
|
-
const raw =
|
|
18174
|
+
const raw = fs41.readFileSync(cachePath(), "utf8");
|
|
18010
18175
|
const parsed = JSON.parse(raw);
|
|
18011
18176
|
if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
|
|
18012
18177
|
return parsed;
|
|
@@ -18017,10 +18182,10 @@ function readCache() {
|
|
|
18017
18182
|
function writeCache(cache) {
|
|
18018
18183
|
try {
|
|
18019
18184
|
const file = cachePath();
|
|
18020
|
-
|
|
18185
|
+
fs41.mkdirSync(path45.dirname(file), { recursive: true });
|
|
18021
18186
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
18022
|
-
|
|
18023
|
-
|
|
18187
|
+
fs41.writeFileSync(tmp, JSON.stringify(cache));
|
|
18188
|
+
fs41.renameSync(tmp, file);
|
|
18024
18189
|
} catch {
|
|
18025
18190
|
}
|
|
18026
18191
|
}
|
|
@@ -18094,8 +18259,8 @@ function isLinkedInstall() {
|
|
|
18094
18259
|
timeout: 2e3
|
|
18095
18260
|
}).trim();
|
|
18096
18261
|
if (!root) return false;
|
|
18097
|
-
const pkgPath =
|
|
18098
|
-
return
|
|
18262
|
+
const pkgPath = path45.join(root, PKG_NAME);
|
|
18263
|
+
return fs41.lstatSync(pkgPath).isSymbolicLink();
|
|
18099
18264
|
} catch {
|
|
18100
18265
|
return false;
|
|
18101
18266
|
}
|
|
@@ -18131,7 +18296,7 @@ function maybeAutoUpdate(currentVersion, latest) {
|
|
|
18131
18296
|
return;
|
|
18132
18297
|
}
|
|
18133
18298
|
try {
|
|
18134
|
-
|
|
18299
|
+
fs41.unlinkSync(cachePath());
|
|
18135
18300
|
} catch {
|
|
18136
18301
|
}
|
|
18137
18302
|
process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
|
|
@@ -18147,7 +18312,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
18147
18312
|
if (process.env.NODE_ENV === "test") return;
|
|
18148
18313
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18149
18314
|
if (process.env.CI) return;
|
|
18150
|
-
const current = true ? "2.61.
|
|
18315
|
+
const current = true ? "2.61.24" : null;
|
|
18151
18316
|
if (!current) return;
|
|
18152
18317
|
const cache = readCache();
|
|
18153
18318
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18164,7 +18329,7 @@ function checkForUpdates() {
|
|
|
18164
18329
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
18165
18330
|
if (process.env.CI) return;
|
|
18166
18331
|
if (!process.stdout.isTTY) return;
|
|
18167
|
-
const current = true ? "2.61.
|
|
18332
|
+
const current = true ? "2.61.24" : null;
|
|
18168
18333
|
if (!current) return;
|
|
18169
18334
|
const cache = readCache();
|
|
18170
18335
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -18184,7 +18349,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
|
18184
18349
|
var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
|
|
18185
18350
|
var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
18186
18351
|
function currentCliVersion() {
|
|
18187
|
-
return true ? "2.61.
|
|
18352
|
+
return true ? "2.61.24" : null;
|
|
18188
18353
|
}
|
|
18189
18354
|
function runCmd(cmd, args2, timeoutMs) {
|
|
18190
18355
|
return new Promise((resolve8) => {
|
|
@@ -18251,7 +18416,7 @@ async function runSelfUpdate() {
|
|
|
18251
18416
|
|
|
18252
18417
|
// src/commands/host/teardown.ts
|
|
18253
18418
|
var import_node_child_process23 = require("child_process");
|
|
18254
|
-
var
|
|
18419
|
+
var fs42 = __toESM(require("fs"));
|
|
18255
18420
|
var defaultDisableService = () => {
|
|
18256
18421
|
try {
|
|
18257
18422
|
(0, import_node_child_process23.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
|
|
@@ -18260,7 +18425,7 @@ var defaultDisableService = () => {
|
|
|
18260
18425
|
};
|
|
18261
18426
|
var defaultTeardownHeadroom = () => {
|
|
18262
18427
|
try {
|
|
18263
|
-
const kind = JSON.parse(
|
|
18428
|
+
const kind = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8")).agent;
|
|
18264
18429
|
if (kind) {
|
|
18265
18430
|
(0, import_node_child_process23.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
|
|
18266
18431
|
}
|
|
@@ -18328,8 +18493,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
|
|
|
18328
18493
|
if (process.env["HEADROOM_ENABLED"] === "1") return null;
|
|
18329
18494
|
try {
|
|
18330
18495
|
const file = headroomConfigPath();
|
|
18331
|
-
if (!
|
|
18332
|
-
const cfg = JSON.parse(
|
|
18496
|
+
if (!fs43.existsSync(file)) return null;
|
|
18497
|
+
const cfg = JSON.parse(fs43.readFileSync(file, "utf8"));
|
|
18333
18498
|
if (!cfg?.enabled) return null;
|
|
18334
18499
|
const agent = cfg.agent ?? "claude";
|
|
18335
18500
|
const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
|
|
@@ -18511,8 +18676,12 @@ var defaultResumeSpawner = (env, cwd) => (0, import_node_child_process24.spawn)(
|
|
|
18511
18676
|
detached: false
|
|
18512
18677
|
});
|
|
18513
18678
|
var defaultOnIdentityRejected = () => {
|
|
18679
|
+
defaultDisableService();
|
|
18514
18680
|
deleteHostIdentity();
|
|
18515
|
-
log.warn(
|
|
18681
|
+
log.warn(
|
|
18682
|
+
"host-agent",
|
|
18683
|
+
"host identity rejected by backend \u2014 disabled service + wiped sealed identity, exiting"
|
|
18684
|
+
);
|
|
18516
18685
|
process.exit(1);
|
|
18517
18686
|
};
|
|
18518
18687
|
var defaultOnUpdated = (version3) => {
|
|
@@ -18830,13 +18999,13 @@ var HostAgentSupervisor = class {
|
|
|
18830
18999
|
const relay = this.relay;
|
|
18831
19000
|
if (!relay) return;
|
|
18832
19001
|
const raw = cmd.payload?.path;
|
|
18833
|
-
const target = typeof raw === "string" && raw.trim() ?
|
|
19002
|
+
const target = typeof raw === "string" && raw.trim() ? path46.resolve(raw.trim()) : os37.homedir();
|
|
18834
19003
|
try {
|
|
18835
|
-
const dirents = await
|
|
19004
|
+
const dirents = await fs43.promises.readdir(target, { withFileTypes: true });
|
|
18836
19005
|
const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
|
|
18837
19006
|
(a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
|
|
18838
19007
|
);
|
|
18839
|
-
const parent =
|
|
19008
|
+
const parent = path46.dirname(target);
|
|
18840
19009
|
await relay.sendResult(cmd.id, "completed", {
|
|
18841
19010
|
path: target,
|
|
18842
19011
|
// null at the filesystem root so the UI can hide the ".." affordance.
|
|
@@ -18931,10 +19100,13 @@ var HostAgentSupervisor = class {
|
|
|
18931
19100
|
"CODEAM_HOST_LABEL=CodeAgent Box",
|
|
18932
19101
|
// The enroll token above is a SINGLE-USE bootstrap, but it lives in the
|
|
18933
19102
|
// container's fixed env — it can't be stripped after first boot like the
|
|
18934
|
-
// self-hosted systemd unit does
|
|
18935
|
-
//
|
|
18936
|
-
//
|
|
18937
|
-
//
|
|
19103
|
+
// self-hosted systemd unit does, so on every restart (docker restart /
|
|
19104
|
+
// reboot / fleet_start_box wake) the redeem terminally expires.
|
|
19105
|
+
// `resolveHostIdentity` now resumes from a sealed identity on ANY
|
|
19106
|
+
// terminal enroll-token rejection (not just ephemeral boxes — see its
|
|
19107
|
+
// doc comment), so this flag is no longer load-bearing for that
|
|
19108
|
+
// decision; kept set for observability/back-compat with older CLI
|
|
19109
|
+
// builds that still gate on it. Not a secret → plain KEY=value.
|
|
18938
19110
|
"-e",
|
|
18939
19111
|
"CODEAM_ENROLL_EPHEMERAL=1",
|
|
18940
19112
|
image
|
|
@@ -19049,9 +19221,9 @@ var HostAgentSupervisor = class {
|
|
|
19049
19221
|
API_TIMEOUT_MS: "3000000",
|
|
19050
19222
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
19051
19223
|
};
|
|
19052
|
-
const houseConfigDir =
|
|
19224
|
+
const houseConfigDir = path46.join(os37.homedir(), ".codeam", "house-claude");
|
|
19053
19225
|
try {
|
|
19054
|
-
|
|
19226
|
+
fs43.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
|
|
19055
19227
|
} catch {
|
|
19056
19228
|
}
|
|
19057
19229
|
childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
|
|
@@ -19069,14 +19241,14 @@ var HostAgentSupervisor = class {
|
|
|
19069
19241
|
report("installing", "installing agent CLI");
|
|
19070
19242
|
await this.runAgentInstall(payload.agentInstallScript);
|
|
19071
19243
|
}
|
|
19072
|
-
const home = process.env.HOME ||
|
|
19244
|
+
const home = process.env.HOME || os37.homedir();
|
|
19073
19245
|
childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
|
|
19074
19246
|
if (payload.cloneToken) {
|
|
19075
19247
|
try {
|
|
19076
19248
|
report("preparing", "configuring git tooling");
|
|
19077
19249
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
19078
19250
|
if (ghCmd) {
|
|
19079
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
19251
|
+
childEnv.PATH = `${codeamBinDir()}${path46.delimiter}${childEnv.PATH}`;
|
|
19080
19252
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
19081
19253
|
}
|
|
19082
19254
|
} catch (e) {
|
|
@@ -19092,7 +19264,7 @@ var HostAgentSupervisor = class {
|
|
|
19092
19264
|
}
|
|
19093
19265
|
if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
|
|
19094
19266
|
report("headroom", "setting up Headroom proxy");
|
|
19095
|
-
const freeBytes = await this.getFreeDisk(
|
|
19267
|
+
const freeBytes = await this.getFreeDisk(os37.homedir());
|
|
19096
19268
|
const alreadyInstalled = this.isHeadroomInstalled();
|
|
19097
19269
|
if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
|
|
19098
19270
|
const freeGb = (freeBytes / 1e9).toFixed(1);
|
|
@@ -19146,6 +19318,9 @@ var HostAgentSupervisor = class {
|
|
|
19146
19318
|
} else {
|
|
19147
19319
|
clearIntegrationsManifest();
|
|
19148
19320
|
}
|
|
19321
|
+
persistOrClearSkillsFromPayload(
|
|
19322
|
+
payload.skills
|
|
19323
|
+
);
|
|
19149
19324
|
report("spawning", "starting agent");
|
|
19150
19325
|
const proc = this.spawnSessionChild(childEnv, cwd, extraArgs);
|
|
19151
19326
|
const child = {
|
|
@@ -19273,7 +19448,7 @@ var HostAgentSupervisor = class {
|
|
|
19273
19448
|
*/
|
|
19274
19449
|
runAgentInstall(script) {
|
|
19275
19450
|
return new Promise((resolve8) => {
|
|
19276
|
-
const home = process.env.HOME ||
|
|
19451
|
+
const home = process.env.HOME || os37.homedir();
|
|
19277
19452
|
const child = (0, import_node_child_process24.spawn)("sh", ["-c", script], {
|
|
19278
19453
|
env: { ...process.env, HOME: home },
|
|
19279
19454
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -19378,10 +19553,10 @@ async function resolveHostIdentity(enrollToken) {
|
|
|
19378
19553
|
return identity;
|
|
19379
19554
|
} catch (err) {
|
|
19380
19555
|
if (isTerminalEnrollError(err)) {
|
|
19381
|
-
if (existing
|
|
19556
|
+
if (existing) {
|
|
19382
19557
|
log.info(
|
|
19383
19558
|
"host-agent",
|
|
19384
|
-
"
|
|
19559
|
+
"enroll token terminally rejected (expired/replayed) but a sealed identity is present; resuming from it \u2014 likely a restart, not a re-enroll"
|
|
19385
19560
|
);
|
|
19386
19561
|
return existing;
|
|
19387
19562
|
}
|
|
@@ -19405,6 +19580,7 @@ async function resolveHostIdentity(enrollToken) {
|
|
|
19405
19580
|
return null;
|
|
19406
19581
|
}
|
|
19407
19582
|
async function hostAgent(args2 = []) {
|
|
19583
|
+
installRelayCrashGuards();
|
|
19408
19584
|
const tokenArg = args2.find((a) => a.startsWith("--token="));
|
|
19409
19585
|
const enrollToken = (tokenArg ? tokenArg.slice("--token=".length).trim() : "") || process.env.CODEAM_ENROLL_TOKEN || void 0;
|
|
19410
19586
|
const identity = await resolveHostIdentity(enrollToken);
|
|
@@ -19464,9 +19640,9 @@ async function configureHeadroom(action, ctx, deps) {
|
|
|
19464
19640
|
}
|
|
19465
19641
|
|
|
19466
19642
|
// src/services/headroom/budget-relaunch.ts
|
|
19467
|
-
var
|
|
19468
|
-
var
|
|
19469
|
-
var
|
|
19643
|
+
var fs44 = __toESM(require("fs"));
|
|
19644
|
+
var os38 = __toESM(require("os"));
|
|
19645
|
+
var path47 = __toESM(require("path"));
|
|
19470
19646
|
var import_child_process13 = require("child_process");
|
|
19471
19647
|
function amendDeploymentManifestBudget(manifest, budget) {
|
|
19472
19648
|
const rawArgs = manifest.proxy_args ?? [];
|
|
@@ -19500,7 +19676,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
|
|
|
19500
19676
|
return { ...manifest, proxy_args: newArgs, base_env: newEnv };
|
|
19501
19677
|
}
|
|
19502
19678
|
function findHeadroomDeployments(homeDir2, deps) {
|
|
19503
|
-
const deployDir =
|
|
19679
|
+
const deployDir = path47.join(homeDir2, ".headroom", "deploy");
|
|
19504
19680
|
let profiles;
|
|
19505
19681
|
try {
|
|
19506
19682
|
profiles = deps.readDir(deployDir);
|
|
@@ -19509,7 +19685,7 @@ function findHeadroomDeployments(homeDir2, deps) {
|
|
|
19509
19685
|
}
|
|
19510
19686
|
const results = [];
|
|
19511
19687
|
for (const profile of profiles) {
|
|
19512
|
-
const manifestPath =
|
|
19688
|
+
const manifestPath = path47.join(deployDir, profile, "manifest.json");
|
|
19513
19689
|
let raw;
|
|
19514
19690
|
try {
|
|
19515
19691
|
raw = deps.readJson(manifestPath);
|
|
@@ -19541,8 +19717,8 @@ async function applyBudgetToHeadroom(budget, deps) {
|
|
|
19541
19717
|
}
|
|
19542
19718
|
function writeManifestReal(manifestPath, manifest) {
|
|
19543
19719
|
const tmp = manifestPath + ".codeam.tmp";
|
|
19544
|
-
|
|
19545
|
-
|
|
19720
|
+
fs44.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
|
|
19721
|
+
fs44.renameSync(tmp, manifestPath);
|
|
19546
19722
|
}
|
|
19547
19723
|
function restartDeploymentReal(profile) {
|
|
19548
19724
|
try {
|
|
@@ -19572,11 +19748,11 @@ function spawnProxyReal2(_budget) {
|
|
|
19572
19748
|
});
|
|
19573
19749
|
}
|
|
19574
19750
|
function makeRealApplyBudgetDeps() {
|
|
19575
|
-
const homeDir2 =
|
|
19751
|
+
const homeDir2 = os38.homedir();
|
|
19576
19752
|
return {
|
|
19577
19753
|
findDeployments: () => findHeadroomDeployments(homeDir2, {
|
|
19578
|
-
readDir: (dir) =>
|
|
19579
|
-
readJson: (filePath) => JSON.parse(
|
|
19754
|
+
readDir: (dir) => fs44.readdirSync(dir),
|
|
19755
|
+
readJson: (filePath) => JSON.parse(fs44.readFileSync(filePath, "utf8"))
|
|
19580
19756
|
}),
|
|
19581
19757
|
writeManifest: writeManifestReal,
|
|
19582
19758
|
restartDeployment: restartDeploymentReal,
|
|
@@ -19586,16 +19762,16 @@ function makeRealApplyBudgetDeps() {
|
|
|
19586
19762
|
}
|
|
19587
19763
|
|
|
19588
19764
|
// src/services/preview/port-registry.ts
|
|
19589
|
-
var
|
|
19590
|
-
var
|
|
19591
|
-
var
|
|
19765
|
+
var fs45 = __toESM(require("fs"));
|
|
19766
|
+
var os39 = __toESM(require("os"));
|
|
19767
|
+
var path48 = __toESM(require("path"));
|
|
19592
19768
|
var import_child_process14 = require("child_process");
|
|
19593
19769
|
function registryPath() {
|
|
19594
|
-
return
|
|
19770
|
+
return path48.join(os39.homedir(), ".codeam", "preview-ports.json");
|
|
19595
19771
|
}
|
|
19596
19772
|
function readRegistry() {
|
|
19597
19773
|
try {
|
|
19598
|
-
const raw =
|
|
19774
|
+
const raw = fs45.readFileSync(registryPath(), "utf8");
|
|
19599
19775
|
const parsed = JSON.parse(raw);
|
|
19600
19776
|
if (parsed && typeof parsed === "object") return parsed;
|
|
19601
19777
|
} catch {
|
|
@@ -19605,10 +19781,10 @@ function readRegistry() {
|
|
|
19605
19781
|
function writeRegistry(reg) {
|
|
19606
19782
|
try {
|
|
19607
19783
|
const file = registryPath();
|
|
19608
|
-
|
|
19784
|
+
fs45.mkdirSync(path48.dirname(file), { recursive: true });
|
|
19609
19785
|
const tmp = `${file}.tmp`;
|
|
19610
|
-
|
|
19611
|
-
|
|
19786
|
+
fs45.writeFileSync(tmp, JSON.stringify(reg), "utf8");
|
|
19787
|
+
fs45.renameSync(tmp, file);
|
|
19612
19788
|
} catch (err) {
|
|
19613
19789
|
log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
19614
19790
|
}
|
|
@@ -20344,8 +20520,8 @@ function activePreviewSessionIds() {
|
|
|
20344
20520
|
|
|
20345
20521
|
// src/services/preview/start-orchestrator.ts
|
|
20346
20522
|
var import_child_process18 = require("child_process");
|
|
20347
|
-
var
|
|
20348
|
-
var
|
|
20523
|
+
var fs50 = __toESM(require("fs"));
|
|
20524
|
+
var path53 = __toESM(require("path"));
|
|
20349
20525
|
var import_which2 = __toESM(require("which"));
|
|
20350
20526
|
var INSTALL_TIMEOUT_MS = 5 * 6e4;
|
|
20351
20527
|
var SETUP_TIMEOUT_MS = 2 * 6e4;
|
|
@@ -20412,8 +20588,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
|
|
|
20412
20588
|
if (args2.length === 0) return detection;
|
|
20413
20589
|
const binName = args2[0];
|
|
20414
20590
|
if (binName.startsWith("-")) return detection;
|
|
20415
|
-
const binPath =
|
|
20416
|
-
if (!
|
|
20591
|
+
const binPath = path53.join(cwd, "node_modules", ".bin", binName);
|
|
20592
|
+
if (!fs50.existsSync(binPath)) return detection;
|
|
20417
20593
|
return {
|
|
20418
20594
|
...detection,
|
|
20419
20595
|
command: binPath,
|
|
@@ -20777,9 +20953,9 @@ async function establishTunnel(ctx, dev) {
|
|
|
20777
20953
|
|
|
20778
20954
|
// src/beads/bd-adapter.ts
|
|
20779
20955
|
var import_child_process19 = require("child_process");
|
|
20780
|
-
var
|
|
20781
|
-
var
|
|
20782
|
-
var
|
|
20956
|
+
var fs51 = __toESM(require("fs"));
|
|
20957
|
+
var os41 = __toESM(require("os"));
|
|
20958
|
+
var path54 = __toESM(require("path"));
|
|
20783
20959
|
var BD_PACKAGE = "@beads/bd";
|
|
20784
20960
|
function resolveBundledBdBinary() {
|
|
20785
20961
|
return _resolveSeam.resolveBundled();
|
|
@@ -20791,11 +20967,11 @@ function _defaultResolveBundled() {
|
|
|
20791
20967
|
} catch {
|
|
20792
20968
|
return null;
|
|
20793
20969
|
}
|
|
20794
|
-
const binDir =
|
|
20970
|
+
const binDir = path54.join(path54.dirname(pkgJsonPath), "bin");
|
|
20795
20971
|
const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
|
|
20796
|
-
const binaryPath =
|
|
20972
|
+
const binaryPath = path54.join(binDir, binaryName);
|
|
20797
20973
|
try {
|
|
20798
|
-
|
|
20974
|
+
fs51.accessSync(binaryPath, fs51.constants.F_OK);
|
|
20799
20975
|
return binaryPath;
|
|
20800
20976
|
} catch {
|
|
20801
20977
|
return null;
|
|
@@ -20805,13 +20981,13 @@ function resolveBdOnPath() {
|
|
|
20805
20981
|
return _resolveSeam.resolveOnPath();
|
|
20806
20982
|
}
|
|
20807
20983
|
function _defaultResolveOnPath() {
|
|
20808
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
20984
|
+
const dirs = (process.env.PATH ?? "").split(path54.delimiter).filter(Boolean);
|
|
20809
20985
|
const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
|
|
20810
20986
|
for (const dir of dirs) {
|
|
20811
20987
|
for (const candidate of candidates) {
|
|
20812
|
-
const full =
|
|
20988
|
+
const full = path54.join(dir, candidate);
|
|
20813
20989
|
try {
|
|
20814
|
-
|
|
20990
|
+
fs51.accessSync(full, fs51.constants.F_OK);
|
|
20815
20991
|
return full;
|
|
20816
20992
|
} catch {
|
|
20817
20993
|
}
|
|
@@ -20896,7 +21072,7 @@ var BdAdapter = class {
|
|
|
20896
21072
|
const env = { ...process.env };
|
|
20897
21073
|
if (!env.HOME) {
|
|
20898
21074
|
try {
|
|
20899
|
-
const home =
|
|
21075
|
+
const home = os41.homedir();
|
|
20900
21076
|
if (home) env.HOME = home;
|
|
20901
21077
|
} catch {
|
|
20902
21078
|
}
|
|
@@ -20988,9 +21164,9 @@ function coerceIssue(row, projectKey) {
|
|
|
20988
21164
|
|
|
20989
21165
|
// src/beads/provisioner.ts
|
|
20990
21166
|
var import_child_process23 = require("child_process");
|
|
20991
|
-
var
|
|
20992
|
-
var
|
|
20993
|
-
var
|
|
21167
|
+
var fs54 = __toESM(require("fs"));
|
|
21168
|
+
var os43 = __toESM(require("os"));
|
|
21169
|
+
var path57 = __toESM(require("path"));
|
|
20994
21170
|
|
|
20995
21171
|
// src/beads/install-bd.ts
|
|
20996
21172
|
var import_child_process20 = require("child_process");
|
|
@@ -21055,9 +21231,9 @@ async function installBd(platform3 = process.platform) {
|
|
|
21055
21231
|
|
|
21056
21232
|
// src/beads/install-dolt.ts
|
|
21057
21233
|
var import_child_process21 = require("child_process");
|
|
21058
|
-
var
|
|
21059
|
-
var
|
|
21060
|
-
var
|
|
21234
|
+
var fs52 = __toESM(require("fs"));
|
|
21235
|
+
var os42 = __toESM(require("os"));
|
|
21236
|
+
var path55 = __toESM(require("path"));
|
|
21061
21237
|
var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
|
|
21062
21238
|
var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
|
|
21063
21239
|
function resolveDoltInstallStrategy(platform3) {
|
|
@@ -21097,11 +21273,11 @@ function resolveDoltInstallStrategy(platform3) {
|
|
|
21097
21273
|
}
|
|
21098
21274
|
var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
|
|
21099
21275
|
function doltPlatformTuple(platform3, arch2) {
|
|
21100
|
-
const
|
|
21276
|
+
const os57 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
|
|
21101
21277
|
const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
|
|
21102
21278
|
if (!a) return null;
|
|
21103
|
-
if (
|
|
21104
|
-
return `${
|
|
21279
|
+
if (os57 === "windows" && a !== "amd64") return null;
|
|
21280
|
+
return `${os57}-${a}`;
|
|
21105
21281
|
}
|
|
21106
21282
|
function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
|
|
21107
21283
|
const tuple = doltPlatformTuple(platform3, arch2);
|
|
@@ -21146,14 +21322,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
|
|
|
21146
21322
|
return result;
|
|
21147
21323
|
}
|
|
21148
21324
|
var _doltPathSeam = {
|
|
21149
|
-
homedir: () =>
|
|
21325
|
+
homedir: () => os42.homedir(),
|
|
21150
21326
|
getPath: () => process.env.PATH ?? "",
|
|
21151
21327
|
setPath: (p2) => {
|
|
21152
21328
|
process.env.PATH = p2;
|
|
21153
21329
|
},
|
|
21154
21330
|
exists: (p2) => {
|
|
21155
21331
|
try {
|
|
21156
|
-
|
|
21332
|
+
fs52.accessSync(p2, fs52.constants.F_OK);
|
|
21157
21333
|
return true;
|
|
21158
21334
|
} catch {
|
|
21159
21335
|
return false;
|
|
@@ -21164,7 +21340,7 @@ function doltBinaryNames(platform3) {
|
|
|
21164
21340
|
return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
|
|
21165
21341
|
}
|
|
21166
21342
|
function knownDoltDirs(platform3) {
|
|
21167
|
-
const P3 = platform3 === "win32" ?
|
|
21343
|
+
const P3 = platform3 === "win32" ? path55.win32 : path55.posix;
|
|
21168
21344
|
const home = _doltPathSeam.homedir();
|
|
21169
21345
|
if (platform3 === "win32") {
|
|
21170
21346
|
return [
|
|
@@ -21180,7 +21356,7 @@ function knownDoltDirs(platform3) {
|
|
|
21180
21356
|
].filter(Boolean);
|
|
21181
21357
|
}
|
|
21182
21358
|
function ensureDoltResolvable(platform3 = process.platform) {
|
|
21183
|
-
const P3 = platform3 === "win32" ?
|
|
21359
|
+
const P3 = platform3 === "win32" ? path55.win32 : path55.posix;
|
|
21184
21360
|
const delim = platform3 === "win32" ? ";" : ":";
|
|
21185
21361
|
const names = doltBinaryNames(platform3);
|
|
21186
21362
|
const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
|
|
@@ -21316,8 +21492,8 @@ async function ensureSharedServer(adapter, options = {}) {
|
|
|
21316
21492
|
// src/beads/project-key.ts
|
|
21317
21493
|
var import_child_process22 = require("child_process");
|
|
21318
21494
|
var crypto2 = __toESM(require("crypto"));
|
|
21319
|
-
var
|
|
21320
|
-
var
|
|
21495
|
+
var fs53 = __toESM(require("fs"));
|
|
21496
|
+
var path56 = __toESM(require("path"));
|
|
21321
21497
|
function normalizeOrigin(raw) {
|
|
21322
21498
|
const trimmed = raw.trim();
|
|
21323
21499
|
if (!trimmed) return null;
|
|
@@ -21343,17 +21519,17 @@ function normalizeOrigin(raw) {
|
|
|
21343
21519
|
return `${host2}/${pathPart}`;
|
|
21344
21520
|
}
|
|
21345
21521
|
function findRepoRoot(cwd) {
|
|
21346
|
-
let dir =
|
|
21522
|
+
let dir = path56.resolve(cwd);
|
|
21347
21523
|
const seen = /* @__PURE__ */ new Set();
|
|
21348
21524
|
for (let i = 0; i < 256; i++) {
|
|
21349
21525
|
if (seen.has(dir)) return null;
|
|
21350
21526
|
seen.add(dir);
|
|
21351
21527
|
try {
|
|
21352
|
-
const stat3 =
|
|
21528
|
+
const stat3 = fs53.statSync(path56.join(dir, ".git"), { throwIfNoEntry: false });
|
|
21353
21529
|
if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
|
|
21354
21530
|
} catch {
|
|
21355
21531
|
}
|
|
21356
|
-
const parent =
|
|
21532
|
+
const parent = path56.dirname(dir);
|
|
21357
21533
|
if (parent === dir) return null;
|
|
21358
21534
|
dir = parent;
|
|
21359
21535
|
}
|
|
@@ -21364,7 +21540,7 @@ var _execSeam2 = {
|
|
|
21364
21540
|
const out2 = (0, import_child_process22.execFileSync)(file, args2, opts);
|
|
21365
21541
|
return typeof out2 === "string" ? out2 : out2.toString("utf8");
|
|
21366
21542
|
},
|
|
21367
|
-
realpath: (p2) =>
|
|
21543
|
+
realpath: (p2) => fs53.realpathSync(p2)
|
|
21368
21544
|
};
|
|
21369
21545
|
function readOrigin(cwd) {
|
|
21370
21546
|
try {
|
|
@@ -21393,7 +21569,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
|
|
|
21393
21569
|
} catch {
|
|
21394
21570
|
}
|
|
21395
21571
|
const hash = crypto2.createHash("sha256").update(real).digest("hex");
|
|
21396
|
-
return { projectKey: `path:${hash}`, projectLabel:
|
|
21572
|
+
return { projectKey: `path:${hash}`, projectLabel: path56.basename(real) || "project" };
|
|
21397
21573
|
}
|
|
21398
21574
|
|
|
21399
21575
|
// src/beads/project-prefix.ts
|
|
@@ -21438,17 +21614,17 @@ var _provisionSeam = {
|
|
|
21438
21614
|
};
|
|
21439
21615
|
var _linkSeam = {
|
|
21440
21616
|
platform: () => process.platform,
|
|
21441
|
-
homedir: () =>
|
|
21617
|
+
homedir: () => os43.homedir(),
|
|
21442
21618
|
isWritableDir: (dir) => {
|
|
21443
21619
|
try {
|
|
21444
|
-
|
|
21620
|
+
fs54.accessSync(dir, fs54.constants.W_OK);
|
|
21445
21621
|
return true;
|
|
21446
21622
|
} catch {
|
|
21447
21623
|
return false;
|
|
21448
21624
|
}
|
|
21449
21625
|
},
|
|
21450
21626
|
ensureDir: (dir) => {
|
|
21451
|
-
|
|
21627
|
+
fs54.mkdirSync(dir, { recursive: true });
|
|
21452
21628
|
},
|
|
21453
21629
|
/**
|
|
21454
21630
|
* A directory to symlink `bd` into so the AGENT's shell + Claude Code's
|
|
@@ -21469,9 +21645,9 @@ var _linkSeam = {
|
|
|
21469
21645
|
* which `linkBdOntoPath` creates if missing.
|
|
21470
21646
|
*/
|
|
21471
21647
|
cliBinDir: () => {
|
|
21472
|
-
const pathDirs = (process.env.PATH ?? "").split(
|
|
21648
|
+
const pathDirs = (process.env.PATH ?? "").split(path57.delimiter).filter(Boolean);
|
|
21473
21649
|
const home = _linkSeam.homedir();
|
|
21474
|
-
const localBin = home ?
|
|
21650
|
+
const localBin = home ? path57.join(home, ".local", "bin") : null;
|
|
21475
21651
|
if (localBin) {
|
|
21476
21652
|
try {
|
|
21477
21653
|
_linkSeam.ensureDir(localBin);
|
|
@@ -21481,16 +21657,16 @@ var _linkSeam = {
|
|
|
21481
21657
|
const candidates = [];
|
|
21482
21658
|
if (localBin) candidates.push(localBin);
|
|
21483
21659
|
try {
|
|
21484
|
-
candidates.push(
|
|
21660
|
+
candidates.push(path57.dirname(process.execPath));
|
|
21485
21661
|
} catch {
|
|
21486
21662
|
}
|
|
21487
21663
|
candidates.push("/usr/local/bin");
|
|
21488
21664
|
const entry = process.argv[1];
|
|
21489
21665
|
if (entry) {
|
|
21490
21666
|
try {
|
|
21491
|
-
candidates.push(
|
|
21667
|
+
candidates.push(path57.dirname(fs54.realpathSync(entry)));
|
|
21492
21668
|
} catch {
|
|
21493
|
-
candidates.push(
|
|
21669
|
+
candidates.push(path57.dirname(entry));
|
|
21494
21670
|
}
|
|
21495
21671
|
}
|
|
21496
21672
|
const onPathWritable = candidates.find(
|
|
@@ -21502,20 +21678,20 @@ var _linkSeam = {
|
|
|
21502
21678
|
/** Current symlink target at `linkPath`, or null when absent / not a link. */
|
|
21503
21679
|
readlink: (linkPath) => {
|
|
21504
21680
|
try {
|
|
21505
|
-
return
|
|
21681
|
+
return fs54.readlinkSync(linkPath);
|
|
21506
21682
|
} catch {
|
|
21507
21683
|
return null;
|
|
21508
21684
|
}
|
|
21509
21685
|
},
|
|
21510
|
-
unlink: (linkPath) =>
|
|
21511
|
-
symlink: (target, linkPath) =>
|
|
21686
|
+
unlink: (linkPath) => fs54.unlinkSync(linkPath),
|
|
21687
|
+
symlink: (target, linkPath) => fs54.symlinkSync(target, linkPath)
|
|
21512
21688
|
};
|
|
21513
21689
|
function linkBdOntoPath(binaryPath) {
|
|
21514
21690
|
if (_linkSeam.platform() === "win32") return;
|
|
21515
21691
|
const binDir = _linkSeam.cliBinDir();
|
|
21516
21692
|
if (!binDir) return;
|
|
21517
21693
|
_linkSeam.ensureDir(binDir);
|
|
21518
|
-
const linkPath =
|
|
21694
|
+
const linkPath = path57.join(binDir, "bd");
|
|
21519
21695
|
if (linkPath === binaryPath) return;
|
|
21520
21696
|
const current = _linkSeam.readlink(linkPath);
|
|
21521
21697
|
if (current === binaryPath) return;
|
|
@@ -21710,7 +21886,7 @@ function dedupeRecipes(agents) {
|
|
|
21710
21886
|
|
|
21711
21887
|
// src/beads/watcher.ts
|
|
21712
21888
|
var crypto4 = __toESM(require("crypto"));
|
|
21713
|
-
var
|
|
21889
|
+
var path58 = __toESM(require("path"));
|
|
21714
21890
|
var API_BASE6 = resolveApiBaseUrl();
|
|
21715
21891
|
var DEBOUNCE_MS2 = 400;
|
|
21716
21892
|
var ZERO_SUMMARY = {
|
|
@@ -21734,7 +21910,7 @@ var BeadsWatcher = class {
|
|
|
21734
21910
|
constructor(opts) {
|
|
21735
21911
|
this.opts = opts;
|
|
21736
21912
|
this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
|
|
21737
|
-
this.feedPath = opts.feedPath ??
|
|
21913
|
+
this.feedPath = opts.feedPath ?? path58.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
|
|
21738
21914
|
this.apiBase = opts.apiBaseUrl ?? API_BASE6;
|
|
21739
21915
|
}
|
|
21740
21916
|
opts;
|
|
@@ -21985,15 +22161,15 @@ async function handleBeadsActionCommand(action, started) {
|
|
|
21985
22161
|
}
|
|
21986
22162
|
|
|
21987
22163
|
// src/beads/config-store.ts
|
|
21988
|
-
var
|
|
21989
|
-
var
|
|
21990
|
-
var
|
|
22164
|
+
var import_node_fs9 = __toESM(require("fs"));
|
|
22165
|
+
var import_node_os8 = __toESM(require("os"));
|
|
22166
|
+
var import_node_path7 = __toESM(require("path"));
|
|
21991
22167
|
function beadsConfigPath() {
|
|
21992
|
-
return
|
|
22168
|
+
return import_node_path7.default.join(import_node_os8.default.homedir(), ".codeam", "beads-config.json");
|
|
21993
22169
|
}
|
|
21994
22170
|
function readBeadsEnabled() {
|
|
21995
22171
|
try {
|
|
21996
|
-
const raw =
|
|
22172
|
+
const raw = import_node_fs9.default.readFileSync(beadsConfigPath(), "utf8");
|
|
21997
22173
|
const cfg = JSON.parse(raw);
|
|
21998
22174
|
return cfg.enabled !== false;
|
|
21999
22175
|
} catch {
|
|
@@ -22002,10 +22178,10 @@ function readBeadsEnabled() {
|
|
|
22002
22178
|
}
|
|
22003
22179
|
function persistBeadsConfig(cfg) {
|
|
22004
22180
|
const file = beadsConfigPath();
|
|
22005
|
-
|
|
22181
|
+
import_node_fs9.default.mkdirSync(import_node_path7.default.dirname(file), { recursive: true });
|
|
22006
22182
|
const tmp = `${file}.tmp`;
|
|
22007
|
-
|
|
22008
|
-
|
|
22183
|
+
import_node_fs9.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
|
|
22184
|
+
import_node_fs9.default.renameSync(tmp, file);
|
|
22009
22185
|
restrictToOwner(file);
|
|
22010
22186
|
}
|
|
22011
22187
|
|
|
@@ -22140,6 +22316,88 @@ async function configureBeads(action, ctx, deps) {
|
|
|
22140
22316
|
return { enabled: true, running, ...p2 };
|
|
22141
22317
|
}
|
|
22142
22318
|
|
|
22319
|
+
// src/skills/configure.ts
|
|
22320
|
+
var import_node_os10 = __toESM(require("os"));
|
|
22321
|
+
|
|
22322
|
+
// src/skills/materialize.ts
|
|
22323
|
+
var import_node_fs10 = __toESM(require("fs"));
|
|
22324
|
+
var import_node_os9 = __toESM(require("os"));
|
|
22325
|
+
var import_node_path8 = __toESM(require("path"));
|
|
22326
|
+
var NS = "codeam-";
|
|
22327
|
+
function skillDirFor(id, home = import_node_os9.default.homedir()) {
|
|
22328
|
+
return import_node_path8.default.join(home, ".claude", "skills", `${NS}${id}`);
|
|
22329
|
+
}
|
|
22330
|
+
function renderSkillMd(id, description, body) {
|
|
22331
|
+
const desc = description.replace(/\s*\n\s*/g, " ").trim();
|
|
22332
|
+
return `---
|
|
22333
|
+
name: ${NS}${id}
|
|
22334
|
+
description: ${JSON.stringify(desc)}
|
|
22335
|
+
---
|
|
22336
|
+
|
|
22337
|
+
${body.trim()}
|
|
22338
|
+
`;
|
|
22339
|
+
}
|
|
22340
|
+
function materializeSkill(id, home = import_node_os9.default.homedir()) {
|
|
22341
|
+
const def = getSkillDefinition(id);
|
|
22342
|
+
if (!def?.delivery.skillFile) return false;
|
|
22343
|
+
try {
|
|
22344
|
+
const dir = skillDirFor(id, home);
|
|
22345
|
+
import_node_fs10.default.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
22346
|
+
import_node_fs10.default.writeFileSync(
|
|
22347
|
+
import_node_path8.default.join(dir, "SKILL.md"),
|
|
22348
|
+
renderSkillMd(id, def.description, def.delivery.skillFile.body),
|
|
22349
|
+
{ encoding: "utf8", mode: 384 }
|
|
22350
|
+
);
|
|
22351
|
+
const baseDir = import_node_path8.default.resolve(dir);
|
|
22352
|
+
const baseDirWithSep = baseDir + import_node_path8.default.sep;
|
|
22353
|
+
for (const [rel, contents] of Object.entries(def.delivery.skillFile.files ?? {})) {
|
|
22354
|
+
const target = import_node_path8.default.join(dir, rel);
|
|
22355
|
+
if (!import_node_path8.default.resolve(target).startsWith(baseDirWithSep) && import_node_path8.default.resolve(target) !== baseDir) {
|
|
22356
|
+
continue;
|
|
22357
|
+
}
|
|
22358
|
+
import_node_fs10.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true, mode: 448 });
|
|
22359
|
+
import_node_fs10.default.writeFileSync(target, contents, { encoding: "utf8", mode: 384 });
|
|
22360
|
+
}
|
|
22361
|
+
return true;
|
|
22362
|
+
} catch (err) {
|
|
22363
|
+
log.warn("skills", `failed to materialize ${id} (best-effort): ${err instanceof Error ? err.message : String(err)}`);
|
|
22364
|
+
return false;
|
|
22365
|
+
}
|
|
22366
|
+
}
|
|
22367
|
+
function removeSkill(id, home = import_node_os9.default.homedir()) {
|
|
22368
|
+
try {
|
|
22369
|
+
import_node_fs10.default.rmSync(skillDirFor(id, home), { recursive: true, force: true });
|
|
22370
|
+
} catch {
|
|
22371
|
+
}
|
|
22372
|
+
}
|
|
22373
|
+
|
|
22374
|
+
// src/skills/configure.ts
|
|
22375
|
+
function currentInstalled() {
|
|
22376
|
+
const m = readSkillsManifest();
|
|
22377
|
+
return (m?.skills ?? []).map((s) => s.id).filter(isSkillId);
|
|
22378
|
+
}
|
|
22379
|
+
function configureSkill(action, skillId, home = import_node_os10.default.homedir()) {
|
|
22380
|
+
if (action === "list") return { ok: true, installed: currentInstalled() };
|
|
22381
|
+
if (!skillId || !isSkillId(skillId)) {
|
|
22382
|
+
return { ok: false, installed: currentInstalled(), error: `unknown skill: ${skillId ?? "(none)"}` };
|
|
22383
|
+
}
|
|
22384
|
+
const set = new Set(currentInstalled());
|
|
22385
|
+
if (action === "add") {
|
|
22386
|
+
if (!materializeSkill(skillId, home)) {
|
|
22387
|
+
return { ok: false, installed: [...set], error: `skill ${skillId} has no skillFile rail` };
|
|
22388
|
+
}
|
|
22389
|
+
set.add(skillId);
|
|
22390
|
+
} else if (action === "remove") {
|
|
22391
|
+
removeSkill(skillId, home);
|
|
22392
|
+
set.delete(skillId);
|
|
22393
|
+
} else {
|
|
22394
|
+
return { ok: false, installed: currentInstalled(), error: `unknown action: ${action}` };
|
|
22395
|
+
}
|
|
22396
|
+
const installed2 = [...set];
|
|
22397
|
+
persistSkillsManifest({ skills: installed2.map((id) => ({ id })) });
|
|
22398
|
+
return { ok: true, installed: installed2 };
|
|
22399
|
+
}
|
|
22400
|
+
|
|
22143
22401
|
// src/commands/start/handlers.ts
|
|
22144
22402
|
var pendingAttachmentFiles = /* @__PURE__ */ new Set();
|
|
22145
22403
|
function cleanupAttachmentTempFiles() {
|
|
@@ -22151,8 +22409,8 @@ function cleanupAttachmentTempFiles() {
|
|
|
22151
22409
|
function saveFilesTemp(files) {
|
|
22152
22410
|
return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
|
|
22153
22411
|
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
|
|
22154
|
-
const tmpPath =
|
|
22155
|
-
|
|
22412
|
+
const tmpPath = path61.join(os47.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
|
|
22413
|
+
fs57.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
|
|
22156
22414
|
pendingAttachmentFiles.add(tmpPath);
|
|
22157
22415
|
return tmpPath;
|
|
22158
22416
|
});
|
|
@@ -22364,9 +22622,9 @@ var listFiles = async (ctx, cmd, parsed) => {
|
|
|
22364
22622
|
await ctx.relay.sendResult(cmd.id, "completed", result);
|
|
22365
22623
|
};
|
|
22366
22624
|
var envReadH = async (ctx, cmd) => {
|
|
22367
|
-
const envPath =
|
|
22625
|
+
const envPath = path61.join(process.cwd(), ".env");
|
|
22368
22626
|
try {
|
|
22369
|
-
const raw = await
|
|
22627
|
+
const raw = await fs57.promises.readFile(envPath, "utf8");
|
|
22370
22628
|
await ctx.relay.sendResult(cmd.id, "completed", {
|
|
22371
22629
|
exists: true,
|
|
22372
22630
|
vars: parseDotenv(raw)
|
|
@@ -22397,17 +22655,22 @@ var envWriteH = async (ctx, cmd, parsed) => {
|
|
|
22397
22655
|
}
|
|
22398
22656
|
seen.add(v.key);
|
|
22399
22657
|
}
|
|
22400
|
-
const envPath =
|
|
22401
|
-
const tmpPath =
|
|
22658
|
+
const envPath = path61.join(process.cwd(), ".env");
|
|
22659
|
+
const tmpPath = path61.join(process.cwd(), ".env.codeam.tmp");
|
|
22402
22660
|
try {
|
|
22403
|
-
await
|
|
22404
|
-
await
|
|
22661
|
+
await fs57.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
|
|
22662
|
+
await fs57.promises.rename(tmpPath, envPath);
|
|
22405
22663
|
await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
|
|
22406
22664
|
} catch (err) {
|
|
22407
|
-
await
|
|
22665
|
+
await fs57.promises.rm(tmpPath, { force: true }).catch(() => void 0);
|
|
22408
22666
|
await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
|
|
22409
22667
|
}
|
|
22410
22668
|
};
|
|
22669
|
+
var skillsConfigureH = async (ctx, cmd, parsed) => {
|
|
22670
|
+
const action = parsed.action;
|
|
22671
|
+
const res = configureSkill(action ?? "list", parsed.skillId);
|
|
22672
|
+
await ctx.relay.sendResult(cmd.id, res.ok ? "completed" : "failed", res);
|
|
22673
|
+
};
|
|
22411
22674
|
var takeControlH = async (ctx, cmd) => {
|
|
22412
22675
|
if (!ctx.baton) {
|
|
22413
22676
|
await ctx.relay.sendResult(cmd.id, "failed", { code: "NO_BATON" });
|
|
@@ -22448,7 +22711,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
22448
22711
|
let configuredAgent = rawAgentId;
|
|
22449
22712
|
if (!configuredAgent) {
|
|
22450
22713
|
try {
|
|
22451
|
-
const raw = JSON.parse(
|
|
22714
|
+
const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
|
|
22452
22715
|
configuredAgent = raw.agent ?? "";
|
|
22453
22716
|
} catch {
|
|
22454
22717
|
}
|
|
@@ -22482,7 +22745,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
|
|
|
22482
22745
|
persist: persistHeadroomConfig,
|
|
22483
22746
|
readEnabled: () => {
|
|
22484
22747
|
try {
|
|
22485
|
-
const raw = JSON.parse(
|
|
22748
|
+
const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
|
|
22486
22749
|
return raw.enabled === true;
|
|
22487
22750
|
} catch {
|
|
22488
22751
|
return false;
|
|
@@ -22739,7 +23002,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
|
|
|
22739
23002
|
});
|
|
22740
23003
|
const token = ctx.pluginAuthToken;
|
|
22741
23004
|
void (async () => {
|
|
22742
|
-
const
|
|
23005
|
+
const os57 = createOsStrategy();
|
|
22743
23006
|
try {
|
|
22744
23007
|
const report = await reviewPullRequest(
|
|
22745
23008
|
{
|
|
@@ -22748,7 +23011,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
|
|
|
22748
23011
|
baseBranch: parsed.baseBranch
|
|
22749
23012
|
},
|
|
22750
23013
|
{
|
|
22751
|
-
runReview: (input) => new CoderabbitRuntimeStrategy(
|
|
23014
|
+
runReview: (input) => new CoderabbitRuntimeStrategy(os57).runOneShot(input),
|
|
22752
23015
|
runGh: (args2) => defaultRunGh(args2),
|
|
22753
23016
|
postReport: async (r) => {
|
|
22754
23017
|
if (!token) return;
|
|
@@ -22786,7 +23049,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
22786
23049
|
}
|
|
22787
23050
|
let headroomActive = false;
|
|
22788
23051
|
try {
|
|
22789
|
-
const raw = JSON.parse(
|
|
23052
|
+
const raw = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
|
|
22790
23053
|
headroomActive = raw.enabled === true;
|
|
22791
23054
|
} catch {
|
|
22792
23055
|
}
|
|
@@ -22796,7 +23059,7 @@ var headroomBudgetH = async (ctx, cmd) => {
|
|
|
22796
23059
|
}
|
|
22797
23060
|
let existingConfig = { enabled: true };
|
|
22798
23061
|
try {
|
|
22799
|
-
existingConfig = JSON.parse(
|
|
23062
|
+
existingConfig = JSON.parse(fs57.readFileSync(headroomConfigPath(), "utf8"));
|
|
22800
23063
|
} catch {
|
|
22801
23064
|
}
|
|
22802
23065
|
if (payload.budgetEnabled && payload.budgetUsd != null) {
|
|
@@ -22909,9 +23172,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
|
|
|
22909
23172
|
function buildNpmInstallInvocation(opts) {
|
|
22910
23173
|
const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
|
|
22911
23174
|
const execPath = opts?.execPath ?? process.execPath;
|
|
22912
|
-
const exists2 = opts?.existsSync ??
|
|
23175
|
+
const exists2 = opts?.existsSync ?? fs57.existsSync;
|
|
22913
23176
|
const platform3 = opts?.platform ?? process.platform;
|
|
22914
|
-
const p2 = platform3 === "win32" ?
|
|
23177
|
+
const p2 = platform3 === "win32" ? path61.win32 : path61.posix;
|
|
22915
23178
|
const normalized = entryScript.split(/[\\/]/).join("/");
|
|
22916
23179
|
const marker = "/lib/node_modules/codeam-cli/";
|
|
22917
23180
|
const markerIdx = normalized.indexOf(marker);
|
|
@@ -23497,6 +23760,7 @@ var handlers = {
|
|
|
23497
23760
|
save_preview_config: savePreviewConfigH,
|
|
23498
23761
|
env_read: envReadH,
|
|
23499
23762
|
env_write: envWriteH,
|
|
23763
|
+
skills_configure: skillsConfigureH,
|
|
23500
23764
|
take_control: takeControlH,
|
|
23501
23765
|
handback: handbackH,
|
|
23502
23766
|
headroom_configure: headroomConfigureH,
|
|
@@ -23577,29 +23841,6 @@ function buildKeepAlive(ctx) {
|
|
|
23577
23841
|
};
|
|
23578
23842
|
}
|
|
23579
23843
|
|
|
23580
|
-
// src/lib/process-guards.ts
|
|
23581
|
-
var installed = false;
|
|
23582
|
-
function installRelayCrashGuards() {
|
|
23583
|
-
if (installed) return;
|
|
23584
|
-
installed = true;
|
|
23585
|
-
process.on("unhandledRejection", (reason) => {
|
|
23586
|
-
log.error("process", `unhandledRejection \u2014 relay kept alive \u2014 ${describeReason(reason)}`);
|
|
23587
|
-
});
|
|
23588
|
-
process.on("uncaughtException", (err) => {
|
|
23589
|
-
log.error("process", `uncaughtException \u2014 relay kept alive \u2014 ${describeReason(err)}`);
|
|
23590
|
-
});
|
|
23591
|
-
}
|
|
23592
|
-
function describeReason(reason) {
|
|
23593
|
-
if (reason instanceof Error) {
|
|
23594
|
-
return reason.stack ?? `${reason.name}: ${reason.message}`;
|
|
23595
|
-
}
|
|
23596
|
-
try {
|
|
23597
|
-
return typeof reason === "string" ? reason : JSON.stringify(reason);
|
|
23598
|
-
} catch {
|
|
23599
|
-
return String(reason);
|
|
23600
|
-
}
|
|
23601
|
-
}
|
|
23602
|
-
|
|
23603
23844
|
// src/commands/start-infra-only.ts
|
|
23604
23845
|
var INFRA_ONLY_COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
23605
23846
|
// File ops (drive the dashboard's Files panel + open-file).
|
|
@@ -23796,11 +24037,11 @@ function resolveTokenValue(args2) {
|
|
|
23796
24037
|
}
|
|
23797
24038
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
23798
24039
|
if (fileFlag) {
|
|
23799
|
-
const
|
|
24040
|
+
const path78 = fileFlag.slice("--token-file=".length);
|
|
23800
24041
|
try {
|
|
23801
|
-
const content =
|
|
23802
|
-
if (content.length === 0) fail(`--token-file ${
|
|
23803
|
-
rmIfExistsQuiet(
|
|
24042
|
+
const content = fs58.readFileSync(path78, "utf8").trim();
|
|
24043
|
+
if (content.length === 0) fail(`--token-file ${path78} is empty`);
|
|
24044
|
+
rmIfExistsQuiet(path78);
|
|
23804
24045
|
return content;
|
|
23805
24046
|
} catch (err) {
|
|
23806
24047
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -23829,7 +24070,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
|
|
|
23829
24070
|
pluginId,
|
|
23830
24071
|
ideName: "codeam-cli (codespace)",
|
|
23831
24072
|
ideVersion: process.env.npm_package_version ?? "unknown",
|
|
23832
|
-
hostname:
|
|
24073
|
+
hostname: os48.hostname(),
|
|
23833
24074
|
codespaceName: process.env.CODESPACE_NAME ?? "",
|
|
23834
24075
|
// Current git branch of the codespace's working directory, so the
|
|
23835
24076
|
// backend can populate `PairedSession.branch` for the codespace pair.
|
|
@@ -23890,7 +24131,7 @@ async function claim(token, pluginId, pluginSecretHash) {
|
|
|
23890
24131
|
}
|
|
23891
24132
|
}
|
|
23892
24133
|
function pairAutoLockPath() {
|
|
23893
|
-
return
|
|
24134
|
+
return path62.join(os48.homedir(), ".codeam", "pair-auto.lock");
|
|
23894
24135
|
}
|
|
23895
24136
|
function isLivePairAuto(pid) {
|
|
23896
24137
|
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
@@ -23900,7 +24141,7 @@ function isLivePairAuto(pid) {
|
|
|
23900
24141
|
if (e.code !== "EPERM") return false;
|
|
23901
24142
|
}
|
|
23902
24143
|
try {
|
|
23903
|
-
return
|
|
24144
|
+
return fs58.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
|
|
23904
24145
|
} catch {
|
|
23905
24146
|
return true;
|
|
23906
24147
|
}
|
|
@@ -23910,24 +24151,24 @@ function isLiveCodeam(pid) {
|
|
|
23910
24151
|
}
|
|
23911
24152
|
function daemonLockPath(sessionId) {
|
|
23912
24153
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
23913
|
-
return
|
|
24154
|
+
return path62.join(os48.homedir(), ".codeam", `daemon-${safe}.lock`);
|
|
23914
24155
|
}
|
|
23915
24156
|
function acquireDaemonLock(sessionId) {
|
|
23916
24157
|
const lockPath = daemonLockPath(sessionId);
|
|
23917
24158
|
try {
|
|
23918
|
-
|
|
24159
|
+
fs58.mkdirSync(path62.dirname(lockPath), { recursive: true });
|
|
23919
24160
|
try {
|
|
23920
|
-
|
|
24161
|
+
fs58.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
23921
24162
|
} catch (e) {
|
|
23922
24163
|
if (e.code !== "EEXIST") throw e;
|
|
23923
|
-
const holder = Number(
|
|
24164
|
+
const holder = Number(fs58.readFileSync(lockPath, "utf8").trim());
|
|
23924
24165
|
if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
|
|
23925
|
-
|
|
24166
|
+
fs58.writeFileSync(lockPath, String(process.pid));
|
|
23926
24167
|
}
|
|
23927
24168
|
const release3 = () => {
|
|
23928
24169
|
try {
|
|
23929
|
-
if (
|
|
23930
|
-
|
|
24170
|
+
if (fs58.existsSync(lockPath) && Number(fs58.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24171
|
+
fs58.unlinkSync(lockPath);
|
|
23931
24172
|
}
|
|
23932
24173
|
} catch {
|
|
23933
24174
|
}
|
|
@@ -23949,19 +24190,19 @@ function acquireDaemonLock(sessionId) {
|
|
|
23949
24190
|
function acquireSingletonLock() {
|
|
23950
24191
|
const lockPath = pairAutoLockPath();
|
|
23951
24192
|
try {
|
|
23952
|
-
|
|
24193
|
+
fs58.mkdirSync(path62.dirname(lockPath), { recursive: true });
|
|
23953
24194
|
try {
|
|
23954
|
-
|
|
24195
|
+
fs58.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
23955
24196
|
} catch (e) {
|
|
23956
24197
|
if (e.code !== "EEXIST") throw e;
|
|
23957
|
-
const holder = Number(
|
|
24198
|
+
const holder = Number(fs58.readFileSync(lockPath, "utf8").trim());
|
|
23958
24199
|
if (isLivePairAuto(holder)) return false;
|
|
23959
|
-
|
|
24200
|
+
fs58.writeFileSync(lockPath, String(process.pid));
|
|
23960
24201
|
}
|
|
23961
24202
|
process.once("exit", () => {
|
|
23962
24203
|
try {
|
|
23963
|
-
if (
|
|
23964
|
-
|
|
24204
|
+
if (fs58.existsSync(lockPath) && Number(fs58.readFileSync(lockPath, "utf8").trim()) === process.pid) {
|
|
24205
|
+
fs58.unlinkSync(lockPath);
|
|
23965
24206
|
}
|
|
23966
24207
|
} catch {
|
|
23967
24208
|
}
|
|
@@ -24407,7 +24648,7 @@ var AgentService = class _AgentService {
|
|
|
24407
24648
|
};
|
|
24408
24649
|
|
|
24409
24650
|
// src/agents/acp/adapters.ts
|
|
24410
|
-
var
|
|
24651
|
+
var path64 = __toESM(require("path"));
|
|
24411
24652
|
|
|
24412
24653
|
// src/agents/acp/agent-binary.ts
|
|
24413
24654
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -24583,11 +24824,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
|
|
|
24583
24824
|
|
|
24584
24825
|
// src/agents/kimi/installer.ts
|
|
24585
24826
|
var import_node_child_process26 = require("child_process");
|
|
24586
|
-
var
|
|
24587
|
-
var
|
|
24827
|
+
var import_node_os11 = require("os");
|
|
24828
|
+
var import_node_path9 = require("path");
|
|
24588
24829
|
var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
|
|
24589
24830
|
function kimiBinDir() {
|
|
24590
|
-
return (0,
|
|
24831
|
+
return (0, import_node_path9.join)(process.env.KIMI_CODE_HOME || (0, import_node_path9.join)((0, import_node_os11.homedir)(), ".kimi-code"), "bin");
|
|
24591
24832
|
}
|
|
24592
24833
|
function kimiRuns() {
|
|
24593
24834
|
const r = (0, import_node_child_process26.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
|
|
@@ -24650,13 +24891,13 @@ function resolveBin(pkgName, binName) {
|
|
|
24650
24891
|
try {
|
|
24651
24892
|
const manifestPath = require_.resolve(`${pkgName}/package.json`);
|
|
24652
24893
|
const manifest = require_(`${pkgName}/package.json`);
|
|
24653
|
-
const pkgDir =
|
|
24894
|
+
const pkgDir = path64.dirname(manifestPath);
|
|
24654
24895
|
const bin = manifest.bin;
|
|
24655
24896
|
if (!bin) return null;
|
|
24656
|
-
if (typeof bin === "string") return
|
|
24897
|
+
if (typeof bin === "string") return path64.resolve(pkgDir, bin);
|
|
24657
24898
|
const target = binName ?? Object.keys(bin)[0];
|
|
24658
24899
|
if (!target || !bin[target]) return null;
|
|
24659
|
-
return
|
|
24900
|
+
return path64.resolve(pkgDir, bin[target]);
|
|
24660
24901
|
} catch {
|
|
24661
24902
|
return null;
|
|
24662
24903
|
}
|
|
@@ -24791,9 +25032,9 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
|
|
|
24791
25032
|
var import_node_crypto10 = require("crypto");
|
|
24792
25033
|
|
|
24793
25034
|
// src/services/history.service.ts
|
|
24794
|
-
var
|
|
24795
|
-
var
|
|
24796
|
-
var
|
|
25035
|
+
var fs60 = __toESM(require("fs"));
|
|
25036
|
+
var path65 = __toESM(require("path"));
|
|
25037
|
+
var os50 = __toESM(require("os"));
|
|
24797
25038
|
var https7 = __toESM(require("https"));
|
|
24798
25039
|
var http6 = __toESM(require("http"));
|
|
24799
25040
|
var import_zod2 = require("zod");
|
|
@@ -24820,7 +25061,7 @@ function parseJsonl(filePath) {
|
|
|
24820
25061
|
const messages = [];
|
|
24821
25062
|
let raw;
|
|
24822
25063
|
try {
|
|
24823
|
-
raw =
|
|
25064
|
+
raw = fs60.readFileSync(filePath, "utf8");
|
|
24824
25065
|
} catch (err) {
|
|
24825
25066
|
if (err.code !== "ENOENT") {
|
|
24826
25067
|
log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
|
|
@@ -24961,7 +25202,7 @@ var HistoryService = class _HistoryService {
|
|
|
24961
25202
|
return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
|
|
24962
25203
|
}
|
|
24963
25204
|
get projectDir() {
|
|
24964
|
-
return this.runtime.resolveHistoryDir(this.cwd) ??
|
|
25205
|
+
return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os50.homedir(), ".claude", "projects", encodeCwd(this.cwd));
|
|
24965
25206
|
}
|
|
24966
25207
|
/** Set the current Claude conversation ID (extracted from /cost command or session start) */
|
|
24967
25208
|
setCurrentConversationId(id) {
|
|
@@ -24973,7 +25214,7 @@ var HistoryService = class _HistoryService {
|
|
|
24973
25214
|
/** Return the current message count in the active conversation. */
|
|
24974
25215
|
getCurrentMessageCount() {
|
|
24975
25216
|
if (!this.currentConversationId) return 0;
|
|
24976
|
-
const filePath =
|
|
25217
|
+
const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
24977
25218
|
return parseJsonl(filePath).length;
|
|
24978
25219
|
}
|
|
24979
25220
|
/**
|
|
@@ -24984,7 +25225,7 @@ var HistoryService = class _HistoryService {
|
|
|
24984
25225
|
const deadline = Date.now() + timeoutMs;
|
|
24985
25226
|
while (Date.now() < deadline) {
|
|
24986
25227
|
if (!this.currentConversationId) return null;
|
|
24987
|
-
const filePath =
|
|
25228
|
+
const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
|
|
24988
25229
|
const messages = parseJsonl(filePath);
|
|
24989
25230
|
if (messages.length > previousCount) {
|
|
24990
25231
|
for (let i = messages.length - 1; i >= previousCount; i--) {
|
|
@@ -25010,16 +25251,16 @@ var HistoryService = class _HistoryService {
|
|
|
25010
25251
|
const dir = this.projectDir;
|
|
25011
25252
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
25012
25253
|
try {
|
|
25013
|
-
const files =
|
|
25254
|
+
const files = fs60.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
25014
25255
|
try {
|
|
25015
|
-
const stat3 =
|
|
25256
|
+
const stat3 = fs60.statSync(path65.join(dir, e.name));
|
|
25016
25257
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
25017
25258
|
} catch {
|
|
25018
25259
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
25019
25260
|
}
|
|
25020
25261
|
}).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
25021
25262
|
if (files.length > 0) {
|
|
25022
|
-
this.currentConversationId =
|
|
25263
|
+
this.currentConversationId = path65.basename(files[0].name, ".jsonl");
|
|
25023
25264
|
}
|
|
25024
25265
|
} catch {
|
|
25025
25266
|
}
|
|
@@ -25053,13 +25294,13 @@ var HistoryService = class _HistoryService {
|
|
|
25053
25294
|
const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
|
|
25054
25295
|
let entries;
|
|
25055
25296
|
try {
|
|
25056
|
-
entries =
|
|
25297
|
+
entries = fs60.readdirSync(dir, { withFileTypes: true });
|
|
25057
25298
|
} catch {
|
|
25058
25299
|
return null;
|
|
25059
25300
|
}
|
|
25060
25301
|
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
25061
25302
|
try {
|
|
25062
|
-
const stat3 =
|
|
25303
|
+
const stat3 = fs60.statSync(path65.join(dir, e.name));
|
|
25063
25304
|
return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
|
|
25064
25305
|
} catch {
|
|
25065
25306
|
return { name: e.name, mtime: 0, birthtime: 0 };
|
|
@@ -25068,12 +25309,12 @@ var HistoryService = class _HistoryService {
|
|
|
25068
25309
|
if (files.length === 0) return null;
|
|
25069
25310
|
const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
|
|
25070
25311
|
if (!files.some((f) => f.name === targetFile)) return null;
|
|
25071
|
-
return this.extractUsageFromFile(
|
|
25312
|
+
return this.extractUsageFromFile(path65.join(dir, targetFile));
|
|
25072
25313
|
}
|
|
25073
25314
|
extractUsageFromFile(filePath) {
|
|
25074
25315
|
let raw;
|
|
25075
25316
|
try {
|
|
25076
|
-
raw =
|
|
25317
|
+
raw = fs60.readFileSync(filePath, "utf8");
|
|
25077
25318
|
} catch {
|
|
25078
25319
|
return null;
|
|
25079
25320
|
}
|
|
@@ -25118,9 +25359,9 @@ var HistoryService = class _HistoryService {
|
|
|
25118
25359
|
let totalCost = 0;
|
|
25119
25360
|
let files;
|
|
25120
25361
|
try {
|
|
25121
|
-
files =
|
|
25362
|
+
files = fs60.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
|
|
25122
25363
|
try {
|
|
25123
|
-
return
|
|
25364
|
+
return fs60.statSync(path65.join(projectDir, f)).mtimeMs >= monthStartMs;
|
|
25124
25365
|
} catch {
|
|
25125
25366
|
return false;
|
|
25126
25367
|
}
|
|
@@ -25131,7 +25372,7 @@ var HistoryService = class _HistoryService {
|
|
|
25131
25372
|
for (const file of files) {
|
|
25132
25373
|
let raw;
|
|
25133
25374
|
try {
|
|
25134
|
-
raw =
|
|
25375
|
+
raw = fs60.readFileSync(path65.join(projectDir, file), "utf8");
|
|
25135
25376
|
} catch {
|
|
25136
25377
|
continue;
|
|
25137
25378
|
}
|
|
@@ -25210,7 +25451,7 @@ var HistoryService = class _HistoryService {
|
|
|
25210
25451
|
if (this.runtime.resolveHistoryFile) {
|
|
25211
25452
|
return this.runtime.resolveHistoryFile(this.cwd, sessionId);
|
|
25212
25453
|
}
|
|
25213
|
-
return
|
|
25454
|
+
return path65.join(this.projectDir, `${sessionId}.jsonl`);
|
|
25214
25455
|
}
|
|
25215
25456
|
/**
|
|
25216
25457
|
* Parse a conversation's messages from disk, agent-aware. Claude uses the
|
|
@@ -25244,7 +25485,7 @@ var HistoryService = class _HistoryService {
|
|
|
25244
25485
|
};
|
|
25245
25486
|
});
|
|
25246
25487
|
}
|
|
25247
|
-
return parseJsonl(
|
|
25488
|
+
return parseJsonl(path65.join(this.projectDir, `${sessionId}.jsonl`));
|
|
25248
25489
|
}
|
|
25249
25490
|
async loadConversation(sessionId) {
|
|
25250
25491
|
const messages = this.readConversation(sessionId);
|
|
@@ -25312,7 +25553,7 @@ var HistoryService = class _HistoryService {
|
|
|
25312
25553
|
if (!filePath) return false;
|
|
25313
25554
|
let mtimeMs;
|
|
25314
25555
|
try {
|
|
25315
|
-
mtimeMs =
|
|
25556
|
+
mtimeMs = fs60.statSync(filePath).mtimeMs;
|
|
25316
25557
|
} catch {
|
|
25317
25558
|
return false;
|
|
25318
25559
|
}
|
|
@@ -25387,10 +25628,10 @@ var HistoryService = class _HistoryService {
|
|
|
25387
25628
|
|
|
25388
25629
|
// src/agents/acp/client.ts
|
|
25389
25630
|
var import_node_child_process27 = require("child_process");
|
|
25390
|
-
var
|
|
25631
|
+
var fs61 = __toESM(require("fs/promises"));
|
|
25391
25632
|
var fsSync = __toESM(require("fs"));
|
|
25392
|
-
var
|
|
25393
|
-
var
|
|
25633
|
+
var os51 = __toESM(require("os"));
|
|
25634
|
+
var path66 = __toESM(require("path"));
|
|
25394
25635
|
var import_node_stream = require("stream");
|
|
25395
25636
|
|
|
25396
25637
|
// ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
|
|
@@ -30175,7 +30416,7 @@ var AcpClient = class {
|
|
|
30175
30416
|
},
|
|
30176
30417
|
readTextFile: async (params) => {
|
|
30177
30418
|
try {
|
|
30178
|
-
const content = await
|
|
30419
|
+
const content = await fs61.readFile(params.path, "utf8");
|
|
30179
30420
|
return applyLineRange(content, params.line ?? null, params.limit ?? null);
|
|
30180
30421
|
} catch (err) {
|
|
30181
30422
|
const code = err.code;
|
|
@@ -30195,7 +30436,7 @@ var AcpClient = class {
|
|
|
30195
30436
|
},
|
|
30196
30437
|
writeTextFile: async (params) => {
|
|
30197
30438
|
try {
|
|
30198
|
-
await
|
|
30439
|
+
await fs61.writeFile(params.path, params.content, "utf8");
|
|
30199
30440
|
return {};
|
|
30200
30441
|
} catch (err) {
|
|
30201
30442
|
const code = err.code;
|
|
@@ -30255,29 +30496,29 @@ function applyLineRange(content, line, limit) {
|
|
|
30255
30496
|
return { content: lines.slice(start2, end).join("\n") };
|
|
30256
30497
|
}
|
|
30257
30498
|
function knownAgentBinaryDirs() {
|
|
30258
|
-
const home =
|
|
30499
|
+
const home = os51.homedir();
|
|
30259
30500
|
const out2 = [];
|
|
30260
30501
|
out2.push("/tmp/codeam-node20/bin");
|
|
30261
30502
|
for (const root of [
|
|
30262
30503
|
"/usr/local/share/nvm/versions/node",
|
|
30263
|
-
|
|
30504
|
+
path66.join(home, ".nvm/versions/node")
|
|
30264
30505
|
]) {
|
|
30265
30506
|
try {
|
|
30266
30507
|
for (const child of fsSync.readdirSync(root)) {
|
|
30267
|
-
out2.push(
|
|
30508
|
+
out2.push(path66.join(root, child, "bin"));
|
|
30268
30509
|
}
|
|
30269
30510
|
} catch {
|
|
30270
30511
|
}
|
|
30271
30512
|
}
|
|
30272
|
-
out2.push(
|
|
30513
|
+
out2.push(path66.join(home, ".volta/bin"));
|
|
30273
30514
|
out2.push("/usr/local/bin");
|
|
30274
30515
|
out2.push("/usr/bin");
|
|
30275
|
-
out2.push(
|
|
30276
|
-
out2.push(
|
|
30516
|
+
out2.push(path66.join(home, ".local/bin"));
|
|
30517
|
+
out2.push(path66.join(home, "bin"));
|
|
30277
30518
|
if (process.platform === "win32") {
|
|
30278
30519
|
const { LOCALAPPDATA, APPDATA } = process.env;
|
|
30279
|
-
if (LOCALAPPDATA) out2.push(
|
|
30280
|
-
if (APPDATA) out2.push(
|
|
30520
|
+
if (LOCALAPPDATA) out2.push(path66.join(LOCALAPPDATA, "cursor-agent"));
|
|
30521
|
+
if (APPDATA) out2.push(path66.join(APPDATA, "npm"));
|
|
30281
30522
|
}
|
|
30282
30523
|
return out2.filter((p2) => {
|
|
30283
30524
|
try {
|
|
@@ -30289,7 +30530,7 @@ function knownAgentBinaryDirs() {
|
|
|
30289
30530
|
}
|
|
30290
30531
|
function expandPathForAgentBinaries(existingPath) {
|
|
30291
30532
|
const existing = new Set(
|
|
30292
|
-
existingPath.split(
|
|
30533
|
+
existingPath.split(path66.delimiter).filter((p2) => p2.length > 0)
|
|
30293
30534
|
);
|
|
30294
30535
|
const additions = [];
|
|
30295
30536
|
for (const dir of knownAgentBinaryDirs()) {
|
|
@@ -30299,7 +30540,7 @@ function expandPathForAgentBinaries(existingPath) {
|
|
|
30299
30540
|
}
|
|
30300
30541
|
}
|
|
30301
30542
|
if (additions.length === 0) return existingPath;
|
|
30302
|
-
return [...additions, existingPath].filter((p2) => p2.length > 0).join(
|
|
30543
|
+
return [...additions, existingPath].filter((p2) => p2.length > 0).join(path66.delimiter);
|
|
30303
30544
|
}
|
|
30304
30545
|
|
|
30305
30546
|
// src/agents/acp/headroom-budget-proxy.ts
|
|
@@ -30781,15 +31022,15 @@ function commonPrefixLength(a, b) {
|
|
|
30781
31022
|
|
|
30782
31023
|
// src/agents/acp/onboarding.ts
|
|
30783
31024
|
var import_child_process27 = require("child_process");
|
|
30784
|
-
var
|
|
30785
|
-
var
|
|
30786
|
-
var
|
|
31025
|
+
var fs62 = __toESM(require("fs"));
|
|
31026
|
+
var os52 = __toESM(require("os"));
|
|
31027
|
+
var path67 = __toESM(require("path"));
|
|
30787
31028
|
var _onboardingSeam = {
|
|
30788
|
-
markerPath: (sessionId) =>
|
|
30789
|
-
exists: (p2) =>
|
|
31029
|
+
markerPath: (sessionId) => path67.join(os52.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
31030
|
+
exists: (p2) => fs62.existsSync(p2),
|
|
30790
31031
|
write: (p2) => {
|
|
30791
|
-
|
|
30792
|
-
|
|
31032
|
+
fs62.mkdirSync(path67.dirname(p2), { recursive: true });
|
|
31033
|
+
fs62.writeFileSync(p2, "");
|
|
30793
31034
|
},
|
|
30794
31035
|
disabled: () => {
|
|
30795
31036
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -30826,7 +31067,7 @@ function resolveRepoName(cwd) {
|
|
|
30826
31067
|
if (name) return name;
|
|
30827
31068
|
}
|
|
30828
31069
|
}
|
|
30829
|
-
const base =
|
|
31070
|
+
const base = path67.basename(cwd || "");
|
|
30830
31071
|
if (base && !isUuid(base)) return base;
|
|
30831
31072
|
return "this project";
|
|
30832
31073
|
}
|
|
@@ -31078,13 +31319,13 @@ var import_crypto5 = require("crypto");
|
|
|
31078
31319
|
|
|
31079
31320
|
// src/services/turn-files/git-changeset.ts
|
|
31080
31321
|
var import_child_process28 = require("child_process");
|
|
31081
|
-
var
|
|
31082
|
-
var
|
|
31322
|
+
var fs64 = __toESM(require("fs/promises"));
|
|
31323
|
+
var path69 = __toESM(require("path"));
|
|
31083
31324
|
|
|
31084
31325
|
// src/services/turn-files/review-ignore.ts
|
|
31085
31326
|
var import_ignore2 = __toESM(require("ignore"));
|
|
31086
|
-
var
|
|
31087
|
-
var
|
|
31327
|
+
var fs63 = __toESM(require("fs"));
|
|
31328
|
+
var path68 = __toESM(require("path"));
|
|
31088
31329
|
var CURATED_REVIEW_IGNORE = [
|
|
31089
31330
|
// Google Cloud SDK (the incident) — installs a huge python tree.
|
|
31090
31331
|
"google-cloud-sdk/",
|
|
@@ -31123,7 +31364,7 @@ var CURATED_REVIEW_IGNORE = [
|
|
|
31123
31364
|
function makeReviewIgnore(repoRoot) {
|
|
31124
31365
|
const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
|
|
31125
31366
|
try {
|
|
31126
|
-
const custom =
|
|
31367
|
+
const custom = fs63.readFileSync(path68.join(repoRoot, ".codeam", "reviewignore"), "utf8");
|
|
31127
31368
|
ig.add(custom);
|
|
31128
31369
|
} catch {
|
|
31129
31370
|
}
|
|
@@ -31168,7 +31409,7 @@ async function collectRepoChangeset(opts) {
|
|
|
31168
31409
|
let stats;
|
|
31169
31410
|
if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
|
|
31170
31411
|
const lineCount = await readUntrackedLineCount(
|
|
31171
|
-
|
|
31412
|
+
path69.join(opts.repoRoot, row.filePath)
|
|
31172
31413
|
);
|
|
31173
31414
|
stats = { added: lineCount, removed: 0 };
|
|
31174
31415
|
} else {
|
|
@@ -31199,7 +31440,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
31199
31440
|
}
|
|
31200
31441
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
31201
31442
|
try {
|
|
31202
|
-
const content = await
|
|
31443
|
+
const content = await fs64.readFile(absPath, "utf8");
|
|
31203
31444
|
let count = 0;
|
|
31204
31445
|
let pos = -1;
|
|
31205
31446
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -31291,7 +31532,7 @@ function defaultRunGit(cwd, args2) {
|
|
|
31291
31532
|
});
|
|
31292
31533
|
}
|
|
31293
31534
|
async function discoverRepos(workingDir, maxDepth = 4) {
|
|
31294
|
-
const
|
|
31535
|
+
const fs69 = await import("fs/promises");
|
|
31295
31536
|
const out2 = [];
|
|
31296
31537
|
await walk(workingDir, 0);
|
|
31297
31538
|
return out2;
|
|
@@ -31299,7 +31540,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
31299
31540
|
if (depth > maxDepth) return;
|
|
31300
31541
|
let entries = [];
|
|
31301
31542
|
try {
|
|
31302
|
-
const dirents = await
|
|
31543
|
+
const dirents = await fs69.readdir(dir, { withFileTypes: true });
|
|
31303
31544
|
entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
|
|
31304
31545
|
} catch {
|
|
31305
31546
|
return;
|
|
@@ -31310,8 +31551,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
31310
31551
|
if (hasGit) {
|
|
31311
31552
|
out2.push({
|
|
31312
31553
|
repoRoot: dir,
|
|
31313
|
-
repoPath:
|
|
31314
|
-
repoName:
|
|
31554
|
+
repoPath: path69.relative(workingDir, dir),
|
|
31555
|
+
repoName: path69.basename(dir)
|
|
31315
31556
|
});
|
|
31316
31557
|
return;
|
|
31317
31558
|
}
|
|
@@ -31319,14 +31560,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
31319
31560
|
if (!entry.isDirectory) continue;
|
|
31320
31561
|
if (entry.name === "node_modules") continue;
|
|
31321
31562
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
31322
|
-
await walk(
|
|
31563
|
+
await walk(path69.join(dir, entry.name), depth + 1);
|
|
31323
31564
|
}
|
|
31324
31565
|
}
|
|
31325
31566
|
}
|
|
31326
31567
|
|
|
31327
31568
|
// src/services/turn-files/files-outbox.ts
|
|
31328
|
-
var
|
|
31329
|
-
var
|
|
31569
|
+
var fs65 = __toESM(require("fs/promises"));
|
|
31570
|
+
var path70 = __toESM(require("path"));
|
|
31330
31571
|
var import_os11 = require("os");
|
|
31331
31572
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
31332
31573
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -31359,16 +31600,16 @@ var FilesOutbox = class {
|
|
|
31359
31600
|
backoffIndex = 0;
|
|
31360
31601
|
stopped = false;
|
|
31361
31602
|
constructor(opts) {
|
|
31362
|
-
const base = opts.baseDir ??
|
|
31363
|
-
this.filePath =
|
|
31603
|
+
const base = opts.baseDir ?? path70.join(homeDir(), HOME_OUTBOX_DIR);
|
|
31604
|
+
this.filePath = path70.join(base, `${opts.sessionId}.jsonl`);
|
|
31364
31605
|
this.post = opts.post;
|
|
31365
31606
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
31366
31607
|
}
|
|
31367
31608
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
31368
31609
|
* line is durable on disk (not once the POST succeeds). */
|
|
31369
31610
|
async enqueue(entry) {
|
|
31370
|
-
await
|
|
31371
|
-
await
|
|
31611
|
+
await fs65.mkdir(path70.dirname(this.filePath), { recursive: true });
|
|
31612
|
+
await fs65.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
31372
31613
|
this.backoffIndex = 0;
|
|
31373
31614
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
31374
31615
|
}
|
|
@@ -31459,7 +31700,7 @@ var FilesOutbox = class {
|
|
|
31459
31700
|
async readAll() {
|
|
31460
31701
|
let raw = "";
|
|
31461
31702
|
try {
|
|
31462
|
-
raw = await
|
|
31703
|
+
raw = await fs65.readFile(this.filePath, "utf8");
|
|
31463
31704
|
} catch {
|
|
31464
31705
|
return [];
|
|
31465
31706
|
}
|
|
@@ -31483,12 +31724,12 @@ var FilesOutbox = class {
|
|
|
31483
31724
|
async rewrite(entries) {
|
|
31484
31725
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
31485
31726
|
if (entries.length === 0) {
|
|
31486
|
-
await
|
|
31727
|
+
await fs65.unlink(this.filePath).catch(() => void 0);
|
|
31487
31728
|
return;
|
|
31488
31729
|
}
|
|
31489
31730
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
31490
|
-
await
|
|
31491
|
-
await
|
|
31731
|
+
await fs65.writeFile(tmpPath, payload, "utf8");
|
|
31732
|
+
await fs65.rename(tmpPath, this.filePath);
|
|
31492
31733
|
}
|
|
31493
31734
|
};
|
|
31494
31735
|
function applyJitter(ms) {
|
|
@@ -32237,6 +32478,13 @@ async function setModeH(ctx) {
|
|
|
32237
32478
|
}
|
|
32238
32479
|
return;
|
|
32239
32480
|
}
|
|
32481
|
+
async function skillsConfigureH2(ctx) {
|
|
32482
|
+
const { cmd, relay } = ctx;
|
|
32483
|
+
const payload = cmd.payload;
|
|
32484
|
+
const res = configureSkill(payload?.action ?? "list", payload?.skillId);
|
|
32485
|
+
await relay.sendResult(cmd.id, res.ok ? "completed" : "failed", res);
|
|
32486
|
+
return;
|
|
32487
|
+
}
|
|
32240
32488
|
async function ackEmptyH(ctx) {
|
|
32241
32489
|
const { cmd, relay } = ctx;
|
|
32242
32490
|
await relay.sendResult(cmd.id, "completed", {});
|
|
@@ -32504,7 +32752,8 @@ var ACP_COMMAND_HANDLERS = {
|
|
|
32504
32752
|
request_preview_detect: previewH,
|
|
32505
32753
|
preview_start: previewH,
|
|
32506
32754
|
preview_stop: previewH,
|
|
32507
|
-
save_preview_config: previewH
|
|
32755
|
+
save_preview_config: previewH,
|
|
32756
|
+
skills_configure: skillsConfigureH2
|
|
32508
32757
|
};
|
|
32509
32758
|
async function dispatchAcpCommand(ctx) {
|
|
32510
32759
|
const handler = ACP_COMMAND_HANDLERS[ctx.cmd.type];
|
|
@@ -34430,6 +34679,26 @@ function buildMcpServersForStart(ctx) {
|
|
|
34430
34679
|
return servers;
|
|
34431
34680
|
}
|
|
34432
34681
|
|
|
34682
|
+
// src/skills/provision.ts
|
|
34683
|
+
var import_node_os12 = __toESM(require("os"));
|
|
34684
|
+
function provisionSkillsForStart(home = import_node_os12.default.homedir()) {
|
|
34685
|
+
const materialized = [];
|
|
34686
|
+
try {
|
|
34687
|
+
const manifest = readSkillsManifest();
|
|
34688
|
+
if (!manifest || manifest.skills.length === 0) return { materialized };
|
|
34689
|
+
for (const entry of manifest.skills) {
|
|
34690
|
+
if (!isSkillId(entry.id)) continue;
|
|
34691
|
+
if (materializeSkill(entry.id, home)) materialized.push(entry.id);
|
|
34692
|
+
}
|
|
34693
|
+
if (materialized.length) {
|
|
34694
|
+
log.info("skills", `materialized ${materialized.length} skill(s): ${materialized.join(", ")}`);
|
|
34695
|
+
}
|
|
34696
|
+
} catch (err) {
|
|
34697
|
+
log.warn("skills", `provisionSkillsForStart failed (best-effort): ${err instanceof Error ? err.message : String(err)}`);
|
|
34698
|
+
}
|
|
34699
|
+
return { materialized };
|
|
34700
|
+
}
|
|
34701
|
+
|
|
34433
34702
|
// src/baton/baton-controller.ts
|
|
34434
34703
|
var BatonController = class {
|
|
34435
34704
|
constructor(deps) {
|
|
@@ -34777,7 +35046,7 @@ var AcpDriver = class {
|
|
|
34777
35046
|
};
|
|
34778
35047
|
|
|
34779
35048
|
// src/baton/transcript-mirror.ts
|
|
34780
|
-
var
|
|
35049
|
+
var fs66 = __toESM(require("fs"));
|
|
34781
35050
|
var TranscriptMirror = class {
|
|
34782
35051
|
constructor(deps) {
|
|
34783
35052
|
this.deps = deps;
|
|
@@ -34844,7 +35113,7 @@ var TranscriptMirror = class {
|
|
|
34844
35113
|
}
|
|
34845
35114
|
};
|
|
34846
35115
|
function defaultWatch(file, onChange) {
|
|
34847
|
-
const w3 =
|
|
35116
|
+
const w3 = fs66.watch(file, { persistent: false }, () => onChange());
|
|
34848
35117
|
return () => w3.close();
|
|
34849
35118
|
}
|
|
34850
35119
|
|
|
@@ -35106,16 +35375,16 @@ function toEpochMs(ts) {
|
|
|
35106
35375
|
}
|
|
35107
35376
|
|
|
35108
35377
|
// src/agents/claude/onboarding.ts
|
|
35109
|
-
var
|
|
35110
|
-
var
|
|
35111
|
-
var
|
|
35378
|
+
var fs67 = __toESM(require("fs"));
|
|
35379
|
+
var os54 = __toESM(require("os"));
|
|
35380
|
+
var path71 = __toESM(require("path"));
|
|
35112
35381
|
var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
|
|
35113
35382
|
function ensureClaudeOnboarded(cwd) {
|
|
35114
35383
|
try {
|
|
35115
|
-
const file =
|
|
35384
|
+
const file = path71.join(os54.homedir(), ".claude.json");
|
|
35116
35385
|
let config = {};
|
|
35117
35386
|
try {
|
|
35118
|
-
config = JSON.parse(
|
|
35387
|
+
config = JSON.parse(fs67.readFileSync(file, "utf8"));
|
|
35119
35388
|
} catch {
|
|
35120
35389
|
}
|
|
35121
35390
|
let changed = false;
|
|
@@ -35140,8 +35409,8 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
35140
35409
|
}
|
|
35141
35410
|
}
|
|
35142
35411
|
if (!changed) return;
|
|
35143
|
-
|
|
35144
|
-
|
|
35412
|
+
fs67.mkdirSync(path71.dirname(file), { recursive: true });
|
|
35413
|
+
fs67.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
35145
35414
|
log.info(
|
|
35146
35415
|
"claude",
|
|
35147
35416
|
`pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
|
|
@@ -35252,6 +35521,7 @@ async function start(requestedAgent) {
|
|
|
35252
35521
|
pluginAuthToken: session.pluginAuthToken ?? void 0,
|
|
35253
35522
|
pollSecret: session.pollSecret
|
|
35254
35523
|
});
|
|
35524
|
+
provisionSkillsForStart();
|
|
35255
35525
|
const depsReady = process.env.CODESPACES === "true" ? provisionProjectDependencies(cwd).catch(() => void 0) : Promise.resolve();
|
|
35256
35526
|
if (process.env.CODESPACES === "true") {
|
|
35257
35527
|
const GATE_TIMEOUT_MS = 24e4;
|
|
@@ -35857,7 +36127,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
|
|
|
35857
36127
|
var import_child_process29 = require("child_process");
|
|
35858
36128
|
var import_util4 = require("util");
|
|
35859
36129
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
35860
|
-
var
|
|
36130
|
+
var path72 = __toESM(require("path"));
|
|
35861
36131
|
var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
|
|
35862
36132
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
35863
36133
|
function resetStdinForChild() {
|
|
@@ -36346,7 +36616,7 @@ var GitHubCodespacesProvider = class {
|
|
|
36346
36616
|
});
|
|
36347
36617
|
}
|
|
36348
36618
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
36349
|
-
const remoteDir =
|
|
36619
|
+
const remoteDir = path72.posix.dirname(remotePath);
|
|
36350
36620
|
const parts = [
|
|
36351
36621
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
36352
36622
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -36416,7 +36686,7 @@ function shellQuote(s) {
|
|
|
36416
36686
|
// src/services/providers/gitpod.ts
|
|
36417
36687
|
var import_child_process30 = require("child_process");
|
|
36418
36688
|
var import_util5 = require("util");
|
|
36419
|
-
var
|
|
36689
|
+
var path73 = __toESM(require("path"));
|
|
36420
36690
|
var import_picocolors10 = __toESM(require("picocolors"));
|
|
36421
36691
|
var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
|
|
36422
36692
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -36656,7 +36926,7 @@ var GitpodProvider = class {
|
|
|
36656
36926
|
});
|
|
36657
36927
|
}
|
|
36658
36928
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
36659
|
-
const remoteDir =
|
|
36929
|
+
const remoteDir = path73.posix.dirname(remotePath);
|
|
36660
36930
|
const parts = [
|
|
36661
36931
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
36662
36932
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -36692,7 +36962,7 @@ function shellQuote2(s) {
|
|
|
36692
36962
|
// src/services/providers/gitlab-workspaces.ts
|
|
36693
36963
|
var import_child_process31 = require("child_process");
|
|
36694
36964
|
var import_util6 = require("util");
|
|
36695
|
-
var
|
|
36965
|
+
var path74 = __toESM(require("path"));
|
|
36696
36966
|
var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
|
|
36697
36967
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
36698
36968
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -36952,7 +37222,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
36952
37222
|
}
|
|
36953
37223
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
36954
37224
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
36955
|
-
const remoteDir =
|
|
37225
|
+
const remoteDir = path74.posix.dirname(remotePath);
|
|
36956
37226
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
36957
37227
|
if (options.mode != null) {
|
|
36958
37228
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -37020,7 +37290,7 @@ function shellQuote3(s) {
|
|
|
37020
37290
|
// src/services/providers/railway.ts
|
|
37021
37291
|
var import_child_process32 = require("child_process");
|
|
37022
37292
|
var import_util7 = require("util");
|
|
37023
|
-
var
|
|
37293
|
+
var path75 = __toESM(require("path"));
|
|
37024
37294
|
var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
|
|
37025
37295
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
37026
37296
|
function resetStdinForChild4() {
|
|
@@ -37256,7 +37526,7 @@ var RailwayProvider = class {
|
|
|
37256
37526
|
if (!projectId || !serviceId) {
|
|
37257
37527
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
37258
37528
|
}
|
|
37259
|
-
const remoteDir =
|
|
37529
|
+
const remoteDir = path75.posix.dirname(remotePath);
|
|
37260
37530
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
37261
37531
|
if (options.mode != null) {
|
|
37262
37532
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -37902,8 +38172,8 @@ async function invite() {
|
|
|
37902
38172
|
var import_node_dns = require("dns");
|
|
37903
38173
|
var import_node_util5 = require("util");
|
|
37904
38174
|
var import_node_crypto12 = require("crypto");
|
|
37905
|
-
var
|
|
37906
|
-
var
|
|
38175
|
+
var fs68 = __toESM(require("fs"));
|
|
38176
|
+
var path76 = __toESM(require("path"));
|
|
37907
38177
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
37908
38178
|
var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
|
|
37909
38179
|
async function checkDns(apiBase2) {
|
|
@@ -37959,13 +38229,13 @@ async function checkHealth(apiBase2) {
|
|
|
37959
38229
|
}
|
|
37960
38230
|
}
|
|
37961
38231
|
function checkConfigDir() {
|
|
37962
|
-
const dir =
|
|
38232
|
+
const dir = path76.join(require("os").homedir(), ".codeam");
|
|
37963
38233
|
try {
|
|
37964
|
-
|
|
37965
|
-
const probe =
|
|
37966
|
-
|
|
37967
|
-
const read2 =
|
|
37968
|
-
|
|
38234
|
+
fs68.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
38235
|
+
const probe = path76.join(dir, ".doctor-probe");
|
|
38236
|
+
fs68.writeFileSync(probe, "ok", { mode: 384 });
|
|
38237
|
+
const read2 = fs68.readFileSync(probe, "utf8");
|
|
38238
|
+
fs68.unlinkSync(probe);
|
|
37969
38239
|
if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
|
|
37970
38240
|
return {
|
|
37971
38241
|
id: "config-dir",
|
|
@@ -38005,9 +38275,9 @@ function checkSessions() {
|
|
|
38005
38275
|
}
|
|
38006
38276
|
}
|
|
38007
38277
|
function checkAgentBinaries() {
|
|
38008
|
-
const
|
|
38278
|
+
const os57 = createOsStrategy();
|
|
38009
38279
|
return getEnabledAgents().map((meta) => {
|
|
38010
|
-
const found =
|
|
38280
|
+
const found = os57.findInPath(meta.binaryName);
|
|
38011
38281
|
return {
|
|
38012
38282
|
id: `agent-${meta.id}`,
|
|
38013
38283
|
label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
|
|
@@ -38029,7 +38299,7 @@ function checkNodePty() {
|
|
|
38029
38299
|
detail: "not required on this platform"
|
|
38030
38300
|
};
|
|
38031
38301
|
}
|
|
38032
|
-
const vendoredPath =
|
|
38302
|
+
const vendoredPath = path76.join(__dirname, "vendor", "node-pty");
|
|
38033
38303
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
38034
38304
|
try {
|
|
38035
38305
|
require(target);
|
|
@@ -38071,7 +38341,7 @@ function checkChokidar() {
|
|
|
38071
38341
|
}
|
|
38072
38342
|
async function doctor(args2 = []) {
|
|
38073
38343
|
const json = args2.includes("--json");
|
|
38074
|
-
const cliVersion = true ? "2.61.
|
|
38344
|
+
const cliVersion = true ? "2.61.24" : "0.0.0-dev";
|
|
38075
38345
|
const apiBase2 = resolveApiBaseUrl();
|
|
38076
38346
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
38077
38347
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -38269,9 +38539,9 @@ async function completion(args2) {
|
|
|
38269
38539
|
|
|
38270
38540
|
// src/integrations/mcp-run.ts
|
|
38271
38541
|
var import_node_child_process29 = require("child_process");
|
|
38272
|
-
var
|
|
38273
|
-
var
|
|
38274
|
-
var
|
|
38542
|
+
var import_node_fs11 = require("fs");
|
|
38543
|
+
var import_node_os13 = __toESM(require("os"));
|
|
38544
|
+
var import_node_path10 = __toESM(require("path"));
|
|
38275
38545
|
|
|
38276
38546
|
// src/integrations/token-client.ts
|
|
38277
38547
|
var REFRESH_AHEAD_MS = 5 * 60 * 1e3;
|
|
@@ -38493,13 +38763,13 @@ function commandExists(command2) {
|
|
|
38493
38763
|
}
|
|
38494
38764
|
function localBinCandidates(command2) {
|
|
38495
38765
|
return [
|
|
38496
|
-
|
|
38497
|
-
|
|
38766
|
+
import_node_path10.default.join(import_node_os13.default.homedir(), ".local", "bin", command2),
|
|
38767
|
+
import_node_path10.default.join(import_node_os13.default.homedir(), ".cargo", "bin", command2)
|
|
38498
38768
|
];
|
|
38499
38769
|
}
|
|
38500
38770
|
function resolveLauncherPath(command2, deps = {
|
|
38501
38771
|
commandExists,
|
|
38502
|
-
existsSync:
|
|
38772
|
+
existsSync: import_node_fs11.existsSync
|
|
38503
38773
|
}) {
|
|
38504
38774
|
if (deps.commandExists(command2)) return command2;
|
|
38505
38775
|
for (const candidate of localBinCandidates(command2)) {
|
|
@@ -38582,7 +38852,7 @@ async function mcpRun(args2) {
|
|
|
38582
38852
|
// src/commands/version.ts
|
|
38583
38853
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
38584
38854
|
function version2() {
|
|
38585
|
-
const v = true ? "2.61.
|
|
38855
|
+
const v = true ? "2.61.24" : "unknown";
|
|
38586
38856
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
38587
38857
|
}
|
|
38588
38858
|
|
|
@@ -38731,10 +39001,10 @@ var EXIT_CODE_NAMES = {
|
|
|
38731
39001
|
};
|
|
38732
39002
|
|
|
38733
39003
|
// src/index.ts
|
|
38734
|
-
var
|
|
39004
|
+
var os56 = __toESM(require("os"));
|
|
38735
39005
|
if (!process.env.HOME) {
|
|
38736
39006
|
try {
|
|
38737
|
-
const home =
|
|
39007
|
+
const home = os56.homedir();
|
|
38738
39008
|
if (home) process.env.HOME = home;
|
|
38739
39009
|
} catch {
|
|
38740
39010
|
}
|