@oxagen/cli 2.1.4-430 → 2.1.4-438
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 +131 -10
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -22995,7 +22995,7 @@ import { readFileSync as readFileSync10 } from "node:fs";
|
|
|
22995
22995
|
import { dirname as dirname7, resolve as resolve2 } from "node:path";
|
|
22996
22996
|
import { fileURLToPath } from "node:url";
|
|
22997
22997
|
function readVersion() {
|
|
22998
|
-
if (true) return "2.1.4-
|
|
22998
|
+
if (true) return "2.1.4-438";
|
|
22999
22999
|
try {
|
|
23000
23000
|
const here = dirname7(fileURLToPath(import.meta.url));
|
|
23001
23001
|
const pkg = JSON.parse(
|
|
@@ -51676,7 +51676,7 @@ var init_package = __esm({
|
|
|
51676
51676
|
"package.json"() {
|
|
51677
51677
|
package_default = {
|
|
51678
51678
|
name: "@oxagen/cli",
|
|
51679
|
-
version: "2.1.4-
|
|
51679
|
+
version: "2.1.4-438",
|
|
51680
51680
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
51681
51681
|
type: "module",
|
|
51682
51682
|
main: "./dist/index.js",
|
|
@@ -57966,7 +57966,7 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
57966
57966
|
});
|
|
57967
57967
|
|
|
57968
57968
|
// ../../packages/oxagen/src/contracts/context.steering.shared.ts
|
|
57969
|
-
var recordKindSchema2, steeringPrKindSchema, proposalKindSchema, RECORD_KINDS2, STEERING_PR_KINDS, GOVERNANCE_LINEAGE, recordForceSchema2, constraintEffectSchema, publishedSharingScopeSchema, appendKindSchema, proposalStatusSchema, proposalStateSchema, repositoryProviderSchema, governanceModeSchema, GOVERNANCE_MODES2, checkNameSchema, CHECK_NAMES, steeringCheckNameSchema, STEERING_CHECK_NAMES, instant, checkResultSchema, RECORD_LINEAGE_ID, lineageIdSchema, proposedRecordSchema, proposalSupportSchema, proposalViewSchema, publishedRecordSchema;
|
|
57969
|
+
var recordKindSchema2, steeringPrKindSchema, proposalKindSchema, RECORD_KINDS2, STEERING_PR_KINDS, GOVERNANCE_LINEAGE, recordForceSchema2, constraintEffectSchema, publishedSharingScopeSchema, appendKindSchema, proposalStatusSchema, proposalStateSchema, repositoryProviderSchema, governanceModeSchema, GOVERNANCE_MODES2, checkNameSchema, CHECK_NAMES, steeringCheckNameSchema, STEERING_CHECK_NAMES, instant, checkResultSchema, checkFindingSchema, RECORD_LINEAGE_ID, lineageIdSchema, proposedRecordSchema, proposalSupportSchema, proposalViewSchema, publishedRecordSchema;
|
|
57970
57970
|
var init_context_steering_shared = __esm({
|
|
57971
57971
|
"../../packages/oxagen/src/contracts/context.steering.shared.ts"() {
|
|
57972
57972
|
"use strict";
|
|
@@ -58058,6 +58058,15 @@ var init_context_steering_shared = __esm({
|
|
|
58058
58058
|
startedAt: instant.nullable(),
|
|
58059
58059
|
completedAt: instant.nullable()
|
|
58060
58060
|
}).strict();
|
|
58061
|
+
checkFindingSchema = external_exports.object({
|
|
58062
|
+
rule: external_exports.enum(["managed-block"]),
|
|
58063
|
+
/** The file the finding is in. */
|
|
58064
|
+
path: external_exports.string(),
|
|
58065
|
+
/** The line it starts on, when the check could name one. */
|
|
58066
|
+
line: external_exports.number().int().positive().nullable(),
|
|
58067
|
+
/** One sentence saying what the check found. */
|
|
58068
|
+
message: external_exports.string()
|
|
58069
|
+
}).strict();
|
|
58061
58070
|
RECORD_LINEAGE_ID = new RegExp(
|
|
58062
58071
|
`^(?!${GOVERNANCE_LINEAGE}$)${STEERING_RECORD_LINEAGE.source.replace(/^\^/, "")}`
|
|
58063
58072
|
);
|
|
@@ -70791,15 +70800,38 @@ var init_lineage = __esm({
|
|
|
70791
70800
|
});
|
|
70792
70801
|
|
|
70793
70802
|
// ../../packages/steering-check/src/checks/owned.ts
|
|
70794
|
-
function
|
|
70803
|
+
function lockServer(path2) {
|
|
70804
|
+
return path2.split("/")[2];
|
|
70805
|
+
}
|
|
70806
|
+
function lockFinding(path2, line, verb, problems) {
|
|
70807
|
+
const shown2 = problems.slice(0, 3).join(" ");
|
|
70808
|
+
const more = problems.length > 3 ? ` ${problems.length - 3} more problems follow.` : "";
|
|
70809
|
+
return find7({
|
|
70810
|
+
rule: "oxagen-writes",
|
|
70811
|
+
path: path2,
|
|
70812
|
+
line,
|
|
70813
|
+
field: null,
|
|
70814
|
+
message: `This steering PR ${verb} ${path2}, and the lock it holds is not one Oxagen writes. ${shown2}${more}`,
|
|
70815
|
+
expected: `${path2} as Studio's Review or a sync writes it.`,
|
|
70816
|
+
fix: `Restore ${path2} from the production branch. Change the server's tools in Studio and open its Review, or sync the server, and Oxagen writes the lock.`
|
|
70817
|
+
});
|
|
70818
|
+
}
|
|
70819
|
+
function writesFindings(env, base2) {
|
|
70795
70820
|
const findings = [];
|
|
70821
|
+
const readLock3 = env.servers?.lock;
|
|
70796
70822
|
for (const path2 of [...env.changed, ...env.removed].sort()) {
|
|
70797
|
-
const
|
|
70823
|
+
const kind = classifySteeringRepoPath(path2);
|
|
70824
|
+
const what = OXAGEN_WRITES[kind];
|
|
70798
70825
|
if (what === void 0) continue;
|
|
70799
|
-
const before =
|
|
70826
|
+
const before = base2.get(path2);
|
|
70800
70827
|
const after = env.head.get(path2);
|
|
70801
70828
|
const line = after === void 0 ? null : before === void 0 ? 1 : firstDifferingLine(before, after);
|
|
70802
70829
|
const verb = after === void 0 ? "removes" : before === void 0 ? "adds" : "changes";
|
|
70830
|
+
if (kind === "server-lock" && after !== void 0 && readLock3 !== void 0) {
|
|
70831
|
+
const outcome = readLock3(lockServer(path2), env.head, base2);
|
|
70832
|
+
if (!outcome.ok) findings.push(lockFinding(path2, line, verb, outcome.problems));
|
|
70833
|
+
continue;
|
|
70834
|
+
}
|
|
70803
70835
|
findings.push(
|
|
70804
70836
|
find7({
|
|
70805
70837
|
rule: "oxagen-writes",
|
|
@@ -70867,7 +70899,7 @@ var init_owned = __esm({
|
|
|
70867
70899
|
MANAGED_FILES = [AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH];
|
|
70868
70900
|
BEGIN_MARKER = "<!-- oxagen:begin managed sha256:... -->";
|
|
70869
70901
|
ownedCheck = (env) => {
|
|
70870
|
-
const findings = env.base === null ? [] : writesFindings(env);
|
|
70902
|
+
const findings = env.base === null ? [] : writesFindings(env, env.base);
|
|
70871
70903
|
for (const path2 of MANAGED_FILES) {
|
|
70872
70904
|
if (env.base !== null && !env.changed.has(path2) && !env.removed.has(path2)) continue;
|
|
70873
70905
|
const finding = managedFinding(env, path2);
|
|
@@ -74513,6 +74545,9 @@ async function promoteWorkspaceMemories(input) {
|
|
|
74513
74545
|
async function dismissWorkspaceMemories(input) {
|
|
74514
74546
|
return apiPostOrThrow(ROUTES.dismiss, input);
|
|
74515
74547
|
}
|
|
74548
|
+
async function dropMemoryPrRecord(input) {
|
|
74549
|
+
return apiPostOrThrow(ROUTES.drop, input);
|
|
74550
|
+
}
|
|
74516
74551
|
function truncate2(text4, max2) {
|
|
74517
74552
|
const line = text4.trim().replace(/\s+/g, " ");
|
|
74518
74553
|
return line.length <= max2 ? line : `${line.slice(0, max2 - 3)}...`;
|
|
@@ -74639,6 +74674,15 @@ function formatDismissResult(result2, restore) {
|
|
|
74639
74674
|
);
|
|
74640
74675
|
return lines.join("\n");
|
|
74641
74676
|
}
|
|
74677
|
+
function formatDropResult(result2) {
|
|
74678
|
+
const pr = result2.pull_request;
|
|
74679
|
+
const short5 = result2.commit_sha.slice(0, 7);
|
|
74680
|
+
return [
|
|
74681
|
+
result2.already_dropped ? `${result2.path} was already dropped from memory PR #${pr.number} in commit ${short5}.` : `Dropped ${result2.path} from memory PR #${pr.number} in commit ${short5} on ${pr.branch}.`,
|
|
74682
|
+
"When the PR merges, the record's statements are rejected and its memories wait again.",
|
|
74683
|
+
pr.url
|
|
74684
|
+
].join("\n");
|
|
74685
|
+
}
|
|
74642
74686
|
var ROUTES, WORKSPACE_MEMORY_STATES, STATE_LABELS, SKIP_REASONS2, SKIPPED_STATES;
|
|
74643
74687
|
var init_workspace_memory_client = __esm({
|
|
74644
74688
|
"src/lib/workspace-memory-client.ts"() {
|
|
@@ -74647,7 +74691,8 @@ var init_workspace_memory_client = __esm({
|
|
|
74647
74691
|
list: "context/steering/memories/list",
|
|
74648
74692
|
get: "context/steering/memories/get",
|
|
74649
74693
|
promote: "context/steering/memories/promote",
|
|
74650
|
-
dismiss: "context/steering/memories/dismiss"
|
|
74694
|
+
dismiss: "context/steering/memories/dismiss",
|
|
74695
|
+
drop: "context/steering/memory-prs/records/drop"
|
|
74651
74696
|
};
|
|
74652
74697
|
WORKSPACE_MEMORY_STATES = [
|
|
74653
74698
|
"waiting",
|
|
@@ -74684,6 +74729,7 @@ __export(memory_exports, {
|
|
|
74684
74729
|
MEMORY_COMMAND_CAPABILITIES: () => MEMORY_COMMAND_CAPABILITIES,
|
|
74685
74730
|
MEMORY_IMPORT_CAPABILITIES: () => MEMORY_IMPORT_CAPABILITIES,
|
|
74686
74731
|
handleMemoryDismiss: () => handleMemoryDismiss,
|
|
74732
|
+
handleMemoryDrop: () => handleMemoryDrop,
|
|
74687
74733
|
handleMemoryImport: () => handleMemoryImport,
|
|
74688
74734
|
handleMemoryList: () => handleMemoryList,
|
|
74689
74735
|
handleMemoryPromote: () => handleMemoryPromote,
|
|
@@ -74795,6 +74841,23 @@ async function handleMemoryDismiss(ids, opts, writer = stdoutWriter) {
|
|
|
74795
74841
|
handleApiError(err2, writer);
|
|
74796
74842
|
}
|
|
74797
74843
|
}
|
|
74844
|
+
async function handleMemoryDrop(number2, path2, opts, writer = stdoutWriter) {
|
|
74845
|
+
if (!/^\d+$/.test(number2.trim()) || Number(number2) < 1)
|
|
74846
|
+
failCommand(`Invalid memory PR number "${number2}". Use the PR's number, such as 12.`, writer);
|
|
74847
|
+
const pr = Number(number2.trim());
|
|
74848
|
+
if (path2.trim() === "")
|
|
74849
|
+
failCommand("Name the record file to drop, such as steering/memory/workspace/general/use-pnpm.md.", writer);
|
|
74850
|
+
try {
|
|
74851
|
+
const result2 = await dropMemoryPrRecord({ number: pr, path: path2.trim() });
|
|
74852
|
+
if (opts.json) {
|
|
74853
|
+
writer.write(JSON.stringify(result2, null, 2));
|
|
74854
|
+
return;
|
|
74855
|
+
}
|
|
74856
|
+
writer.write(formatDropResult(result2));
|
|
74857
|
+
} catch (err2) {
|
|
74858
|
+
handleApiError(err2, writer);
|
|
74859
|
+
}
|
|
74860
|
+
}
|
|
74798
74861
|
async function handleMemoryImport(files2, opts, writer = stdoutWriter) {
|
|
74799
74862
|
if (files2.length === 0) {
|
|
74800
74863
|
failCommand(
|
|
@@ -74824,7 +74887,8 @@ var init_memory2 = __esm({
|
|
|
74824
74887
|
"list_workspace_memories",
|
|
74825
74888
|
"get_workspace_memory",
|
|
74826
74889
|
"promote_memories",
|
|
74827
|
-
"dismiss_memories"
|
|
74890
|
+
"dismiss_memories",
|
|
74891
|
+
"drop_memory_record"
|
|
74828
74892
|
];
|
|
74829
74893
|
HARNESSES2 = ["claude-code", "codex", "cursor", "stella", "claude-desktop"];
|
|
74830
74894
|
KINDS2 = [
|
|
@@ -112977,6 +113041,56 @@ function lockFindings2(name, text4, lock) {
|
|
|
112977
113041
|
}
|
|
112978
113042
|
return findings;
|
|
112979
113043
|
}
|
|
113044
|
+
function versionProblem(name, key, entry2, before) {
|
|
113045
|
+
const tool = `${name}__${key}`;
|
|
113046
|
+
if (before === void 0) {
|
|
113047
|
+
return entry2.version === 1 ? null : `${tool} is at version ${entry2.version}, and a tool new to the lock starts at version 1.`;
|
|
113048
|
+
}
|
|
113049
|
+
if (before.definition_hash === entry2.definition_hash) {
|
|
113050
|
+
return entry2.version === before.version ? null : `${tool} is at version ${entry2.version}. Its definition_hash is the production lock's, so its version stays ${before.version}.`;
|
|
113051
|
+
}
|
|
113052
|
+
return entry2.version === before.version + 1 ? null : `${tool} is at version ${entry2.version}. Its definition_hash differs from the production lock's, so its version is ${before.version + 1}.`;
|
|
113053
|
+
}
|
|
113054
|
+
function lockOutcome(name, head2, base2) {
|
|
113055
|
+
const path2 = toolsLockPath(name);
|
|
113056
|
+
const text4 = head2.get(path2);
|
|
113057
|
+
if (text4 === void 0) return { ok: false, problems: [`The steering PR holds no ${path2}.`] };
|
|
113058
|
+
const read2 = parseLock(text4);
|
|
113059
|
+
if (!read2.ok) {
|
|
113060
|
+
const problems2 = read2.issues.map(
|
|
113061
|
+
(issue) => closed(issue.field === null ? issue.message : `${issue.field}: ${issue.message}`)
|
|
113062
|
+
);
|
|
113063
|
+
return { ok: false, problems: problems2 };
|
|
113064
|
+
}
|
|
113065
|
+
const pinned = read2.value;
|
|
113066
|
+
const problems = [];
|
|
113067
|
+
const serverText = head2.get(serverTomlPath(name));
|
|
113068
|
+
const server = serverText === void 0 ? void 0 : parseServerToml(serverText);
|
|
113069
|
+
if (server?.ok === true && server.value.source.type !== pinned.source.type) {
|
|
113070
|
+
problems.push(`The lock's source is ${pinned.source.type}, and server.toml's source is ${server.value.source.type}.`);
|
|
113071
|
+
}
|
|
113072
|
+
const toolsText = head2.get(toolsTomlPath(name));
|
|
113073
|
+
const tools = toolsText === void 0 ? void 0 : parseToolsToml(toolsText);
|
|
113074
|
+
if (tools?.ok === true) {
|
|
113075
|
+
const imported = tools.value.tools ?? {};
|
|
113076
|
+
for (const key of Object.keys(pinned.tools)) {
|
|
113077
|
+
if (!Object.hasOwn(imported, key)) {
|
|
113078
|
+
problems.push(`The lock holds ${name}__${key}, and tools.toml imports no tool keyed ${key}.`);
|
|
113079
|
+
}
|
|
113080
|
+
}
|
|
113081
|
+
}
|
|
113082
|
+
const baseText = base2.get(path2);
|
|
113083
|
+
const previous = baseText === void 0 ? null : readLock2(baseText);
|
|
113084
|
+
if (previous === null || previous.ok) {
|
|
113085
|
+
const prior = previous === null ? {} : previous.lock.tools;
|
|
113086
|
+
const entries2 = Object.entries(pinned.tools);
|
|
113087
|
+
for (const [key, entry2] of entries2) {
|
|
113088
|
+
const problem = versionProblem(name, key, entry2, Object.hasOwn(prior, key) ? prior[key] : void 0);
|
|
113089
|
+
if (problem !== null) problems.push(problem);
|
|
113090
|
+
}
|
|
113091
|
+
}
|
|
113092
|
+
return problems.length === 0 ? { ok: true } : { ok: false, problems };
|
|
113093
|
+
}
|
|
112980
113094
|
function toolField(tool, field) {
|
|
112981
113095
|
return field === void 0 ? `tools.${tool}` : `tools.${tool}.${field}`;
|
|
112982
113096
|
}
|
|
@@ -113243,7 +113357,8 @@ var init_servers = __esm({
|
|
|
113243
113357
|
CALLS_FILE = "tests/calls.jsonl";
|
|
113244
113358
|
SERVER_READERS = {
|
|
113245
113359
|
server: (text4) => outcomeOf2(parseServerToml(text4)),
|
|
113246
|
-
tools: (text4) => outcomeOf2(parseToolsToml(text4))
|
|
113360
|
+
tools: (text4) => outcomeOf2(parseToolsToml(text4)),
|
|
113361
|
+
lock: (name, head2, base2) => lockOutcome(name, head2, base2)
|
|
113247
113362
|
};
|
|
113248
113363
|
DEFINITION_SOURCES = /* @__PURE__ */ new Set(["openapi", "graphql", "grpc"]);
|
|
113249
113364
|
RESYNC = "Restore tools.lock.json from the production branch. If the production branch has this lock, sync the server in Studio so Oxagen writes it again.";
|
|
@@ -116150,6 +116265,12 @@ function buildProgram() {
|
|
|
116150
116265
|
await handleMemoryDismiss2(ids, opts);
|
|
116151
116266
|
}
|
|
116152
116267
|
);
|
|
116268
|
+
memory.command("drop <number> <path>").description(
|
|
116269
|
+
"Drop one proposed record from an open memory PR. When the PR merges, the record's statements are rejected and its memories wait again"
|
|
116270
|
+
).option("--json", "Output JSON").action(async (number2, path2, opts) => {
|
|
116271
|
+
const { handleMemoryDrop: handleMemoryDrop2 } = await Promise.resolve().then(() => (init_memory2(), memory_exports));
|
|
116272
|
+
await handleMemoryDrop2(number2, path2, opts);
|
|
116273
|
+
});
|
|
116153
116274
|
memory.command("import <files...>").description(
|
|
116154
116275
|
"Read Markdown files into steering records with a kind and a force for each statement. Previews unless --yes."
|
|
116155
116276
|
).option(
|
package/package.json
CHANGED