@oxagen/cli 2.1.4-965 → 2.1.4-976
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 +124 -37
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -5307,7 +5307,22 @@ var init_envelope = __esm({
|
|
|
5307
5307
|
// like `proof.observed`. Its strict schema is
|
|
5308
5308
|
// `hostEgressRefusedMessageSchema` in `@oxagen/oxagen/sandbox-host/protocol`,
|
|
5309
5309
|
// which this leaf package cannot import.
|
|
5310
|
-
"oxagen:egress_refused": external_exports.object({}).catchall(json)
|
|
5310
|
+
"oxagen:egress_refused": external_exports.object({}).catchall(json),
|
|
5311
|
+
// The in-app assistant's frames (#5943, ADR-5969). The control plane writes
|
|
5312
|
+
// them on the assistant's own session (`assistant-session.ts` in
|
|
5313
|
+
// @oxagen/agent), never a host. A model call and a tool call each take two
|
|
5314
|
+
// frames: the write-ahead request, durable before the provider or the tool
|
|
5315
|
+
// is reached, and the completion. The history summary is the context a
|
|
5316
|
+
// turn carried in place of its older messages, and the goal verdict is one
|
|
5317
|
+
// verifier round. Each body is opaque on the wire, like `proof.observed`:
|
|
5318
|
+
// its members are the receipt the assistant recorded, and the readers in
|
|
5319
|
+
// @oxagen/run-ledger read them by name.
|
|
5320
|
+
"model.engine_call_started": external_exports.object({}).catchall(json),
|
|
5321
|
+
"model.engine_call_completed": external_exports.object({}).catchall(json),
|
|
5322
|
+
"tool.engine_call_started": external_exports.object({}).catchall(json),
|
|
5323
|
+
"tool.engine_call_completed": external_exports.object({}).catchall(json),
|
|
5324
|
+
"context.history_summarized": external_exports.object({}).catchall(json),
|
|
5325
|
+
"verification.goal_verdict": external_exports.object({}).catchall(json)
|
|
5311
5326
|
};
|
|
5312
5327
|
TACHO_KINDS = Object.keys(KIND_BODIES);
|
|
5313
5328
|
agentIdentitySchema = external_exports.object({
|
|
@@ -22940,6 +22955,15 @@ function setupTokenCommand(claude, platform) {
|
|
|
22940
22955
|
return { file: "script", args: ["-q", "-e", "-c", inner, "/dev/null"] };
|
|
22941
22956
|
return void 0;
|
|
22942
22957
|
}
|
|
22958
|
+
function shellQuote(value) {
|
|
22959
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
22960
|
+
}
|
|
22961
|
+
function setupTokenShellLine(claude, platform) {
|
|
22962
|
+
const command2 = setupTokenCommand(claude, platform);
|
|
22963
|
+
if (command2 === void 0) return void 0;
|
|
22964
|
+
const script = [command2.file, ...command2.args].map(shellQuote).join(" ");
|
|
22965
|
+
return `sleep 2147483647 | { ${script}; echo "${SETUP_TOKEN_EXIT_MARK}$?"; }`;
|
|
22966
|
+
}
|
|
22943
22967
|
function runClaudeSetupToken(options) {
|
|
22944
22968
|
const command2 = setupTokenCommand(
|
|
22945
22969
|
options.claude,
|
|
@@ -22958,28 +22982,69 @@ function runClaudeSetupToken(options) {
|
|
|
22958
22982
|
);
|
|
22959
22983
|
return;
|
|
22960
22984
|
}
|
|
22961
|
-
const
|
|
22962
|
-
|
|
22963
|
-
|
|
22985
|
+
const env = options.env ?? process.env;
|
|
22986
|
+
if (options.interactive) {
|
|
22987
|
+
const child2 = spawn(command2.file, command2.args, {
|
|
22988
|
+
stdio: ["inherit", "pipe", "inherit"],
|
|
22989
|
+
env
|
|
22990
|
+
});
|
|
22991
|
+
let output2 = "";
|
|
22992
|
+
child2.stdout?.setEncoding("utf8");
|
|
22993
|
+
child2.stdout?.on("data", (chunk2) => {
|
|
22994
|
+
output2 += chunk2;
|
|
22995
|
+
options.write(chunk2);
|
|
22996
|
+
});
|
|
22997
|
+
child2.on("error", reject);
|
|
22998
|
+
child2.on(
|
|
22999
|
+
"close",
|
|
23000
|
+
(code) => resolve25({
|
|
23001
|
+
token: extractSetupToken(output2),
|
|
23002
|
+
code: code ?? 1,
|
|
23003
|
+
captured: true
|
|
23004
|
+
})
|
|
23005
|
+
);
|
|
23006
|
+
return;
|
|
23007
|
+
}
|
|
23008
|
+
const line = setupTokenShellLine(
|
|
23009
|
+
options.claude,
|
|
23010
|
+
options.platform ?? process.platform
|
|
23011
|
+
);
|
|
23012
|
+
const child = spawn("sh", ["-c", line], {
|
|
23013
|
+
detached: true,
|
|
23014
|
+
stdio: ["ignore", "pipe", "inherit"],
|
|
23015
|
+
env
|
|
22964
23016
|
});
|
|
22965
23017
|
let output = "";
|
|
23018
|
+
let exited;
|
|
23019
|
+
const mark = new RegExp(`${SETUP_TOKEN_EXIT_MARK}(\\d+)`);
|
|
23020
|
+
const stopGroup = () => {
|
|
23021
|
+
try {
|
|
23022
|
+
if (child.pid !== void 0) process.kill(-child.pid, "SIGTERM");
|
|
23023
|
+
} catch {
|
|
23024
|
+
}
|
|
23025
|
+
};
|
|
22966
23026
|
child.stdout?.setEncoding("utf8");
|
|
22967
23027
|
child.stdout?.on("data", (chunk2) => {
|
|
22968
23028
|
output += chunk2;
|
|
22969
|
-
|
|
23029
|
+
const found = mark.exec(output);
|
|
23030
|
+
options.write(chunk2.replace(mark, "").replace(SETUP_TOKEN_EXIT_MARK, ""));
|
|
23031
|
+
if (found !== null && exited === void 0) {
|
|
23032
|
+
exited = Number(found[1]);
|
|
23033
|
+
stopGroup();
|
|
23034
|
+
}
|
|
22970
23035
|
});
|
|
22971
23036
|
child.on("error", reject);
|
|
22972
|
-
child.on(
|
|
22973
|
-
|
|
22974
|
-
resolve25({
|
|
22975
|
-
token: extractSetupToken(output),
|
|
22976
|
-
code: code ?? 1,
|
|
23037
|
+
child.on(
|
|
23038
|
+
"close",
|
|
23039
|
+
(code) => resolve25({
|
|
23040
|
+
token: extractSetupToken(output.replace(mark, "")),
|
|
23041
|
+
code: exited ?? code ?? 1,
|
|
22977
23042
|
captured: true
|
|
22978
|
-
})
|
|
22979
|
-
|
|
23043
|
+
})
|
|
23044
|
+
);
|
|
22980
23045
|
});
|
|
22981
23046
|
}
|
|
22982
|
-
var TOKEN, TOKEN_CHAR, ANSI;
|
|
23047
|
+
var TOKEN, TOKEN_CHAR, ANSI, SETUP_TOKEN_EXIT_MARK;
|
|
22983
23048
|
var init_claude_setup_token = __esm({
|
|
22984
23049
|
"../../packages/tacho/src/host/claude-setup-token.ts"() {
|
|
22985
23050
|
"use strict";
|
|
@@ -22988,6 +23053,7 @@ var init_claude_setup_token = __esm({
|
|
|
22988
23053
|
TOKEN_CHAR = /[A-Za-z0-9_-]/;
|
|
22989
23054
|
ANSI = // biome-ignore lint/suspicious/noControlCharactersInRegex: terminal escapes
|
|
22990
23055
|
/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)|\u001b\[[0-?]*[ -/]*[@-~]|\u001b[@-Z\\-_]/g;
|
|
23056
|
+
SETUP_TOKEN_EXIT_MARK = "__oxagen_setup_token_exit__=";
|
|
22991
23057
|
}
|
|
22992
23058
|
});
|
|
22993
23059
|
|
|
@@ -25711,7 +25777,7 @@ import { readFileSync as readFileSync10 } from "node:fs";
|
|
|
25711
25777
|
import { dirname as dirname9, resolve as resolve3 } from "node:path";
|
|
25712
25778
|
import { fileURLToPath } from "node:url";
|
|
25713
25779
|
function readVersion() {
|
|
25714
|
-
if (true) return "2.1.4-
|
|
25780
|
+
if (true) return "2.1.4-976";
|
|
25715
25781
|
try {
|
|
25716
25782
|
const here = dirname9(fileURLToPath(import.meta.url));
|
|
25717
25783
|
const pkg = JSON.parse(
|
|
@@ -25796,7 +25862,7 @@ function transientBinDir(binDir, env = process.env) {
|
|
|
25796
25862
|
return "an AppImage mount";
|
|
25797
25863
|
return void 0;
|
|
25798
25864
|
}
|
|
25799
|
-
function
|
|
25865
|
+
function shellQuote2(value, platform = process.platform) {
|
|
25800
25866
|
if (/^[A-Za-z0-9_@%+=:,./-]+$/.test(value)) return value;
|
|
25801
25867
|
if (platform === "win32") return `"${value}"`;
|
|
25802
25868
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
@@ -25847,8 +25913,8 @@ function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath =
|
|
|
25847
25913
|
const dir = P.dirname(tacho);
|
|
25848
25914
|
const transient2 = transientBinDir(dir, env);
|
|
25849
25915
|
return {
|
|
25850
|
-
hookCommand: `${
|
|
25851
|
-
credentialHelperCommand: helperCommandFor(
|
|
25916
|
+
hookCommand: `${shellQuote2(tacho, platform)} hook`,
|
|
25917
|
+
credentialHelperCommand: helperCommandFor(shellQuote2(tacho, platform)),
|
|
25852
25918
|
daemonCommand: [tacho, "daemon"],
|
|
25853
25919
|
mcpStdioCommand: [tacho, "mcp-stdio"],
|
|
25854
25920
|
binDir: dir,
|
|
@@ -25862,9 +25928,9 @@ function runtimeCommands(entry2 = process.argv[1], env = process.env, nodePath =
|
|
|
25862
25928
|
const flagged = transient !== void 0 ? { transient } : {};
|
|
25863
25929
|
const node2 = stableExecutablePath(nodePath, platform, exists);
|
|
25864
25930
|
return {
|
|
25865
|
-
hookCommand: `${
|
|
25931
|
+
hookCommand: `${shellQuote2(node2, platform)} ${shellQuote2(P.join(binDir, "tacho-hook.mjs"), platform)}`,
|
|
25866
25932
|
credentialHelperCommand: helperCommandFor(
|
|
25867
|
-
`${
|
|
25933
|
+
`${shellQuote2(node2, platform)} ${shellQuote2(P.join(binDir, "tacho.mjs"), platform)}`
|
|
25868
25934
|
),
|
|
25869
25935
|
daemonCommand: [node2, P.join(binDir, "tachod.mjs")],
|
|
25870
25936
|
mcpStdioCommand: [node2, P.join(binDir, "tacho.mjs"), "mcp-stdio"],
|
|
@@ -25892,7 +25958,7 @@ function oxagenRuntimeCommands(entry2 = process.argv[1], env = process.env, node
|
|
|
25892
25958
|
} else {
|
|
25893
25959
|
return runtimeCommands(void 0, env, nodePath, platform, false, exists);
|
|
25894
25960
|
}
|
|
25895
|
-
const line = prefix.map((word) =>
|
|
25961
|
+
const line = prefix.map((word) => shellQuote2(word, platform)).join(" ");
|
|
25896
25962
|
const binDir = P.dirname(prefix[prefix.length - 1]);
|
|
25897
25963
|
const transient = transientBinDir(binDir, env);
|
|
25898
25964
|
return {
|
|
@@ -29352,7 +29418,7 @@ function githubConfigure(options, rootDeps) {
|
|
|
29352
29418
|
const helperBase = deps.runtime.credentialHelperCommand;
|
|
29353
29419
|
if (!helperBase)
|
|
29354
29420
|
throw new Error("This installation has no credential helper command");
|
|
29355
|
-
const helper = `!${helperBase.replace(/credential issue --harness claude-code$/, "github credential")} --harness ${
|
|
29421
|
+
const helper = `!${helperBase.replace(/credential issue --harness claude-code$/, "github credential")} --harness ${shellQuote2(options.harness, deps.platform)} --cwd ${shellQuote2(cwd, deps.platform)}`;
|
|
29356
29422
|
const previous = (host.github_repositories ?? []).find(
|
|
29357
29423
|
(entry2) => sameReceipt(entry2, cwd, repository)
|
|
29358
29424
|
);
|
|
@@ -31144,7 +31210,7 @@ function runtimeOf(host) {
|
|
|
31144
31210
|
if (first === void 0 || !files2.every((file) => existsSync16(file)))
|
|
31145
31211
|
return void 0;
|
|
31146
31212
|
const binDir = dirname13(first);
|
|
31147
|
-
const tacho = host.daemon_command[0] === first ?
|
|
31213
|
+
const tacho = host.daemon_command[0] === first ? shellQuote2(first) : `${host.daemon_command[0]} ${shellQuote2(join22(binDir, "tacho.mjs"))}`;
|
|
31148
31214
|
return {
|
|
31149
31215
|
hookCommand: host.hook_command,
|
|
31150
31216
|
credentialHelperCommand: helperCommandFor(tacho),
|
|
@@ -34979,7 +35045,7 @@ __export(cli_exports, {
|
|
|
34979
35045
|
runtimeCommands: () => runtimeCommands,
|
|
34980
35046
|
serviceInstalled: () => serviceInstalled,
|
|
34981
35047
|
sessionRefusal: () => sessionRefusal,
|
|
34982
|
-
shellQuote: () =>
|
|
35048
|
+
shellQuote: () => shellQuote2,
|
|
34983
35049
|
shimError: () => shimError,
|
|
34984
35050
|
shippingHealth: () => shippingHealth,
|
|
34985
35051
|
signInIfNoCredential: () => signInIfNoCredential,
|
|
@@ -39028,9 +39094,9 @@ function hardenedGitArgs(cwd, args, globals = []) {
|
|
|
39028
39094
|
];
|
|
39029
39095
|
}
|
|
39030
39096
|
function hardenedGitShellPrefix() {
|
|
39031
|
-
return ["git", ...HARDENED_GIT_CONFIG.map(
|
|
39097
|
+
return ["git", ...HARDENED_GIT_CONFIG.map(shellQuote3)].join(" ");
|
|
39032
39098
|
}
|
|
39033
|
-
function
|
|
39099
|
+
function shellQuote3(value) {
|
|
39034
39100
|
return /^[A-Za-z0-9_./=:-]+$/.test(value) ? value : `'${value.replace(/'/g, "'\\''")}'`;
|
|
39035
39101
|
}
|
|
39036
39102
|
function hardenedGitExecOptions(repository) {
|
|
@@ -39847,7 +39913,7 @@ var init_privilege = __esm({
|
|
|
39847
39913
|
// ../../packages/tacho/src/contained/sandbox/launcher.ts
|
|
39848
39914
|
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
39849
39915
|
import { join as join29 } from "node:path";
|
|
39850
|
-
function
|
|
39916
|
+
function shellQuote4(value) {
|
|
39851
39917
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
39852
39918
|
}
|
|
39853
39919
|
function sandboxHarnessEnvironment(request3, gatewayPort) {
|
|
@@ -39873,7 +39939,7 @@ function ptyCommand(argv) {
|
|
|
39873
39939
|
"-f",
|
|
39874
39940
|
"-e",
|
|
39875
39941
|
"-c",
|
|
39876
|
-
`exec ${argv.map(
|
|
39942
|
+
`exec ${argv.map(shellQuote4).join(" ")}`,
|
|
39877
39943
|
"/dev/null"
|
|
39878
39944
|
]
|
|
39879
39945
|
};
|
|
@@ -41597,9 +41663,17 @@ function createWorkOrderAutostart(deps) {
|
|
|
41597
41663
|
log(`work order ${id2}: the harness ${ended}`);
|
|
41598
41664
|
return;
|
|
41599
41665
|
}
|
|
41600
|
-
const [status2, ahead] = await Promise.all([
|
|
41666
|
+
const [status2, ahead, current] = await Promise.all([
|
|
41601
41667
|
git6(worktree, ["status", "--porcelain"]),
|
|
41602
|
-
base2 === void 0 ? Promise.resolve({ ok: false, out: "", error: "no base commit" }) : git6(worktree, [
|
|
41668
|
+
base2 === void 0 ? Promise.resolve({ ok: false, out: "", error: "no base commit" }) : git6(worktree, [
|
|
41669
|
+
"rev-list",
|
|
41670
|
+
"--count",
|
|
41671
|
+
"HEAD",
|
|
41672
|
+
"--not",
|
|
41673
|
+
base2,
|
|
41674
|
+
"--remotes"
|
|
41675
|
+
]),
|
|
41676
|
+
git6(worktree, ["branch", "--show-current"])
|
|
41603
41677
|
]);
|
|
41604
41678
|
const clean = status2.ok && status2.out.length === 0 && ahead.ok && ahead.out === "0";
|
|
41605
41679
|
if (!clean || root === void 0) {
|
|
@@ -41615,13 +41689,26 @@ function createWorkOrderAutostart(deps) {
|
|
|
41615
41689
|
);
|
|
41616
41690
|
if (!removed.ok) {
|
|
41617
41691
|
log(
|
|
41618
|
-
`work order ${id2}: the harness ${ended} and left
|
|
41692
|
+
`work order ${id2}: the harness ${ended} and left nothing that is not on a remote, but Git could not remove ${worktree}: ${removed.error}`
|
|
41619
41693
|
);
|
|
41620
41694
|
return;
|
|
41621
41695
|
}
|
|
41622
|
-
|
|
41696
|
+
const used = /* @__PURE__ */ new Set();
|
|
41697
|
+
if (branch !== void 0) used.add(branch);
|
|
41698
|
+
if (current.ok && current.out.length > 0) used.add(current.out);
|
|
41699
|
+
for (const name of used) {
|
|
41700
|
+
const unpushed = await git6(root, [
|
|
41701
|
+
"rev-list",
|
|
41702
|
+
"--count",
|
|
41703
|
+
name,
|
|
41704
|
+
"--not",
|
|
41705
|
+
"--remotes"
|
|
41706
|
+
]);
|
|
41707
|
+
if (unpushed.ok && unpushed.out === "0")
|
|
41708
|
+
await git6(root, ["branch", "-D", name]);
|
|
41709
|
+
}
|
|
41623
41710
|
log(
|
|
41624
|
-
`work order ${id2}: the harness ${ended} and left
|
|
41711
|
+
`work order ${id2}: the harness ${ended} and left nothing that is not on a remote, so its worktree is removed${mark.log !== void 0 ? `. Its output is in ${mark.log}` : ""}.`
|
|
41625
41712
|
);
|
|
41626
41713
|
}
|
|
41627
41714
|
function watch2(id2, workspace, exited) {
|
|
@@ -60199,7 +60286,7 @@ var init_package = __esm({
|
|
|
60199
60286
|
"package.json"() {
|
|
60200
60287
|
package_default = {
|
|
60201
60288
|
name: "@oxagen/cli",
|
|
60202
|
-
version: "2.1.4-
|
|
60289
|
+
version: "2.1.4-976",
|
|
60203
60290
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
60204
60291
|
type: "module",
|
|
60205
60292
|
main: "./dist/index.js",
|
|
@@ -79283,10 +79370,10 @@ var init_run_list = __esm({
|
|
|
79283
79370
|
/** `owner/name` as the frame recorded it; null when it recorded none. */
|
|
79284
79371
|
repository: external_exports.string().max(512).nullable(),
|
|
79285
79372
|
/**
|
|
79286
|
-
* The state
|
|
79287
|
-
*
|
|
79288
|
-
*
|
|
79289
|
-
* renders "status unknown", never a guessed "open".
|
|
79373
|
+
* The state `forge.pull_requests` holds for the pull request, which the
|
|
79374
|
+
* forge sync keeps current from each delivery and each recorded link
|
|
79375
|
+
* (ADR-288, #5949). Null when the store holds no row for it, and a caller
|
|
79376
|
+
* then renders "status unknown", never a guessed "open".
|
|
79290
79377
|
*/
|
|
79291
79378
|
state: external_exports.enum(["open", "draft", "merged", "closed"]).nullable(),
|
|
79292
79379
|
/**
|
package/package.json
CHANGED