@oxagen/cli 2.1.4-447 → 2.1.4-453
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/oxagen.mjs +702 -309
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -7838,6 +7838,7 @@ function sessionScopeForEnrollment(next, previous) {
|
|
|
7838
7838
|
function harnessFilesRecord(paths) {
|
|
7839
7839
|
return {
|
|
7840
7840
|
claude_settings: paths.claudeSettings,
|
|
7841
|
+
claude_user_config: paths.claudeUserConfig,
|
|
7841
7842
|
codex_hooks: paths.codexHooks,
|
|
7842
7843
|
cursor_hooks: [...paths.cursorHooks],
|
|
7843
7844
|
stella_toml: paths.stellaToml,
|
|
@@ -7852,6 +7853,9 @@ function withRecordedHarnessFiles(paths, host) {
|
|
|
7852
7853
|
return {
|
|
7853
7854
|
...paths,
|
|
7854
7855
|
claudeSettings,
|
|
7856
|
+
// A record from before #5287 has no entry, and the host it describes
|
|
7857
|
+
// never had the Oxagen MCP server written, so this process's path stands.
|
|
7858
|
+
claudeUserConfig: record.claude_user_config ?? paths.claudeUserConfig,
|
|
7855
7859
|
claudeProjects: record.claude_settings !== void 0 ? join3(dirname3(claudeSettings), "projects") : paths.claudeProjects,
|
|
7856
7860
|
codexHooks: record.codex_hooks ?? paths.codexHooks,
|
|
7857
7861
|
cursorHooks: record.cursor_hooks ?? paths.cursorHooks,
|
|
@@ -8022,6 +8026,8 @@ var init_host_file = __esm({
|
|
|
8022
8026
|
HOST_FILE_SCHEMA = "tacho.host.v1";
|
|
8023
8027
|
harnessFilesRecordSchema = external_exports.object({
|
|
8024
8028
|
claude_settings: external_exports.string().min(1),
|
|
8029
|
+
/** Claude Code's user config, which holds the Oxagen MCP server entry. */
|
|
8030
|
+
claude_user_config: external_exports.string().min(1),
|
|
8025
8031
|
codex_hooks: external_exports.string().min(1),
|
|
8026
8032
|
cursor_hooks: external_exports.array(external_exports.string().min(1)),
|
|
8027
8033
|
stella_toml: external_exports.string().min(1),
|
|
@@ -8161,6 +8167,22 @@ var init_host_file = __esm({
|
|
|
8161
8167
|
* beside ours; this is the `displaced_env` of the connected tier.
|
|
8162
8168
|
*/
|
|
8163
8169
|
displaced_mcp_servers: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())).default({}),
|
|
8170
|
+
/**
|
|
8171
|
+
* When this enrollment last wrote the `oxagen` server into a wrapped
|
|
8172
|
+
* harness's user MCP config, by harness (#5287). Today that is only
|
|
8173
|
+
* `claude-code`. Two readers use it:
|
|
8174
|
+
*
|
|
8175
|
+
* - `oxagen agent status` adds the server once to a live enrollment
|
|
8176
|
+
* made before enroll wrote it, and an entry here says it already
|
|
8177
|
+
* did. A person who later removes the server keeps it removed until
|
|
8178
|
+
* they enroll again.
|
|
8179
|
+
* - The Stop hook asks only a session that started after this time.
|
|
8180
|
+
* Claude Code loads MCP servers when a session starts, so a session
|
|
8181
|
+
* already running when the entry was written does not have the tool.
|
|
8182
|
+
*
|
|
8183
|
+
* Optional: a host enrolled before #5287 has none.
|
|
8184
|
+
*/
|
|
8185
|
+
mcp_registered_at: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
8164
8186
|
/**
|
|
8165
8187
|
* Where the harness files were when this host enrolled
|
|
8166
8188
|
* (`harnessFilesRecord`). Optional: a host enrolled before this field
|
|
@@ -9022,6 +9044,9 @@ import { join as join6 } from "node:path";
|
|
|
9022
9044
|
function claudeConfigDirFor(env, home) {
|
|
9023
9045
|
return env["CLAUDE_CONFIG_DIR"] ?? join6(home, ".claude");
|
|
9024
9046
|
}
|
|
9047
|
+
function claudeUserConfigFor(env, home) {
|
|
9048
|
+
return join6(env["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json");
|
|
9049
|
+
}
|
|
9025
9050
|
function codexHomeFor(env, home) {
|
|
9026
9051
|
return env["CODEX_HOME"] ?? join6(home, ".codex");
|
|
9027
9052
|
}
|
|
@@ -9044,6 +9069,7 @@ function tachoHome(env = process.env, home = homedir(), platform = process.platf
|
|
|
9044
9069
|
log: join6(tachoDir, "tachod.log"),
|
|
9045
9070
|
daemonLauncher: join6(tachoDir, "tachod.cmd"),
|
|
9046
9071
|
claudeSettings: join6(claudeConfigDir, "settings.json"),
|
|
9072
|
+
claudeUserConfig: claudeUserConfigFor(env, home),
|
|
9047
9073
|
claudeProjects: join6(claudeConfigDir, "projects"),
|
|
9048
9074
|
codexHooks: join6(codexHome, "hooks.json"),
|
|
9049
9075
|
cursorHooks: cursorHooksPaths(home, platform, env),
|
|
@@ -9060,6 +9086,7 @@ function homeOf(paths) {
|
|
|
9060
9086
|
log: paths.log,
|
|
9061
9087
|
daemonLauncher: paths.daemonLauncher,
|
|
9062
9088
|
claudeSettings: paths.claudeSettings,
|
|
9089
|
+
claudeUserConfig: paths.claudeUserConfig,
|
|
9063
9090
|
claudeProjects: paths.claudeProjects,
|
|
9064
9091
|
codexHooks: paths.codexHooks,
|
|
9065
9092
|
cursorHooks: paths.cursorHooks,
|
|
@@ -20367,6 +20394,304 @@ var init_backfill3 = __esm({
|
|
|
20367
20394
|
}
|
|
20368
20395
|
});
|
|
20369
20396
|
|
|
20397
|
+
// ../../packages/tacho/src/host/claude-code-mcp-writer.ts
|
|
20398
|
+
function mergeClaudeCodeMcpConfig(existing, config) {
|
|
20399
|
+
return mergeOxagenMcpServer(existing, config, "stdio");
|
|
20400
|
+
}
|
|
20401
|
+
function stripClaudeCodeMcpConfig(existing, enrollmentId, restore = {}) {
|
|
20402
|
+
return stripOxagenMcpServer(existing, enrollmentId, restore);
|
|
20403
|
+
}
|
|
20404
|
+
function claudeCodeSessionHasOxagenTools(check2) {
|
|
20405
|
+
if (!check2.hasGatewayKey || check2.registeredAt === void 0) return false;
|
|
20406
|
+
const registered = Date.parse(check2.registeredAt);
|
|
20407
|
+
const started = Date.parse(check2.sessionStartedAt);
|
|
20408
|
+
if (!Number.isFinite(registered) || !Number.isFinite(started)) return false;
|
|
20409
|
+
if (started < registered) return false;
|
|
20410
|
+
return oxagenMcpPresence(check2.readUserConfig(), check2.enrollmentId).present;
|
|
20411
|
+
}
|
|
20412
|
+
function claudeUserConfigShapeProblem(document) {
|
|
20413
|
+
return mcpConfigShapeProblem(document);
|
|
20414
|
+
}
|
|
20415
|
+
var init_claude_code_mcp_writer = __esm({
|
|
20416
|
+
"../../packages/tacho/src/host/claude-code-mcp-writer.ts"() {
|
|
20417
|
+
"use strict";
|
|
20418
|
+
init_mcp_config_writer();
|
|
20419
|
+
}
|
|
20420
|
+
});
|
|
20421
|
+
|
|
20422
|
+
// ../../packages/tacho/src/host/install-lock.ts
|
|
20423
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
20424
|
+
import {
|
|
20425
|
+
closeSync as closeSync3,
|
|
20426
|
+
existsSync as existsSync4,
|
|
20427
|
+
linkSync,
|
|
20428
|
+
mkdirSync as mkdirSync4,
|
|
20429
|
+
openSync as openSync3,
|
|
20430
|
+
readdirSync as readdirSync5,
|
|
20431
|
+
readFileSync as readFileSync5,
|
|
20432
|
+
renameSync as renameSync3,
|
|
20433
|
+
rmdirSync as rmdirSync3,
|
|
20434
|
+
unlinkSync as unlinkSync3,
|
|
20435
|
+
writeSync as writeSync2
|
|
20436
|
+
} from "node:fs";
|
|
20437
|
+
import { dirname as dirname4, join as join12 } from "node:path";
|
|
20438
|
+
function readLock(path2) {
|
|
20439
|
+
try {
|
|
20440
|
+
return readFileSync5(path2, "utf8");
|
|
20441
|
+
} catch {
|
|
20442
|
+
return void 0;
|
|
20443
|
+
}
|
|
20444
|
+
}
|
|
20445
|
+
function holderOf(text4) {
|
|
20446
|
+
try {
|
|
20447
|
+
return JSON.parse(text4 ?? "");
|
|
20448
|
+
} catch {
|
|
20449
|
+
return {};
|
|
20450
|
+
}
|
|
20451
|
+
}
|
|
20452
|
+
function removeQuietly(path2) {
|
|
20453
|
+
try {
|
|
20454
|
+
unlinkSync3(path2);
|
|
20455
|
+
} catch {
|
|
20456
|
+
}
|
|
20457
|
+
}
|
|
20458
|
+
function pidAlive(pid) {
|
|
20459
|
+
try {
|
|
20460
|
+
process.kill(pid, 0);
|
|
20461
|
+
return true;
|
|
20462
|
+
} catch (error) {
|
|
20463
|
+
return error.code === "EPERM";
|
|
20464
|
+
}
|
|
20465
|
+
}
|
|
20466
|
+
function acquireInstallLock(root, now = Date.now, alive = pidAlive) {
|
|
20467
|
+
const path2 = join12(root, "install.lock");
|
|
20468
|
+
const created = [];
|
|
20469
|
+
let dir = root;
|
|
20470
|
+
while (!existsSync4(dir) && dirname4(dir) !== dir) {
|
|
20471
|
+
created.unshift(dir);
|
|
20472
|
+
dir = dirname4(dir);
|
|
20473
|
+
}
|
|
20474
|
+
mkdirSync4(root, { recursive: true, mode: 448 });
|
|
20475
|
+
const token = randomBytes3(12).toString("hex");
|
|
20476
|
+
const liveHolder = (holder) => typeof holder.pid === "number" && typeof holder.at === "number" && now() - holder.at < STALE_AFTER_MS && alive(holder.pid) ? holder.pid : void 0;
|
|
20477
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
20478
|
+
try {
|
|
20479
|
+
const fd2 = openSync3(path2, "wx", 384);
|
|
20480
|
+
writeSync2(fd2, JSON.stringify({ pid: process.pid, at: now(), token }));
|
|
20481
|
+
closeSync3(fd2);
|
|
20482
|
+
return {
|
|
20483
|
+
release: () => {
|
|
20484
|
+
if (holderOf(readLock(path2)).token === token) removeQuietly(path2);
|
|
20485
|
+
for (const made of [...created].reverse()) {
|
|
20486
|
+
try {
|
|
20487
|
+
if (readdirSync5(made).length === 0) rmdirSync3(made);
|
|
20488
|
+
} catch {
|
|
20489
|
+
}
|
|
20490
|
+
}
|
|
20491
|
+
}
|
|
20492
|
+
};
|
|
20493
|
+
} catch (error) {
|
|
20494
|
+
if (error.code !== "EEXIST") throw error;
|
|
20495
|
+
const live = liveHolder(holderOf(readLock(path2)));
|
|
20496
|
+
if (live !== void 0) return { heldBy: live };
|
|
20497
|
+
const aside = `${path2}.${process.pid}.${token}.stale`;
|
|
20498
|
+
try {
|
|
20499
|
+
renameSync3(path2, aside);
|
|
20500
|
+
} catch (renameError) {
|
|
20501
|
+
if (renameError.code === "ENOENT") continue;
|
|
20502
|
+
throw renameError;
|
|
20503
|
+
}
|
|
20504
|
+
const moved = liveHolder(holderOf(readLock(aside)));
|
|
20505
|
+
if (moved !== void 0) {
|
|
20506
|
+
try {
|
|
20507
|
+
linkSync(aside, path2);
|
|
20508
|
+
} catch {
|
|
20509
|
+
}
|
|
20510
|
+
removeQuietly(aside);
|
|
20511
|
+
return { heldBy: moved };
|
|
20512
|
+
}
|
|
20513
|
+
removeQuietly(aside);
|
|
20514
|
+
}
|
|
20515
|
+
}
|
|
20516
|
+
return { heldBy: -1 };
|
|
20517
|
+
}
|
|
20518
|
+
var STALE_AFTER_MS;
|
|
20519
|
+
var init_install_lock = __esm({
|
|
20520
|
+
"../../packages/tacho/src/host/install-lock.ts"() {
|
|
20521
|
+
"use strict";
|
|
20522
|
+
STALE_AFTER_MS = 10 * 6e4;
|
|
20523
|
+
}
|
|
20524
|
+
});
|
|
20525
|
+
|
|
20526
|
+
// ../../packages/tacho/src/cli/agent-deps.ts
|
|
20527
|
+
function agentDeps(deps, paths) {
|
|
20528
|
+
if (JSON.stringify(paths) === JSON.stringify(deps.paths)) return deps;
|
|
20529
|
+
const rebound = deps.atAgent?.(paths) ?? { ...deps, paths };
|
|
20530
|
+
return {
|
|
20531
|
+
...deps,
|
|
20532
|
+
...rebound,
|
|
20533
|
+
paths,
|
|
20534
|
+
serviceManager: deps.serviceManager,
|
|
20535
|
+
out: deps.out,
|
|
20536
|
+
err: deps.err
|
|
20537
|
+
};
|
|
20538
|
+
}
|
|
20539
|
+
function depsForHarness(deps, harness) {
|
|
20540
|
+
const agent = agentHolding(deps.paths, harness);
|
|
20541
|
+
return agent === void 0 ? deps : depsForAgent(deps, agent);
|
|
20542
|
+
}
|
|
20543
|
+
function depsForAgent(deps, agent) {
|
|
20544
|
+
const host = agent.host ?? readHostFileLenient(agent.paths.hostFile).salvaged;
|
|
20545
|
+
return agentDeps(deps, withRecordedHarnessFiles(agent.paths, host));
|
|
20546
|
+
}
|
|
20547
|
+
var init_agent_deps = __esm({
|
|
20548
|
+
"../../packages/tacho/src/cli/agent-deps.ts"() {
|
|
20549
|
+
"use strict";
|
|
20550
|
+
init_agents();
|
|
20551
|
+
init_host_file();
|
|
20552
|
+
}
|
|
20553
|
+
});
|
|
20554
|
+
|
|
20555
|
+
// ../../packages/tacho/src/cli/claude-code-mcp.ts
|
|
20556
|
+
function canServeOxagenTools(host) {
|
|
20557
|
+
return host.gateway_api_key !== void 0;
|
|
20558
|
+
}
|
|
20559
|
+
function registerClaudeCodeMcp(host, deps) {
|
|
20560
|
+
const edit = deps.editClaudeUserConfig;
|
|
20561
|
+
if (edit === void 0)
|
|
20562
|
+
return {
|
|
20563
|
+
host,
|
|
20564
|
+
result: "skipped",
|
|
20565
|
+
reason: "this build cannot edit Claude Code's user config",
|
|
20566
|
+
displaced: false
|
|
20567
|
+
};
|
|
20568
|
+
if (!canServeOxagenTools(host))
|
|
20569
|
+
return {
|
|
20570
|
+
host,
|
|
20571
|
+
result: "skipped",
|
|
20572
|
+
reason: "this enrollment has no gateway key, so the collector cannot serve Oxagen's tools. Run `oxagen agent enroll --force` to enroll this machine again with one",
|
|
20573
|
+
displaced: false
|
|
20574
|
+
};
|
|
20575
|
+
const path2 = deps.paths.claudeUserConfig;
|
|
20576
|
+
const shim = host.mcp_stdio_command ?? deps.runtime.mcpStdioCommand;
|
|
20577
|
+
let current = host;
|
|
20578
|
+
if (current.harness_files?.claude_user_config !== path2) {
|
|
20579
|
+
current = {
|
|
20580
|
+
...current,
|
|
20581
|
+
harness_files: { ...current.harness_files, claude_user_config: path2 }
|
|
20582
|
+
};
|
|
20583
|
+
writeHostFile(deps.paths.hostFile, current);
|
|
20584
|
+
}
|
|
20585
|
+
let result2 = "present";
|
|
20586
|
+
let displaced = false;
|
|
20587
|
+
let wroteEntry = false;
|
|
20588
|
+
edit((document) => {
|
|
20589
|
+
const problem = claudeUserConfigShapeProblem(document);
|
|
20590
|
+
if (problem !== void 0) throw new HarnessFileError(path2, problem);
|
|
20591
|
+
const merged = mergeClaudeCodeMcpConfig(document, {
|
|
20592
|
+
enrollmentId: current.host_enrollment_id,
|
|
20593
|
+
port: current.port,
|
|
20594
|
+
localToken: current.local_token,
|
|
20595
|
+
shimCommand: shim[0],
|
|
20596
|
+
shimArgs: shim.slice(1, -1),
|
|
20597
|
+
...deps.env["TACHO_HOME"] !== void 0 ? { tachoHome: deps.env["TACHO_HOME"] } : {}
|
|
20598
|
+
});
|
|
20599
|
+
if (!merged.changed) return void 0;
|
|
20600
|
+
if (Object.keys(merged.displaced).length > 0) {
|
|
20601
|
+
displaced = true;
|
|
20602
|
+
current = {
|
|
20603
|
+
...current,
|
|
20604
|
+
displaced_mcp_servers: {
|
|
20605
|
+
...current.displaced_mcp_servers,
|
|
20606
|
+
[HARNESS]: {
|
|
20607
|
+
...current.displaced_mcp_servers[HARNESS],
|
|
20608
|
+
// The server the person put under the name most recently wins:
|
|
20609
|
+
// one there now replaced whatever an earlier run moved aside.
|
|
20610
|
+
...merged.displaced
|
|
20611
|
+
}
|
|
20612
|
+
}
|
|
20613
|
+
};
|
|
20614
|
+
writeHostFile(deps.paths.hostFile, current);
|
|
20615
|
+
}
|
|
20616
|
+
result2 = "written";
|
|
20617
|
+
wroteEntry = true;
|
|
20618
|
+
return merged.config;
|
|
20619
|
+
});
|
|
20620
|
+
if (wroteEntry || current.mcp_registered_at?.[HARNESS] === void 0) {
|
|
20621
|
+
current = {
|
|
20622
|
+
...current,
|
|
20623
|
+
mcp_registered_at: {
|
|
20624
|
+
...current.mcp_registered_at,
|
|
20625
|
+
[HARNESS]: new Date(deps.now()).toISOString()
|
|
20626
|
+
}
|
|
20627
|
+
};
|
|
20628
|
+
writeHostFile(deps.paths.hostFile, current);
|
|
20629
|
+
}
|
|
20630
|
+
return { host: current, result: result2, displaced };
|
|
20631
|
+
}
|
|
20632
|
+
function needsClaudeCodeMcp(host) {
|
|
20633
|
+
return host.revoked_at === null && host.harnesses.includes(HARNESS) && canServeOxagenTools(host) && host.mcp_registered_at?.[HARNESS] === void 0;
|
|
20634
|
+
}
|
|
20635
|
+
function addMissingClaudeCodeMcp(deps) {
|
|
20636
|
+
if (deps.editClaudeUserConfig === void 0) return [];
|
|
20637
|
+
const pending = listAgents(deps.paths).filter(
|
|
20638
|
+
(agent) => agentIsLive(agent) && needsClaudeCodeMcp(agent.host)
|
|
20639
|
+
);
|
|
20640
|
+
if (pending.length === 0) return [];
|
|
20641
|
+
const lock = acquireInstallLock(deps.paths.tachoDir, deps.now);
|
|
20642
|
+
if ("heldBy" in lock) return [];
|
|
20643
|
+
const added = [];
|
|
20644
|
+
try {
|
|
20645
|
+
for (const agent of pending) {
|
|
20646
|
+
const own = depsForAgent(deps, agent);
|
|
20647
|
+
const host = readHostFile(own.paths.hostFile);
|
|
20648
|
+
if (host === void 0 || !needsClaudeCodeMcp(host)) continue;
|
|
20649
|
+
const recorded = host.harness_files;
|
|
20650
|
+
if (recorded?.claude_user_config === void 0 && recorded?.claude_settings !== void 0 && recorded.claude_settings !== agent.paths.claudeSettings) {
|
|
20651
|
+
added.push({
|
|
20652
|
+
agentKey: host.agent_key,
|
|
20653
|
+
path: own.paths.claudeUserConfig,
|
|
20654
|
+
ok: false,
|
|
20655
|
+
problem: `this agent was enrolled with Claude Code's settings at ${recorded.claude_settings}, and this command finds them at ${agent.paths.claudeSettings}, so it cannot tell which .claude.json Claude Code reads. Run \`oxagen agent enroll\` from a shell with the CLAUDE_CONFIG_DIR you enrolled with`
|
|
20656
|
+
});
|
|
20657
|
+
continue;
|
|
20658
|
+
}
|
|
20659
|
+
try {
|
|
20660
|
+
const outcome = registerClaudeCodeMcp(host, own);
|
|
20661
|
+
added.push({
|
|
20662
|
+
agentKey: host.agent_key,
|
|
20663
|
+
path: own.paths.claudeUserConfig,
|
|
20664
|
+
ok: outcome.result !== "skipped",
|
|
20665
|
+
...outcome.reason !== void 0 ? { problem: outcome.reason } : {}
|
|
20666
|
+
});
|
|
20667
|
+
} catch (error) {
|
|
20668
|
+
added.push({
|
|
20669
|
+
agentKey: host.agent_key,
|
|
20670
|
+
path: own.paths.claudeUserConfig,
|
|
20671
|
+
ok: false,
|
|
20672
|
+
problem: error instanceof Error ? error.message : String(error)
|
|
20673
|
+
});
|
|
20674
|
+
}
|
|
20675
|
+
}
|
|
20676
|
+
} finally {
|
|
20677
|
+
lock.release();
|
|
20678
|
+
}
|
|
20679
|
+
return added;
|
|
20680
|
+
}
|
|
20681
|
+
var HARNESS;
|
|
20682
|
+
var init_claude_code_mcp = __esm({
|
|
20683
|
+
"../../packages/tacho/src/cli/claude-code-mcp.ts"() {
|
|
20684
|
+
"use strict";
|
|
20685
|
+
init_agents();
|
|
20686
|
+
init_claude_code_mcp_writer();
|
|
20687
|
+
init_harness_file();
|
|
20688
|
+
init_host_file();
|
|
20689
|
+
init_install_lock();
|
|
20690
|
+
init_agent_deps();
|
|
20691
|
+
HARNESS = "claude-code";
|
|
20692
|
+
}
|
|
20693
|
+
});
|
|
20694
|
+
|
|
20370
20695
|
// ../../packages/tacho/src/host/model-base-url-toml.ts
|
|
20371
20696
|
function splitLines(text4) {
|
|
20372
20697
|
const lines = [];
|
|
@@ -20480,13 +20805,13 @@ var init_model_base_url_toml = __esm({
|
|
|
20480
20805
|
import { createHash as createHash5 } from "node:crypto";
|
|
20481
20806
|
import {
|
|
20482
20807
|
chmodSync as chmodSync3,
|
|
20483
|
-
existsSync as
|
|
20484
|
-
mkdirSync as
|
|
20485
|
-
readFileSync as
|
|
20808
|
+
existsSync as existsSync5,
|
|
20809
|
+
mkdirSync as mkdirSync5,
|
|
20810
|
+
readFileSync as readFileSync6,
|
|
20486
20811
|
statSync as statSync3,
|
|
20487
|
-
unlinkSync as
|
|
20812
|
+
unlinkSync as unlinkSync4
|
|
20488
20813
|
} from "node:fs";
|
|
20489
|
-
import { basename as basename3, dirname as
|
|
20814
|
+
import { basename as basename3, dirname as dirname5, join as join13 } from "node:path";
|
|
20490
20815
|
function claudeToolSearchEnabled(value) {
|
|
20491
20816
|
return typeof value === "string" && /^(true|auto(:\d+)?)$/i.test(value);
|
|
20492
20817
|
}
|
|
@@ -20500,19 +20825,19 @@ function isModelProxyBaseUrl(harness, value) {
|
|
|
20500
20825
|
}
|
|
20501
20826
|
function modelBaseUrlFile(harness, homes) {
|
|
20502
20827
|
if (harness === "claude-code")
|
|
20503
|
-
return
|
|
20828
|
+
return join13(
|
|
20504
20829
|
homes.claudeConfigDir ?? harnessConfigDirs(homes.home).claudeConfigDir,
|
|
20505
20830
|
"settings.json"
|
|
20506
20831
|
);
|
|
20507
20832
|
if (harness === "codex")
|
|
20508
|
-
return
|
|
20833
|
+
return join13(
|
|
20509
20834
|
homes.codexHome ?? harnessConfigDirs(homes.home).codexHome,
|
|
20510
20835
|
"config.toml"
|
|
20511
20836
|
);
|
|
20512
|
-
const stellaHome = homes.stellaHome ??
|
|
20513
|
-
const toml =
|
|
20514
|
-
const json2 =
|
|
20515
|
-
return !
|
|
20837
|
+
const stellaHome = homes.stellaHome ?? join13(homes.home, ".stella");
|
|
20838
|
+
const toml = join13(stellaHome, "stella.toml");
|
|
20839
|
+
const json2 = join13(stellaHome, "settings.json");
|
|
20840
|
+
return !existsSync5(toml) && existsSync5(json2) ? json2 : toml;
|
|
20516
20841
|
}
|
|
20517
20842
|
function keyLabel(harness) {
|
|
20518
20843
|
if (harness === "claude-code") return `env.${CLAUDE_KEY}`;
|
|
@@ -20522,7 +20847,7 @@ function isJsonFile(file) {
|
|
|
20522
20847
|
return file.endsWith(".json");
|
|
20523
20848
|
}
|
|
20524
20849
|
function sidecarFor(file) {
|
|
20525
|
-
return
|
|
20850
|
+
return join13(dirname5(file), `.${basename3(file)}.oxagen-model-base-url.json`);
|
|
20526
20851
|
}
|
|
20527
20852
|
function modelBaseUrlBackupPath(harness, home, stellaHome, dirs = {}) {
|
|
20528
20853
|
return sidecarFor(fileFor(harness, homesOf(home, stellaHome, dirs)));
|
|
@@ -20539,9 +20864,9 @@ function sha256(text4) {
|
|
|
20539
20864
|
return createHash5("sha256").update(text4, "utf8").digest("hex");
|
|
20540
20865
|
}
|
|
20541
20866
|
function readSidecar(path2) {
|
|
20542
|
-
if (!
|
|
20867
|
+
if (!existsSync5(path2)) return void 0;
|
|
20543
20868
|
try {
|
|
20544
|
-
const parsed = JSON.parse(
|
|
20869
|
+
const parsed = JSON.parse(readFileSync6(path2, "utf8"));
|
|
20545
20870
|
if (parsed.schema !== SIDECAR_SCHEMA) return void 0;
|
|
20546
20871
|
if (typeof parsed.written_sha256 !== "string") return void 0;
|
|
20547
20872
|
return {
|
|
@@ -20566,7 +20891,7 @@ function readSidecar(path2) {
|
|
|
20566
20891
|
}
|
|
20567
20892
|
}
|
|
20568
20893
|
function writeAtomicPreserving(path2, data) {
|
|
20569
|
-
|
|
20894
|
+
mkdirSync5(dirname5(path2), { recursive: true });
|
|
20570
20895
|
let mode = 384;
|
|
20571
20896
|
let owner;
|
|
20572
20897
|
try {
|
|
@@ -20582,7 +20907,7 @@ function writeAtomicPreserving(path2, data) {
|
|
|
20582
20907
|
}
|
|
20583
20908
|
function readTextIfExists(path2) {
|
|
20584
20909
|
try {
|
|
20585
|
-
return
|
|
20910
|
+
return readFileSync6(path2, "utf8");
|
|
20586
20911
|
} catch (error) {
|
|
20587
20912
|
if (error.code === "ENOENT") return void 0;
|
|
20588
20913
|
throw error;
|
|
@@ -20673,9 +20998,9 @@ function stellaManagedSettingsPath(platform = process.platform, env = process.en
|
|
|
20673
20998
|
const named = env["STELLA_MANAGED_SETTINGS"];
|
|
20674
20999
|
if (named !== void 0 && named.length > 0) return named;
|
|
20675
21000
|
const dir = platform === "darwin" ? "/Library/Application Support/stella" : "/etc/stella";
|
|
20676
|
-
const toml =
|
|
20677
|
-
const json2 =
|
|
20678
|
-
return !
|
|
21001
|
+
const toml = join13(dir, "stella.toml");
|
|
21002
|
+
const json2 = join13(dir, "settings.json");
|
|
21003
|
+
return !existsSync5(toml) && existsSync5(json2) ? json2 : toml;
|
|
20679
21004
|
}
|
|
20680
21005
|
function managedShadow(harness, managedFile, expected) {
|
|
20681
21006
|
try {
|
|
@@ -20934,7 +21259,7 @@ function applyOne(harness, options) {
|
|
|
20934
21259
|
original_base64: orphan ? "" : (
|
|
20935
21260
|
// The raw bytes, not the decoded text: restore is byte-exact even
|
|
20936
21261
|
// for a file that is not clean UTF-8.
|
|
20937
|
-
(text4 === void 0 ? Buffer.alloc(0) :
|
|
21262
|
+
(text4 === void 0 ? Buffer.alloc(0) : readFileSync6(file)).toString("base64")
|
|
20938
21263
|
),
|
|
20939
21264
|
written_sha256: orphan ? "" : sha256(next),
|
|
20940
21265
|
previous,
|
|
@@ -20955,7 +21280,7 @@ function restoreOne(harness, options) {
|
|
|
20955
21280
|
const sidecar = readSidecar(backup);
|
|
20956
21281
|
const text4 = readTextIfExists(file);
|
|
20957
21282
|
const dropSidecar = () => {
|
|
20958
|
-
if (
|
|
21283
|
+
if (existsSync5(backup)) unlinkSync4(backup);
|
|
20959
21284
|
};
|
|
20960
21285
|
if (text4 === void 0) {
|
|
20961
21286
|
dropSidecar();
|
|
@@ -20968,7 +21293,7 @@ function restoreOne(harness, options) {
|
|
|
20968
21293
|
Buffer.from(sidecar.original_base64, "base64")
|
|
20969
21294
|
);
|
|
20970
21295
|
} else {
|
|
20971
|
-
|
|
21296
|
+
unlinkSync4(file);
|
|
20972
21297
|
}
|
|
20973
21298
|
dropSidecar();
|
|
20974
21299
|
return true;
|
|
@@ -21070,8 +21395,8 @@ var init_model_base_url = __esm({
|
|
|
21070
21395
|
});
|
|
21071
21396
|
|
|
21072
21397
|
// ../../packages/tacho/src/host/run-token.ts
|
|
21073
|
-
import { createHmac, randomBytes as
|
|
21074
|
-
import { readFileSync as
|
|
21398
|
+
import { createHmac, randomBytes as randomBytes4, timingSafeEqual } from "node:crypto";
|
|
21399
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
21075
21400
|
function keyFromBytes(bytes) {
|
|
21076
21401
|
if (bytes.length !== KEY_BYTES)
|
|
21077
21402
|
throw new Error(
|
|
@@ -21081,7 +21406,7 @@ function keyFromBytes(bytes) {
|
|
|
21081
21406
|
return { bytes, id };
|
|
21082
21407
|
}
|
|
21083
21408
|
function generateRunTokenKey() {
|
|
21084
|
-
return keyFromBytes(
|
|
21409
|
+
return keyFromBytes(randomBytes4(KEY_BYTES));
|
|
21085
21410
|
}
|
|
21086
21411
|
function runTokenKeyFromHex(hex) {
|
|
21087
21412
|
const trimmed = hex.trim();
|
|
@@ -21092,7 +21417,7 @@ function runTokenKeyFromHex(hex) {
|
|
|
21092
21417
|
function loadOrCreateRunTokenKey(path2) {
|
|
21093
21418
|
try {
|
|
21094
21419
|
return {
|
|
21095
|
-
key: runTokenKeyFromHex(
|
|
21420
|
+
key: runTokenKeyFromHex(readFileSync7(path2, "utf8")),
|
|
21096
21421
|
created: false
|
|
21097
21422
|
};
|
|
21098
21423
|
} catch (error) {
|
|
@@ -21105,7 +21430,7 @@ function loadOrCreateRunTokenKey(path2) {
|
|
|
21105
21430
|
}
|
|
21106
21431
|
function readRunTokenKey(path2) {
|
|
21107
21432
|
try {
|
|
21108
|
-
return runTokenKeyFromHex(
|
|
21433
|
+
return runTokenKeyFromHex(readFileSync7(path2, "utf8"));
|
|
21109
21434
|
} catch (error) {
|
|
21110
21435
|
if (error.code === "ENOENT") return void 0;
|
|
21111
21436
|
throw error;
|
|
@@ -21128,7 +21453,7 @@ function mintRunToken(options) {
|
|
|
21128
21453
|
throw new Error("run token would already be expired when minted");
|
|
21129
21454
|
const claims = {
|
|
21130
21455
|
v: 1,
|
|
21131
|
-
tid: `rt_${
|
|
21456
|
+
tid: `rt_${randomBytes4(10).toString("hex")}`,
|
|
21132
21457
|
host: options.host,
|
|
21133
21458
|
harness: options.harness,
|
|
21134
21459
|
provider: options.provider,
|
|
@@ -21239,14 +21564,14 @@ var init_run_token = __esm({
|
|
|
21239
21564
|
import { createHash as createHash6 } from "node:crypto";
|
|
21240
21565
|
import {
|
|
21241
21566
|
chmodSync as chmodSync4,
|
|
21242
|
-
existsSync as
|
|
21567
|
+
existsSync as existsSync6,
|
|
21243
21568
|
lstatSync as lstatSync2,
|
|
21244
|
-
mkdirSync as
|
|
21245
|
-
readFileSync as
|
|
21569
|
+
mkdirSync as mkdirSync6,
|
|
21570
|
+
readFileSync as readFileSync8,
|
|
21246
21571
|
statSync as statSync4,
|
|
21247
|
-
unlinkSync as
|
|
21572
|
+
unlinkSync as unlinkSync5
|
|
21248
21573
|
} from "node:fs";
|
|
21249
|
-
import { basename as basename4, dirname as
|
|
21574
|
+
import { basename as basename4, dirname as dirname6, join as join14 } from "node:path";
|
|
21250
21575
|
function isTachoHelper(value) {
|
|
21251
21576
|
return typeof value === "string" && HELPER_MARK.test(value);
|
|
21252
21577
|
}
|
|
@@ -21254,16 +21579,16 @@ function helperCommandFor(tachoCommand) {
|
|
|
21254
21579
|
return `${tachoCommand} credential issue --harness claude-code`;
|
|
21255
21580
|
}
|
|
21256
21581
|
function fileFor2(harness, homes) {
|
|
21257
|
-
return harness === "claude-code" ?
|
|
21582
|
+
return harness === "claude-code" ? join14(
|
|
21258
21583
|
homes.claudeConfigDir ?? harnessConfigDirs(homes.home).claudeConfigDir,
|
|
21259
21584
|
"settings.json"
|
|
21260
|
-
) :
|
|
21585
|
+
) : join14(
|
|
21261
21586
|
homes.codexHome ?? harnessConfigDirs(homes.home).codexHome,
|
|
21262
21587
|
"auth.json"
|
|
21263
21588
|
);
|
|
21264
21589
|
}
|
|
21265
21590
|
function sidecarFor2(file) {
|
|
21266
|
-
return
|
|
21591
|
+
return join14(dirname6(file), `.${basename4(file)}.oxagen-model-credential.json`);
|
|
21267
21592
|
}
|
|
21268
21593
|
function modelCredentialBackupPath(harness, home, dirs = {}) {
|
|
21269
21594
|
return sidecarFor2(fileFor2(harness, { ...dirs, home }));
|
|
@@ -21272,9 +21597,9 @@ function sha2562(text4) {
|
|
|
21272
21597
|
return createHash6("sha256").update(text4, "utf8").digest("hex");
|
|
21273
21598
|
}
|
|
21274
21599
|
function readSidecar2(path2) {
|
|
21275
|
-
if (!
|
|
21600
|
+
if (!existsSync6(path2)) return void 0;
|
|
21276
21601
|
try {
|
|
21277
|
-
const parsed = JSON.parse(
|
|
21602
|
+
const parsed = JSON.parse(readFileSync8(path2, "utf8"));
|
|
21278
21603
|
if (parsed.schema !== SIDECAR_SCHEMA2) return void 0;
|
|
21279
21604
|
if (typeof parsed.written_sha256 !== "string") return void 0;
|
|
21280
21605
|
return {
|
|
@@ -21294,7 +21619,7 @@ function readSidecar2(path2) {
|
|
|
21294
21619
|
}
|
|
21295
21620
|
}
|
|
21296
21621
|
function writeAtomicPreserving2(path2, data) {
|
|
21297
|
-
|
|
21622
|
+
mkdirSync6(dirname6(path2), { recursive: true });
|
|
21298
21623
|
let mode = 384;
|
|
21299
21624
|
let owner;
|
|
21300
21625
|
try {
|
|
@@ -21310,7 +21635,7 @@ function writeAtomicPreserving2(path2, data) {
|
|
|
21310
21635
|
}
|
|
21311
21636
|
function readTextIfExists2(path2) {
|
|
21312
21637
|
try {
|
|
21313
|
-
return
|
|
21638
|
+
return readFileSync8(path2, "utf8");
|
|
21314
21639
|
} catch (error) {
|
|
21315
21640
|
if (error.code === "ENOENT") return void 0;
|
|
21316
21641
|
throw error;
|
|
@@ -21543,7 +21868,7 @@ function restoreClaude(options, released) {
|
|
|
21543
21868
|
const sidecar = readSidecar2(backup);
|
|
21544
21869
|
const text4 = readTextIfExists2(file);
|
|
21545
21870
|
const dropSidecar = () => {
|
|
21546
|
-
if (
|
|
21871
|
+
if (existsSync6(backup)) unlinkSync5(backup);
|
|
21547
21872
|
};
|
|
21548
21873
|
if (text4 === void 0) {
|
|
21549
21874
|
if (released !== void 0) {
|
|
@@ -21600,7 +21925,7 @@ function restoreCodex(options, released) {
|
|
|
21600
21925
|
const sidecar = readSidecar2(backup);
|
|
21601
21926
|
const text4 = readTextIfExists2(file);
|
|
21602
21927
|
const dropSidecar = () => {
|
|
21603
|
-
if (
|
|
21928
|
+
if (existsSync6(backup)) unlinkSync5(backup);
|
|
21604
21929
|
};
|
|
21605
21930
|
if (text4 === void 0) {
|
|
21606
21931
|
if (released !== void 0) {
|
|
@@ -21627,7 +21952,7 @@ function restoreCodex(options, released) {
|
|
|
21627
21952
|
if (released !== void 0) auth[CODEX_KEY2] = released.secret;
|
|
21628
21953
|
else delete auth[CODEX_KEY2];
|
|
21629
21954
|
if (sidecar !== void 0 && !sidecar.existed && Object.keys(auth).length === 0) {
|
|
21630
|
-
|
|
21955
|
+
unlinkSync5(file);
|
|
21631
21956
|
dropSidecar();
|
|
21632
21957
|
return { changed: true, secretRestored: released !== void 0 };
|
|
21633
21958
|
}
|
|
@@ -21772,42 +22097,13 @@ var init_model_credential = __esm({
|
|
|
21772
22097
|
}
|
|
21773
22098
|
});
|
|
21774
22099
|
|
|
21775
|
-
// ../../packages/tacho/src/cli/agent-deps.ts
|
|
21776
|
-
function agentDeps(deps, paths) {
|
|
21777
|
-
if (JSON.stringify(paths) === JSON.stringify(deps.paths)) return deps;
|
|
21778
|
-
const rebound = deps.atAgent?.(paths) ?? { ...deps, paths };
|
|
21779
|
-
return {
|
|
21780
|
-
...deps,
|
|
21781
|
-
...rebound,
|
|
21782
|
-
paths,
|
|
21783
|
-
serviceManager: deps.serviceManager,
|
|
21784
|
-
out: deps.out,
|
|
21785
|
-
err: deps.err
|
|
21786
|
-
};
|
|
21787
|
-
}
|
|
21788
|
-
function depsForHarness(deps, harness) {
|
|
21789
|
-
const agent = agentHolding(deps.paths, harness);
|
|
21790
|
-
return agent === void 0 ? deps : depsForAgent(deps, agent);
|
|
21791
|
-
}
|
|
21792
|
-
function depsForAgent(deps, agent) {
|
|
21793
|
-
const host = agent.host ?? readHostFileLenient(agent.paths.hostFile).salvaged;
|
|
21794
|
-
return agentDeps(deps, withRecordedHarnessFiles(agent.paths, host));
|
|
21795
|
-
}
|
|
21796
|
-
var init_agent_deps = __esm({
|
|
21797
|
-
"../../packages/tacho/src/cli/agent-deps.ts"() {
|
|
21798
|
-
"use strict";
|
|
21799
|
-
init_agents();
|
|
21800
|
-
init_host_file();
|
|
21801
|
-
}
|
|
21802
|
-
});
|
|
21803
|
-
|
|
21804
22100
|
// ../../packages/tacho/src/cli/credential.ts
|
|
21805
|
-
import { existsSync as
|
|
21806
|
-
import { dirname as
|
|
22101
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
22102
|
+
import { dirname as dirname7 } from "node:path";
|
|
21807
22103
|
function harnessDirsOf(deps) {
|
|
21808
22104
|
return {
|
|
21809
|
-
claudeConfigDir:
|
|
21810
|
-
codexHome:
|
|
22105
|
+
claudeConfigDir: dirname7(deps.paths.claudeSettings),
|
|
22106
|
+
codexHome: dirname7(deps.paths.codexHooks)
|
|
21811
22107
|
};
|
|
21812
22108
|
}
|
|
21813
22109
|
function parseCredentialMode(value) {
|
|
@@ -22058,7 +22354,7 @@ async function restoreCredentials(host, deps, mode = "unenroll", only) {
|
|
|
22058
22354
|
try {
|
|
22059
22355
|
if (host !== void 0 && !host.harnesses.includes(harness)) {
|
|
22060
22356
|
const dirs = harnessDirsOf(deps);
|
|
22061
|
-
const hasReceipt =
|
|
22357
|
+
const hasReceipt = existsSync7(
|
|
22062
22358
|
modelCredentialBackupPath(harness, deps.home, dirs)
|
|
22063
22359
|
);
|
|
22064
22360
|
if (!hasReceipt && !hasOrphanedModelCredential(harness, deps.home, dirs))
|
|
@@ -22289,20 +22585,20 @@ var init_codex_app_server = __esm({
|
|
|
22289
22585
|
});
|
|
22290
22586
|
|
|
22291
22587
|
// ../../packages/tacho/src/host/credential-store.ts
|
|
22292
|
-
import { createCipheriv, createDecipheriv, randomBytes as
|
|
22588
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes5 } from "node:crypto";
|
|
22293
22589
|
import {
|
|
22294
|
-
closeSync as
|
|
22295
|
-
existsSync as
|
|
22590
|
+
closeSync as closeSync4,
|
|
22591
|
+
existsSync as existsSync8,
|
|
22296
22592
|
fsyncSync as fsyncSync2,
|
|
22297
|
-
openSync as
|
|
22298
|
-
readFileSync as
|
|
22593
|
+
openSync as openSync4,
|
|
22594
|
+
readFileSync as readFileSync9,
|
|
22299
22595
|
statSync as statSync5,
|
|
22300
|
-
unlinkSync as
|
|
22301
|
-
writeSync as
|
|
22596
|
+
unlinkSync as unlinkSync6,
|
|
22597
|
+
writeSync as writeSync3
|
|
22302
22598
|
} from "node:fs";
|
|
22303
22599
|
function readKey(path2) {
|
|
22304
22600
|
try {
|
|
22305
|
-
const hex =
|
|
22601
|
+
const hex = readFileSync9(path2, "utf8").trim();
|
|
22306
22602
|
if (!/^[0-9a-f]{64}$/i.test(hex))
|
|
22307
22603
|
throw new Error(`${path2} does not hold a 32-byte key`);
|
|
22308
22604
|
return Buffer.from(hex, "hex");
|
|
@@ -22314,7 +22610,7 @@ function readKey(path2) {
|
|
|
22314
22610
|
function loadOrCreateKey(path2) {
|
|
22315
22611
|
const existing = readKey(path2);
|
|
22316
22612
|
if (existing !== void 0) return existing;
|
|
22317
|
-
const key =
|
|
22613
|
+
const key = randomBytes5(KEY_BYTES2);
|
|
22318
22614
|
writeSensitiveFileAtomic(path2, `${key.toString("hex")}
|
|
22319
22615
|
`);
|
|
22320
22616
|
return key;
|
|
@@ -22331,16 +22627,16 @@ function overwriteInPlace(path2) {
|
|
|
22331
22627
|
let fd2;
|
|
22332
22628
|
try {
|
|
22333
22629
|
const size = statSync5(path2).size;
|
|
22334
|
-
fd2 =
|
|
22335
|
-
|
|
22630
|
+
fd2 = openSync4(path2, "r+");
|
|
22631
|
+
writeSync3(fd2, randomBytes5(Math.max(size, KEY_BYTES2 * 2)), 0, void 0, 0);
|
|
22336
22632
|
fsyncSync2(fd2);
|
|
22337
22633
|
} catch {
|
|
22338
22634
|
} finally {
|
|
22339
|
-
if (fd2 !== void 0)
|
|
22635
|
+
if (fd2 !== void 0) closeSync4(fd2);
|
|
22340
22636
|
}
|
|
22341
22637
|
}
|
|
22342
22638
|
function seal(key, secret, aad) {
|
|
22343
|
-
const nonce =
|
|
22639
|
+
const nonce = randomBytes5(12);
|
|
22344
22640
|
const cipher = createCipheriv("aes-256-gcm", key, nonce);
|
|
22345
22641
|
cipher.setAAD(Buffer.from(aad, "utf8"));
|
|
22346
22642
|
const ciphertext = Buffer.concat([
|
|
@@ -22385,7 +22681,7 @@ function openCredentialStore(paths) {
|
|
|
22385
22681
|
function readAll() {
|
|
22386
22682
|
let text4;
|
|
22387
22683
|
try {
|
|
22388
|
-
text4 =
|
|
22684
|
+
text4 = readFileSync9(paths.file, "utf8");
|
|
22389
22685
|
} catch (error) {
|
|
22390
22686
|
if (error.code === "ENOENT") return [];
|
|
22391
22687
|
throw error;
|
|
@@ -22399,7 +22695,7 @@ function openCredentialStore(paths) {
|
|
|
22399
22695
|
}
|
|
22400
22696
|
function writeAll2(entries2) {
|
|
22401
22697
|
if (entries2.length === 0) {
|
|
22402
|
-
if (
|
|
22698
|
+
if (existsSync8(paths.file)) unlinkSync6(paths.file);
|
|
22403
22699
|
return;
|
|
22404
22700
|
}
|
|
22405
22701
|
writeSensitiveFileAtomic(
|
|
@@ -22454,9 +22750,9 @@ function openCredentialStore(paths) {
|
|
|
22454
22750
|
},
|
|
22455
22751
|
status: () => readAll().map(custodyOf),
|
|
22456
22752
|
shred: () => {
|
|
22457
|
-
if (
|
|
22753
|
+
if (existsSync8(paths.key)) overwriteInPlace(paths.key);
|
|
22458
22754
|
for (const path2 of [paths.file, paths.key])
|
|
22459
|
-
if (
|
|
22755
|
+
if (existsSync8(path2)) unlinkSync6(path2);
|
|
22460
22756
|
}
|
|
22461
22757
|
};
|
|
22462
22758
|
}
|
|
@@ -22500,16 +22796,87 @@ var init_credential_store = __esm({
|
|
|
22500
22796
|
}
|
|
22501
22797
|
});
|
|
22502
22798
|
|
|
22799
|
+
// ../../packages/tacho/src/host/claude-config-lock.ts
|
|
22800
|
+
import { mkdirSync as mkdirSync7, rmdirSync as rmdirSync4, statSync as statSync6 } from "node:fs";
|
|
22801
|
+
function sleepSync(ms) {
|
|
22802
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
22803
|
+
}
|
|
22804
|
+
function claudeConfigLockPath(file) {
|
|
22805
|
+
return `${file}.lock`;
|
|
22806
|
+
}
|
|
22807
|
+
function withClaudeConfigLock(file, edit, options = {}) {
|
|
22808
|
+
const lock = claudeConfigLockPath(file);
|
|
22809
|
+
const now = options.now ?? Date.now;
|
|
22810
|
+
const sleep3 = options.sleep ?? sleepSync;
|
|
22811
|
+
const staleMs = options.staleMs ?? CLAUDE_CONFIG_LOCK_STALE_MS;
|
|
22812
|
+
const waitMs = options.waitMs ?? CLAUDE_CONFIG_LOCK_WAIT_MS;
|
|
22813
|
+
const deadline = now() + waitMs;
|
|
22814
|
+
let held = false;
|
|
22815
|
+
for (; ; ) {
|
|
22816
|
+
try {
|
|
22817
|
+
mkdirSync7(lock);
|
|
22818
|
+
held = true;
|
|
22819
|
+
break;
|
|
22820
|
+
} catch (error) {
|
|
22821
|
+
const code = error.code;
|
|
22822
|
+
if (code === "ENOENT") break;
|
|
22823
|
+
if (code !== "EEXIST") throw error;
|
|
22824
|
+
}
|
|
22825
|
+
let modified;
|
|
22826
|
+
try {
|
|
22827
|
+
modified = statSync6(lock).mtimeMs;
|
|
22828
|
+
} catch {
|
|
22829
|
+
modified = void 0;
|
|
22830
|
+
}
|
|
22831
|
+
let retryNow = modified === void 0;
|
|
22832
|
+
if (modified !== void 0 && now() - modified > staleMs) {
|
|
22833
|
+
try {
|
|
22834
|
+
if (statSync6(lock).mtimeMs === modified) {
|
|
22835
|
+
rmdirSync4(lock);
|
|
22836
|
+
retryNow = true;
|
|
22837
|
+
}
|
|
22838
|
+
} catch {
|
|
22839
|
+
}
|
|
22840
|
+
}
|
|
22841
|
+
if (now() >= deadline)
|
|
22842
|
+
throw new HarnessFileError(
|
|
22843
|
+
file,
|
|
22844
|
+
`is being saved by Claude Code, which held its lock (${lock}) for more than ${Math.round(waitMs / 1e3)} seconds; nothing was written, so run the command again in a moment`
|
|
22845
|
+
);
|
|
22846
|
+
if (!retryNow) sleep3(RETRY_MS);
|
|
22847
|
+
}
|
|
22848
|
+
try {
|
|
22849
|
+
return edit();
|
|
22850
|
+
} finally {
|
|
22851
|
+
if (held) {
|
|
22852
|
+
try {
|
|
22853
|
+
rmdirSync4(lock);
|
|
22854
|
+
} catch {
|
|
22855
|
+
}
|
|
22856
|
+
}
|
|
22857
|
+
}
|
|
22858
|
+
}
|
|
22859
|
+
var CLAUDE_CONFIG_LOCK_STALE_MS, CLAUDE_CONFIG_LOCK_WAIT_MS, RETRY_MS;
|
|
22860
|
+
var init_claude_config_lock = __esm({
|
|
22861
|
+
"../../packages/tacho/src/host/claude-config-lock.ts"() {
|
|
22862
|
+
"use strict";
|
|
22863
|
+
init_harness_file();
|
|
22864
|
+
CLAUDE_CONFIG_LOCK_STALE_MS = 1e4;
|
|
22865
|
+
CLAUDE_CONFIG_LOCK_WAIT_MS = 3e3;
|
|
22866
|
+
RETRY_MS = 25;
|
|
22867
|
+
}
|
|
22868
|
+
});
|
|
22869
|
+
|
|
22503
22870
|
// ../../packages/tacho/src/host/service.ts
|
|
22504
|
-
import { join as
|
|
22871
|
+
import { join as join15 } from "node:path";
|
|
22505
22872
|
import {
|
|
22506
|
-
existsSync as
|
|
22507
|
-
readdirSync as
|
|
22508
|
-
readFileSync as
|
|
22509
|
-
rmdirSync as
|
|
22510
|
-
unlinkSync as
|
|
22873
|
+
existsSync as existsSync9,
|
|
22874
|
+
readdirSync as readdirSync6,
|
|
22875
|
+
readFileSync as readFileSync10,
|
|
22876
|
+
rmdirSync as rmdirSync5,
|
|
22877
|
+
unlinkSync as unlinkSync7
|
|
22511
22878
|
} from "node:fs";
|
|
22512
|
-
import { randomBytes as
|
|
22879
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
22513
22880
|
function xmlEscape(value) {
|
|
22514
22881
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
22515
22882
|
}
|
|
@@ -22581,8 +22948,8 @@ function blockingSleep(ms) {
|
|
|
22581
22948
|
}
|
|
22582
22949
|
function launchdManager(options) {
|
|
22583
22950
|
const sleep3 = options.sleep ?? blockingSleep;
|
|
22584
|
-
const dir =
|
|
22585
|
-
const unitPath =
|
|
22951
|
+
const dir = join15(options.home, "Library", "LaunchAgents");
|
|
22952
|
+
const unitPath = join15(dir, `${SERVICE_LABEL}.plist`);
|
|
22586
22953
|
const domain = `gui/${options.uid ?? process.getuid?.() ?? 501}`;
|
|
22587
22954
|
const target2 = `${domain}/${SERVICE_LABEL}`;
|
|
22588
22955
|
const loaded = () => options.exec("launchctl", ["print", target2]).status === 0;
|
|
@@ -22601,7 +22968,7 @@ function launchdManager(options) {
|
|
|
22601
22968
|
unitPath,
|
|
22602
22969
|
install: (spec) => {
|
|
22603
22970
|
const plist = renderLaunchdPlist(spec);
|
|
22604
|
-
const unchanged =
|
|
22971
|
+
const unchanged = existsSync9(unitPath) && readFileSync10(unitPath, "utf8") === plist;
|
|
22605
22972
|
if (unchanged && loaded()) {
|
|
22606
22973
|
const kicked = options.exec("launchctl", ["kickstart", "-k", target2]);
|
|
22607
22974
|
if (kicked.status === 0 && loaded()) return;
|
|
@@ -22630,10 +22997,10 @@ function launchdManager(options) {
|
|
|
22630
22997
|
uninstall: () => {
|
|
22631
22998
|
options.exec("launchctl", ["bootout", target2]);
|
|
22632
22999
|
if (!waitUntilGone()) throw stillLoaded("unenroll");
|
|
22633
|
-
if (
|
|
23000
|
+
if (existsSync9(unitPath)) unlinkSync7(unitPath);
|
|
22634
23001
|
},
|
|
22635
23002
|
status: () => {
|
|
22636
|
-
const installed =
|
|
23003
|
+
const installed = existsSync9(unitPath);
|
|
22637
23004
|
const result2 = options.exec("launchctl", [
|
|
22638
23005
|
"print",
|
|
22639
23006
|
`${domain}/${SERVICE_LABEL}`
|
|
@@ -22650,8 +23017,8 @@ function noUserManager(result2) {
|
|
|
22650
23017
|
}
|
|
22651
23018
|
function stopByPidFile(options) {
|
|
22652
23019
|
const { pidPath } = options;
|
|
22653
|
-
if (pidPath === void 0 || !
|
|
22654
|
-
const record = parseDaemonPid(
|
|
23020
|
+
if (pidPath === void 0 || !existsSync9(pidPath)) return;
|
|
23021
|
+
const record = parseDaemonPid(readFileSync10(pidPath, "utf8"));
|
|
22655
23022
|
if (record === void 0) return;
|
|
22656
23023
|
const sleep3 = options.sleep ?? blockingSleep;
|
|
22657
23024
|
const processes = options.processes ?? {
|
|
@@ -22683,9 +23050,9 @@ function stopByPidFile(options) {
|
|
|
22683
23050
|
);
|
|
22684
23051
|
}
|
|
22685
23052
|
function systemdManager(options) {
|
|
22686
|
-
const dir =
|
|
22687
|
-
const unitPath =
|
|
22688
|
-
const wants =
|
|
23053
|
+
const dir = join15(options.home, ".config", "systemd", "user");
|
|
23054
|
+
const unitPath = join15(dir, "tachod.service");
|
|
23055
|
+
const wants = join15(dir, "default.target.wants");
|
|
22689
23056
|
return {
|
|
22690
23057
|
kind: "systemd",
|
|
22691
23058
|
unitPath,
|
|
@@ -22695,8 +23062,8 @@ function systemdManager(options) {
|
|
|
22695
23062
|
throw new Error(
|
|
22696
23063
|
`no systemd user manager is available (${probe.stderr.trim().split("\n")[0] ?? ""})`
|
|
22697
23064
|
);
|
|
22698
|
-
const previous =
|
|
22699
|
-
const createsWants = previous === void 0 ? !
|
|
23065
|
+
const previous = existsSync9(unitPath) ? readFileSync10(unitPath, "utf8") : void 0;
|
|
23066
|
+
const createsWants = previous === void 0 ? !existsSync9(wants) : previous.includes(CREATED_WANTS_MARK);
|
|
22700
23067
|
ensureDir(dir, 493);
|
|
22701
23068
|
writeSensitiveFileAtomic(
|
|
22702
23069
|
unitPath,
|
|
@@ -22736,7 +23103,7 @@ function systemdManager(options) {
|
|
|
22736
23103
|
]);
|
|
22737
23104
|
if (noUserManager(disabled)) {
|
|
22738
23105
|
stopByPidFile(options);
|
|
22739
|
-
if (
|
|
23106
|
+
if (existsSync9(unitPath)) unlinkSync7(unitPath);
|
|
22740
23107
|
return;
|
|
22741
23108
|
}
|
|
22742
23109
|
const active2 = options.exec("systemctl", [
|
|
@@ -22745,13 +23112,13 @@ function systemdManager(options) {
|
|
|
22745
23112
|
"tachod.service"
|
|
22746
23113
|
]);
|
|
22747
23114
|
const stopped2 = active2.status === 3 && ["inactive", "failed"].includes(active2.stdout.trim()) || active2.status === 4 && active2.stdout.trim() === "unknown";
|
|
22748
|
-
if (!stopped2 || disabled.status !== 0 &&
|
|
23115
|
+
if (!stopped2 || disabled.status !== 0 && existsSync9(unitPath)) {
|
|
22749
23116
|
throw new Error(
|
|
22750
23117
|
`systemctl could not remove tachod.service: ${disabled.stderr.trim() || active2.stderr.trim() || active2.stdout.trim() || "service state is unknown"}`
|
|
22751
23118
|
);
|
|
22752
23119
|
}
|
|
22753
|
-
const unit =
|
|
22754
|
-
if (unit !== void 0)
|
|
23120
|
+
const unit = existsSync9(unitPath) ? readFileSync10(unitPath, "utf8") : void 0;
|
|
23121
|
+
if (unit !== void 0) unlinkSync7(unitPath);
|
|
22755
23122
|
try {
|
|
22756
23123
|
const reload = options.exec("systemctl", ["--user", "daemon-reload"]);
|
|
22757
23124
|
if (reload.status !== 0)
|
|
@@ -22764,13 +23131,13 @@ function systemdManager(options) {
|
|
|
22764
23131
|
}
|
|
22765
23132
|
if (unit?.includes(CREATED_WANTS_MARK) === true) {
|
|
22766
23133
|
try {
|
|
22767
|
-
if (
|
|
23134
|
+
if (readdirSync6(wants).length === 0) rmdirSync5(wants);
|
|
22768
23135
|
} catch {
|
|
22769
23136
|
}
|
|
22770
23137
|
}
|
|
22771
23138
|
},
|
|
22772
23139
|
status: () => {
|
|
22773
|
-
const installed =
|
|
23140
|
+
const installed = existsSync9(unitPath);
|
|
22774
23141
|
const result2 = options.exec("systemctl", [
|
|
22775
23142
|
"--user",
|
|
22776
23143
|
"is-active",
|
|
@@ -22822,11 +23189,11 @@ function tasklistImage(listing, pid) {
|
|
|
22822
23189
|
return void 0;
|
|
22823
23190
|
}
|
|
22824
23191
|
function schtasksManager(options) {
|
|
22825
|
-
const launcher = options.launcherPath ??
|
|
22826
|
-
const pidPath = options.pidPath ??
|
|
23192
|
+
const launcher = options.launcherPath ?? join15(options.home, "tachod.cmd");
|
|
23193
|
+
const pidPath = options.pidPath ?? join15(launcher, "..", "tachod.pid");
|
|
22827
23194
|
const livePid = () => {
|
|
22828
|
-
if (!
|
|
22829
|
-
const record = parseDaemonPid(
|
|
23195
|
+
if (!existsSync9(pidPath)) return void 0;
|
|
23196
|
+
const record = parseDaemonPid(readFileSync10(pidPath, "utf8"));
|
|
22830
23197
|
if (record === void 0) return void 0;
|
|
22831
23198
|
const { pid } = record;
|
|
22832
23199
|
const query = options.exec("tasklist", [
|
|
@@ -22865,7 +23232,7 @@ function schtasksManager(options) {
|
|
|
22865
23232
|
unitPath: launcher,
|
|
22866
23233
|
install: (spec) => {
|
|
22867
23234
|
stopDaemon();
|
|
22868
|
-
ensureDir(
|
|
23235
|
+
ensureDir(join15(launcher, ".."), 493);
|
|
22869
23236
|
writeSensitiveFileAtomic(
|
|
22870
23237
|
launcher,
|
|
22871
23238
|
renderWindowsLauncher(
|
|
@@ -22877,7 +23244,7 @@ function schtasksManager(options) {
|
|
|
22877
23244
|
// an empty directory stayed behind (#4317). The daemon uses
|
|
22878
23245
|
// absolute paths only.
|
|
22879
23246
|
{ ...spec, workingDirectory: options.home },
|
|
22880
|
-
|
|
23247
|
+
randomBytes6(8).toString("hex")
|
|
22881
23248
|
),
|
|
22882
23249
|
384
|
|
22883
23250
|
);
|
|
@@ -22919,7 +23286,7 @@ function schtasksManager(options) {
|
|
|
22919
23286
|
`schtasks /Delete failed: ${deleted.stderr.trim() || "task removal was not confirmed"}`
|
|
22920
23287
|
);
|
|
22921
23288
|
}
|
|
22922
|
-
if (
|
|
23289
|
+
if (existsSync9(launcher)) unlinkSync7(launcher);
|
|
22923
23290
|
},
|
|
22924
23291
|
status: () => {
|
|
22925
23292
|
const result2 = options.exec("schtasks", [
|
|
@@ -22992,15 +23359,15 @@ var init_service = __esm({
|
|
|
22992
23359
|
});
|
|
22993
23360
|
|
|
22994
23361
|
// ../../packages/tacho/src/version.ts
|
|
22995
|
-
import { readFileSync as
|
|
22996
|
-
import { dirname as
|
|
23362
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
23363
|
+
import { dirname as dirname8, resolve as resolve2 } from "node:path";
|
|
22997
23364
|
import { fileURLToPath } from "node:url";
|
|
22998
23365
|
function readVersion() {
|
|
22999
|
-
if (true) return "2.1.4-
|
|
23366
|
+
if (true) return "2.1.4-453";
|
|
23000
23367
|
try {
|
|
23001
|
-
const here =
|
|
23368
|
+
const here = dirname8(fileURLToPath(import.meta.url));
|
|
23002
23369
|
const pkg = JSON.parse(
|
|
23003
|
-
|
|
23370
|
+
readFileSync11(resolve2(here, "..", "package.json"), "utf8")
|
|
23004
23371
|
);
|
|
23005
23372
|
return pkg.version ?? "0.0.0";
|
|
23006
23373
|
} catch {
|
|
@@ -23017,8 +23384,8 @@ var init_version = __esm({
|
|
|
23017
23384
|
|
|
23018
23385
|
// ../../packages/tacho/src/cli/deps.ts
|
|
23019
23386
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
23020
|
-
import { randomBytes as
|
|
23021
|
-
import { existsSync as
|
|
23387
|
+
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
23388
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
23022
23389
|
import { get as httpGet, request as httpRequest } from "node:http";
|
|
23023
23390
|
import { createServer } from "node:net";
|
|
23024
23391
|
import {
|
|
@@ -23029,7 +23396,7 @@ import {
|
|
|
23029
23396
|
userInfo
|
|
23030
23397
|
} from "node:os";
|
|
23031
23398
|
import { createRequire } from "node:module";
|
|
23032
|
-
import { dirname as
|
|
23399
|
+
import { dirname as dirname9, posix as posix2, resolve as resolve3, win32 as win323 } from "node:path";
|
|
23033
23400
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
23034
23401
|
function configPicker(env, home) {
|
|
23035
23402
|
let config = {};
|
|
@@ -23095,7 +23462,7 @@ function isNativeBuild() {
|
|
|
23095
23462
|
function exeName(name, platform) {
|
|
23096
23463
|
return platform === "win32" ? `${name}.exe` : name;
|
|
23097
23464
|
}
|
|
23098
|
-
function stableExecutablePath(executable, platform, exists =
|
|
23465
|
+
function stableExecutablePath(executable, platform, exists = existsSync10) {
|
|
23099
23466
|
const stable = platform === "win32" ? executable.replace(
|
|
23100
23467
|
/^(.*\\apps\\[^\\]+\\)(?!current\\)[^\\]+(\\.*)$/i,
|
|
23101
23468
|
"$1current$2"
|
|
@@ -23105,7 +23472,7 @@ function stableExecutablePath(executable, platform, exists = existsSync9) {
|
|
|
23105
23472
|
);
|
|
23106
23473
|
return stable !== executable && exists(stable) ? stable : executable;
|
|
23107
23474
|
}
|
|
23108
|
-
function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath = process.execPath, platform = process.platform, native = isNativeBuild(), exists =
|
|
23475
|
+
function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath = process.execPath, platform = process.platform, native = isNativeBuild(), exists = existsSync10) {
|
|
23109
23476
|
const P = platform === "win32" ? win323 : posix2;
|
|
23110
23477
|
const named = env["TACHO_BIN_DIR"];
|
|
23111
23478
|
let binDir = named;
|
|
@@ -23113,7 +23480,7 @@ function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath =
|
|
|
23113
23480
|
if (native) {
|
|
23114
23481
|
binDir = P.dirname(nodePath);
|
|
23115
23482
|
} else {
|
|
23116
|
-
const here =
|
|
23483
|
+
const here = dirname9(fileURLToPath2(import.meta.url));
|
|
23117
23484
|
const entryDir = entry2 !== void 0 ? P.dirname(P.resolve(entry2)) : void 0;
|
|
23118
23485
|
if (entryDir !== void 0 && exists(P.join(entryDir, "tachod.mjs")))
|
|
23119
23486
|
binDir = entryDir;
|
|
@@ -23154,7 +23521,7 @@ function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath =
|
|
|
23154
23521
|
...flagged
|
|
23155
23522
|
};
|
|
23156
23523
|
}
|
|
23157
|
-
function oxagenRuntimeCommands(entry2 = process.argv[1], env = process.env, nodePath = process.execPath, platform = process.platform, native = isNativeBuild(), exists =
|
|
23524
|
+
function oxagenRuntimeCommands(entry2 = process.argv[1], env = process.env, nodePath = process.execPath, platform = process.platform, native = isNativeBuild(), exists = existsSync10) {
|
|
23158
23525
|
const P = platform === "win32" ? win323 : posix2;
|
|
23159
23526
|
const named = env["TACHO_BIN_DIR"];
|
|
23160
23527
|
let prefix;
|
|
@@ -23241,7 +23608,7 @@ function whereExecutable(result2) {
|
|
|
23241
23608
|
function shellExecutable(result2) {
|
|
23242
23609
|
return outputLines(result2).reverse().find((line) => line.startsWith("/"));
|
|
23243
23610
|
}
|
|
23244
|
-
function harnessFacts(exec4, name, platform = process.platform, env = process.env, home = env["HOME"] ?? env["USERPROFILE"] ?? "", exists =
|
|
23611
|
+
function harnessFacts(exec4, name, platform = process.platform, env = process.env, home = env["HOME"] ?? env["USERPROFILE"] ?? "", exists = existsSync10) {
|
|
23245
23612
|
let path2;
|
|
23246
23613
|
if (platform === "win32") {
|
|
23247
23614
|
path2 = whereExecutable(exec4("where", [name]));
|
|
@@ -23269,7 +23636,7 @@ function harnessFacts(exec4, name, platform = process.platform, env = process.en
|
|
|
23269
23636
|
const match = /(\d+\.\d+\.\d+)/.exec(version2.stdout);
|
|
23270
23637
|
return { path: path2, ...match?.[1] !== void 0 ? { version: match[1] } : {} };
|
|
23271
23638
|
}
|
|
23272
|
-
function claudeDesktopFacts(platform = process.platform, home = homedir3(), env = process.env, exists =
|
|
23639
|
+
function claudeDesktopFacts(platform = process.platform, home = homedir3(), env = process.env, exists = existsSync10) {
|
|
23273
23640
|
const candidates = platform === "darwin" ? ["/Applications/Claude.app", `${home}/Applications/Claude.app`] : platform === "win32" ? [
|
|
23274
23641
|
`${env["LOCALAPPDATA"] ?? `${home}\\AppData\\Local`}\\AnthropicClaude`,
|
|
23275
23642
|
`${env["LOCALAPPDATA"] ?? `${home}\\AppData\\Local`}\\Programs\\Claude`
|
|
@@ -23279,7 +23646,7 @@ function claudeDesktopFacts(platform = process.platform, home = homedir3(), env
|
|
|
23279
23646
|
}
|
|
23280
23647
|
return { installed: false };
|
|
23281
23648
|
}
|
|
23282
|
-
function cursorAppFacts(platform = process.platform, home = homedir3(), env = process.env, exists =
|
|
23649
|
+
function cursorAppFacts(platform = process.platform, home = homedir3(), env = process.env, exists = existsSync10) {
|
|
23283
23650
|
const local = env["LOCALAPPDATA"] ?? `${home}\\AppData\\Local`;
|
|
23284
23651
|
const programs = env["PROGRAMFILES"] ?? "C:\\Program Files";
|
|
23285
23652
|
const candidates = platform === "darwin" ? ["/Applications/Cursor.app", `${home}/Applications/Cursor.app`] : platform === "win32" ? [`${local}\\Programs\\cursor`, `${programs}\\Cursor`] : [];
|
|
@@ -23323,8 +23690,8 @@ function defaultCliDeps(overrides = {}, managed = {}) {
|
|
|
23323
23690
|
const paths = overrides.paths ?? defaultAgentPaths(tachoHome(env, home, platform));
|
|
23324
23691
|
const harnessFiles = new HarnessFiles(paths.dir);
|
|
23325
23692
|
const harnessDirs = {
|
|
23326
|
-
claudeConfigDir:
|
|
23327
|
-
codexHome:
|
|
23693
|
+
claudeConfigDir: dirname9(paths.claudeSettings),
|
|
23694
|
+
codexHome: dirname9(paths.codexHooks)
|
|
23328
23695
|
};
|
|
23329
23696
|
const daemonGet = async (path2) => {
|
|
23330
23697
|
const host = readHostFile(paths.hostFile);
|
|
@@ -23432,6 +23799,21 @@ function defaultCliDeps(overrides = {}, managed = {}) {
|
|
|
23432
23799
|
`
|
|
23433
23800
|
);
|
|
23434
23801
|
},
|
|
23802
|
+
// Claude Code rewrites this file all the time, so the read is taken
|
|
23803
|
+
// inside its lock, not before it. proper-lockfile resolves a file's real
|
|
23804
|
+
// path before it locks it, so Claude Code holds no lock on a file that
|
|
23805
|
+
// does not exist yet, and neither does this.
|
|
23806
|
+
editClaudeUserConfig: (edit) => {
|
|
23807
|
+
const file = paths.claudeUserConfig;
|
|
23808
|
+
const apply = () => {
|
|
23809
|
+
const next = edit(harnessFiles.readJson(file));
|
|
23810
|
+
if (next !== void 0)
|
|
23811
|
+
harnessFiles.write(file, `${JSON.stringify(next, null, 2)}
|
|
23812
|
+
`);
|
|
23813
|
+
};
|
|
23814
|
+
if (existsSync10(file)) withClaudeConfigLock(file, apply);
|
|
23815
|
+
else apply();
|
|
23816
|
+
},
|
|
23435
23817
|
harnessWriteProblem: (path2) => harnessFiles.writeProblem(path2),
|
|
23436
23818
|
settleHarnessFiles: () => settleOrThrow(harnessFiles),
|
|
23437
23819
|
// The base URL and the vendor key live in the files the hooks went into,
|
|
@@ -23542,7 +23924,7 @@ function defaultCliDeps(overrides = {}, managed = {}) {
|
|
|
23542
23924
|
server.close(() => resolvePromise(port));
|
|
23543
23925
|
});
|
|
23544
23926
|
}),
|
|
23545
|
-
randomToken: () =>
|
|
23927
|
+
randomToken: () => randomBytes7(24).toString("hex"),
|
|
23546
23928
|
sleep: (ms) => new Promise((resolvePromise) => setTimeout(resolvePromise, ms)),
|
|
23547
23929
|
wrapperVersion: TACHO_VERSION,
|
|
23548
23930
|
atAgent: (agentPaths2) => defaultCliDeps({ ...overrides, paths: agentPaths2 }, managed),
|
|
@@ -23556,6 +23938,7 @@ var init_deps = __esm({
|
|
|
23556
23938
|
init_hook_client();
|
|
23557
23939
|
init_codex_app_server();
|
|
23558
23940
|
init_credential_store();
|
|
23941
|
+
init_claude_config_lock();
|
|
23559
23942
|
init_fs();
|
|
23560
23943
|
init_harness_file();
|
|
23561
23944
|
init_host_file();
|
|
@@ -24074,7 +24457,7 @@ import {
|
|
|
24074
24457
|
sign as sign2,
|
|
24075
24458
|
verify as verify2
|
|
24076
24459
|
} from "node:crypto";
|
|
24077
|
-
import { readFileSync as
|
|
24460
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
24078
24461
|
function encodePublicKey(privateKey) {
|
|
24079
24462
|
const spki = createPublicKey2(privateKey).export({
|
|
24080
24463
|
type: "spki",
|
|
@@ -24112,7 +24495,7 @@ function deviceKeyPem(key) {
|
|
|
24112
24495
|
function loadOrCreateDeviceKey(path2) {
|
|
24113
24496
|
try {
|
|
24114
24497
|
return {
|
|
24115
|
-
key: deviceKeyFromPem(
|
|
24498
|
+
key: deviceKeyFromPem(readFileSync12(path2, "utf8")),
|
|
24116
24499
|
created: false
|
|
24117
24500
|
};
|
|
24118
24501
|
} catch (error) {
|
|
@@ -24150,110 +24533,6 @@ var init_device_key = __esm({
|
|
|
24150
24533
|
}
|
|
24151
24534
|
});
|
|
24152
24535
|
|
|
24153
|
-
// ../../packages/tacho/src/host/install-lock.ts
|
|
24154
|
-
import { randomBytes as randomBytes7 } from "node:crypto";
|
|
24155
|
-
import {
|
|
24156
|
-
closeSync as closeSync4,
|
|
24157
|
-
existsSync as existsSync10,
|
|
24158
|
-
linkSync,
|
|
24159
|
-
mkdirSync as mkdirSync6,
|
|
24160
|
-
openSync as openSync4,
|
|
24161
|
-
readdirSync as readdirSync6,
|
|
24162
|
-
readFileSync as readFileSync12,
|
|
24163
|
-
renameSync as renameSync3,
|
|
24164
|
-
rmdirSync as rmdirSync4,
|
|
24165
|
-
unlinkSync as unlinkSync7,
|
|
24166
|
-
writeSync as writeSync3
|
|
24167
|
-
} from "node:fs";
|
|
24168
|
-
import { dirname as dirname9, join as join15 } from "node:path";
|
|
24169
|
-
function readLock(path2) {
|
|
24170
|
-
try {
|
|
24171
|
-
return readFileSync12(path2, "utf8");
|
|
24172
|
-
} catch {
|
|
24173
|
-
return void 0;
|
|
24174
|
-
}
|
|
24175
|
-
}
|
|
24176
|
-
function holderOf(text4) {
|
|
24177
|
-
try {
|
|
24178
|
-
return JSON.parse(text4 ?? "");
|
|
24179
|
-
} catch {
|
|
24180
|
-
return {};
|
|
24181
|
-
}
|
|
24182
|
-
}
|
|
24183
|
-
function removeQuietly(path2) {
|
|
24184
|
-
try {
|
|
24185
|
-
unlinkSync7(path2);
|
|
24186
|
-
} catch {
|
|
24187
|
-
}
|
|
24188
|
-
}
|
|
24189
|
-
function pidAlive(pid) {
|
|
24190
|
-
try {
|
|
24191
|
-
process.kill(pid, 0);
|
|
24192
|
-
return true;
|
|
24193
|
-
} catch (error) {
|
|
24194
|
-
return error.code === "EPERM";
|
|
24195
|
-
}
|
|
24196
|
-
}
|
|
24197
|
-
function acquireInstallLock(root, now = Date.now, alive = pidAlive) {
|
|
24198
|
-
const path2 = join15(root, "install.lock");
|
|
24199
|
-
const created = [];
|
|
24200
|
-
let dir = root;
|
|
24201
|
-
while (!existsSync10(dir) && dirname9(dir) !== dir) {
|
|
24202
|
-
created.unshift(dir);
|
|
24203
|
-
dir = dirname9(dir);
|
|
24204
|
-
}
|
|
24205
|
-
mkdirSync6(root, { recursive: true, mode: 448 });
|
|
24206
|
-
const token = randomBytes7(12).toString("hex");
|
|
24207
|
-
const liveHolder = (holder) => typeof holder.pid === "number" && typeof holder.at === "number" && now() - holder.at < STALE_AFTER_MS && alive(holder.pid) ? holder.pid : void 0;
|
|
24208
|
-
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
24209
|
-
try {
|
|
24210
|
-
const fd2 = openSync4(path2, "wx", 384);
|
|
24211
|
-
writeSync3(fd2, JSON.stringify({ pid: process.pid, at: now(), token }));
|
|
24212
|
-
closeSync4(fd2);
|
|
24213
|
-
return {
|
|
24214
|
-
release: () => {
|
|
24215
|
-
if (holderOf(readLock(path2)).token === token) removeQuietly(path2);
|
|
24216
|
-
for (const made of [...created].reverse()) {
|
|
24217
|
-
try {
|
|
24218
|
-
if (readdirSync6(made).length === 0) rmdirSync4(made);
|
|
24219
|
-
} catch {
|
|
24220
|
-
}
|
|
24221
|
-
}
|
|
24222
|
-
}
|
|
24223
|
-
};
|
|
24224
|
-
} catch (error) {
|
|
24225
|
-
if (error.code !== "EEXIST") throw error;
|
|
24226
|
-
const live = liveHolder(holderOf(readLock(path2)));
|
|
24227
|
-
if (live !== void 0) return { heldBy: live };
|
|
24228
|
-
const aside = `${path2}.${process.pid}.${token}.stale`;
|
|
24229
|
-
try {
|
|
24230
|
-
renameSync3(path2, aside);
|
|
24231
|
-
} catch (renameError) {
|
|
24232
|
-
if (renameError.code === "ENOENT") continue;
|
|
24233
|
-
throw renameError;
|
|
24234
|
-
}
|
|
24235
|
-
const moved = liveHolder(holderOf(readLock(aside)));
|
|
24236
|
-
if (moved !== void 0) {
|
|
24237
|
-
try {
|
|
24238
|
-
linkSync(aside, path2);
|
|
24239
|
-
} catch {
|
|
24240
|
-
}
|
|
24241
|
-
removeQuietly(aside);
|
|
24242
|
-
return { heldBy: moved };
|
|
24243
|
-
}
|
|
24244
|
-
removeQuietly(aside);
|
|
24245
|
-
}
|
|
24246
|
-
}
|
|
24247
|
-
return { heldBy: -1 };
|
|
24248
|
-
}
|
|
24249
|
-
var STALE_AFTER_MS;
|
|
24250
|
-
var init_install_lock = __esm({
|
|
24251
|
-
"../../packages/tacho/src/host/install-lock.ts"() {
|
|
24252
|
-
"use strict";
|
|
24253
|
-
STALE_AFTER_MS = 10 * 6e4;
|
|
24254
|
-
}
|
|
24255
|
-
});
|
|
24256
|
-
|
|
24257
24536
|
// ../../packages/tacho/src/host/wal-index.ts
|
|
24258
24537
|
import {
|
|
24259
24538
|
appendFileSync,
|
|
@@ -24261,7 +24540,7 @@ import {
|
|
|
24261
24540
|
existsSync as existsSync11,
|
|
24262
24541
|
openSync as openSync5,
|
|
24263
24542
|
readSync as readSync2,
|
|
24264
|
-
statSync as
|
|
24543
|
+
statSync as statSync7,
|
|
24265
24544
|
unlinkSync as unlinkSync8
|
|
24266
24545
|
} from "node:fs";
|
|
24267
24546
|
import { open as open2 } from "node:fs/promises";
|
|
@@ -24279,7 +24558,7 @@ function parseStoredBody(text4) {
|
|
|
24279
24558
|
return void 0;
|
|
24280
24559
|
return stored;
|
|
24281
24560
|
}
|
|
24282
|
-
function readTailLine(path2, size =
|
|
24561
|
+
function readTailLine(path2, size = statSync7(path2).size, window2 = SCAN_CHUNK_BYTES) {
|
|
24283
24562
|
if (size === 0) return void 0;
|
|
24284
24563
|
const fd2 = openSync5(path2, "r");
|
|
24285
24564
|
try {
|
|
@@ -24496,7 +24775,7 @@ var init_wal_index = __esm({
|
|
|
24496
24775
|
}
|
|
24497
24776
|
/** The index to extend, and the byte the scan starts from. */
|
|
24498
24777
|
base(sessionUuid2, bodiesPath) {
|
|
24499
|
-
const size =
|
|
24778
|
+
const size = statSync7(bodiesPath).size;
|
|
24500
24779
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
24501
24780
|
if (held !== void 0 && held.covered <= size) return held;
|
|
24502
24781
|
this.discard(sessionUuid2);
|
|
@@ -24570,7 +24849,7 @@ ${lines.join("\n")}
|
|
|
24570
24849
|
* answers undefined.
|
|
24571
24850
|
*/
|
|
24572
24851
|
covering(sessionUuid2, bodiesPath) {
|
|
24573
|
-
const size =
|
|
24852
|
+
const size = statSync7(bodiesPath).size;
|
|
24574
24853
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
24575
24854
|
if (held === void 0 || held.covered !== size) return void 0;
|
|
24576
24855
|
this.remember(sessionUuid2, held);
|
|
@@ -24584,7 +24863,7 @@ ${lines.join("\n")}
|
|
|
24584
24863
|
* file.
|
|
24585
24864
|
*/
|
|
24586
24865
|
held(sessionUuid2, bodiesPath) {
|
|
24587
|
-
const size =
|
|
24866
|
+
const size = statSync7(bodiesPath).size;
|
|
24588
24867
|
const held = this.cached.get(sessionUuid2) ?? this.load(sessionUuid2);
|
|
24589
24868
|
if (held === void 0 || held.covered > size) return void 0;
|
|
24590
24869
|
this.remember(sessionUuid2, held);
|
|
@@ -24593,7 +24872,7 @@ ${lines.join("\n")}
|
|
|
24593
24872
|
/** The index of a body file, built or extended to cover the whole file. */
|
|
24594
24873
|
ensure(sessionUuid2, bodiesPath, onInvalidRecord, onWriteFailure) {
|
|
24595
24874
|
const index = this.base(sessionUuid2, bodiesPath);
|
|
24596
|
-
const size =
|
|
24875
|
+
const size = statSync7(bodiesPath).size;
|
|
24597
24876
|
if (index.covered < size) {
|
|
24598
24877
|
const result2 = {
|
|
24599
24878
|
added: [],
|
|
@@ -24647,7 +24926,7 @@ ${lines.join("\n")}
|
|
|
24647
24926
|
for (let attempt = 0; ; attempt += 1) {
|
|
24648
24927
|
const generation = this.generationOf(sessionUuid2);
|
|
24649
24928
|
const index = this.base(sessionUuid2, bodiesPath);
|
|
24650
|
-
const size =
|
|
24929
|
+
const size = statSync7(bodiesPath).size;
|
|
24651
24930
|
if (index.covered >= size) {
|
|
24652
24931
|
this.remember(sessionUuid2, index);
|
|
24653
24932
|
return index;
|
|
@@ -24687,7 +24966,7 @@ import {
|
|
|
24687
24966
|
readSync as readSync3,
|
|
24688
24967
|
truncateSync,
|
|
24689
24968
|
renameSync as renameSync4,
|
|
24690
|
-
statSync as
|
|
24969
|
+
statSync as statSync8,
|
|
24691
24970
|
unlinkSync as unlinkSync9,
|
|
24692
24971
|
writeSync as writeSync4
|
|
24693
24972
|
} from "node:fs";
|
|
@@ -24698,7 +24977,7 @@ function activityAt(event) {
|
|
|
24698
24977
|
return Number.isFinite(at) ? at : Number.NEGATIVE_INFINITY;
|
|
24699
24978
|
}
|
|
24700
24979
|
function sizeOf(path2) {
|
|
24701
|
-
return
|
|
24980
|
+
return statSync8(path2, { throwIfNoEntry: false })?.size ?? 0;
|
|
24702
24981
|
}
|
|
24703
24982
|
var BODY_READ_SLICE, BODY_DROP_SLICE_BYTES, BODY_DROP_SCANS, NEWLINE, EVENT_TAIL_WINDOW, WalRecoveryConflict, Wal;
|
|
24704
24983
|
var init_wal = __esm({
|
|
@@ -25058,7 +25337,7 @@ ${lines.join("\n")}
|
|
|
25058
25337
|
for (const session of sessions) {
|
|
25059
25338
|
if (sizes.has(session)) continue;
|
|
25060
25339
|
const path2 = pathOf2(session);
|
|
25061
|
-
sizes.set(session, existsSync12(path2) ?
|
|
25340
|
+
sizes.set(session, existsSync12(path2) ? statSync8(path2).size : void 0);
|
|
25062
25341
|
}
|
|
25063
25342
|
return sizes;
|
|
25064
25343
|
}
|
|
@@ -25074,7 +25353,7 @@ ${lines.join("\n")}
|
|
|
25074
25353
|
try {
|
|
25075
25354
|
if (!existsSync12(path2)) continue;
|
|
25076
25355
|
if (size === void 0) unlinkSync9(path2);
|
|
25077
|
-
else if (
|
|
25356
|
+
else if (statSync8(path2).size !== size) truncateSync(path2, size);
|
|
25078
25357
|
} catch (error) {
|
|
25079
25358
|
onFailure(session, error);
|
|
25080
25359
|
}
|
|
@@ -25737,7 +26016,7 @@ ${lines.join("\n")}
|
|
|
25737
26016
|
const lastSeq = this.lastWrittenSeq(sessionUuid2);
|
|
25738
26017
|
if (lastSeq === void 0) return 0;
|
|
25739
26018
|
const path2 = this.bodyFileFor(sessionUuid2);
|
|
25740
|
-
const size =
|
|
26019
|
+
const size = statSync8(path2).size;
|
|
25741
26020
|
let keep = size;
|
|
25742
26021
|
let cut2 = 0;
|
|
25743
26022
|
while (keep > 0) {
|
|
@@ -25770,7 +26049,7 @@ ${lines.join("\n")}
|
|
|
25770
26049
|
*/
|
|
25771
26050
|
lastWrittenSeq(sessionUuid2) {
|
|
25772
26051
|
const path2 = this.fileFor(sessionUuid2);
|
|
25773
|
-
if (!existsSync12(path2) ||
|
|
26052
|
+
if (!existsSync12(path2) || statSync8(path2).size === 0) return -1;
|
|
25774
26053
|
return this.lastEvent(sessionUuid2)?.seq;
|
|
25775
26054
|
}
|
|
25776
26055
|
/**
|
|
@@ -25801,7 +26080,7 @@ ${lines.join("\n")}
|
|
|
25801
26080
|
*eventsBackward(sessionUuid2) {
|
|
25802
26081
|
const path2 = this.fileFor(sessionUuid2);
|
|
25803
26082
|
if (!existsSync12(path2)) return;
|
|
25804
|
-
let end =
|
|
26083
|
+
let end = statSync8(path2).size;
|
|
25805
26084
|
while (end > 0) {
|
|
25806
26085
|
const line = readTailLine(path2, end, EVENT_TAIL_WINDOW);
|
|
25807
26086
|
if (line === void 0) return;
|
|
@@ -25832,7 +26111,7 @@ ${lines.join("\n")}
|
|
|
25832
26111
|
this.unverifiedResume.delete(sessionUuid2);
|
|
25833
26112
|
let holds2 = false;
|
|
25834
26113
|
try {
|
|
25835
|
-
if (mark.offset <=
|
|
26114
|
+
if (mark.offset <= statSync8(path2).size) {
|
|
25836
26115
|
const line = readTailLine(path2, mark.offset, EVENT_TAIL_WINDOW);
|
|
25837
26116
|
holds2 = line !== void 0 && line.terminated && line.end === mark.offset && JSON.parse(line.text).seq === mark.afterSeq;
|
|
25838
26117
|
}
|
|
@@ -26228,7 +26507,7 @@ ${lines.join("\n")}
|
|
|
26228
26507
|
if (sealedAt === void 0) continue;
|
|
26229
26508
|
const path2 = this.fileFor(session);
|
|
26230
26509
|
try {
|
|
26231
|
-
const age = now - Math.max(Date.parse(sealedAt),
|
|
26510
|
+
const age = now - Math.max(Date.parse(sealedAt), statSync8(path2).mtimeMs);
|
|
26232
26511
|
if (age < retainMs) continue;
|
|
26233
26512
|
const last = this.lastSeqOf(session);
|
|
26234
26513
|
if (last < 0 || last > this.shippedThrough(session)) continue;
|
|
@@ -26250,7 +26529,7 @@ ${lines.join("\n")}
|
|
|
26250
26529
|
if (removed.includes(session) || existsSync12(this.fileFor(session)))
|
|
26251
26530
|
continue;
|
|
26252
26531
|
try {
|
|
26253
|
-
if (now -
|
|
26532
|
+
if (now - statSync8(this.bodyFileFor(session)).mtimeMs < retainMs)
|
|
26254
26533
|
continue;
|
|
26255
26534
|
} catch (error) {
|
|
26256
26535
|
this.bodyFailure(session, "cleanup", error);
|
|
@@ -27304,7 +27583,7 @@ import {
|
|
|
27304
27583
|
existsSync as existsSync15,
|
|
27305
27584
|
lstatSync as lstatSync3,
|
|
27306
27585
|
readdirSync as readdirSync8,
|
|
27307
|
-
rmdirSync as
|
|
27586
|
+
rmdirSync as rmdirSync6,
|
|
27308
27587
|
rmSync as rmSync2,
|
|
27309
27588
|
unlinkSync as unlinkSync10
|
|
27310
27589
|
} from "node:fs";
|
|
@@ -27541,6 +27820,24 @@ async function stripEnrollmentHooks(host, deps, settle3 = false) {
|
|
|
27541
27820
|
}
|
|
27542
27821
|
});
|
|
27543
27822
|
}
|
|
27823
|
+
let claudeCodeMcpChanged;
|
|
27824
|
+
const editUserConfig = deps.editClaudeUserConfig;
|
|
27825
|
+
if (editUserConfig !== void 0 && (host?.harnesses === void 0 || host.harnesses.includes("claude-code"))) {
|
|
27826
|
+
const userConfig = deps.paths.claudeUserConfig;
|
|
27827
|
+
attempt(userConfig, () => {
|
|
27828
|
+
editUserConfig((current) => {
|
|
27829
|
+
if (current === void 0) return void 0;
|
|
27830
|
+
const stripped = stripClaudeCodeMcpConfig(
|
|
27831
|
+
current,
|
|
27832
|
+
host?.host_enrollment_id,
|
|
27833
|
+
host?.displaced_mcp_servers?.["claude-code"] ?? {}
|
|
27834
|
+
);
|
|
27835
|
+
if (!stripped.changed) return void 0;
|
|
27836
|
+
claudeCodeMcpChanged = userConfig;
|
|
27837
|
+
return stripped.config;
|
|
27838
|
+
});
|
|
27839
|
+
});
|
|
27840
|
+
}
|
|
27544
27841
|
if (settle3 && failed3.length === 0) {
|
|
27545
27842
|
try {
|
|
27546
27843
|
deps.settleHarnessFiles?.();
|
|
@@ -27558,6 +27855,7 @@ async function stripEnrollmentHooks(host, deps, settle3 = false) {
|
|
|
27558
27855
|
cursorChanged,
|
|
27559
27856
|
stellaChanged,
|
|
27560
27857
|
claudeDesktopChanged,
|
|
27858
|
+
...claudeCodeMcpChanged !== void 0 ? { claudeCodeMcpChanged } : {},
|
|
27561
27859
|
failed: failed3
|
|
27562
27860
|
};
|
|
27563
27861
|
}
|
|
@@ -27670,7 +27968,7 @@ function restartForRemaining(installed, deps) {
|
|
|
27670
27968
|
}
|
|
27671
27969
|
function removeIfEmpty(dir) {
|
|
27672
27970
|
try {
|
|
27673
|
-
if (readdirSync8(dir).length === 0)
|
|
27971
|
+
if (readdirSync8(dir).length === 0) rmdirSync6(dir);
|
|
27674
27972
|
} catch {
|
|
27675
27973
|
}
|
|
27676
27974
|
}
|
|
@@ -27760,6 +28058,11 @@ async function unenrollLocked(options, deps) {
|
|
|
27760
28058
|
" Quit Claude Desktop and open it again for the change to take effect"
|
|
27761
28059
|
);
|
|
27762
28060
|
}
|
|
28061
|
+
if (stripped.claudeCodeMcpChanged !== void 0) {
|
|
28062
|
+
deps.out(
|
|
28063
|
+
` Oxagen's MCP server removed from ${stripped.claudeCodeMcpChanged}`
|
|
28064
|
+
);
|
|
28065
|
+
}
|
|
27763
28066
|
for (const failure2 of stripped.failed) {
|
|
27764
28067
|
incomplete = true;
|
|
27765
28068
|
warnings.push(
|
|
@@ -27891,6 +28194,7 @@ var init_unenroll = __esm({
|
|
|
27891
28194
|
"../../packages/tacho/src/cli/unenroll.ts"() {
|
|
27892
28195
|
"use strict";
|
|
27893
28196
|
init_install_lock();
|
|
28197
|
+
init_claude_code_mcp_writer();
|
|
27894
28198
|
init_claude_desktop_writer();
|
|
27895
28199
|
init_codex_hook_trust();
|
|
27896
28200
|
init_codex_writer();
|
|
@@ -28639,6 +28943,32 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
|
|
|
28639
28943
|
deps.out(" already present; nothing to change");
|
|
28640
28944
|
}
|
|
28641
28945
|
});
|
|
28946
|
+
if (harnesses.includes("claude-code") && !unhooked.includes("claude-code") && deps.editClaudeUserConfig !== void 0) {
|
|
28947
|
+
deps.out(` Claude Code MCP server: ${deps.paths.claudeUserConfig}`);
|
|
28948
|
+
try {
|
|
28949
|
+
const registered = registerClaudeCodeMcp(host, deps);
|
|
28950
|
+
host = registered.host;
|
|
28951
|
+
if (registered.result === "skipped")
|
|
28952
|
+
warnings.push(
|
|
28953
|
+
`Claude Code was not given Oxagen's tools: ${registered.reason ?? "unknown reason"}. Until it has them, the Stop hook asks Claude Code for no reflection.`
|
|
28954
|
+
);
|
|
28955
|
+
else if (registered.result === "written")
|
|
28956
|
+
deps.out(
|
|
28957
|
+
" `oxagen` server written; a new Claude Code session lists Oxagen's tools"
|
|
28958
|
+
);
|
|
28959
|
+
else deps.out(" already present; nothing to change");
|
|
28960
|
+
if (registered.displaced)
|
|
28961
|
+
warnings.push(
|
|
28962
|
+
"an MCP server already used the name `oxagen` in Claude Code; it was moved aside and unenroll restores it"
|
|
28963
|
+
);
|
|
28964
|
+
} catch (error) {
|
|
28965
|
+
host = readHostFile(deps.paths.hostFile) ?? host;
|
|
28966
|
+
warnings.push(
|
|
28967
|
+
`Claude Code was not given Oxagen's tools: ${error instanceof Error ? error.message : String(error)}. The hooks are written. Run \`oxagen agent enroll\` again to add the tools; until then the Stop hook asks Claude Code for no reflection.`
|
|
28968
|
+
);
|
|
28969
|
+
deps.out(" not written (see the warning below)");
|
|
28970
|
+
}
|
|
28971
|
+
}
|
|
28642
28972
|
hook("codex", () => {
|
|
28643
28973
|
deps.out(` Codex: ${deps.paths.codexHooks}`);
|
|
28644
28974
|
const merged = mergeCodexHooks(deps.readCodexHooks(), hookConfig);
|
|
@@ -29013,6 +29343,7 @@ var init_enroll = __esm({
|
|
|
29013
29343
|
init_credential();
|
|
29014
29344
|
init_github();
|
|
29015
29345
|
init_agent_deps();
|
|
29346
|
+
init_claude_code_mcp();
|
|
29016
29347
|
init_daemon_service();
|
|
29017
29348
|
init_policy_mode();
|
|
29018
29349
|
init_status();
|
|
@@ -29915,9 +30246,9 @@ import {
|
|
|
29915
30246
|
readFileSync as readFileSync14,
|
|
29916
30247
|
readlinkSync as readlinkSync3,
|
|
29917
30248
|
realpathSync as realpathSync2,
|
|
29918
|
-
rmdirSync as
|
|
30249
|
+
rmdirSync as rmdirSync7,
|
|
29919
30250
|
rmSync as rmSync4,
|
|
29920
|
-
statSync as
|
|
30251
|
+
statSync as statSync9,
|
|
29921
30252
|
unlinkSync as unlinkSync11
|
|
29922
30253
|
} from "node:fs";
|
|
29923
30254
|
import { dirname as dirname13, isAbsolute, join as join19, relative, resolve as resolve6, sep } from "node:path";
|
|
@@ -30073,7 +30404,7 @@ function removeFile(path2, tally2, note = "") {
|
|
|
30073
30404
|
function removeDirIfEmpty(dir) {
|
|
30074
30405
|
try {
|
|
30075
30406
|
if (readdirSync9(dir).length > 0) return false;
|
|
30076
|
-
|
|
30407
|
+
rmdirSync7(dir);
|
|
30077
30408
|
return true;
|
|
30078
30409
|
} catch {
|
|
30079
30410
|
return false;
|
|
@@ -30092,7 +30423,7 @@ function removeProfileBlock(path2, tally2) {
|
|
|
30092
30423
|
if (updated === text4) return;
|
|
30093
30424
|
try {
|
|
30094
30425
|
const real = realpathSync2(path2);
|
|
30095
|
-
writeFileAtomic(real, updated, { mode:
|
|
30426
|
+
writeFileAtomic(real, updated, { mode: statSync9(real).mode & 4095 });
|
|
30096
30427
|
tally2.removed.push(`the Oxagen PATH lines in ${path2}`);
|
|
30097
30428
|
} catch (error) {
|
|
30098
30429
|
tally2.left.push(`cannot rewrite ${path2}: ${reasonOf3(error)}`);
|
|
@@ -31163,10 +31494,12 @@ __export(cli_exports, {
|
|
|
31163
31494
|
MODEL_CREDENTIAL_HARNESSES: () => MODEL_CREDENTIAL_HARNESSES,
|
|
31164
31495
|
SHIPPING_STALL_MS: () => SHIPPING_STALL_MS,
|
|
31165
31496
|
STATIC_TOKEN_RENEW_WINDOW_MS: () => STATIC_TOKEN_RENEW_WINDOW_MS,
|
|
31497
|
+
addMissingClaudeCodeMcp: () => addMissingClaudeCodeMcp,
|
|
31166
31498
|
agentNameFromCommand: () => agentNameFromCommand,
|
|
31167
31499
|
backfillCommand: () => backfillCommand,
|
|
31168
31500
|
brokerCredentials: () => brokerCredentials,
|
|
31169
31501
|
brokerEnvVar: () => brokerEnvVar,
|
|
31502
|
+
canServeOxagenTools: () => canServeOxagenTools,
|
|
31170
31503
|
claudeDesktopFacts: () => claudeDesktopFacts,
|
|
31171
31504
|
claudeFacts: () => claudeFacts,
|
|
31172
31505
|
credentialIssue: () => credentialIssue,
|
|
@@ -31192,6 +31525,7 @@ __export(cli_exports, {
|
|
|
31192
31525
|
isNativeBuild: () => isNativeBuild,
|
|
31193
31526
|
moveOffTachoNames: () => moveOffTachoNames,
|
|
31194
31527
|
namesTachoExecutable: () => namesTachoExecutable,
|
|
31528
|
+
needsClaudeCodeMcp: () => needsClaudeCodeMcp,
|
|
31195
31529
|
observedTiers: () => observedTiers,
|
|
31196
31530
|
oxagenRuntimeCommands: () => oxagenRuntimeCommands,
|
|
31197
31531
|
parseCredentialMode: () => parseCredentialMode,
|
|
@@ -31200,6 +31534,7 @@ __export(cli_exports, {
|
|
|
31200
31534
|
readDesktopRecord: () => readDesktopRecord,
|
|
31201
31535
|
reassign: () => reassign,
|
|
31202
31536
|
reassignTarget: () => reassignTarget,
|
|
31537
|
+
registerClaudeCodeMcp: () => registerClaudeCodeMcp,
|
|
31203
31538
|
removePathBlocks: () => removePathBlocks,
|
|
31204
31539
|
repointCommands: () => repointCommands,
|
|
31205
31540
|
resolveApiUrl: () => resolveApiUrl,
|
|
@@ -31242,6 +31577,7 @@ var init_cli = __esm({
|
|
|
31242
31577
|
"../../packages/tacho/src/cli/index.ts"() {
|
|
31243
31578
|
"use strict";
|
|
31244
31579
|
init_backfill3();
|
|
31580
|
+
init_claude_code_mcp();
|
|
31245
31581
|
init_credential();
|
|
31246
31582
|
init_deps();
|
|
31247
31583
|
init_detect();
|
|
@@ -37378,6 +37714,7 @@ function reflectionAsk(record, options) {
|
|
|
37378
37714
|
const state = states.get(record);
|
|
37379
37715
|
if (state === void 0 || state.asked || state.reflected || state.signals.size === 0)
|
|
37380
37716
|
return void 0;
|
|
37717
|
+
if (!options.toolRegistered()) return void 0;
|
|
37381
37718
|
state.asked = true;
|
|
37382
37719
|
const full = askText(state, true);
|
|
37383
37720
|
return full.length <= REFLECTION_ASK_MAX_CHARS ? full : askText(state, false);
|
|
@@ -38683,7 +39020,10 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
38683
39020
|
const ask = input.agent_id !== void 0 ? void 0 : reflectionAsk(record, {
|
|
38684
39021
|
harness: record.customAgent !== void 0 ? void 0 : record.harness ?? "claude-code",
|
|
38685
39022
|
stopHookActive: input["stop_hook_active"] === true,
|
|
38686
|
-
replayed: replay !== void 0
|
|
39023
|
+
replayed: replay !== void 0,
|
|
39024
|
+
toolRegistered: () => deps.reflectionToolRegistered?.({
|
|
39025
|
+
startedAt: record.startedAt
|
|
39026
|
+
}) ?? false
|
|
38687
39027
|
});
|
|
38688
39028
|
const texts = [
|
|
38689
39029
|
...drainMidTurn(input, record, deps, events, replay, ask?.length ?? 0),
|
|
@@ -45688,7 +46028,7 @@ var init_model_proxy_listener = __esm({
|
|
|
45688
46028
|
import {
|
|
45689
46029
|
createServer as createServer4
|
|
45690
46030
|
} from "node:http";
|
|
45691
|
-
import { chmodSync as chmodSync7, existsSync as existsSync18, statSync as
|
|
46031
|
+
import { chmodSync as chmodSync7, existsSync as existsSync18, statSync as statSync10, unlinkSync as unlinkSync12 } from "node:fs";
|
|
45692
46032
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
45693
46033
|
import { createConnection } from "node:net";
|
|
45694
46034
|
function readBody(req) {
|
|
@@ -45960,7 +46300,7 @@ function createRequestHandler(api, log, options = {}) {
|
|
|
45960
46300
|
}
|
|
45961
46301
|
async function removeStaleSocket(socketPath) {
|
|
45962
46302
|
if (!existsSync18(socketPath)) return;
|
|
45963
|
-
if (!
|
|
46303
|
+
if (!statSync10(socketPath).isSocket()) {
|
|
45964
46304
|
throw new Error(`collector socket path is not a socket: ${socketPath}`);
|
|
45965
46305
|
}
|
|
45966
46306
|
const stale = await new Promise((resolve20, reject) => {
|
|
@@ -46748,7 +47088,7 @@ import {
|
|
|
46748
47088
|
readdirSync as readdirSync12,
|
|
46749
47089
|
readFileSync as readFileSync18,
|
|
46750
47090
|
renameSync as renameSync5,
|
|
46751
|
-
statSync as
|
|
47091
|
+
statSync as statSync11,
|
|
46752
47092
|
unlinkSync as unlinkSync13,
|
|
46753
47093
|
writeFileSync as writeFileSync3
|
|
46754
47094
|
} from "node:fs";
|
|
@@ -46923,6 +47263,22 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
46923
47263
|
))
|
|
46924
47264
|
memoryUses.note({ ...file, ...run });
|
|
46925
47265
|
};
|
|
47266
|
+
const reflectionToolRegistered = (session) => {
|
|
47267
|
+
try {
|
|
47268
|
+
const current = readHostFile(paths.hostFile) ?? host;
|
|
47269
|
+
return claudeCodeSessionHasOxagenTools({
|
|
47270
|
+
enrollmentId: current.host_enrollment_id,
|
|
47271
|
+
hasGatewayKey: current.gateway_api_key !== void 0,
|
|
47272
|
+
registeredAt: current.mcp_registered_at?.["claude-code"],
|
|
47273
|
+
sessionStartedAt: session.startedAt,
|
|
47274
|
+
readUserConfig: () => readJsonFileIfExists(
|
|
47275
|
+
withRecordedHarnessFiles(paths, current).claudeUserConfig
|
|
47276
|
+
)
|
|
47277
|
+
});
|
|
47278
|
+
} catch {
|
|
47279
|
+
return false;
|
|
47280
|
+
}
|
|
47281
|
+
};
|
|
46926
47282
|
const localServers = options.localServers === true ? createMachineLoop({
|
|
46927
47283
|
host: () => host,
|
|
46928
47284
|
fetch: options.fetch ?? globalThis.fetch,
|
|
@@ -46988,7 +47344,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
46988
47344
|
processStarts: hookProcessStarts,
|
|
46989
47345
|
adoptedChain: (sessionUuid2) => backfillLedger.chainHead(sessionUuid2)
|
|
46990
47346
|
});
|
|
46991
|
-
const priorStateWrittenAt = existsSync20(paths.daemonState) ?
|
|
47347
|
+
const priorStateWrittenAt = existsSync20(paths.daemonState) ? statSync11(paths.daemonState).mtimeMs : void 0;
|
|
46992
47348
|
const sealedState = parseSealedState(
|
|
46993
47349
|
readJsonStateFile(
|
|
46994
47350
|
paths.daemonSealedState,
|
|
@@ -48064,7 +48420,8 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
48064
48420
|
cedar: loadCedarRuntime,
|
|
48065
48421
|
skills,
|
|
48066
48422
|
...recallMemories !== void 0 ? { recallMemories } : {},
|
|
48067
|
-
...noteMemoryReads !== void 0 ? { noteMemoryReads } : {}
|
|
48423
|
+
...noteMemoryReads !== void 0 ? { noteMemoryReads } : {},
|
|
48424
|
+
reflectionToolRegistered
|
|
48068
48425
|
},
|
|
48069
48426
|
envelope2.replay,
|
|
48070
48427
|
envelope2.harness,
|
|
@@ -49013,7 +49370,7 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
49013
49370
|
if (!name.endsWith(".json")) continue;
|
|
49014
49371
|
const file = join34(paths.quarantine, name);
|
|
49015
49372
|
try {
|
|
49016
|
-
if (at -
|
|
49373
|
+
if (at - statSync11(file).mtimeMs < retainMs) continue;
|
|
49017
49374
|
unlinkSync13(file);
|
|
49018
49375
|
removed += 1;
|
|
49019
49376
|
} catch {
|
|
@@ -49443,6 +49800,7 @@ var init_daemon = __esm({
|
|
|
49443
49800
|
init_device_key();
|
|
49444
49801
|
init_fs();
|
|
49445
49802
|
init_host_file();
|
|
49803
|
+
init_claude_code_mcp_writer();
|
|
49446
49804
|
init_model_base_url();
|
|
49447
49805
|
init_model_credential();
|
|
49448
49806
|
init_run_token();
|
|
@@ -49878,7 +50236,7 @@ import {
|
|
|
49878
50236
|
constants as constants3,
|
|
49879
50237
|
fstatSync as fstatSync2,
|
|
49880
50238
|
lstatSync as lstatSync7,
|
|
49881
|
-
mkdirSync as
|
|
50239
|
+
mkdirSync as mkdirSync8,
|
|
49882
50240
|
openSync as openSync7,
|
|
49883
50241
|
readSync as readSync4,
|
|
49884
50242
|
realpathSync as realpathSync5,
|
|
@@ -49887,7 +50245,7 @@ import {
|
|
|
49887
50245
|
import { dirname as dirname20, join as join35, resolve as resolve13 } from "node:path";
|
|
49888
50246
|
function bundlePath(root, relative10, create2 = false) {
|
|
49889
50247
|
const absolute = resolve13(root);
|
|
49890
|
-
if (create2)
|
|
50248
|
+
if (create2) mkdirSync8(absolute, { recursive: true, mode: 448 });
|
|
49891
50249
|
if (lstatSync7(absolute).isSymbolicLink() || !lstatSync7(absolute).isDirectory()) {
|
|
49892
50250
|
throw new Error("ARP bundle root must be a directory, not a symlink");
|
|
49893
50251
|
}
|
|
@@ -49903,7 +50261,7 @@ function bundlePath(root, relative10, create2 = false) {
|
|
|
49903
50261
|
}
|
|
49904
50262
|
} catch (error) {
|
|
49905
50263
|
if (error.code !== "ENOENT") throw error;
|
|
49906
|
-
if (create2 && i2 < parts.length - 1)
|
|
50264
|
+
if (create2 && i2 < parts.length - 1) mkdirSync8(current, { mode: 448 });
|
|
49907
50265
|
else if (i2 < parts.length - 1) throw error;
|
|
49908
50266
|
}
|
|
49909
50267
|
}
|
|
@@ -50767,7 +51125,7 @@ import {
|
|
|
50767
51125
|
constants as constants4,
|
|
50768
51126
|
fstatSync as fstatSync3,
|
|
50769
51127
|
lstatSync as lstatSync8,
|
|
50770
|
-
mkdirSync as
|
|
51128
|
+
mkdirSync as mkdirSync9,
|
|
50771
51129
|
openSync as openSync8,
|
|
50772
51130
|
readSync as readSync5,
|
|
50773
51131
|
realpathSync as realpathSync6,
|
|
@@ -50897,7 +51255,7 @@ function captureCheckpoint(options) {
|
|
|
50897
51255
|
executable: (file.mode & 73) !== 0
|
|
50898
51256
|
});
|
|
50899
51257
|
}
|
|
50900
|
-
|
|
51258
|
+
mkdirSync9(out, { mode: 448 });
|
|
50901
51259
|
try {
|
|
50902
51260
|
const blob = (value) => storeBlob(out, Buffer.from(jcs(value)), "application/json");
|
|
50903
51261
|
const entries2 = [];
|
|
@@ -51084,16 +51442,16 @@ function prepareCheckpoint(options) {
|
|
|
51084
51442
|
}
|
|
51085
51443
|
return { entry: entry2, bytes: null };
|
|
51086
51444
|
});
|
|
51087
|
-
|
|
51445
|
+
mkdirSync9(destination, { mode: 448 });
|
|
51088
51446
|
try {
|
|
51089
51447
|
const restored = join36(destination, "workspace");
|
|
51090
|
-
|
|
51448
|
+
mkdirSync9(restored, { mode: 448 });
|
|
51091
51449
|
for (const { entry: entry2, bytes } of files2) {
|
|
51092
51450
|
const path2 = join36(restored, entry2.path);
|
|
51093
51451
|
if (entry2.kind === "directory")
|
|
51094
|
-
|
|
51452
|
+
mkdirSync9(path2, { recursive: true, mode: 448 });
|
|
51095
51453
|
else {
|
|
51096
|
-
|
|
51454
|
+
mkdirSync9(dirname21(path2), { recursive: true, mode: 448 });
|
|
51097
51455
|
if (bytes === null) fail2("Workspace file has no bytes.");
|
|
51098
51456
|
writeFileSync6(path2, bytes, {
|
|
51099
51457
|
flag: "wx",
|
|
@@ -51102,7 +51460,7 @@ function prepareCheckpoint(options) {
|
|
|
51102
51460
|
}
|
|
51103
51461
|
}
|
|
51104
51462
|
const promptDir = join36(restored, ".arp");
|
|
51105
|
-
|
|
51463
|
+
mkdirSync9(promptDir, { mode: 448 });
|
|
51106
51464
|
const promptFile = join36(promptDir, "handoff.json");
|
|
51107
51465
|
const prompt = {
|
|
51108
51466
|
checkpoint_digest: checkpointDigest,
|
|
@@ -51677,7 +52035,7 @@ var init_package = __esm({
|
|
|
51677
52035
|
"package.json"() {
|
|
51678
52036
|
package_default = {
|
|
51679
52037
|
name: "@oxagen/cli",
|
|
51680
|
-
version: "2.1.4-
|
|
52038
|
+
version: "2.1.4-453",
|
|
51681
52039
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
51682
52040
|
type: "module",
|
|
51683
52041
|
main: "./dist/index.js",
|
|
@@ -51788,7 +52146,7 @@ var init_atomic_write = __esm({
|
|
|
51788
52146
|
// src/lib/config.ts
|
|
51789
52147
|
import { homedir as homedir8 } from "os";
|
|
51790
52148
|
import { join as join38 } from "path";
|
|
51791
|
-
import { readFileSync as readFileSync21, mkdirSync as
|
|
52149
|
+
import { readFileSync as readFileSync21, mkdirSync as mkdirSync10, existsSync as existsSync22 } from "fs";
|
|
51792
52150
|
function getConfigDir() {
|
|
51793
52151
|
return CONFIG_DIR;
|
|
51794
52152
|
}
|
|
@@ -51809,7 +52167,7 @@ Run \`oxagen login\` to re-authenticate.
|
|
|
51809
52167
|
function writeConfig(patch) {
|
|
51810
52168
|
const current = readConfig();
|
|
51811
52169
|
const next = { ...current, ...patch };
|
|
51812
|
-
if (!existsSync22(CONFIG_DIR))
|
|
52170
|
+
if (!existsSync22(CONFIG_DIR)) mkdirSync10(CONFIG_DIR, { recursive: true });
|
|
51813
52171
|
atomicWriteFileSync(CONFIG_FILE, JSON.stringify(next, null, 2));
|
|
51814
52172
|
}
|
|
51815
52173
|
function clearConfig() {
|
|
@@ -52364,6 +52722,34 @@ var init_api = __esm({
|
|
|
52364
52722
|
}
|
|
52365
52723
|
});
|
|
52366
52724
|
|
|
52725
|
+
// src/commands/add-claude-code-mcp.ts
|
|
52726
|
+
async function addClaudeCodeMcp(writer) {
|
|
52727
|
+
const { addMissingClaudeCodeMcp: addMissingClaudeCodeMcp2, defaultCliDeps: defaultCliDeps2, oxagenRuntimeCommands: oxagenRuntimeCommands2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
52728
|
+
let added;
|
|
52729
|
+
try {
|
|
52730
|
+
added = addMissingClaudeCodeMcp2(
|
|
52731
|
+
defaultCliDeps2({
|
|
52732
|
+
out: () => void 0,
|
|
52733
|
+
err: (line) => writer.writeErr(line),
|
|
52734
|
+
runtime: oxagenRuntimeCommands2()
|
|
52735
|
+
})
|
|
52736
|
+
);
|
|
52737
|
+
} catch (error) {
|
|
52738
|
+
writer.writeErr(
|
|
52739
|
+
`Could not check Claude Code for Oxagen's MCP server: ${error instanceof Error ? error.message : String(error)}. Run \`oxagen agent enroll\` to add it.`
|
|
52740
|
+
);
|
|
52741
|
+
return;
|
|
52742
|
+
}
|
|
52743
|
+
for (const agent of added)
|
|
52744
|
+
writer.writeErr(
|
|
52745
|
+
agent.ok ? `Added Oxagen's MCP server to Claude Code for ${agent.agentKey} in ${agent.path}. New Claude Code sessions list Oxagen's tools.` : `Could not add Oxagen's MCP server to Claude Code for ${agent.agentKey}: ${agent.problem ?? "unknown reason"}. The hooks keep working. Run \`oxagen agent enroll\` to try again.`
|
|
52746
|
+
);
|
|
52747
|
+
}
|
|
52748
|
+
var init_add_claude_code_mcp = __esm({
|
|
52749
|
+
"src/commands/add-claude-code-mcp.ts"() {
|
|
52750
|
+
}
|
|
52751
|
+
});
|
|
52752
|
+
|
|
52367
52753
|
// src/commands/move-off-tacho.ts
|
|
52368
52754
|
async function moveOffTacho(writer) {
|
|
52369
52755
|
const { defaultCliDeps: defaultCliDeps2, moveOffTachoNames: moveOffTachoNames2, oxagenRuntimeCommands: oxagenRuntimeCommands2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
@@ -52463,6 +52849,7 @@ async function handleTachoEnroll(opts, writer = stdoutWriter) {
|
|
|
52463
52849
|
async function handleTachoStatus(opts, writer = stdoutWriter) {
|
|
52464
52850
|
const { status: status2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
52465
52851
|
await moveOffTacho(writer);
|
|
52852
|
+
await addClaudeCodeMcp(writer);
|
|
52466
52853
|
const report = await status2(opts, await tachoDeps(writer));
|
|
52467
52854
|
const reports = [report, ...report.enrollments ?? []];
|
|
52468
52855
|
return report.enrolled && !reports.some((entry2) => entry2.shipping?.healthy === false);
|
|
@@ -52679,6 +53066,7 @@ var init_tacho = __esm({
|
|
|
52679
53066
|
init_config();
|
|
52680
53067
|
init_capture_writer();
|
|
52681
53068
|
init_api();
|
|
53069
|
+
init_add_claude_code_mcp();
|
|
52682
53070
|
init_move_off_tacho();
|
|
52683
53071
|
}
|
|
52684
53072
|
});
|
|
@@ -56809,7 +57197,7 @@ var init_src2 = __esm({
|
|
|
56809
57197
|
// src/commands/workspace-link.ts
|
|
56810
57198
|
import {
|
|
56811
57199
|
existsSync as existsSync23,
|
|
56812
|
-
mkdirSync as
|
|
57200
|
+
mkdirSync as mkdirSync11,
|
|
56813
57201
|
readFileSync as readFileSync22,
|
|
56814
57202
|
rmSync as rmSync9,
|
|
56815
57203
|
writeFileSync as writeFileSync8
|
|
@@ -56834,7 +57222,7 @@ function readWorkspaceLink(cwd) {
|
|
|
56834
57222
|
}
|
|
56835
57223
|
function writeWorkspaceLink(cwd, link) {
|
|
56836
57224
|
const dir = join44(cwd, ".oxagen");
|
|
56837
|
-
|
|
57225
|
+
mkdirSync11(dir, { recursive: true });
|
|
56838
57226
|
writeFileSync8(workspaceLinkPath(cwd), JSON.stringify(link, null, 2), "utf8");
|
|
56839
57227
|
}
|
|
56840
57228
|
var init_workspace_link = __esm({
|
|
@@ -58284,7 +58672,7 @@ var init_runtime_shared = __esm({
|
|
|
58284
58672
|
function spanDays(from, to) {
|
|
58285
58673
|
return (Date.parse(`${to}T00:00:00Z`) - Date.parse(`${from}T00:00:00Z`)) / DAY_MS + 1;
|
|
58286
58674
|
}
|
|
58287
|
-
var costBasisSchema, microsSchema, moneySchema, costSchema, daySchema, monthSchema, SPEND_RANGE_DAYS_MAX, DAY_MS, dayRangeSchema, principalPublicIdSchema, tokenCountsSchema, spendGroupKindSchema, ratioSchema, spendFigureSchema, spendDaySchema, unmeteredRunsSchema;
|
|
58675
|
+
var costBasisSchema, microsSchema, moneySchema, costSchema, daySchema, monthSchema, SPEND_RANGE_DAYS_MAX, DAY_MS, dayRangeSchema, principalPublicIdSchema, tokenCountsSchema, standingTokensSchema, spendGroupKindSchema, ratioSchema, spendFigureSchema, spendDaySchema, unmeteredRunsSchema;
|
|
58288
58676
|
var init_spend_shared = __esm({
|
|
58289
58677
|
"../../packages/oxagen/src/contracts/spend.shared.ts"() {
|
|
58290
58678
|
"use strict";
|
|
@@ -58333,6 +58721,11 @@ var init_spend_shared = __esm({
|
|
|
58333
58721
|
*/
|
|
58334
58722
|
server_tool_request: external_exports.number().int().nonnegative()
|
|
58335
58723
|
}).strict();
|
|
58724
|
+
standingTokensSchema = external_exports.object({
|
|
58725
|
+
toolDefinitionTokens: external_exports.number().int().nonnegative().nullable(),
|
|
58726
|
+
contextFrameTokens: external_exports.number().int().nonnegative().nullable(),
|
|
58727
|
+
steeringTokens: external_exports.number().int().nonnegative().nullable()
|
|
58728
|
+
}).strict();
|
|
58336
58729
|
spendGroupKindSchema = external_exports.enum([
|
|
58337
58730
|
"operator",
|
|
58338
58731
|
"agent",
|
|
@@ -74221,7 +74614,7 @@ __export(verify_exports, {
|
|
|
74221
74614
|
readBundle: () => readBundle,
|
|
74222
74615
|
verifyBundle: () => verifyBundle3
|
|
74223
74616
|
});
|
|
74224
|
-
import { existsSync as existsSync25, readFileSync as readFileSync23, statSync as
|
|
74617
|
+
import { existsSync as existsSync25, readFileSync as readFileSync23, statSync as statSync12 } from "node:fs";
|
|
74225
74618
|
import { join as join47 } from "node:path";
|
|
74226
74619
|
function readDirectory(dir) {
|
|
74227
74620
|
const read2 = (name) => {
|
|
@@ -74267,7 +74660,7 @@ function readBundle(path2) {
|
|
|
74267
74660
|
if (!existsSync25(path2)) {
|
|
74268
74661
|
throw new BundleReadError(`${path2} does not exist.`);
|
|
74269
74662
|
}
|
|
74270
|
-
return
|
|
74663
|
+
return statSync12(path2).isDirectory() ? readDirectory(path2) : readZip(path2);
|
|
74271
74664
|
}
|
|
74272
74665
|
function digestLabel(state) {
|
|
74273
74666
|
return state === "not_carried" ? "not carried" : state;
|
|
@@ -75161,7 +75554,7 @@ import {
|
|
|
75161
75554
|
appendFileSync as appendFileSync4,
|
|
75162
75555
|
existsSync as existsSync26,
|
|
75163
75556
|
lstatSync as lstatSync9,
|
|
75164
|
-
mkdirSync as
|
|
75557
|
+
mkdirSync as mkdirSync12,
|
|
75165
75558
|
readFileSync as readFileSync24,
|
|
75166
75559
|
readdirSync as readdirSync13,
|
|
75167
75560
|
realpathSync as realpathSync8,
|
|
@@ -75258,7 +75651,7 @@ function machineId(configDir = getConfigDir()) {
|
|
|
75258
75651
|
}
|
|
75259
75652
|
if (secret === null) {
|
|
75260
75653
|
secret = randomBytes11(32).toString("hex");
|
|
75261
|
-
|
|
75654
|
+
mkdirSync12(configDir, { recursive: true });
|
|
75262
75655
|
writeFileSync10(file, `${secret}
|
|
75263
75656
|
`, { encoding: "utf8", mode: 384 });
|
|
75264
75657
|
}
|
|
@@ -75810,12 +76203,12 @@ __export(pull_exports, {
|
|
|
75810
76203
|
import { createHash as createHash19 } from "node:crypto";
|
|
75811
76204
|
import {
|
|
75812
76205
|
lstatSync as lstatSync10,
|
|
75813
|
-
mkdirSync as
|
|
76206
|
+
mkdirSync as mkdirSync13,
|
|
75814
76207
|
readFileSync as readFileSync25,
|
|
75815
76208
|
readdirSync as readdirSync14,
|
|
75816
76209
|
realpathSync as realpathSync9,
|
|
75817
76210
|
rmSync as rmSync10,
|
|
75818
|
-
rmdirSync as
|
|
76211
|
+
rmdirSync as rmdirSync8
|
|
75819
76212
|
} from "node:fs";
|
|
75820
76213
|
import {
|
|
75821
76214
|
dirname as dirname27,
|
|
@@ -75986,7 +76379,7 @@ function pruneEmptyDirs(root, path2) {
|
|
|
75986
76379
|
while (dir.startsWith(stop + sep7)) {
|
|
75987
76380
|
try {
|
|
75988
76381
|
if (readdirSync14(dir).length > 0) return;
|
|
75989
|
-
|
|
76382
|
+
rmdirSync8(dir);
|
|
75990
76383
|
} catch {
|
|
75991
76384
|
return;
|
|
75992
76385
|
}
|
|
@@ -75998,7 +76391,7 @@ function applyPlan(root, plan) {
|
|
|
75998
76391
|
for (const d of plan.deletes) assertInsideOxagen(root, d);
|
|
75999
76392
|
for (const w of plan.writes) {
|
|
76000
76393
|
const abs = join49(root, ...w.path.split("/"));
|
|
76001
|
-
|
|
76394
|
+
mkdirSync13(dirname27(abs), { recursive: true });
|
|
76002
76395
|
atomicWriteFileSync(abs, w.content);
|
|
76003
76396
|
}
|
|
76004
76397
|
for (const d of plan.deletes) {
|
|
@@ -113384,10 +113777,10 @@ import { execFileSync as execFileSync2 } from "node:child_process";
|
|
|
113384
113777
|
import { createHash as createHash20 } from "node:crypto";
|
|
113385
113778
|
import {
|
|
113386
113779
|
lstatSync as lstatSync11,
|
|
113387
|
-
mkdirSync as
|
|
113780
|
+
mkdirSync as mkdirSync14,
|
|
113388
113781
|
readFileSync as readFileSync26,
|
|
113389
113782
|
readlinkSync as readlinkSync4,
|
|
113390
|
-
statSync as
|
|
113783
|
+
statSync as statSync13
|
|
113391
113784
|
} from "node:fs";
|
|
113392
113785
|
import { dirname as dirname28, isAbsolute as isAbsolute14, join as join50, relative as relative9, resolve as resolve19, sep as sep8 } from "node:path";
|
|
113393
113786
|
function git5(cwd, args, input) {
|
|
@@ -113495,14 +113888,14 @@ function chooseBase(root, ref2) {
|
|
|
113495
113888
|
}
|
|
113496
113889
|
function isFile(path2) {
|
|
113497
113890
|
try {
|
|
113498
|
-
return
|
|
113891
|
+
return statSync13(path2).isFile();
|
|
113499
113892
|
} catch {
|
|
113500
113893
|
return false;
|
|
113501
113894
|
}
|
|
113502
113895
|
}
|
|
113503
113896
|
function isDir(path2) {
|
|
113504
113897
|
try {
|
|
113505
|
-
return
|
|
113898
|
+
return statSync13(path2).isDirectory();
|
|
113506
113899
|
} catch {
|
|
113507
113900
|
return false;
|
|
113508
113901
|
}
|
|
@@ -113618,7 +114011,7 @@ async function publishedInputs(root, deps, refresh, out) {
|
|
|
113618
114011
|
}
|
|
113619
114012
|
if (file !== null) {
|
|
113620
114013
|
try {
|
|
113621
|
-
|
|
114014
|
+
mkdirSync14(dirname28(file), { recursive: true });
|
|
113622
114015
|
atomicWriteFileSync(
|
|
113623
114016
|
file,
|
|
113624
114017
|
JSON.stringify({
|