@mrciphersmith/keryx 0.3.42 → 0.3.43
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/dist/cli.js +171 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -14119,7 +14119,7 @@ var package_default;
|
|
|
14119
14119
|
var init_package = __esm(() => {
|
|
14120
14120
|
package_default = {
|
|
14121
14121
|
name: "@mrciphersmith/keryx",
|
|
14122
|
-
version: "0.3.
|
|
14122
|
+
version: "0.3.43",
|
|
14123
14123
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
14124
14124
|
private: false,
|
|
14125
14125
|
publishConfig: {
|
|
@@ -85714,6 +85714,127 @@ var init_contracts = __esm(() => {
|
|
|
85714
85714
|
];
|
|
85715
85715
|
});
|
|
85716
85716
|
|
|
85717
|
+
// src/harness/external/strict-schema.ts
|
|
85718
|
+
function isSchema(value) {
|
|
85719
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
85720
|
+
}
|
|
85721
|
+
function mapSchemas(value) {
|
|
85722
|
+
const out = {};
|
|
85723
|
+
if (!isSchema(value))
|
|
85724
|
+
return out;
|
|
85725
|
+
for (const [key, child] of Object.entries(value))
|
|
85726
|
+
out[key] = toStrictNode(child);
|
|
85727
|
+
return out;
|
|
85728
|
+
}
|
|
85729
|
+
function makeNullable(schema) {
|
|
85730
|
+
const type = schema.type;
|
|
85731
|
+
if (typeof type === "string") {
|
|
85732
|
+
if (type === "null")
|
|
85733
|
+
return schema;
|
|
85734
|
+
const out = { ...schema, type: [type, "null"] };
|
|
85735
|
+
if (Array.isArray(schema.enum) && !schema.enum.includes(null))
|
|
85736
|
+
out.enum = [...schema.enum, null];
|
|
85737
|
+
return out;
|
|
85738
|
+
}
|
|
85739
|
+
if (Array.isArray(type)) {
|
|
85740
|
+
if (type.includes("null")) {
|
|
85741
|
+
const out = { ...schema };
|
|
85742
|
+
if (Array.isArray(schema.enum) && !schema.enum.includes(null))
|
|
85743
|
+
out.enum = [...schema.enum, null];
|
|
85744
|
+
return out;
|
|
85745
|
+
}
|
|
85746
|
+
const out = { ...schema, type: [...type, "null"] };
|
|
85747
|
+
if (Array.isArray(schema.enum) && !schema.enum.includes(null))
|
|
85748
|
+
out.enum = [...schema.enum, null];
|
|
85749
|
+
return out;
|
|
85750
|
+
}
|
|
85751
|
+
if (Array.isArray(schema.enum) && schema.anyOf === undefined) {
|
|
85752
|
+
return schema.enum.includes(null) ? schema : { ...schema, enum: [...schema.enum, null] };
|
|
85753
|
+
}
|
|
85754
|
+
if (Array.isArray(schema.anyOf)) {
|
|
85755
|
+
return { ...schema, anyOf: [...schema.anyOf, NULL_SCHEMA] };
|
|
85756
|
+
}
|
|
85757
|
+
return { anyOf: [schema, NULL_SCHEMA] };
|
|
85758
|
+
}
|
|
85759
|
+
function toStrictNode(node) {
|
|
85760
|
+
if (!isSchema(node))
|
|
85761
|
+
return {};
|
|
85762
|
+
const out = {};
|
|
85763
|
+
if (node.type !== undefined)
|
|
85764
|
+
out.type = node.type;
|
|
85765
|
+
if (Array.isArray(node.enum))
|
|
85766
|
+
out.enum = [...node.enum];
|
|
85767
|
+
else if ("const" in node)
|
|
85768
|
+
out.enum = [node.const];
|
|
85769
|
+
if (typeof node.$ref === "string")
|
|
85770
|
+
out.$ref = node.$ref;
|
|
85771
|
+
const union = node.anyOf ?? node.oneOf;
|
|
85772
|
+
if (Array.isArray(union))
|
|
85773
|
+
out.anyOf = union.map(toStrictNode);
|
|
85774
|
+
if (isSchema(node.items))
|
|
85775
|
+
out.items = toStrictNode(node.items);
|
|
85776
|
+
if (isSchema(node.$defs))
|
|
85777
|
+
out.$defs = mapSchemas(node.$defs);
|
|
85778
|
+
const isObject = node.type === "object" || isSchema(node.properties);
|
|
85779
|
+
if (isObject) {
|
|
85780
|
+
const required = new Set(Array.isArray(node.required) ? node.required : []);
|
|
85781
|
+
const properties = {};
|
|
85782
|
+
for (const [key, child] of Object.entries(isSchema(node.properties) ? node.properties : {})) {
|
|
85783
|
+
const strict = toStrictNode(child);
|
|
85784
|
+
properties[key] = required.has(key) ? strict : makeNullable(strict);
|
|
85785
|
+
}
|
|
85786
|
+
out.type ??= "object";
|
|
85787
|
+
out.properties = properties;
|
|
85788
|
+
out.required = Object.keys(properties);
|
|
85789
|
+
out.additionalProperties = false;
|
|
85790
|
+
}
|
|
85791
|
+
return out;
|
|
85792
|
+
}
|
|
85793
|
+
function toStrictOutputSchema(bundled) {
|
|
85794
|
+
return toStrictNode(bundled);
|
|
85795
|
+
}
|
|
85796
|
+
function resolveRef3(node, root) {
|
|
85797
|
+
let current = node;
|
|
85798
|
+
for (let hops = 0;typeof current.$ref === "string" && hops < 16; hops += 1) {
|
|
85799
|
+
const ref = current.$ref;
|
|
85800
|
+
if (!ref.startsWith("#/"))
|
|
85801
|
+
return current;
|
|
85802
|
+
let target = root;
|
|
85803
|
+
for (const part of ref.slice(2).split("/")) {
|
|
85804
|
+
target = isSchema(target) ? target[decodeURIComponent(part)] : undefined;
|
|
85805
|
+
}
|
|
85806
|
+
if (!isSchema(target))
|
|
85807
|
+
return current;
|
|
85808
|
+
current = target;
|
|
85809
|
+
}
|
|
85810
|
+
return current;
|
|
85811
|
+
}
|
|
85812
|
+
function dropNulls(value, node, root) {
|
|
85813
|
+
if (!isSchema(node))
|
|
85814
|
+
return value;
|
|
85815
|
+
const schema = resolveRef3(node, root);
|
|
85816
|
+
if (Array.isArray(value)) {
|
|
85817
|
+
return isSchema(schema.items) ? value.map((item) => dropNulls(item, schema.items, root)) : value;
|
|
85818
|
+
}
|
|
85819
|
+
if (!isSchema(value) || !isSchema(schema.properties))
|
|
85820
|
+
return value;
|
|
85821
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
85822
|
+
const out = {};
|
|
85823
|
+
for (const [key, child] of Object.entries(value)) {
|
|
85824
|
+
if (child === null && !required.has(key) && key in schema.properties)
|
|
85825
|
+
continue;
|
|
85826
|
+
out[key] = dropNulls(child, schema.properties[key], root);
|
|
85827
|
+
}
|
|
85828
|
+
return out;
|
|
85829
|
+
}
|
|
85830
|
+
function dropOptionalNulls(value, bundled) {
|
|
85831
|
+
return isSchema(bundled) ? dropNulls(value, bundled, bundled) : value;
|
|
85832
|
+
}
|
|
85833
|
+
var NULL_SCHEMA;
|
|
85834
|
+
var init_strict_schema = __esm(() => {
|
|
85835
|
+
NULL_SCHEMA = { type: "null" };
|
|
85836
|
+
});
|
|
85837
|
+
|
|
85717
85838
|
// src/harness/external/prompt.ts
|
|
85718
85839
|
function byteLength(text) {
|
|
85719
85840
|
return Buffer.byteLength(text, "utf8");
|
|
@@ -87661,6 +87782,7 @@ async function superviseExternalRun(input, deps) {
|
|
|
87661
87782
|
if (verdict === "drained") {
|
|
87662
87783
|
return build(reportedExitCode ?? exitCodeFromEvents(events), false);
|
|
87663
87784
|
}
|
|
87785
|
+
const exitedBeforeKill = reportedExitCode;
|
|
87664
87786
|
handle.kill();
|
|
87665
87787
|
const grace = afterMs2(input.killGraceMs ?? DEFAULT_KILL_GRACE_MS, undefined);
|
|
87666
87788
|
const code = await Promise.race([exited, grace.promise]);
|
|
@@ -87668,7 +87790,7 @@ async function superviseExternalRun(input, deps) {
|
|
|
87668
87790
|
if (verdict === "timeout") {
|
|
87669
87791
|
return build(code ?? EXTERNAL_TIMEOUT_EXIT_CODE, true);
|
|
87670
87792
|
}
|
|
87671
|
-
return build(
|
|
87793
|
+
return build(exitedBeforeKill ?? exitCodeFromEvents(events), false);
|
|
87672
87794
|
}
|
|
87673
87795
|
function deferred() {
|
|
87674
87796
|
let resolve = () => {
|
|
@@ -87737,7 +87859,7 @@ function describeError(error) {
|
|
|
87737
87859
|
return "unknown error";
|
|
87738
87860
|
}
|
|
87739
87861
|
}
|
|
87740
|
-
var EXTERNAL_TIMEOUT_EXIT_CODE = 124, STDOUT_HEAD_BYTES, STDOUT_TAIL_BYTES, DEFAULT_KILL_GRACE_MS = 2000, DEFAULT_TERMINAL_SETTLE_MS = 2000, SUPERVISION_TICK_DIVISOR = 4, SUPERVISION_TICK_FLOOR_MS = 5;
|
|
87862
|
+
var EXTERNAL_TIMEOUT_EXIT_CODE = 124, STDOUT_HEAD_BYTES, STDOUT_TAIL_BYTES, DEFAULT_KILL_GRACE_MS = 2000, DEFAULT_TERMINAL_SETTLE_MS = 2000, CODEX_TERMINAL_SETTLE_MS = 1e4, SUPERVISION_TICK_DIVISOR = 4, SUPERVISION_TICK_FLOOR_MS = 5;
|
|
87741
87863
|
var init_supervise = __esm(() => {
|
|
87742
87864
|
init_bounded();
|
|
87743
87865
|
init_bun_spawn_port();
|
|
@@ -88705,6 +88827,22 @@ async function runExternalChild(input, deps) {
|
|
|
88705
88827
|
return refuse2("Error", schemaPrep.reason);
|
|
88706
88828
|
const { schema: resultSchema, schemaText: resultSchemaText, schemaPath: resultSchemaPath, schemaDir } = schemaPrep;
|
|
88707
88829
|
const resultSchemaInline = await prepareInlineSchema(resultSchema);
|
|
88830
|
+
const bundledResultSchema = JSON.parse(resultSchemaInline);
|
|
88831
|
+
const codexStrict = entry.id === "codex-cli";
|
|
88832
|
+
let resultSchemaPathForCodec = resultSchemaPath;
|
|
88833
|
+
if (codexStrict) {
|
|
88834
|
+
resultSchemaPathForCodec = path208.join(schemaDir, STRICT_SCHEMA_FILE);
|
|
88835
|
+
try {
|
|
88836
|
+
await writeFile32(resultSchemaPathForCodec, JSON.stringify(toStrictOutputSchema(bundledResultSchema)), "utf8");
|
|
88837
|
+
} catch (error) {
|
|
88838
|
+
await rm15(schemaDir, { recursive: true, force: true }).catch(() => {
|
|
88839
|
+
return;
|
|
88840
|
+
});
|
|
88841
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88842
|
+
return refuse2("Error", `failed to prepare the required result schema for validation: ${message}`);
|
|
88843
|
+
}
|
|
88844
|
+
}
|
|
88845
|
+
const normalize = codexStrict ? (value) => dropOptionalNulls(value, bundledResultSchema) : undefined;
|
|
88708
88846
|
try {
|
|
88709
88847
|
const assembled = buildExternalPrompt({
|
|
88710
88848
|
taskTitle: input.taskTitle,
|
|
@@ -88731,7 +88869,7 @@ async function runExternalChild(input, deps) {
|
|
|
88731
88869
|
write: sandbox === "worktree-write",
|
|
88732
88870
|
worktreePath: created.path,
|
|
88733
88871
|
prompt: assembled.prompt,
|
|
88734
|
-
validate: (built) => validateStructuredResult(built, resultSchema)
|
|
88872
|
+
validate: (built) => validateStructuredResult(built, resultSchema, normalize)
|
|
88735
88873
|
});
|
|
88736
88874
|
}
|
|
88737
88875
|
const runInput = {
|
|
@@ -88741,7 +88879,7 @@ async function runExternalChild(input, deps) {
|
|
|
88741
88879
|
...input.runtime.model === undefined || input.runtime.model === null ? {} : { model: input.runtime.model },
|
|
88742
88880
|
...input.sessionId === undefined ? {} : { sessionId: input.sessionId },
|
|
88743
88881
|
...input.runtime.maxCostUnits === undefined || input.runtime.maxCostUnits === null ? {} : { maxCostUnits: input.runtime.maxCostUnits },
|
|
88744
|
-
resultSchemaPath,
|
|
88882
|
+
resultSchemaPath: resultSchemaPathForCodec,
|
|
88745
88883
|
resultSchema: resultSchemaInline,
|
|
88746
88884
|
printTimeoutSeconds: Math.ceil(input.timeoutMs / 1000)
|
|
88747
88885
|
};
|
|
@@ -88762,6 +88900,7 @@ async function runExternalChild(input, deps) {
|
|
|
88762
88900
|
timeoutMs: input.timeoutMs,
|
|
88763
88901
|
...entry.maxStderrBytes === undefined ? {} : { maxStderrBytes: entry.maxStderrBytes },
|
|
88764
88902
|
stdin: streaming ? "pipe" : "ignore",
|
|
88903
|
+
...entry.id === "codex-cli" ? { terminalSettleMs: CODEX_TERMINAL_SETTLE_MS } : {},
|
|
88765
88904
|
...streaming ? {
|
|
88766
88905
|
initialStdin: [
|
|
88767
88906
|
codec.encodeStdinMessage(assembled.prompt)
|
|
@@ -88777,8 +88916,14 @@ async function runExternalChild(input, deps) {
|
|
|
88777
88916
|
...deps.onSupervisionTrigger === undefined ? {} : { onSupervisionTrigger: deps.onSupervisionTrigger }
|
|
88778
88917
|
});
|
|
88779
88918
|
const cause = outcome.overflow ?? codec.classifyFailure(outcome);
|
|
88780
|
-
const built = buildOutcome({
|
|
88781
|
-
|
|
88919
|
+
const built = buildOutcome({
|
|
88920
|
+
cause,
|
|
88921
|
+
outcome,
|
|
88922
|
+
argv,
|
|
88923
|
+
worktreePath: created.path,
|
|
88924
|
+
finalMessageOnly: entry.id === "codex-cli"
|
|
88925
|
+
});
|
|
88926
|
+
return await validateStructuredResult(built, resultSchema, normalize);
|
|
88782
88927
|
} finally {
|
|
88783
88928
|
await deps.worktree.remove(input.worktreeId).catch(() => {
|
|
88784
88929
|
return;
|
|
@@ -88790,7 +88935,7 @@ async function runExternalChild(input, deps) {
|
|
|
88790
88935
|
});
|
|
88791
88936
|
}
|
|
88792
88937
|
}
|
|
88793
|
-
async function validateStructuredResult(built, resultSchema) {
|
|
88938
|
+
async function validateStructuredResult(built, resultSchema, normalize) {
|
|
88794
88939
|
if (built.status !== "Completed")
|
|
88795
88940
|
return built;
|
|
88796
88941
|
let parsed;
|
|
@@ -88800,12 +88945,13 @@ async function validateStructuredResult(built, resultSchema) {
|
|
|
88800
88945
|
const message = error instanceof Error ? error.message : String(error);
|
|
88801
88946
|
return structuredResultError(`structured result is not valid JSON: ${message}`, built);
|
|
88802
88947
|
}
|
|
88803
|
-
const
|
|
88948
|
+
const normalized = normalize === undefined ? parsed : normalize(parsed);
|
|
88949
|
+
const validationErrors = await validateJson(normalized, resultSchema);
|
|
88804
88950
|
if (validationErrors.length > 0) {
|
|
88805
88951
|
const detail = validationErrors.slice(0, 3).map((e) => `${e.path}: ${e.message}`).join("; ");
|
|
88806
88952
|
return structuredResultError(`structured result failed subagent-result schema validation: ${detail}`, built);
|
|
88807
88953
|
}
|
|
88808
|
-
return built;
|
|
88954
|
+
return normalized === parsed ? built : { ...built, output: JSON.stringify(normalized) };
|
|
88809
88955
|
}
|
|
88810
88956
|
async function runAcpBranch(args) {
|
|
88811
88957
|
const { input, deps, entry, worktreePath } = args;
|
|
@@ -88865,10 +89011,10 @@ async function runAcpBranch(args) {
|
|
|
88865
89011
|
return { ...final, acp: record };
|
|
88866
89012
|
}
|
|
88867
89013
|
function buildOutcome(args) {
|
|
88868
|
-
const { cause, outcome, argv, worktreePath } = args;
|
|
89014
|
+
const { cause, outcome, argv, worktreePath, finalMessageOnly } = args;
|
|
88869
89015
|
const sessionRef = findSessionRef(outcome.events);
|
|
88870
89016
|
const costUnits = findCostUnits(outcome.events);
|
|
88871
|
-
const text = collectAssistantText(outcome.events);
|
|
89017
|
+
const text = collectAssistantText(outcome.events, finalMessageOnly);
|
|
88872
89018
|
const base = {
|
|
88873
89019
|
argv,
|
|
88874
89020
|
worktreePath,
|
|
@@ -88903,13 +89049,21 @@ function findCostUnits(events) {
|
|
|
88903
89049
|
}
|
|
88904
89050
|
return cost;
|
|
88905
89051
|
}
|
|
88906
|
-
function collectAssistantText(events) {
|
|
89052
|
+
function collectAssistantText(events, finalMessageOnly) {
|
|
88907
89053
|
for (let i = events.length - 1;i >= 0; i -= 1) {
|
|
88908
89054
|
const event = events[i];
|
|
88909
89055
|
if (event?.kind === "child_finished" && event.text !== undefined && event.text.trim().length > 0) {
|
|
88910
89056
|
return event.text.trim();
|
|
88911
89057
|
}
|
|
88912
89058
|
}
|
|
89059
|
+
if (finalMessageOnly) {
|
|
89060
|
+
for (let i = events.length - 1;i >= 0; i -= 1) {
|
|
89061
|
+
const event = events[i];
|
|
89062
|
+
if (event?.kind === "assistant_text" && event.text.trim().length > 0)
|
|
89063
|
+
return event.text.trim();
|
|
89064
|
+
}
|
|
89065
|
+
return "";
|
|
89066
|
+
}
|
|
88913
89067
|
const parts = [];
|
|
88914
89068
|
for (const event of events) {
|
|
88915
89069
|
if (event.kind === "assistant_text")
|
|
@@ -88918,10 +89072,11 @@ function collectAssistantText(events) {
|
|
|
88918
89072
|
return parts.join(`
|
|
88919
89073
|
`).trim();
|
|
88920
89074
|
}
|
|
88921
|
-
var DEFAULT_BUDGET_THRESHOLD_FRACTION = 0.8, DEFAULT_NO_PROGRESS_INTERVAL_MS = 30000, DENIED_CAUSE_MARKERS;
|
|
89075
|
+
var DEFAULT_BUDGET_THRESHOLD_FRACTION = 0.8, DEFAULT_NO_PROGRESS_INTERVAL_MS = 30000, DENIED_CAUSE_MARKERS, STRICT_SCHEMA_FILE = "subagent-result.strict.schema.json";
|
|
88922
89076
|
var init_runtime2 = __esm(() => {
|
|
88923
89077
|
init_contracts();
|
|
88924
89078
|
init_dispatch();
|
|
89079
|
+
init_strict_schema();
|
|
88925
89080
|
init_env();
|
|
88926
89081
|
init_prompt2();
|
|
88927
89082
|
init_registry3();
|
|
@@ -92204,7 +92359,7 @@ function describeValue4(value) {
|
|
|
92204
92359
|
return "null";
|
|
92205
92360
|
return typeof value;
|
|
92206
92361
|
}
|
|
92207
|
-
function
|
|
92362
|
+
function resolveRef4(ref, rootSchema) {
|
|
92208
92363
|
if (ref.startsWith("#/$defs/")) {
|
|
92209
92364
|
const name = ref.replace("#/$defs/", "");
|
|
92210
92365
|
const schema = rootSchema.$defs?.[name];
|
|
@@ -92226,7 +92381,7 @@ function validateAgainstSchema3(value, schema, rootSchema) {
|
|
|
92226
92381
|
}
|
|
92227
92382
|
function walk4(value, schema, valuePath, rootSchema, errors) {
|
|
92228
92383
|
if (schema.$ref) {
|
|
92229
|
-
const resolved =
|
|
92384
|
+
const resolved = resolveRef4(schema.$ref, rootSchema);
|
|
92230
92385
|
walk4(value, resolved.schema, valuePath, resolved.root, errors);
|
|
92231
92386
|
return;
|
|
92232
92387
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.43",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|