codeam-cli 2.75.20 → 2.75.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/index.js +298 -267
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to `codeam-cli` are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.75.21] — 2026-09-25
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **cli:** Close ACP tool rows whose completion carries no content
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
|
|
15
|
+
- **cli:** Build opencode config paths with path.join so Windows CI passes
|
|
16
|
+
|
|
17
|
+
## [2.75.20] — 2026-09-25
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **cli:** Preview heals a committed host-allow shim instead of wrapping it
|
|
22
|
+
|
|
7
23
|
## [2.75.19] — 2026-09-25
|
|
8
24
|
|
|
9
25
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -357,7 +357,7 @@ function defaultSpawn(timeoutMs) {
|
|
|
357
357
|
});
|
|
358
358
|
}
|
|
359
359
|
function resolveConvexBin(cwd) {
|
|
360
|
-
const local =
|
|
360
|
+
const local = path93.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
|
|
361
361
|
if (fs79.existsSync(local)) return { cmd: local, args: [] };
|
|
362
362
|
return { cmd: "npx", args: ["--yes", "convex"] };
|
|
363
363
|
}
|
|
@@ -489,13 +489,13 @@ async function runConvexAdminMcp(client3, id) {
|
|
|
489
489
|
});
|
|
490
490
|
await server.connect(new StdioServerTransport());
|
|
491
491
|
}
|
|
492
|
-
var import_node_child_process32, fs79,
|
|
492
|
+
var import_node_child_process32, fs79, path93, TOOLS;
|
|
493
493
|
var init_convex_admin_mcp = __esm({
|
|
494
494
|
"src/integrations/convex-admin-mcp.ts"() {
|
|
495
495
|
"use strict";
|
|
496
496
|
import_node_child_process32 = require("child_process");
|
|
497
497
|
fs79 = __toESM(require("fs"));
|
|
498
|
-
|
|
498
|
+
path93 = __toESM(require("path"));
|
|
499
499
|
TOOLS = [
|
|
500
500
|
{
|
|
501
501
|
name: "tables",
|
|
@@ -3525,11 +3525,11 @@ function quiet(fn) {
|
|
|
3525
3525
|
log.debug(TAG, "ignored sync error", err);
|
|
3526
3526
|
}
|
|
3527
3527
|
}
|
|
3528
|
-
function rmIfExistsQuiet(
|
|
3528
|
+
function rmIfExistsQuiet(path95) {
|
|
3529
3529
|
try {
|
|
3530
|
-
fs2.rmSync(
|
|
3530
|
+
fs2.rmSync(path95, { force: true });
|
|
3531
3531
|
} catch (err) {
|
|
3532
|
-
log.debug(TAG, `rmIfExists failed for ${
|
|
3532
|
+
log.debug(TAG, `rmIfExists failed for ${path95}`, err);
|
|
3533
3533
|
}
|
|
3534
3534
|
}
|
|
3535
3535
|
function killQuiet(target, signal = "SIGTERM") {
|
|
@@ -3733,8 +3733,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
|
|
|
3733
3733
|
return decodedFile;
|
|
3734
3734
|
};
|
|
3735
3735
|
}
|
|
3736
|
-
function normalizeWindowsPath(
|
|
3737
|
-
return
|
|
3736
|
+
function normalizeWindowsPath(path95) {
|
|
3737
|
+
return path95.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
3738
3738
|
}
|
|
3739
3739
|
|
|
3740
3740
|
// ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
|
|
@@ -6467,13 +6467,13 @@ var PostHogCoreStateless = class {
|
|
|
6467
6467
|
sentFromRoute += batchMessages.length;
|
|
6468
6468
|
}
|
|
6469
6469
|
}
|
|
6470
|
-
async _sendOtlpBatch({ path:
|
|
6470
|
+
async _sendOtlpBatch({ path: path95, payload }) {
|
|
6471
6471
|
if (this.disabled) return {
|
|
6472
6472
|
kind: "fatal",
|
|
6473
6473
|
error: new Error("The client is disabled")
|
|
6474
6474
|
};
|
|
6475
6475
|
const serialized = JSON.stringify(payload);
|
|
6476
|
-
const url2 = `${this.host}/i/v1/${
|
|
6476
|
+
const url2 = `${this.host}/i/v1/${path95}?token=${encodeURIComponent(this.apiKey)}`;
|
|
6477
6477
|
const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
|
|
6478
6478
|
const fetchOptions = {
|
|
6479
6479
|
method: "POST",
|
|
@@ -7713,14 +7713,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
|
|
|
7713
7713
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
7714
7714
|
return frames;
|
|
7715
7715
|
}
|
|
7716
|
-
async function openRegularSourceFile(
|
|
7716
|
+
async function openRegularSourceFile(path95, openSourceFile, logger) {
|
|
7717
7717
|
let fileHandle;
|
|
7718
7718
|
let isValid = false;
|
|
7719
7719
|
try {
|
|
7720
|
-
fileHandle = await openSourceFile(
|
|
7720
|
+
fileHandle = await openSourceFile(path95, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
|
|
7721
7721
|
const fileStat = await fileHandle.stat();
|
|
7722
7722
|
if (!fileStat.isFile()) return;
|
|
7723
|
-
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${
|
|
7723
|
+
if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path95}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
|
|
7724
7724
|
isValid = true;
|
|
7725
7725
|
return fileHandle;
|
|
7726
7726
|
} catch {
|
|
@@ -7730,8 +7730,8 @@ async function openRegularSourceFile(path94, openSourceFile, logger) {
|
|
|
7730
7730
|
});
|
|
7731
7731
|
}
|
|
7732
7732
|
}
|
|
7733
|
-
async function getContextLinesFromFile(
|
|
7734
|
-
const fileHandle = await openRegularSourceFile(
|
|
7733
|
+
async function getContextLinesFromFile(path95, ranges, output, cacheKey, openSourceFile, logger) {
|
|
7734
|
+
const fileHandle = await openRegularSourceFile(path95, openSourceFile, logger);
|
|
7735
7735
|
if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
|
|
7736
7736
|
const openedFileHandle = fileHandle;
|
|
7737
7737
|
return new Promise((resolve12) => {
|
|
@@ -7833,22 +7833,22 @@ function clearLineContext(frame) {
|
|
|
7833
7833
|
delete frame.context_line;
|
|
7834
7834
|
delete frame.post_context;
|
|
7835
7835
|
}
|
|
7836
|
-
function shouldSkipContextLinesForFile(
|
|
7837
|
-
return
|
|
7836
|
+
function shouldSkipContextLinesForFile(path95) {
|
|
7837
|
+
return path95.startsWith("node:") || path95.endsWith(".min.js") || path95.endsWith(".min.cjs") || path95.endsWith(".min.mjs") || path95.startsWith("data:");
|
|
7838
7838
|
}
|
|
7839
7839
|
function shouldSkipContextLinesForFrame(frame) {
|
|
7840
7840
|
if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
|
|
7841
7841
|
if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
|
|
7842
7842
|
return false;
|
|
7843
7843
|
}
|
|
7844
|
-
function makeSourceCacheKey(
|
|
7845
|
-
if ((0, import_node_path.isAbsolute)(
|
|
7844
|
+
function makeSourceCacheKey(path95, basePath) {
|
|
7845
|
+
if ((0, import_node_path.isAbsolute)(path95)) return JSON.stringify([
|
|
7846
7846
|
null,
|
|
7847
|
-
|
|
7847
|
+
path95
|
|
7848
7848
|
]);
|
|
7849
7849
|
return void 0 === basePath ? void 0 : JSON.stringify([
|
|
7850
7850
|
basePath,
|
|
7851
|
-
|
|
7851
|
+
path95
|
|
7852
7852
|
]);
|
|
7853
7853
|
}
|
|
7854
7854
|
function rangeExistsInContentCache(cacheKey, range) {
|
|
@@ -10509,7 +10509,7 @@ function readAnonId() {
|
|
|
10509
10509
|
}
|
|
10510
10510
|
function superProperties() {
|
|
10511
10511
|
return {
|
|
10512
|
-
cliVersion: true ? "2.75.
|
|
10512
|
+
cliVersion: true ? "2.75.22" : "0.0.0-dev",
|
|
10513
10513
|
nodeVersion: process.version,
|
|
10514
10514
|
platform: process.platform,
|
|
10515
10515
|
arch: process.arch,
|
|
@@ -10751,7 +10751,7 @@ var http = __toESM(require("http"));
|
|
|
10751
10751
|
// package.json
|
|
10752
10752
|
var package_default = {
|
|
10753
10753
|
name: "codeam-cli",
|
|
10754
|
-
version: "2.75.
|
|
10754
|
+
version: "2.75.22",
|
|
10755
10755
|
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.",
|
|
10756
10756
|
type: "commonjs",
|
|
10757
10757
|
main: "dist/index.js",
|
|
@@ -12081,7 +12081,7 @@ var CommandRelayService = class _CommandRelayService {
|
|
|
12081
12081
|
// fresh + clear the "CLI update available" banner after a self-update
|
|
12082
12082
|
// (a codespace that reinstalls @latest reconnects via heartbeat, not
|
|
12083
12083
|
// pair/reconnect). Older backends ignore the extra field.
|
|
12084
|
-
..."2.75.
|
|
12084
|
+
..."2.75.22" ? { ideVersion: "2.75.22" } : {}
|
|
12085
12085
|
};
|
|
12086
12086
|
try {
|
|
12087
12087
|
const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
|
|
@@ -19601,8 +19601,8 @@ function pickLine(obj) {
|
|
|
19601
19601
|
function toHunk(raw, groupSeverity) {
|
|
19602
19602
|
if (!raw || typeof raw !== "object") return null;
|
|
19603
19603
|
const o = raw;
|
|
19604
|
-
const
|
|
19605
|
-
if (!
|
|
19604
|
+
const path95 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
|
|
19605
|
+
if (!path95) return null;
|
|
19606
19606
|
const message = asString(
|
|
19607
19607
|
pick(o, [
|
|
19608
19608
|
"comment",
|
|
@@ -19619,7 +19619,7 @@ function toHunk(raw, groupSeverity) {
|
|
|
19619
19619
|
const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
|
|
19620
19620
|
const locObj = pick(o, ["location"]) ?? o;
|
|
19621
19621
|
return {
|
|
19622
|
-
path:
|
|
19622
|
+
path: path95.trim(),
|
|
19623
19623
|
line: pickLine(o) ?? pickLine(locObj),
|
|
19624
19624
|
severity,
|
|
19625
19625
|
message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
|
|
@@ -19702,10 +19702,10 @@ function parsePlain(stdout) {
|
|
|
19702
19702
|
for (const line of stdout.split(/\r?\n/)) {
|
|
19703
19703
|
const m = line.match(HUNK_LINE_RE);
|
|
19704
19704
|
if (!m) continue;
|
|
19705
|
-
const [,
|
|
19706
|
-
if (!
|
|
19705
|
+
const [, path95, lineNo, sevToken, message] = m;
|
|
19706
|
+
if (!path95 || !lineNo || !message) continue;
|
|
19707
19707
|
hunks.push({
|
|
19708
|
-
path:
|
|
19708
|
+
path: path95.trim(),
|
|
19709
19709
|
line: Number(lineNo),
|
|
19710
19710
|
severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
|
|
19711
19711
|
message: message.trim().replace(/^[*-]\s+/, "")
|
|
@@ -28266,11 +28266,11 @@ function resolveTokenValue(args2) {
|
|
|
28266
28266
|
}
|
|
28267
28267
|
const fileFlag = args2.find((a) => a.startsWith("--token-file="));
|
|
28268
28268
|
if (fileFlag) {
|
|
28269
|
-
const
|
|
28269
|
+
const path95 = fileFlag.slice("--token-file=".length);
|
|
28270
28270
|
try {
|
|
28271
|
-
const content = fs51.readFileSync(
|
|
28272
|
-
if (content.length === 0) fail(`--token-file ${
|
|
28273
|
-
rmIfExistsQuiet(
|
|
28271
|
+
const content = fs51.readFileSync(path95, "utf8").trim();
|
|
28272
|
+
if (content.length === 0) fail(`--token-file ${path95} is empty`);
|
|
28273
|
+
rmIfExistsQuiet(path95);
|
|
28274
28274
|
return content;
|
|
28275
28275
|
} catch (err) {
|
|
28276
28276
|
fail(`Could not read --token-file: ${err.message}`);
|
|
@@ -29204,9 +29204,9 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
|
|
|
29204
29204
|
|
|
29205
29205
|
// src/agents/acp/runner.ts
|
|
29206
29206
|
var import_node_crypto10 = require("crypto");
|
|
29207
|
-
var
|
|
29208
|
-
var
|
|
29209
|
-
var
|
|
29207
|
+
var fs68 = __toESM(require("fs"));
|
|
29208
|
+
var os53 = __toESM(require("os"));
|
|
29209
|
+
var path79 = __toESM(require("path"));
|
|
29210
29210
|
|
|
29211
29211
|
// src/lib/provider-routing.ts
|
|
29212
29212
|
var fs53 = __toESM(require("fs"));
|
|
@@ -35913,6 +35913,116 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir(
|
|
|
35913
35913
|
return provisioner.write(auth, homeDir2);
|
|
35914
35914
|
}
|
|
35915
35915
|
|
|
35916
|
+
// src/beads/workflow-hint.ts
|
|
35917
|
+
var fs57 = __toESM(require("fs"));
|
|
35918
|
+
var path68 = __toESM(require("path"));
|
|
35919
|
+
|
|
35920
|
+
// src/agents/claude-memory-file.ts
|
|
35921
|
+
var os48 = __toESM(require("os"));
|
|
35922
|
+
var path67 = __toESM(require("path"));
|
|
35923
|
+
function claudeMemoryFile(homeDir2, env = process.env) {
|
|
35924
|
+
if (homeDir2) return path67.join(homeDir2, ".claude", "CLAUDE.md");
|
|
35925
|
+
const configDir = env.CLAUDE_CONFIG_DIR?.trim();
|
|
35926
|
+
return configDir ? path67.join(configDir, "CLAUDE.md") : path67.join(os48.homedir(), ".claude", "CLAUDE.md");
|
|
35927
|
+
}
|
|
35928
|
+
|
|
35929
|
+
// src/beads/workflow-hint.ts
|
|
35930
|
+
var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
|
|
35931
|
+
var BEADS_HINT = `${BEADS_HINT_MARKER}
|
|
35932
|
+
# Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
|
|
35933
|
+
|
|
35934
|
+
This environment uses **bd (beads)** for issue/task tracking and persistent memory.
|
|
35935
|
+
|
|
35936
|
+
- Use \`bd\` for ALL task tracking \u2014 do NOT use TodoWrite or markdown TODO lists.
|
|
35937
|
+
- Run \`bd prime\` (via your shell tool, once) when you start working on a task, for
|
|
35938
|
+
the full workflow context + project memories. Not needed to answer a greeting or
|
|
35939
|
+
a quick question. On a fresh session beads may still be provisioning for a few
|
|
35940
|
+
seconds \u2014 if \`bd prime\` comes back empty, retry it shortly; it works once the
|
|
35941
|
+
shared server is up.
|
|
35942
|
+
- \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
|
|
35943
|
+
- Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
|
|
35944
|
+
- Run \`bd\` commands through your shell tool and summarize the outcome. Never
|
|
35945
|
+
paste \`bd\` commands or their raw output into your reply.
|
|
35946
|
+
- CodeAgent installs, starts and repairs beads \u2014 not you. If a \`bd\` command
|
|
35947
|
+
fails, carry on with the user's task without task tracking and try \`bd\`
|
|
35948
|
+
again later. Never run \`bd init\`, \`bd bootstrap\`, \`bd doctor --fix\` or
|
|
35949
|
+
\`dolt\` commands yourself: they race the provisioning and can wipe the
|
|
35950
|
+
project's issues.
|
|
35951
|
+
${BEADS_HINT_MARKER}`;
|
|
35952
|
+
function ensureBeadsWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
|
|
35953
|
+
try {
|
|
35954
|
+
let existing = "";
|
|
35955
|
+
try {
|
|
35956
|
+
existing = fs57.readFileSync(file, "utf8");
|
|
35957
|
+
} catch {
|
|
35958
|
+
}
|
|
35959
|
+
if (existing.includes(BEADS_HINT)) return;
|
|
35960
|
+
fs57.mkdirSync(path68.dirname(file), { recursive: true });
|
|
35961
|
+
let next;
|
|
35962
|
+
const open = existing.indexOf(BEADS_HINT_MARKER);
|
|
35963
|
+
const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
|
|
35964
|
+
if (open !== -1 && close !== -1) {
|
|
35965
|
+
next = existing.slice(0, open) + BEADS_HINT + existing.slice(close + BEADS_HINT_MARKER.length);
|
|
35966
|
+
} else {
|
|
35967
|
+
next = existing.trim() ? `${existing.trimEnd()}
|
|
35968
|
+
|
|
35969
|
+
${BEADS_HINT}
|
|
35970
|
+
` : `${BEADS_HINT}
|
|
35971
|
+
`;
|
|
35972
|
+
}
|
|
35973
|
+
fs57.writeFileSync(file, next);
|
|
35974
|
+
} catch {
|
|
35975
|
+
}
|
|
35976
|
+
}
|
|
35977
|
+
|
|
35978
|
+
// src/agents/agent-standard.ts
|
|
35979
|
+
var fs58 = __toESM(require("fs"));
|
|
35980
|
+
var path69 = __toESM(require("path"));
|
|
35981
|
+
var os49 = __toESM(require("os"));
|
|
35982
|
+
function ensureAgentStandard(homeDir2, file = claudeMemoryFile(homeDir2)) {
|
|
35983
|
+
try {
|
|
35984
|
+
let existing = "";
|
|
35985
|
+
try {
|
|
35986
|
+
existing = fs58.readFileSync(file, "utf8");
|
|
35987
|
+
} catch {
|
|
35988
|
+
}
|
|
35989
|
+
if (existing.includes(AGENT_STANDARD_MARKER)) return;
|
|
35990
|
+
fs58.mkdirSync(path69.dirname(file), { recursive: true });
|
|
35991
|
+
const next = existing.trim() ? `${existing.trimEnd()}
|
|
35992
|
+
|
|
35993
|
+
${AGENT_STANDARD_BLOCK}
|
|
35994
|
+
` : `${AGENT_STANDARD_BLOCK}
|
|
35995
|
+
`;
|
|
35996
|
+
fs58.writeFileSync(file, next);
|
|
35997
|
+
} catch {
|
|
35998
|
+
}
|
|
35999
|
+
}
|
|
36000
|
+
var _agentStandardSeam = {
|
|
36001
|
+
isLocalSession: () => isLocalSession(),
|
|
36002
|
+
markerPath: (sessionId) => path69.join(os49.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
|
|
36003
|
+
exists: (p2) => fs58.existsSync(p2),
|
|
36004
|
+
write: (p2) => {
|
|
36005
|
+
fs58.mkdirSync(path69.dirname(p2), { recursive: true });
|
|
36006
|
+
fs58.writeFileSync(p2, "");
|
|
36007
|
+
}
|
|
36008
|
+
};
|
|
36009
|
+
function isClaude(agent) {
|
|
36010
|
+
return agent === "claude" || agent === "claude_code";
|
|
36011
|
+
}
|
|
36012
|
+
function maybePrefaceAgentStandard(blocks, agent, sessionId, seam = _agentStandardSeam) {
|
|
36013
|
+
if (seam.isLocalSession()) return;
|
|
36014
|
+
if (isClaude(agent)) return;
|
|
36015
|
+
if (!sessionId) return;
|
|
36016
|
+
const marker = seam.markerPath(sessionId);
|
|
36017
|
+
try {
|
|
36018
|
+
if (seam.exists(marker)) return;
|
|
36019
|
+
seam.write(marker);
|
|
36020
|
+
} catch {
|
|
36021
|
+
return;
|
|
36022
|
+
}
|
|
36023
|
+
blocks.unshift({ type: "text", text: AGENT_STANDARD_TEXT });
|
|
36024
|
+
}
|
|
36025
|
+
|
|
35916
36026
|
// src/services/streaming/transport.ts
|
|
35917
36027
|
var http10 = __toESM(require("http"));
|
|
35918
36028
|
var https7 = __toESM(require("https"));
|
|
@@ -36586,15 +36696,15 @@ function withholdTrailingPartialFenceMarker(text) {
|
|
|
36586
36696
|
|
|
36587
36697
|
// src/agents/acp/onboarding.ts
|
|
36588
36698
|
var import_child_process28 = require("child_process");
|
|
36589
|
-
var
|
|
36590
|
-
var
|
|
36591
|
-
var
|
|
36699
|
+
var fs59 = __toESM(require("fs"));
|
|
36700
|
+
var os50 = __toESM(require("os"));
|
|
36701
|
+
var path70 = __toESM(require("path"));
|
|
36592
36702
|
var _onboardingSeam = {
|
|
36593
|
-
markerPath: (sessionId) =>
|
|
36594
|
-
exists: (p2) =>
|
|
36703
|
+
markerPath: (sessionId) => path70.join(os50.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
|
|
36704
|
+
exists: (p2) => fs59.existsSync(p2),
|
|
36595
36705
|
write: (p2) => {
|
|
36596
|
-
|
|
36597
|
-
|
|
36706
|
+
fs59.mkdirSync(path70.dirname(p2), { recursive: true });
|
|
36707
|
+
fs59.writeFileSync(p2, "");
|
|
36598
36708
|
},
|
|
36599
36709
|
disabled: () => {
|
|
36600
36710
|
const v = process.env.CODEAM_ONBOARDING_DISABLED;
|
|
@@ -36631,7 +36741,7 @@ function resolveRepoName(cwd) {
|
|
|
36631
36741
|
if (name) return name;
|
|
36632
36742
|
}
|
|
36633
36743
|
}
|
|
36634
|
-
const base =
|
|
36744
|
+
const base = path70.basename(cwd || "");
|
|
36635
36745
|
if (base && !isUuid(base)) return base;
|
|
36636
36746
|
return "this project";
|
|
36637
36747
|
}
|
|
@@ -36711,11 +36821,30 @@ var import_node_crypto9 = require("crypto");
|
|
|
36711
36821
|
var BD_PRIME_COMMAND_RE = /(?:^|[;&|]\s*)bd\s+prime\b/;
|
|
36712
36822
|
var ToolCallTracker = class {
|
|
36713
36823
|
bdPrimeIds = /* @__PURE__ */ new Set();
|
|
36824
|
+
/** Latest non-empty title per open call — see {@link lastTitle}. */
|
|
36825
|
+
titles = /* @__PURE__ */ new Map();
|
|
36714
36826
|
/** Record a `tool_call` so its later `tool_call_update` can be recognised. */
|
|
36715
36827
|
note(update) {
|
|
36716
|
-
if (
|
|
36828
|
+
if (!update.toolCallId) return;
|
|
36829
|
+
if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") return;
|
|
36830
|
+
const title = update.title?.trim();
|
|
36831
|
+
if (title) this.titles.set(update.toolCallId, title);
|
|
36832
|
+
if (update.sessionUpdate !== "tool_call") return;
|
|
36717
36833
|
if (isBdPrimeInvocation(update)) this.bdPrimeIds.add(update.toolCallId);
|
|
36718
36834
|
}
|
|
36835
|
+
/**
|
|
36836
|
+
* The call's most recent title, forgotten once read. claude-agent-acp opens
|
|
36837
|
+
* a Write as "Preparing file…", renames it in a non-terminal update
|
|
36838
|
+
* ("Write FOO.md"), then completes it with NO content and an EMPTY title —
|
|
36839
|
+
* the completion mapped to nothing and the phone showed "Preparing file…"
|
|
36840
|
+
* pending forever (break-it 2026-09-24, fleet box).
|
|
36841
|
+
*/
|
|
36842
|
+
lastTitle(toolCallId) {
|
|
36843
|
+
if (!toolCallId) return null;
|
|
36844
|
+
const title = this.titles.get(toolCallId) ?? null;
|
|
36845
|
+
this.titles.delete(toolCallId);
|
|
36846
|
+
return title;
|
|
36847
|
+
}
|
|
36719
36848
|
/** True when this tool call was `bd prime`; forgets terminal ids. */
|
|
36720
36849
|
isBdPrime(toolCallId, terminal) {
|
|
36721
36850
|
if (!toolCallId) return false;
|
|
@@ -36763,7 +36892,8 @@ function mapSessionUpdate(notification, tracker) {
|
|
|
36763
36892
|
if (update.status !== "completed" && update.status !== "failed") {
|
|
36764
36893
|
return [];
|
|
36765
36894
|
}
|
|
36766
|
-
const
|
|
36895
|
+
const remembered = tracker?.lastTitle(update.toolCallId) ?? null;
|
|
36896
|
+
const rawBody = describeToolCallUpdate(update) ?? remembered;
|
|
36767
36897
|
if (!rawBody) return [];
|
|
36768
36898
|
const body = update.status === "completed" && tracker?.isBdPrime(update.toolCallId, true) ? bdPrimeResultSummary(rawBody) : rawBody;
|
|
36769
36899
|
const prefix = update.status === "failed" ? "[failed] " : "";
|
|
@@ -37003,13 +37133,13 @@ var import_crypto4 = require("crypto");
|
|
|
37003
37133
|
|
|
37004
37134
|
// src/services/turn-files/git-changeset.ts
|
|
37005
37135
|
var import_child_process29 = require("child_process");
|
|
37006
|
-
var
|
|
37007
|
-
var
|
|
37136
|
+
var fs61 = __toESM(require("fs/promises"));
|
|
37137
|
+
var path72 = __toESM(require("path"));
|
|
37008
37138
|
|
|
37009
37139
|
// src/services/turn-files/review-ignore.ts
|
|
37010
37140
|
var import_ignore2 = __toESM(require("ignore"));
|
|
37011
|
-
var
|
|
37012
|
-
var
|
|
37141
|
+
var fs60 = __toESM(require("fs"));
|
|
37142
|
+
var path71 = __toESM(require("path"));
|
|
37013
37143
|
var CURATED_REVIEW_IGNORE = [
|
|
37014
37144
|
// Google Cloud SDK (the incident) — installs a huge python tree.
|
|
37015
37145
|
"google-cloud-sdk/",
|
|
@@ -37048,7 +37178,7 @@ var CURATED_REVIEW_IGNORE = [
|
|
|
37048
37178
|
function makeReviewIgnore(repoRoot) {
|
|
37049
37179
|
const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
|
|
37050
37180
|
try {
|
|
37051
|
-
const custom =
|
|
37181
|
+
const custom = fs60.readFileSync(path71.join(repoRoot, ".codeam", "reviewignore"), "utf8");
|
|
37052
37182
|
ig.add(custom);
|
|
37053
37183
|
} catch {
|
|
37054
37184
|
}
|
|
@@ -37093,7 +37223,7 @@ async function collectRepoChangeset(opts) {
|
|
|
37093
37223
|
let stats;
|
|
37094
37224
|
if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
|
|
37095
37225
|
const lineCount = await readUntrackedLineCount(
|
|
37096
|
-
|
|
37226
|
+
path72.join(opts.repoRoot, row.filePath)
|
|
37097
37227
|
);
|
|
37098
37228
|
stats = { added: lineCount, removed: 0 };
|
|
37099
37229
|
} else {
|
|
@@ -37124,7 +37254,7 @@ function readUntrackedLineCount(absPath) {
|
|
|
37124
37254
|
}
|
|
37125
37255
|
async function defaultReadUntrackedLineCount(absPath) {
|
|
37126
37256
|
try {
|
|
37127
|
-
const content = await
|
|
37257
|
+
const content = await fs61.readFile(absPath, "utf8");
|
|
37128
37258
|
let count = 0;
|
|
37129
37259
|
let pos = -1;
|
|
37130
37260
|
while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
|
|
@@ -37235,8 +37365,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
37235
37365
|
if (hasGit) {
|
|
37236
37366
|
out2.push({
|
|
37237
37367
|
repoRoot: dir,
|
|
37238
|
-
repoPath:
|
|
37239
|
-
repoName:
|
|
37368
|
+
repoPath: path72.relative(workingDir, dir),
|
|
37369
|
+
repoName: path72.basename(dir)
|
|
37240
37370
|
});
|
|
37241
37371
|
return;
|
|
37242
37372
|
}
|
|
@@ -37244,14 +37374,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
|
|
|
37244
37374
|
if (!entry.isDirectory) continue;
|
|
37245
37375
|
if (entry.name === "node_modules") continue;
|
|
37246
37376
|
if (entry.name === "dist" || entry.name === "build") continue;
|
|
37247
|
-
await walk(
|
|
37377
|
+
await walk(path72.join(dir, entry.name), depth + 1);
|
|
37248
37378
|
}
|
|
37249
37379
|
}
|
|
37250
37380
|
}
|
|
37251
37381
|
|
|
37252
37382
|
// src/services/turn-files/files-outbox.ts
|
|
37253
|
-
var
|
|
37254
|
-
var
|
|
37383
|
+
var fs62 = __toESM(require("fs/promises"));
|
|
37384
|
+
var path73 = __toESM(require("path"));
|
|
37255
37385
|
var import_os12 = require("os");
|
|
37256
37386
|
var HOME_OUTBOX_DIR = ".codeam/outbox";
|
|
37257
37387
|
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -37284,16 +37414,16 @@ var FilesOutbox = class {
|
|
|
37284
37414
|
backoffIndex = 0;
|
|
37285
37415
|
stopped = false;
|
|
37286
37416
|
constructor(opts) {
|
|
37287
|
-
const base = opts.baseDir ??
|
|
37288
|
-
this.filePath =
|
|
37417
|
+
const base = opts.baseDir ?? path73.join(homeDir(), HOME_OUTBOX_DIR);
|
|
37418
|
+
this.filePath = path73.join(base, `${opts.sessionId}.jsonl`);
|
|
37289
37419
|
this.post = opts.post;
|
|
37290
37420
|
this.autoSchedule = opts.autoSchedule !== false;
|
|
37291
37421
|
}
|
|
37292
37422
|
/** Persist the entry to disk and trigger a flush. Returns once the
|
|
37293
37423
|
* line is durable on disk (not once the POST succeeds). */
|
|
37294
37424
|
async enqueue(entry) {
|
|
37295
|
-
await
|
|
37296
|
-
await
|
|
37425
|
+
await fs62.mkdir(path73.dirname(this.filePath), { recursive: true });
|
|
37426
|
+
await fs62.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
37297
37427
|
this.backoffIndex = 0;
|
|
37298
37428
|
if (this.autoSchedule) this.scheduleFlush(0);
|
|
37299
37429
|
}
|
|
@@ -37384,7 +37514,7 @@ var FilesOutbox = class {
|
|
|
37384
37514
|
async readAll() {
|
|
37385
37515
|
let raw = "";
|
|
37386
37516
|
try {
|
|
37387
|
-
raw = await
|
|
37517
|
+
raw = await fs62.readFile(this.filePath, "utf8");
|
|
37388
37518
|
} catch {
|
|
37389
37519
|
return [];
|
|
37390
37520
|
}
|
|
@@ -37408,12 +37538,12 @@ var FilesOutbox = class {
|
|
|
37408
37538
|
async rewrite(entries) {
|
|
37409
37539
|
const tmpPath = `${this.filePath}.${process.pid}.tmp`;
|
|
37410
37540
|
if (entries.length === 0) {
|
|
37411
|
-
await
|
|
37541
|
+
await fs62.unlink(this.filePath).catch(() => void 0);
|
|
37412
37542
|
return;
|
|
37413
37543
|
}
|
|
37414
37544
|
const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
37415
|
-
await
|
|
37416
|
-
await
|
|
37545
|
+
await fs62.writeFile(tmpPath, payload, "utf8");
|
|
37546
|
+
await fs62.rename(tmpPath, this.filePath);
|
|
37417
37547
|
}
|
|
37418
37548
|
};
|
|
37419
37549
|
function applyJitter(ms) {
|
|
@@ -37961,8 +38091,8 @@ async function postCredentialSync(opts, fetchImpl = fetch) {
|
|
|
37961
38091
|
|
|
37962
38092
|
// src/packs/gates.ts
|
|
37963
38093
|
var import_node_child_process22 = require("child_process");
|
|
37964
|
-
var
|
|
37965
|
-
var
|
|
38094
|
+
var fs63 = __toESM(require("fs"));
|
|
38095
|
+
var path74 = __toESM(require("path"));
|
|
37966
38096
|
var defaultCommandRunner = (file, args2, cwd, timeoutMs, env) => new Promise((resolve12) => {
|
|
37967
38097
|
(0, import_node_child_process22.execFile)(
|
|
37968
38098
|
file,
|
|
@@ -38012,7 +38142,7 @@ async function changedFiles(run, cwd, from, to) {
|
|
|
38012
38142
|
}
|
|
38013
38143
|
function readWorkspaceFile(cwd, relPath) {
|
|
38014
38144
|
try {
|
|
38015
|
-
return
|
|
38145
|
+
return fs63.readFileSync(path74.join(cwd, relPath), "utf8");
|
|
38016
38146
|
} catch {
|
|
38017
38147
|
return null;
|
|
38018
38148
|
}
|
|
@@ -38021,14 +38151,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
|
|
|
38021
38151
|
var CHECKS_TIMEOUT_MS = 5 * 6e4;
|
|
38022
38152
|
function detectChecksCommand(cwd) {
|
|
38023
38153
|
try {
|
|
38024
|
-
const cfg = JSON.parse(
|
|
38154
|
+
const cfg = JSON.parse(fs63.readFileSync(path74.join(cwd, ".codeam", "pack.json"), "utf8"));
|
|
38025
38155
|
if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
|
|
38026
38156
|
return cfg.checksCommand.trim();
|
|
38027
38157
|
}
|
|
38028
38158
|
} catch {
|
|
38029
38159
|
}
|
|
38030
38160
|
try {
|
|
38031
|
-
const pkg = JSON.parse(
|
|
38161
|
+
const pkg = JSON.parse(fs63.readFileSync(path74.join(cwd, "package.json"), "utf8"));
|
|
38032
38162
|
const test = pkg.scripts?.test;
|
|
38033
38163
|
if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
|
|
38034
38164
|
return "npm test";
|
|
@@ -38046,39 +38176,39 @@ ${res.stderr}`.trim();
|
|
|
38046
38176
|
}
|
|
38047
38177
|
|
|
38048
38178
|
// src/packs/run-store.ts
|
|
38049
|
-
var
|
|
38050
|
-
var
|
|
38179
|
+
var fs64 = __toESM(require("fs"));
|
|
38180
|
+
var path75 = __toESM(require("path"));
|
|
38051
38181
|
var crypto5 = __toESM(require("crypto"));
|
|
38052
38182
|
function packsDir(cwd) {
|
|
38053
|
-
return
|
|
38183
|
+
return path75.join(cwd, ".codeam", "packs");
|
|
38054
38184
|
}
|
|
38055
38185
|
function runDir(cwd, runId) {
|
|
38056
|
-
return
|
|
38186
|
+
return path75.join(packsDir(cwd), runId);
|
|
38057
38187
|
}
|
|
38058
38188
|
function newRunId() {
|
|
38059
38189
|
return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
|
|
38060
38190
|
}
|
|
38061
38191
|
function writeJsonAtomic(file, value) {
|
|
38062
|
-
|
|
38192
|
+
fs64.mkdirSync(path75.dirname(file), { recursive: true });
|
|
38063
38193
|
const tmp = `${file}.tmp`;
|
|
38064
|
-
|
|
38065
|
-
|
|
38194
|
+
fs64.writeFileSync(tmp, JSON.stringify(value, null, 2));
|
|
38195
|
+
fs64.renameSync(tmp, file);
|
|
38066
38196
|
}
|
|
38067
38197
|
function saveRun(cwd, state) {
|
|
38068
|
-
writeJsonAtomic(
|
|
38198
|
+
writeJsonAtomic(path75.join(runDir(cwd, state.runId), "run.json"), state);
|
|
38069
38199
|
}
|
|
38070
38200
|
function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
|
|
38071
38201
|
const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
|
|
38072
|
-
writeJsonAtomic(
|
|
38202
|
+
writeJsonAtomic(path75.join(runDir(cwd, runId), name), handoff);
|
|
38073
38203
|
}
|
|
38074
38204
|
function loadLatestRun(cwd) {
|
|
38075
38205
|
try {
|
|
38076
38206
|
const dir = packsDir(cwd);
|
|
38077
|
-
const entries =
|
|
38207
|
+
const entries = fs64.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
38078
38208
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
38079
|
-
const file =
|
|
38209
|
+
const file = path75.join(dir, entries[i], "run.json");
|
|
38080
38210
|
try {
|
|
38081
|
-
const parsed = JSON.parse(
|
|
38211
|
+
const parsed = JSON.parse(fs64.readFileSync(file, "utf8"));
|
|
38082
38212
|
if (parsed && typeof parsed.runId === "string") return parsed;
|
|
38083
38213
|
} catch {
|
|
38084
38214
|
}
|
|
@@ -38089,17 +38219,17 @@ function loadLatestRun(cwd) {
|
|
|
38089
38219
|
}
|
|
38090
38220
|
function ensureLedgerIgnored(cwd) {
|
|
38091
38221
|
try {
|
|
38092
|
-
const gitDir =
|
|
38093
|
-
if (!
|
|
38094
|
-
const exclude =
|
|
38222
|
+
const gitDir = path75.join(cwd, ".git");
|
|
38223
|
+
if (!fs64.existsSync(gitDir)) return;
|
|
38224
|
+
const exclude = path75.join(gitDir, "info", "exclude");
|
|
38095
38225
|
let existing = "";
|
|
38096
38226
|
try {
|
|
38097
|
-
existing =
|
|
38227
|
+
existing = fs64.readFileSync(exclude, "utf8");
|
|
38098
38228
|
} catch {
|
|
38099
38229
|
}
|
|
38100
38230
|
if (existing.includes(".codeam/packs/")) return;
|
|
38101
|
-
|
|
38102
|
-
|
|
38231
|
+
fs64.mkdirSync(path75.dirname(exclude), { recursive: true });
|
|
38232
|
+
fs64.writeFileSync(exclude, `${existing.trimEnd()}
|
|
38103
38233
|
.codeam/packs/
|
|
38104
38234
|
`.trimStart());
|
|
38105
38235
|
} catch {
|
|
@@ -39439,55 +39569,6 @@ function buildAcpPromptBlocks(payload) {
|
|
|
39439
39569
|
return blocks;
|
|
39440
39570
|
}
|
|
39441
39571
|
|
|
39442
|
-
// src/agents/agent-standard.ts
|
|
39443
|
-
var fs66 = __toESM(require("fs"));
|
|
39444
|
-
var path76 = __toESM(require("path"));
|
|
39445
|
-
var os51 = __toESM(require("os"));
|
|
39446
|
-
function ensureAgentStandard(homeDir2 = os51.homedir()) {
|
|
39447
|
-
try {
|
|
39448
|
-
const file = path76.join(homeDir2, ".claude", "CLAUDE.md");
|
|
39449
|
-
let existing = "";
|
|
39450
|
-
try {
|
|
39451
|
-
existing = fs66.readFileSync(file, "utf8");
|
|
39452
|
-
} catch {
|
|
39453
|
-
}
|
|
39454
|
-
if (existing.includes(AGENT_STANDARD_MARKER)) return;
|
|
39455
|
-
fs66.mkdirSync(path76.dirname(file), { recursive: true });
|
|
39456
|
-
const next = existing.trim() ? `${existing.trimEnd()}
|
|
39457
|
-
|
|
39458
|
-
${AGENT_STANDARD_BLOCK}
|
|
39459
|
-
` : `${AGENT_STANDARD_BLOCK}
|
|
39460
|
-
`;
|
|
39461
|
-
fs66.writeFileSync(file, next);
|
|
39462
|
-
} catch {
|
|
39463
|
-
}
|
|
39464
|
-
}
|
|
39465
|
-
var _agentStandardSeam = {
|
|
39466
|
-
isLocalSession: () => isLocalSession(),
|
|
39467
|
-
markerPath: (sessionId) => path76.join(os51.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
|
|
39468
|
-
exists: (p2) => fs66.existsSync(p2),
|
|
39469
|
-
write: (p2) => {
|
|
39470
|
-
fs66.mkdirSync(path76.dirname(p2), { recursive: true });
|
|
39471
|
-
fs66.writeFileSync(p2, "");
|
|
39472
|
-
}
|
|
39473
|
-
};
|
|
39474
|
-
function isClaude(agent) {
|
|
39475
|
-
return agent === "claude" || agent === "claude_code";
|
|
39476
|
-
}
|
|
39477
|
-
function maybePrefaceAgentStandard(blocks, agent, sessionId, seam = _agentStandardSeam) {
|
|
39478
|
-
if (seam.isLocalSession()) return;
|
|
39479
|
-
if (isClaude(agent)) return;
|
|
39480
|
-
if (!sessionId) return;
|
|
39481
|
-
const marker = seam.markerPath(sessionId);
|
|
39482
|
-
try {
|
|
39483
|
-
if (seam.exists(marker)) return;
|
|
39484
|
-
seam.write(marker);
|
|
39485
|
-
} catch {
|
|
39486
|
-
return;
|
|
39487
|
-
}
|
|
39488
|
-
blocks.unshift({ type: "text", text: AGENT_STANDARD_TEXT });
|
|
39489
|
-
}
|
|
39490
|
-
|
|
39491
39572
|
// src/agents/acp/promptEcho.ts
|
|
39492
39573
|
var MAX_PROMPT_CHARS = 200;
|
|
39493
39574
|
var MAX_AGENT_REPLY_CHARS = 280;
|
|
@@ -41625,16 +41706,19 @@ async function runAcpSession(opts) {
|
|
|
41625
41706
|
switchCredentialEnv = provisionAgentCredentials(agentId, auth);
|
|
41626
41707
|
},
|
|
41627
41708
|
provisionHouseProxy: ({ baseUrl, token, model, managedAgentId }) => {
|
|
41628
|
-
const claudeConfigDir =
|
|
41629
|
-
|
|
41709
|
+
const claudeConfigDir = path79.join(
|
|
41710
|
+
os53.homedir(),
|
|
41630
41711
|
".codeam",
|
|
41631
41712
|
"house-claude",
|
|
41632
41713
|
`switch-${opts.pluginId}`
|
|
41633
41714
|
);
|
|
41634
41715
|
try {
|
|
41635
|
-
|
|
41716
|
+
fs68.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
|
|
41636
41717
|
} catch {
|
|
41637
41718
|
}
|
|
41719
|
+
const memoryFile = path79.join(claudeConfigDir, "CLAUDE.md");
|
|
41720
|
+
ensureBeadsWorkflowHint(void 0, memoryFile);
|
|
41721
|
+
ensureAgentStandard(void 0, memoryFile);
|
|
41638
41722
|
const cfg = {
|
|
41639
41723
|
baseUrl,
|
|
41640
41724
|
token,
|
|
@@ -42840,59 +42924,6 @@ function startClaudeCredentialSync(opts) {
|
|
|
42840
42924
|
};
|
|
42841
42925
|
}
|
|
42842
42926
|
|
|
42843
|
-
// src/beads/workflow-hint.ts
|
|
42844
|
-
var fs68 = __toESM(require("fs"));
|
|
42845
|
-
var path78 = __toESM(require("path"));
|
|
42846
|
-
var os53 = __toESM(require("os"));
|
|
42847
|
-
var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
|
|
42848
|
-
var BEADS_HINT = `${BEADS_HINT_MARKER}
|
|
42849
|
-
# Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
|
|
42850
|
-
|
|
42851
|
-
This environment uses **bd (beads)** for issue/task tracking and persistent memory.
|
|
42852
|
-
|
|
42853
|
-
- Use \`bd\` for ALL task tracking \u2014 do NOT use TodoWrite or markdown TODO lists.
|
|
42854
|
-
- Run \`bd prime\` (via your shell tool, once) when you start working on a task, for
|
|
42855
|
-
the full workflow context + project memories. Not needed to answer a greeting or
|
|
42856
|
-
a quick question. On a fresh session beads may still be provisioning for a few
|
|
42857
|
-
seconds \u2014 if \`bd prime\` comes back empty, retry it shortly; it works once the
|
|
42858
|
-
shared server is up.
|
|
42859
|
-
- \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
|
|
42860
|
-
- Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
|
|
42861
|
-
- Run \`bd\` commands through your shell tool and summarize the outcome. Never
|
|
42862
|
-
paste \`bd\` commands or their raw output into your reply.
|
|
42863
|
-
- CodeAgent installs, starts and repairs beads \u2014 not you. If a \`bd\` command
|
|
42864
|
-
fails, carry on with the user's task without task tracking and try \`bd\`
|
|
42865
|
-
again later. Never run \`bd init\`, \`bd bootstrap\`, \`bd doctor --fix\` or
|
|
42866
|
-
\`dolt\` commands yourself: they race the provisioning and can wipe the
|
|
42867
|
-
project's issues.
|
|
42868
|
-
${BEADS_HINT_MARKER}`;
|
|
42869
|
-
function ensureBeadsWorkflowHint(homeDir2 = os53.homedir()) {
|
|
42870
|
-
try {
|
|
42871
|
-
const file = path78.join(homeDir2, ".claude", "CLAUDE.md");
|
|
42872
|
-
let existing = "";
|
|
42873
|
-
try {
|
|
42874
|
-
existing = fs68.readFileSync(file, "utf8");
|
|
42875
|
-
} catch {
|
|
42876
|
-
}
|
|
42877
|
-
if (existing.includes(BEADS_HINT)) return;
|
|
42878
|
-
fs68.mkdirSync(path78.dirname(file), { recursive: true });
|
|
42879
|
-
let next;
|
|
42880
|
-
const open = existing.indexOf(BEADS_HINT_MARKER);
|
|
42881
|
-
const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
|
|
42882
|
-
if (open !== -1 && close !== -1) {
|
|
42883
|
-
next = existing.slice(0, open) + BEADS_HINT + existing.slice(close + BEADS_HINT_MARKER.length);
|
|
42884
|
-
} else {
|
|
42885
|
-
next = existing.trim() ? `${existing.trimEnd()}
|
|
42886
|
-
|
|
42887
|
-
${BEADS_HINT}
|
|
42888
|
-
` : `${BEADS_HINT}
|
|
42889
|
-
`;
|
|
42890
|
-
}
|
|
42891
|
-
fs68.writeFileSync(file, next);
|
|
42892
|
-
} catch {
|
|
42893
|
-
}
|
|
42894
|
-
}
|
|
42895
|
-
|
|
42896
42927
|
// src/commands/start/pick-session.ts
|
|
42897
42928
|
function pickPinnedSession(pinnedId, listSessions2) {
|
|
42898
42929
|
const id = pinnedId?.trim();
|
|
@@ -42909,7 +42940,7 @@ function pickPinnedSession(pinnedId, listSessions2) {
|
|
|
42909
42940
|
|
|
42910
42941
|
// src/agents/retired-proxy-cleanup.ts
|
|
42911
42942
|
var fs69 = __toESM(require("fs"));
|
|
42912
|
-
var
|
|
42943
|
+
var path80 = __toESM(require("path"));
|
|
42913
42944
|
var os54 = __toESM(require("os"));
|
|
42914
42945
|
var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
|
|
42915
42946
|
var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
|
|
@@ -42921,7 +42952,7 @@ function isHeadroomHook(group) {
|
|
|
42921
42952
|
}
|
|
42922
42953
|
function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
|
|
42923
42954
|
const out2 = { inspected: false, changed: false, removed: [] };
|
|
42924
|
-
const file =
|
|
42955
|
+
const file = path80.join(homeDir2, ".claude", "settings.json");
|
|
42925
42956
|
let parsed;
|
|
42926
42957
|
try {
|
|
42927
42958
|
parsed = JSON.parse(fs69.readFileSync(file, "utf8"));
|
|
@@ -43942,11 +43973,11 @@ function keepDeviceAwake(deps = {}) {
|
|
|
43942
43973
|
// src/agents/claude/onboarding.ts
|
|
43943
43974
|
var fs71 = __toESM(require("fs"));
|
|
43944
43975
|
var os56 = __toESM(require("os"));
|
|
43945
|
-
var
|
|
43976
|
+
var path81 = __toESM(require("path"));
|
|
43946
43977
|
var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
|
|
43947
43978
|
function ensureClaudeOnboarded(cwd) {
|
|
43948
43979
|
try {
|
|
43949
|
-
const file =
|
|
43980
|
+
const file = path81.join(os56.homedir(), ".claude.json");
|
|
43950
43981
|
let config = {};
|
|
43951
43982
|
try {
|
|
43952
43983
|
config = JSON.parse(fs71.readFileSync(file, "utf8"));
|
|
@@ -43974,7 +44005,7 @@ function ensureClaudeOnboarded(cwd) {
|
|
|
43974
44005
|
}
|
|
43975
44006
|
}
|
|
43976
44007
|
if (!changed) return;
|
|
43977
|
-
fs71.mkdirSync(
|
|
44008
|
+
fs71.mkdirSync(path81.dirname(file), { recursive: true });
|
|
43978
44009
|
fs71.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
43979
44010
|
log.info(
|
|
43980
44011
|
"claude",
|
|
@@ -44744,7 +44775,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
|
|
|
44744
44775
|
var import_child_process30 = require("child_process");
|
|
44745
44776
|
var import_util4 = require("util");
|
|
44746
44777
|
var import_picocolors8 = __toESM(require("picocolors"));
|
|
44747
|
-
var
|
|
44778
|
+
var path82 = __toESM(require("path"));
|
|
44748
44779
|
var execFileP5 = (0, import_util4.promisify)(import_child_process30.execFile);
|
|
44749
44780
|
var MAX_BUFFER = 8 * 1024 * 1024;
|
|
44750
44781
|
function resetStdinForChild() {
|
|
@@ -45233,7 +45264,7 @@ var GitHubCodespacesProvider = class {
|
|
|
45233
45264
|
});
|
|
45234
45265
|
}
|
|
45235
45266
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45236
|
-
const remoteDir =
|
|
45267
|
+
const remoteDir = path82.posix.dirname(remotePath);
|
|
45237
45268
|
const parts = [
|
|
45238
45269
|
`mkdir -p ${shellQuote(remoteDir)}`,
|
|
45239
45270
|
`cat > ${shellQuote(remotePath)}`
|
|
@@ -45303,7 +45334,7 @@ function shellQuote(s) {
|
|
|
45303
45334
|
// src/services/providers/gitpod.ts
|
|
45304
45335
|
var import_child_process31 = require("child_process");
|
|
45305
45336
|
var import_util5 = require("util");
|
|
45306
|
-
var
|
|
45337
|
+
var path83 = __toESM(require("path"));
|
|
45307
45338
|
var import_picocolors9 = __toESM(require("picocolors"));
|
|
45308
45339
|
var execFileP6 = (0, import_util5.promisify)(import_child_process31.execFile);
|
|
45309
45340
|
var MAX_BUFFER2 = 8 * 1024 * 1024;
|
|
@@ -45543,7 +45574,7 @@ var GitpodProvider = class {
|
|
|
45543
45574
|
});
|
|
45544
45575
|
}
|
|
45545
45576
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45546
|
-
const remoteDir =
|
|
45577
|
+
const remoteDir = path83.posix.dirname(remotePath);
|
|
45547
45578
|
const parts = [
|
|
45548
45579
|
`mkdir -p ${shellQuote2(remoteDir)}`,
|
|
45549
45580
|
`cat > ${shellQuote2(remotePath)}`
|
|
@@ -45579,7 +45610,7 @@ function shellQuote2(s) {
|
|
|
45579
45610
|
// src/services/providers/gitlab-workspaces.ts
|
|
45580
45611
|
var import_child_process32 = require("child_process");
|
|
45581
45612
|
var import_util6 = require("util");
|
|
45582
|
-
var
|
|
45613
|
+
var path84 = __toESM(require("path"));
|
|
45583
45614
|
var execFileP7 = (0, import_util6.promisify)(import_child_process32.execFile);
|
|
45584
45615
|
var MAX_BUFFER3 = 8 * 1024 * 1024;
|
|
45585
45616
|
var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
|
|
@@ -45839,7 +45870,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
|
|
|
45839
45870
|
}
|
|
45840
45871
|
async uploadFile(workspaceId, remotePath, contents, options = {}) {
|
|
45841
45872
|
const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
|
|
45842
|
-
const remoteDir =
|
|
45873
|
+
const remoteDir = path84.posix.dirname(remotePath);
|
|
45843
45874
|
const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
|
|
45844
45875
|
if (options.mode != null) {
|
|
45845
45876
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
|
|
@@ -45907,7 +45938,7 @@ function shellQuote3(s) {
|
|
|
45907
45938
|
// src/services/providers/railway.ts
|
|
45908
45939
|
var import_child_process33 = require("child_process");
|
|
45909
45940
|
var import_util7 = require("util");
|
|
45910
|
-
var
|
|
45941
|
+
var path85 = __toESM(require("path"));
|
|
45911
45942
|
var execFileP8 = (0, import_util7.promisify)(import_child_process33.execFile);
|
|
45912
45943
|
var MAX_BUFFER4 = 8 * 1024 * 1024;
|
|
45913
45944
|
function resetStdinForChild4() {
|
|
@@ -46143,7 +46174,7 @@ var RailwayProvider = class {
|
|
|
46143
46174
|
if (!projectId || !serviceId) {
|
|
46144
46175
|
throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
|
|
46145
46176
|
}
|
|
46146
|
-
const remoteDir =
|
|
46177
|
+
const remoteDir = path85.posix.dirname(remotePath);
|
|
46147
46178
|
const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
|
|
46148
46179
|
if (options.mode != null) {
|
|
46149
46180
|
parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
|
|
@@ -46685,7 +46716,7 @@ async function stopWorkspaceFromLocal(target) {
|
|
|
46685
46716
|
// src/commands/host/host-client.ts
|
|
46686
46717
|
var fs72 = __toESM(require("fs"));
|
|
46687
46718
|
var os57 = __toESM(require("os"));
|
|
46688
|
-
var
|
|
46719
|
+
var path86 = __toESM(require("path"));
|
|
46689
46720
|
var import_node_crypto11 = require("crypto");
|
|
46690
46721
|
function sampleCpuTimes() {
|
|
46691
46722
|
let idle = 0;
|
|
@@ -46733,7 +46764,7 @@ function apiBase() {
|
|
|
46733
46764
|
return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
|
|
46734
46765
|
}
|
|
46735
46766
|
function hostIdentityPath() {
|
|
46736
|
-
return
|
|
46767
|
+
return path86.join(os57.homedir(), ".codeam", "host-agent.json");
|
|
46737
46768
|
}
|
|
46738
46769
|
function collectOsInfo() {
|
|
46739
46770
|
return {
|
|
@@ -46764,7 +46795,7 @@ function loadHostIdentity() {
|
|
|
46764
46795
|
}
|
|
46765
46796
|
function saveHostIdentity(identity) {
|
|
46766
46797
|
const file = hostIdentityPath();
|
|
46767
|
-
fs72.mkdirSync(
|
|
46798
|
+
fs72.mkdirSync(path86.dirname(file), { recursive: true, mode: 448 });
|
|
46768
46799
|
fs72.writeFileSync(file, JSON.stringify(identity, null, 2), {
|
|
46769
46800
|
encoding: "utf8",
|
|
46770
46801
|
mode: 384
|
|
@@ -47025,7 +47056,7 @@ async function host(args2) {
|
|
|
47025
47056
|
var import_node_child_process30 = require("child_process");
|
|
47026
47057
|
var os62 = __toESM(require("os"));
|
|
47027
47058
|
var fs77 = __toESM(require("fs"));
|
|
47028
|
-
var
|
|
47059
|
+
var path91 = __toESM(require("path"));
|
|
47029
47060
|
|
|
47030
47061
|
// src/skills/persist-from-payload.ts
|
|
47031
47062
|
function persistOrClearSkillsFromPayload(skills) {
|
|
@@ -47036,11 +47067,11 @@ function persistOrClearSkillsFromPayload(skills) {
|
|
|
47036
47067
|
// src/commands/host/session-state.ts
|
|
47037
47068
|
var fs73 = __toESM(require("fs"));
|
|
47038
47069
|
var os58 = __toESM(require("os"));
|
|
47039
|
-
var
|
|
47070
|
+
var path87 = __toESM(require("path"));
|
|
47040
47071
|
function hostSessionStatePath(env = process.env) {
|
|
47041
47072
|
const override = env.CODEAM_HOST_SESSION_STATE_FILE;
|
|
47042
47073
|
if (override && override.trim()) return override.trim();
|
|
47043
|
-
return
|
|
47074
|
+
return path87.join(os58.homedir(), ".codeam", "host-agent-sessions.json");
|
|
47044
47075
|
}
|
|
47045
47076
|
function isRecord5(v) {
|
|
47046
47077
|
if (typeof v !== "object" || v === null) return false;
|
|
@@ -47059,7 +47090,7 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
|
|
|
47059
47090
|
},
|
|
47060
47091
|
save(list) {
|
|
47061
47092
|
try {
|
|
47062
|
-
fs73.mkdirSync(
|
|
47093
|
+
fs73.mkdirSync(path87.dirname(file), { recursive: true, mode: 448 });
|
|
47063
47094
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
47064
47095
|
fs73.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
|
|
47065
47096
|
mode: 384
|
|
@@ -47093,9 +47124,9 @@ function planSessionResume(records, max) {
|
|
|
47093
47124
|
return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
|
|
47094
47125
|
}
|
|
47095
47126
|
function pickSavedSessionForWorkspace(sessions3, cwd) {
|
|
47096
|
-
const target =
|
|
47127
|
+
const target = path87.resolve(cwd);
|
|
47097
47128
|
const matches = sessions3.filter(
|
|
47098
|
-
(s) => !!s.cwd &&
|
|
47129
|
+
(s) => !!s.cwd && path87.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
|
|
47099
47130
|
);
|
|
47100
47131
|
if (matches.length === 0) return null;
|
|
47101
47132
|
matches.sort((a, b) => b.pairedAt - a.pairedAt);
|
|
@@ -47105,23 +47136,23 @@ function pickSavedSessionForWorkspace(sessions3, cwd) {
|
|
|
47105
47136
|
// src/commands/host/workspace.ts
|
|
47106
47137
|
var fs74 = __toESM(require("fs"));
|
|
47107
47138
|
var os59 = __toESM(require("os"));
|
|
47108
|
-
var
|
|
47139
|
+
var path88 = __toESM(require("path"));
|
|
47109
47140
|
var import_node_child_process25 = require("child_process");
|
|
47110
47141
|
var import_node_util5 = require("util");
|
|
47111
47142
|
var execFileP9 = (0, import_node_util5.promisify)(import_node_child_process25.execFile);
|
|
47112
47143
|
function isAbsolutePathTarget(target) {
|
|
47113
|
-
return
|
|
47144
|
+
return path88.isAbsolute(target);
|
|
47114
47145
|
}
|
|
47115
47146
|
function selfHostedWorkspaceRoot() {
|
|
47116
|
-
return
|
|
47147
|
+
return path88.join(os59.homedir(), ".codeam", "self-hosted");
|
|
47117
47148
|
}
|
|
47118
47149
|
function deployIdFromWorkspace(cwd) {
|
|
47119
47150
|
if (!cwd) return null;
|
|
47120
47151
|
const root = selfHostedWorkspaceRoot();
|
|
47121
|
-
const resolved =
|
|
47122
|
-
const rel =
|
|
47123
|
-
if (!rel || rel.startsWith("..") ||
|
|
47124
|
-
const parts = rel.split(
|
|
47152
|
+
const resolved = path88.resolve(cwd);
|
|
47153
|
+
const rel = path88.relative(root, resolved);
|
|
47154
|
+
if (!rel || rel.startsWith("..") || path88.isAbsolute(rel)) return null;
|
|
47155
|
+
const parts = rel.split(path88.sep).filter(Boolean);
|
|
47125
47156
|
if (parts.length !== 1) return null;
|
|
47126
47157
|
return parts[0];
|
|
47127
47158
|
}
|
|
@@ -47193,7 +47224,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
|
|
|
47193
47224
|
const isGitlab = provider === "gitlab";
|
|
47194
47225
|
if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
|
|
47195
47226
|
if (!cloneToken) return;
|
|
47196
|
-
const credFile =
|
|
47227
|
+
const credFile = path88.join(dest, ".git", "codeam-credentials");
|
|
47197
47228
|
const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
|
|
47198
47229
|
` : `https://x-access-token:${cloneToken}@github.com
|
|
47199
47230
|
`;
|
|
@@ -47201,7 +47232,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
|
|
|
47201
47232
|
restrictToOwner(credFile);
|
|
47202
47233
|
const env = nonInteractiveGitEnv();
|
|
47203
47234
|
const git2 = (args2) => execFileP9("git", ["-C", dest, ...args2], { timeout: 3e4, env });
|
|
47204
|
-
const credFilePosix = credFile.split(
|
|
47235
|
+
const credFilePosix = credFile.split(path88.sep).join("/");
|
|
47205
47236
|
await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
|
|
47206
47237
|
});
|
|
47207
47238
|
await git2([
|
|
@@ -47239,8 +47270,8 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
|
|
|
47239
47270
|
}
|
|
47240
47271
|
return repoOrPath;
|
|
47241
47272
|
}
|
|
47242
|
-
const dest =
|
|
47243
|
-
if (fs74.existsSync(
|
|
47273
|
+
const dest = path88.join(selfHostedWorkspaceRoot(), deployId);
|
|
47274
|
+
if (fs74.existsSync(path88.join(dest, ".git"))) {
|
|
47244
47275
|
if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
|
|
47245
47276
|
return dest;
|
|
47246
47277
|
}
|
|
@@ -47265,9 +47296,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
|
|
|
47265
47296
|
var import_node_child_process26 = require("child_process");
|
|
47266
47297
|
var fs75 = __toESM(require("fs"));
|
|
47267
47298
|
var os60 = __toESM(require("os"));
|
|
47268
|
-
var
|
|
47299
|
+
var path89 = __toESM(require("path"));
|
|
47269
47300
|
function codeamBinDir() {
|
|
47270
|
-
return process.env.CODEAM_BIN_DIR ??
|
|
47301
|
+
return process.env.CODEAM_BIN_DIR ?? path89.join(os60.homedir(), ".codeam", "bin");
|
|
47271
47302
|
}
|
|
47272
47303
|
var FALLBACK_GH_VERSION = "2.62.0";
|
|
47273
47304
|
var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
|
|
@@ -47322,8 +47353,8 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
47322
47353
|
const version3 = await resolveVersionFn(token);
|
|
47323
47354
|
const asset = `gh_${version3}_${osToken}_${arch2}`;
|
|
47324
47355
|
const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
|
|
47325
|
-
const tmpRoot = fs75.mkdtempSync(
|
|
47326
|
-
const archive =
|
|
47356
|
+
const tmpRoot = fs75.mkdtempSync(path89.join(os60.tmpdir(), "codeam-gh-"));
|
|
47357
|
+
const archive = path89.join(tmpRoot, `${asset}.${ext}`);
|
|
47327
47358
|
if (!await downloadFn(url2, archive)) {
|
|
47328
47359
|
log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
|
|
47329
47360
|
return null;
|
|
@@ -47333,14 +47364,14 @@ async function ensureGhCli(runner, token, deps = {}) {
|
|
|
47333
47364
|
log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
|
|
47334
47365
|
return null;
|
|
47335
47366
|
}
|
|
47336
|
-
const extractedBin =
|
|
47367
|
+
const extractedBin = path89.join(tmpRoot, asset, "bin", binaryName);
|
|
47337
47368
|
if (!fs75.existsSync(extractedBin)) {
|
|
47338
47369
|
log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
|
|
47339
47370
|
return null;
|
|
47340
47371
|
}
|
|
47341
47372
|
const binDir = codeamBinDir();
|
|
47342
47373
|
fs75.mkdirSync(binDir, { recursive: true });
|
|
47343
|
-
const target =
|
|
47374
|
+
const target = path89.join(binDir, binaryName);
|
|
47344
47375
|
fs75.copyFileSync(extractedBin, target);
|
|
47345
47376
|
fs75.chmodSync(target, 493);
|
|
47346
47377
|
log.info("host-agent", `gh installed to ${target} (v${version3})`);
|
|
@@ -47379,16 +47410,16 @@ async function ensureGhAuth(runner, ghCmd, token) {
|
|
|
47379
47410
|
}
|
|
47380
47411
|
function ghConfigDir() {
|
|
47381
47412
|
if (process.env.GH_CONFIG_DIR) return process.env.GH_CONFIG_DIR;
|
|
47382
|
-
if (process.env.XDG_CONFIG_HOME) return
|
|
47413
|
+
if (process.env.XDG_CONFIG_HOME) return path89.join(process.env.XDG_CONFIG_HOME, "gh");
|
|
47383
47414
|
if (process.platform === "win32" && process.env.APPDATA) {
|
|
47384
|
-
return
|
|
47415
|
+
return path89.join(process.env.APPDATA, "GitHub CLI");
|
|
47385
47416
|
}
|
|
47386
|
-
return
|
|
47417
|
+
return path89.join(os60.homedir(), ".config", "gh");
|
|
47387
47418
|
}
|
|
47388
47419
|
function writeGhHostsToken(token) {
|
|
47389
47420
|
try {
|
|
47390
47421
|
const dir = ghConfigDir();
|
|
47391
|
-
const file =
|
|
47422
|
+
const file = path89.join(dir, "hosts.yml");
|
|
47392
47423
|
if (fs75.existsSync(file)) return false;
|
|
47393
47424
|
fs75.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
47394
47425
|
fs75.writeFileSync(
|
|
@@ -47434,8 +47465,8 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
47434
47465
|
const version3 = await resolveLatestGlabVersion();
|
|
47435
47466
|
const asset = `glab_${version3}_${osToken}_${arch2}`;
|
|
47436
47467
|
const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
|
|
47437
|
-
const tmpRoot = fs75.mkdtempSync(
|
|
47438
|
-
const archive =
|
|
47468
|
+
const tmpRoot = fs75.mkdtempSync(path89.join(os60.tmpdir(), "codeam-glab-"));
|
|
47469
|
+
const archive = path89.join(tmpRoot, `${asset}.${ext}`);
|
|
47439
47470
|
if (!await downloadFn(url2, archive)) {
|
|
47440
47471
|
log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
|
|
47441
47472
|
return null;
|
|
@@ -47446,9 +47477,9 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
47446
47477
|
return null;
|
|
47447
47478
|
}
|
|
47448
47479
|
const candidates = [
|
|
47449
|
-
|
|
47450
|
-
|
|
47451
|
-
|
|
47480
|
+
path89.join(tmpRoot, "bin", binaryName),
|
|
47481
|
+
path89.join(tmpRoot, asset, "bin", binaryName),
|
|
47482
|
+
path89.join(tmpRoot, binaryName)
|
|
47452
47483
|
];
|
|
47453
47484
|
const extractedBin = candidates.find((c2) => fs75.existsSync(c2));
|
|
47454
47485
|
if (!extractedBin) {
|
|
@@ -47457,7 +47488,7 @@ async function ensureGlabCli(runner, deps = {}) {
|
|
|
47457
47488
|
}
|
|
47458
47489
|
const binDir = codeamBinDir();
|
|
47459
47490
|
fs75.mkdirSync(binDir, { recursive: true });
|
|
47460
|
-
const target =
|
|
47491
|
+
const target = path89.join(binDir, binaryName);
|
|
47461
47492
|
fs75.copyFileSync(extractedBin, target);
|
|
47462
47493
|
fs75.chmodSync(target, 493);
|
|
47463
47494
|
log.info("host-agent", `glab installed to ${target} (v${version3})`);
|
|
@@ -47543,7 +47574,7 @@ var import_node_child_process28 = require("child_process");
|
|
|
47543
47574
|
// src/lib/updateNotifier.ts
|
|
47544
47575
|
var fs76 = __toESM(require("fs"));
|
|
47545
47576
|
var os61 = __toESM(require("os"));
|
|
47546
|
-
var
|
|
47577
|
+
var path90 = __toESM(require("path"));
|
|
47547
47578
|
var https8 = __toESM(require("https"));
|
|
47548
47579
|
var import_node_child_process27 = require("child_process");
|
|
47549
47580
|
var import_picocolors12 = __toESM(require("picocolors"));
|
|
@@ -47552,8 +47583,8 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
|
|
|
47552
47583
|
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
47553
47584
|
var REQUEST_TIMEOUT_MS = 1500;
|
|
47554
47585
|
function cachePath() {
|
|
47555
|
-
const dir =
|
|
47556
|
-
return
|
|
47586
|
+
const dir = path90.join(os61.homedir(), ".codeam");
|
|
47587
|
+
return path90.join(dir, "update-check.json");
|
|
47557
47588
|
}
|
|
47558
47589
|
function readCache() {
|
|
47559
47590
|
try {
|
|
@@ -47568,7 +47599,7 @@ function readCache() {
|
|
|
47568
47599
|
function writeCache(cache) {
|
|
47569
47600
|
try {
|
|
47570
47601
|
const file = cachePath();
|
|
47571
|
-
fs76.mkdirSync(
|
|
47602
|
+
fs76.mkdirSync(path90.dirname(file), { recursive: true });
|
|
47572
47603
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
47573
47604
|
fs76.writeFileSync(tmp, JSON.stringify(cache));
|
|
47574
47605
|
fs76.renameSync(tmp, file);
|
|
@@ -47645,7 +47676,7 @@ function isLinkedInstall() {
|
|
|
47645
47676
|
timeout: 2e3
|
|
47646
47677
|
}).trim();
|
|
47647
47678
|
if (!root) return false;
|
|
47648
|
-
const pkgPath =
|
|
47679
|
+
const pkgPath = path90.join(root, PKG_NAME);
|
|
47649
47680
|
return fs76.lstatSync(pkgPath).isSymbolicLink();
|
|
47650
47681
|
} catch {
|
|
47651
47682
|
return false;
|
|
@@ -47698,7 +47729,7 @@ async function autoUpgradeBeforeCriticalCommand() {
|
|
|
47698
47729
|
if (process.env.NODE_ENV === "test") return;
|
|
47699
47730
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47700
47731
|
if (process.env.CI) return;
|
|
47701
|
-
const current2 = true ? "2.75.
|
|
47732
|
+
const current2 = true ? "2.75.22" : null;
|
|
47702
47733
|
if (!current2) return;
|
|
47703
47734
|
const cache = readCache();
|
|
47704
47735
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47715,7 +47746,7 @@ function checkForUpdates() {
|
|
|
47715
47746
|
if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
|
|
47716
47747
|
if (process.env.CI) return;
|
|
47717
47748
|
if (!process.stdout.isTTY) return;
|
|
47718
|
-
const current2 = true ? "2.75.
|
|
47749
|
+
const current2 = true ? "2.75.22" : null;
|
|
47719
47750
|
if (!current2) return;
|
|
47720
47751
|
const cache = readCache();
|
|
47721
47752
|
const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
|
|
@@ -47738,7 +47769,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
|
|
|
47738
47769
|
var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
|
|
47739
47770
|
var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
|
|
47740
47771
|
function currentCliVersion() {
|
|
47741
|
-
return true ? "2.75.
|
|
47772
|
+
return true ? "2.75.22" : null;
|
|
47742
47773
|
}
|
|
47743
47774
|
async function installedVersion(deps) {
|
|
47744
47775
|
const ls = await deps.run(
|
|
@@ -48471,13 +48502,13 @@ var HostAgentSupervisor = class {
|
|
|
48471
48502
|
const relay = this.relay;
|
|
48472
48503
|
if (!relay) return;
|
|
48473
48504
|
const raw = cmd.payload?.path;
|
|
48474
|
-
const target = typeof raw === "string" && raw.trim() ?
|
|
48505
|
+
const target = typeof raw === "string" && raw.trim() ? path91.resolve(raw.trim()) : os62.homedir();
|
|
48475
48506
|
try {
|
|
48476
48507
|
const dirents = await fs77.promises.readdir(target, { withFileTypes: true });
|
|
48477
48508
|
const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
|
|
48478
48509
|
(a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
|
|
48479
48510
|
);
|
|
48480
|
-
const parent =
|
|
48511
|
+
const parent = path91.dirname(target);
|
|
48481
48512
|
await relay.sendResult(cmd.id, "completed", {
|
|
48482
48513
|
path: target,
|
|
48483
48514
|
// null at the filesystem root so the UI can hide the ".." affordance.
|
|
@@ -48824,7 +48855,7 @@ var HostAgentSupervisor = class {
|
|
|
48824
48855
|
...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
|
|
48825
48856
|
CODEAM_AUTO_TOKEN: payload.autoPairToken
|
|
48826
48857
|
};
|
|
48827
|
-
const houseConfigDir =
|
|
48858
|
+
const houseConfigDir = path91.join(
|
|
48828
48859
|
os62.homedir(),
|
|
48829
48860
|
".codeam",
|
|
48830
48861
|
"house-claude",
|
|
@@ -48865,13 +48896,13 @@ var HostAgentSupervisor = class {
|
|
|
48865
48896
|
if ((payload.repoProvider ?? "github") === "gitlab") {
|
|
48866
48897
|
const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
|
|
48867
48898
|
if (glabCmd) {
|
|
48868
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
48899
|
+
childEnv.PATH = `${codeamBinDir()}${path91.delimiter}${childEnv.PATH}`;
|
|
48869
48900
|
await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
|
|
48870
48901
|
}
|
|
48871
48902
|
} else {
|
|
48872
48903
|
const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
|
|
48873
48904
|
if (ghCmd) {
|
|
48874
|
-
childEnv.PATH = `${codeamBinDir()}${
|
|
48905
|
+
childEnv.PATH = `${codeamBinDir()}${path91.delimiter}${childEnv.PATH}`;
|
|
48875
48906
|
await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
|
|
48876
48907
|
}
|
|
48877
48908
|
}
|
|
@@ -48899,8 +48930,8 @@ var HostAgentSupervisor = class {
|
|
|
48899
48930
|
);
|
|
48900
48931
|
if (!payload.suppressOnboardingWelcome) {
|
|
48901
48932
|
try {
|
|
48902
|
-
const cfgDir = childEnv.CLAUDE_CONFIG_DIR ||
|
|
48903
|
-
const projectDir =
|
|
48933
|
+
const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path91.join(os62.homedir(), ".claude");
|
|
48934
|
+
const projectDir = path91.join(cfgDir, "projects", encodeCwd(cwd));
|
|
48904
48935
|
const hasPriorConversation = fs77.existsSync(projectDir) && fs77.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
|
|
48905
48936
|
if (hasPriorConversation) {
|
|
48906
48937
|
childEnv.CODEAM_RESUME_LATEST = "1";
|
|
@@ -49290,8 +49321,8 @@ var HostAgentSupervisor = class {
|
|
|
49290
49321
|
this.untrackChild(deployId);
|
|
49291
49322
|
}
|
|
49292
49323
|
const dirs = [
|
|
49293
|
-
|
|
49294
|
-
|
|
49324
|
+
path91.join(selfHostedWorkspaceRoot(), deployId),
|
|
49325
|
+
path91.join(os62.homedir(), ".codeam", "house-claude", deployId)
|
|
49295
49326
|
];
|
|
49296
49327
|
for (const dir of dirs) {
|
|
49297
49328
|
try {
|
|
@@ -49456,7 +49487,7 @@ var import_node_dns = require("dns");
|
|
|
49456
49487
|
var import_node_util6 = require("util");
|
|
49457
49488
|
var import_node_crypto12 = require("crypto");
|
|
49458
49489
|
var fs78 = __toESM(require("fs"));
|
|
49459
|
-
var
|
|
49490
|
+
var path92 = __toESM(require("path"));
|
|
49460
49491
|
var import_picocolors14 = __toESM(require("picocolors"));
|
|
49461
49492
|
var dnsResolveP = (0, import_node_util6.promisify)(import_node_dns.resolve);
|
|
49462
49493
|
async function checkDns(apiBase2) {
|
|
@@ -49512,10 +49543,10 @@ async function checkHealth(apiBase2) {
|
|
|
49512
49543
|
}
|
|
49513
49544
|
}
|
|
49514
49545
|
function checkConfigDir() {
|
|
49515
|
-
const dir =
|
|
49546
|
+
const dir = path92.join(require("os").homedir(), ".codeam");
|
|
49516
49547
|
try {
|
|
49517
49548
|
fs78.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
49518
|
-
const probe =
|
|
49549
|
+
const probe = path92.join(dir, ".doctor-probe");
|
|
49519
49550
|
fs78.writeFileSync(probe, "ok", { mode: 384 });
|
|
49520
49551
|
const read = fs78.readFileSync(probe, "utf8");
|
|
49521
49552
|
fs78.unlinkSync(probe);
|
|
@@ -49582,7 +49613,7 @@ function checkNodePty() {
|
|
|
49582
49613
|
detail: "not required on this platform"
|
|
49583
49614
|
};
|
|
49584
49615
|
}
|
|
49585
|
-
const vendoredPath =
|
|
49616
|
+
const vendoredPath = path92.join(__dirname, "vendor", "node-pty");
|
|
49586
49617
|
for (const target of [vendoredPath, "node-pty"]) {
|
|
49587
49618
|
try {
|
|
49588
49619
|
require(target);
|
|
@@ -49624,7 +49655,7 @@ function checkChokidar() {
|
|
|
49624
49655
|
}
|
|
49625
49656
|
async function doctor(args2 = []) {
|
|
49626
49657
|
const json = args2.includes("--json");
|
|
49627
|
-
const cliVersion = true ? "2.75.
|
|
49658
|
+
const cliVersion = true ? "2.75.22" : "0.0.0-dev";
|
|
49628
49659
|
const apiBase2 = resolveApiBaseUrl();
|
|
49629
49660
|
const diagnosticId = (0, import_node_crypto12.randomUUID)();
|
|
49630
49661
|
log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
|
|
@@ -50148,7 +50179,7 @@ async function mcpWarm(argv = [], opts = {}) {
|
|
|
50148
50179
|
// src/commands/version.ts
|
|
50149
50180
|
var import_picocolors15 = __toESM(require("picocolors"));
|
|
50150
50181
|
function version2() {
|
|
50151
|
-
const v = true ? "2.75.
|
|
50182
|
+
const v = true ? "2.75.22" : "unknown";
|
|
50152
50183
|
console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
|
|
50153
50184
|
}
|
|
50154
50185
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeam-cli",
|
|
3
|
-
"version": "2.75.
|
|
3
|
+
"version": "2.75.22",
|
|
4
4
|
"description": "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device — async. The terminal companion for CodeAgent Mobile.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|