@mrciphersmith/keryx 0.3.57 → 0.3.59
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 +3480 -1354
- package/dist/core.js +241 -10
- package/package.json +2 -2
package/dist/core.js
CHANGED
|
@@ -24100,6 +24100,8 @@ __export(exports_service2, {
|
|
|
24100
24100
|
AC_KINDS: () => AC_KINDS,
|
|
24101
24101
|
CONFIRMATION_CAVEAT: () => CONFIRMATION_CAVEAT,
|
|
24102
24102
|
DEFAULT_OUTCOME_AUTHOR: () => DEFAULT_OUTCOME_AUTHOR,
|
|
24103
|
+
ORIGIN_KINDS: () => ORIGIN_KINDS,
|
|
24104
|
+
ORIGIN_READINGS: () => ORIGIN_READINGS,
|
|
24103
24105
|
OUTCOME_AUTHORS: () => OUTCOME_AUTHORS,
|
|
24104
24106
|
OUTCOME_AUTHOR_READINGS: () => OUTCOME_AUTHOR_READINGS,
|
|
24105
24107
|
OUTCOME_HINT: () => OUTCOME_HINT,
|
|
@@ -24119,6 +24121,7 @@ __export(exports_service2, {
|
|
|
24119
24121
|
confirmPreconditionError: () => confirmPreconditionError,
|
|
24120
24122
|
createFlowService: () => createFlowService,
|
|
24121
24123
|
describeAcKind: () => describeAcKind,
|
|
24124
|
+
effectiveOutcomeAuthor: () => effectiveOutcomeAuthor,
|
|
24122
24125
|
evaluatedVerdict: () => evaluatedVerdict,
|
|
24123
24126
|
extractCriterionTokens: () => extractCriterionTokens,
|
|
24124
24127
|
factsOnlyVerdict: () => factsOnlyVerdict,
|
|
@@ -24128,7 +24131,10 @@ __export(exports_service2, {
|
|
|
24128
24131
|
hashDiff: () => hashDiff,
|
|
24129
24132
|
intentNoteForNewFlow: () => intentNoteForNewFlow,
|
|
24130
24133
|
isFrozen: () => isFrozen,
|
|
24134
|
+
isOriginKind: () => isOriginKind,
|
|
24131
24135
|
notCheckableVerdict: () => notCheckableVerdict,
|
|
24136
|
+
originDetailLines: () => originDetailLines,
|
|
24137
|
+
originSummary: () => originSummary,
|
|
24132
24138
|
outcomeBulletsFrom: () => outcomeBulletsFrom,
|
|
24133
24139
|
parseAcceptanceCriteria: () => parseAcceptanceCriteria,
|
|
24134
24140
|
parseOutcomeAuthor: () => parseOutcomeAuthor,
|
|
@@ -24137,12 +24143,15 @@ __export(exports_service2, {
|
|
|
24137
24143
|
readAcCheckEnabled: () => readAcCheckEnabled,
|
|
24138
24144
|
readAcKindRecords: () => readAcKindRecords,
|
|
24139
24145
|
readFlow: () => readFlow,
|
|
24146
|
+
readOrigin: () => readOrigin,
|
|
24147
|
+
readOriginKind: () => readOriginKind,
|
|
24140
24148
|
readOutcomeAuthor: () => readOutcomeAuthor,
|
|
24141
24149
|
renderAcCheckAdvisoryNotice: () => renderAcCheckAdvisoryNotice,
|
|
24142
24150
|
renderAcCheckReport: () => renderAcCheckReport,
|
|
24143
24151
|
renderAcKindDistribution: () => renderAcKindDistribution,
|
|
24144
24152
|
reportFromRecords: () => reportFromRecords,
|
|
24145
24153
|
resolveFlowDir: () => resolveFlowDir,
|
|
24154
|
+
resolveOrigin: () => resolveOrigin,
|
|
24146
24155
|
sectionOf: () => sectionOf,
|
|
24147
24156
|
selectMatchedHunks: () => selectMatchedHunks,
|
|
24148
24157
|
statementFrom: () => statementFrom,
|
|
@@ -25613,6 +25622,129 @@ function parseOutcomeAuthor(raw, flag = "--outcome-author") {
|
|
|
25613
25622
|
const shown = typeof raw === "string" ? `"${raw}"` : "nothing";
|
|
25614
25623
|
throw new Error(`${flag} must be one of: ${OUTCOME_AUTHORS.join(", ")} (got ${shown}).`);
|
|
25615
25624
|
}
|
|
25625
|
+
|
|
25626
|
+
// src/flow/origin.ts
|
|
25627
|
+
var ORIGIN_KINDS = ["human-request", "agent-finding", "agent-proposal"];
|
|
25628
|
+
var ORIGIN_READINGS = [...ORIGIN_KINDS, "unknown"];
|
|
25629
|
+
function isOriginKind(value) {
|
|
25630
|
+
return typeof value === "string" && ORIGIN_KINDS.includes(value);
|
|
25631
|
+
}
|
|
25632
|
+
function nonBlank(value) {
|
|
25633
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
25634
|
+
}
|
|
25635
|
+
function readOrigin(value) {
|
|
25636
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
25637
|
+
return;
|
|
25638
|
+
const raw = value;
|
|
25639
|
+
if (!isOriginKind(raw.kind))
|
|
25640
|
+
return;
|
|
25641
|
+
const origin = { kind: raw.kind };
|
|
25642
|
+
if (typeof raw.quote === "string" && raw.quote.length > 0)
|
|
25643
|
+
origin.quote = raw.quote;
|
|
25644
|
+
if (typeof raw.source === "string" && raw.source.length > 0)
|
|
25645
|
+
origin.source = raw.source;
|
|
25646
|
+
return origin;
|
|
25647
|
+
}
|
|
25648
|
+
function readOriginKind(value) {
|
|
25649
|
+
return readOrigin(value)?.kind ?? "unknown";
|
|
25650
|
+
}
|
|
25651
|
+
function resolveOrigin(input) {
|
|
25652
|
+
if (!isOriginKind(input.kind)) {
|
|
25653
|
+
return {
|
|
25654
|
+
note: `origin kind "${input.kind}" is not one of: ${ORIGIN_KINDS.join(", ")}; origin stays unknown.`
|
|
25655
|
+
};
|
|
25656
|
+
}
|
|
25657
|
+
const hasQuote = nonBlank(input.quote);
|
|
25658
|
+
const hasSource = nonBlank(input.source);
|
|
25659
|
+
if (input.kind === "human-request") {
|
|
25660
|
+
if (!hasQuote && !hasSource) {
|
|
25661
|
+
return { note: "origin human-request needs a verbatim --quote and a --source; neither was given, origin stays unknown." };
|
|
25662
|
+
}
|
|
25663
|
+
if (!hasQuote) {
|
|
25664
|
+
return { note: "origin human-request needs a verbatim --quote of the human's first message; none was given, origin stays unknown." };
|
|
25665
|
+
}
|
|
25666
|
+
if (!hasSource) {
|
|
25667
|
+
return { note: "origin human-request needs a --source (channel, message id or time); none was given, origin stays unknown." };
|
|
25668
|
+
}
|
|
25669
|
+
} else if (!hasSource) {
|
|
25670
|
+
return { note: `origin ${input.kind} needs a --source (the check, review or test that produced it); none was given, origin stays unknown.` };
|
|
25671
|
+
}
|
|
25672
|
+
const origin = { kind: input.kind };
|
|
25673
|
+
if (hasQuote)
|
|
25674
|
+
origin.quote = input.quote;
|
|
25675
|
+
if (hasSource)
|
|
25676
|
+
origin.source = input.source;
|
|
25677
|
+
return { origin };
|
|
25678
|
+
}
|
|
25679
|
+
function effectiveOutcomeAuthor(flow) {
|
|
25680
|
+
const explicit = readOutcomeAuthor(flow.outcomeAuthor);
|
|
25681
|
+
if (explicit !== "unknown")
|
|
25682
|
+
return explicit;
|
|
25683
|
+
return readOrigin(flow.origin) === undefined ? "unknown" : "agent";
|
|
25684
|
+
}
|
|
25685
|
+
function originSummary(origin) {
|
|
25686
|
+
if (origin === undefined)
|
|
25687
|
+
return "unknown";
|
|
25688
|
+
const parts = [origin.kind];
|
|
25689
|
+
if (origin.quote !== undefined)
|
|
25690
|
+
parts.push(`quote: ${JSON.stringify(origin.quote)}`);
|
|
25691
|
+
if (origin.source !== undefined)
|
|
25692
|
+
parts.push(`source: ${origin.source}`);
|
|
25693
|
+
return parts.join("; ");
|
|
25694
|
+
}
|
|
25695
|
+
function originDetailLines(origin, indent = "") {
|
|
25696
|
+
if (origin === undefined)
|
|
25697
|
+
return [`${indent}origin: unknown`];
|
|
25698
|
+
const lines = [`${indent}origin: ${origin.kind}`];
|
|
25699
|
+
if (origin.quote !== undefined) {
|
|
25700
|
+
const [first = "", ...rest] = origin.quote.split(`
|
|
25701
|
+
`);
|
|
25702
|
+
lines.push(`${indent} quote: \xAB${first}`, ...rest.map((line) => `${indent} ${line}`));
|
|
25703
|
+
lines[lines.length - 1] += "\xBB";
|
|
25704
|
+
}
|
|
25705
|
+
if (origin.source !== undefined)
|
|
25706
|
+
lines.push(`${indent} source: ${origin.source}`);
|
|
25707
|
+
return lines;
|
|
25708
|
+
}
|
|
25709
|
+
var REQUEST_LABEL = "\u0417\u0430\u043F\u0440\u043E\u0441 (\u0434\u043E\u0441\u043B\u043E\u0432\u043D\u043E)";
|
|
25710
|
+
var SOURCE_LABEL = "\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A";
|
|
25711
|
+
var FORMALIZATION_LABEL = "\u042D\u0444\u0444\u0435\u043A\u0442 (\u0444\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0430\u0433\u0435\u043D\u0442\u0430)";
|
|
25712
|
+
var OBSERVE_LABEL = "\u041A\u0430\u043A \u043D\u0430\u0431\u043B\u044E\u0434\u0430\u0442\u044C (\u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0430\u0433\u0435\u043D\u0442\u0430)";
|
|
25713
|
+
var REQUEST_PLACEHOLDER = "<the human's request, verbatim, no translation or paraphrase>";
|
|
25714
|
+
var SOURCE_PLACEHOLDER = "<where the finding or proposal came from: check, review, test or discussion>";
|
|
25715
|
+
var FORMALIZATION_PLACEHOLDER = "<the effect that has to be true when this flow is done, in your own words>";
|
|
25716
|
+
var OBSERVE_PLACEHOLDER = "<how the effect can be observed once the flow is done>";
|
|
25717
|
+
var ORIGIN_PLACEHOLDER_BULLETS = [
|
|
25718
|
+
`- ${REQUEST_LABEL}: ${REQUEST_PLACEHOLDER}`,
|
|
25719
|
+
`- ${SOURCE_LABEL}: ${SOURCE_PLACEHOLDER}`,
|
|
25720
|
+
`- ${FORMALIZATION_LABEL}: ${FORMALIZATION_PLACEHOLDER}`,
|
|
25721
|
+
`- ${OBSERVE_LABEL}: ${OBSERVE_PLACEHOLDER}`
|
|
25722
|
+
];
|
|
25723
|
+
function renderOriginBullets(origin) {
|
|
25724
|
+
const first = [];
|
|
25725
|
+
if (origin.kind === "human-request") {
|
|
25726
|
+
first.push(...bulletWithText(REQUEST_LABEL, origin.quote === undefined ? undefined : `\xAB${origin.quote}\xBB`, REQUEST_PLACEHOLDER));
|
|
25727
|
+
if (origin.source !== undefined)
|
|
25728
|
+
first[first.length - 1] += ` (source: ${origin.source})`;
|
|
25729
|
+
} else {
|
|
25730
|
+
first.push(...bulletWithText(SOURCE_LABEL, origin.source, SOURCE_PLACEHOLDER));
|
|
25731
|
+
if (origin.quote !== undefined)
|
|
25732
|
+
first.push(...bulletWithText(REQUEST_LABEL, `\xAB${origin.quote}\xBB`, REQUEST_PLACEHOLDER));
|
|
25733
|
+
}
|
|
25734
|
+
return [
|
|
25735
|
+
...first,
|
|
25736
|
+
`- ${FORMALIZATION_LABEL}: ${FORMALIZATION_PLACEHOLDER}`,
|
|
25737
|
+
`- ${OBSERVE_LABEL}: ${OBSERVE_PLACEHOLDER}`
|
|
25738
|
+
];
|
|
25739
|
+
}
|
|
25740
|
+
function bulletWithText(label, text, placeholder) {
|
|
25741
|
+
if (text === undefined)
|
|
25742
|
+
return [`- ${label}: ${placeholder}`];
|
|
25743
|
+
const lines = text.split(`
|
|
25744
|
+
`);
|
|
25745
|
+
const head = `- ${label}: ${lines[0] ?? ""}`;
|
|
25746
|
+
return [head, ...lines.slice(1).map((line) => ` ${line}`)];
|
|
25747
|
+
}
|
|
25616
25748
|
// src/flow/identity.ts
|
|
25617
25749
|
function resolveSignerIdentity(input) {
|
|
25618
25750
|
const stated = input.stated?.trim();
|
|
@@ -25908,6 +26040,23 @@ function flowStateSchema() {
|
|
|
25908
26040
|
enum: ["agent", "human"],
|
|
25909
26041
|
description: "Who wrote the outcome criterion. Written by `flow init --outcome-author` (default `agent`; `human` only when the flag says so, never inferred) and changed only by `flow outcome author`, which journals the change. Absent on flows created before the field existed, and read as `unknown` (neither agent nor human). Gates nothing."
|
|
25910
26042
|
},
|
|
26043
|
+
origin: {
|
|
26044
|
+
type: "object",
|
|
26045
|
+
additionalProperties: false,
|
|
26046
|
+
required: ["kind"],
|
|
26047
|
+
description: "Where the flow came from. Written by `flow init --origin <kind> [--quote] [--source]` and changed only by `flow origin set`, which journals the change. `human-request` is recorded only with a verbatim quote and a source; `agent-finding` and `agent-proposal` only with a source. Absent on flows created before the field existed and on flows whose evidence was not enough, and read as `unknown`. Gates nothing.",
|
|
26048
|
+
properties: {
|
|
26049
|
+
kind: { type: "string", enum: ["human-request", "agent-finding", "agent-proposal"] },
|
|
26050
|
+
quote: {
|
|
26051
|
+
type: "string",
|
|
26052
|
+
description: "The human's request, verbatim and byte for byte: no translation, no paraphrase."
|
|
26053
|
+
},
|
|
26054
|
+
source: {
|
|
26055
|
+
type: "string",
|
|
26056
|
+
description: "Where the request or finding came from: channel, message id, time, or the check that produced it."
|
|
26057
|
+
}
|
|
26058
|
+
}
|
|
26059
|
+
},
|
|
25911
26060
|
signatures: {
|
|
25912
26061
|
type: "array",
|
|
25913
26062
|
description: "Append-only signing record for `flow ac confirm` and a passing `flow complete`. Absent means never signed under this field's existence.",
|
|
@@ -26845,17 +26994,24 @@ function outcomeBulletsFrom(markdown) {
|
|
|
26845
26994
|
if (body === null)
|
|
26846
26995
|
return null;
|
|
26847
26996
|
const bullets = [];
|
|
26997
|
+
let skipping = false;
|
|
26848
26998
|
for (const line of body.split(/\r?\n/)) {
|
|
26849
26999
|
const bullet = /^\s*[-*]\s+(.*)$/.exec(line);
|
|
26850
27000
|
if ((bullet?.[1] ?? line).trim() === OUTCOME_HINT)
|
|
26851
27001
|
continue;
|
|
26852
|
-
if (bullet !== null)
|
|
26853
|
-
|
|
26854
|
-
|
|
27002
|
+
if (bullet !== null) {
|
|
27003
|
+
skipping = isOriginTemplateBullet(bullet[1] ?? "");
|
|
27004
|
+
if (!skipping)
|
|
27005
|
+
bullets.push((bullet[1] ?? "").trim());
|
|
27006
|
+
} else if (line.trim().length > 0 && !skipping && bullets.length > 0)
|
|
26855
27007
|
bullets[bullets.length - 1] += ` ${line.trim()}`;
|
|
26856
27008
|
}
|
|
26857
27009
|
return bullets.filter((bullet) => bullet.length > 0);
|
|
26858
27010
|
}
|
|
27011
|
+
function isOriginTemplateBullet(text) {
|
|
27012
|
+
const trimmed = text.trim();
|
|
27013
|
+
return trimmed.startsWith(`${REQUEST_LABEL}:`) || trimmed.startsWith(`${SOURCE_LABEL}:`) || ORIGIN_PLACEHOLDER_BULLETS.some((placeholder) => placeholder.slice(2) === trimmed);
|
|
27014
|
+
}
|
|
26859
27015
|
var INIT_INTENT_NOTE = "note: no intent statement extractable from description.md \u2014 the product index will hold no statement for this flow";
|
|
26860
27016
|
function initIntentNote(description) {
|
|
26861
27017
|
return flowStatementFrom(description) === null ? INIT_INTENT_NOTE : null;
|
|
@@ -27417,7 +27573,9 @@ async function flowFoldersInHead(cwd, dirs) {
|
|
|
27417
27573
|
}
|
|
27418
27574
|
|
|
27419
27575
|
// src/flow/templates.ts
|
|
27420
|
-
function renderDescription(title, source) {
|
|
27576
|
+
function renderDescription(title, source, origin) {
|
|
27577
|
+
const outcome = origin === undefined ? OUTCOME_HINT : renderOriginBullets(origin).join(`
|
|
27578
|
+
`);
|
|
27421
27579
|
return `# ${title}
|
|
27422
27580
|
|
|
27423
27581
|
Status: draft (flow-init skill formalizes this)
|
|
@@ -27433,7 +27591,7 @@ What must be true when this flow is done.
|
|
|
27433
27591
|
|
|
27434
27592
|
## Outcome criteria
|
|
27435
27593
|
|
|
27436
|
-
${
|
|
27594
|
+
${outcome}
|
|
27437
27595
|
|
|
27438
27596
|
## Out of Scope
|
|
27439
27597
|
|
|
@@ -27750,7 +27908,24 @@ function createFlowService(deps) {
|
|
|
27750
27908
|
if (input.owner !== undefined && !input.owner.trim()) {
|
|
27751
27909
|
throw new Error(BLANK_OWNER_MESSAGE);
|
|
27752
27910
|
}
|
|
27753
|
-
const outcomeAuthor = input.outcomeAuthor === undefined ?
|
|
27911
|
+
const outcomeAuthor = input.outcomeAuthor === undefined ? undefined : parseOutcomeAuthor(input.outcomeAuthor);
|
|
27912
|
+
let originNote;
|
|
27913
|
+
let origin;
|
|
27914
|
+
let originDraft;
|
|
27915
|
+
if (input.origin !== undefined) {
|
|
27916
|
+
const resolution = resolveOrigin({ kind: input.origin, quote: input.originQuote, source: input.originSource });
|
|
27917
|
+
origin = resolution.origin;
|
|
27918
|
+
originNote = resolution.note;
|
|
27919
|
+
if (isOriginKind(input.origin)) {
|
|
27920
|
+
originDraft = {
|
|
27921
|
+
kind: input.origin,
|
|
27922
|
+
...input.originQuote?.trim() ? { quote: input.originQuote } : {},
|
|
27923
|
+
...input.originSource?.trim() ? { source: input.originSource } : {}
|
|
27924
|
+
};
|
|
27925
|
+
}
|
|
27926
|
+
} else if (input.originQuote !== undefined || input.originSource !== undefined) {
|
|
27927
|
+
originNote = "--quote/--source were given without --origin; origin stays unknown.";
|
|
27928
|
+
}
|
|
27754
27929
|
const trackerReady = deps.tracker ? await deps.tracker.detect() : false;
|
|
27755
27930
|
const tracker = trackerReady ? deps.tracker : null;
|
|
27756
27931
|
const issueRef = input.issue && deps.tracker ? deps.tracker.parseRef(input.issue) : null;
|
|
@@ -27806,12 +27981,13 @@ function createFlowService(deps) {
|
|
|
27806
27981
|
pr: { url: null },
|
|
27807
27982
|
...input.baseBranch === undefined ? {} : { baseBranch: input.baseBranch },
|
|
27808
27983
|
...input.owner?.trim() ? { owner: ownerIdentity(input.owner.trim(), "`--owner` flag on `flow init`") } : {},
|
|
27809
|
-
outcomeAuthor,
|
|
27984
|
+
...outcomeAuthor !== undefined ? { outcomeAuthor } : origin === undefined ? { outcomeAuthor: DEFAULT_OUTCOME_AUTHOR } : {},
|
|
27985
|
+
...origin === undefined ? {} : { origin },
|
|
27810
27986
|
tasks: DEFAULT_TASKS.map((task) => ({ ...task, status: "todo" })),
|
|
27811
27987
|
history: [{ at: createdAt, event: "created" }]
|
|
27812
27988
|
};
|
|
27813
27989
|
const sourceLabel = input.issue ?? "user description";
|
|
27814
|
-
await writeFileAtomic(path56.join(absolute, "description.md"), renderDescription(title, sourceLabel));
|
|
27990
|
+
await writeFileAtomic(path56.join(absolute, "description.md"), renderDescription(title, originDraft === undefined ? sourceLabel : `${sourceLabel} (origin: ${originDraft.kind})`, originDraft));
|
|
27815
27991
|
await writeFileAtomic(path56.join(absolute, "context.md"), context.markdown);
|
|
27816
27992
|
await writeFileAtomic(path56.join(absolute, "plan.md"), renderPlan());
|
|
27817
27993
|
await writeFileAtomic(path56.join(absolute, "tasks.md"), renderTasksDoc());
|
|
@@ -27819,7 +27995,12 @@ function createFlowService(deps) {
|
|
|
27819
27995
|
await writeFileAtomic(path56.join(absolute, "journal.md"), renderJournal(createdAt));
|
|
27820
27996
|
await writeFlow(input.cwd, dir, flow);
|
|
27821
27997
|
await recordAllocation(scope, { id, dir, at: createdAt, project: scope.project });
|
|
27822
|
-
return {
|
|
27998
|
+
return {
|
|
27999
|
+
flow,
|
|
28000
|
+
dir: path56.relative(input.cwd, absolute),
|
|
28001
|
+
contextNotes: context.notes,
|
|
28002
|
+
...originNote === undefined ? {} : { originNote }
|
|
28003
|
+
};
|
|
27823
28004
|
});
|
|
27824
28005
|
},
|
|
27825
28006
|
async list({ cwd }) {
|
|
@@ -27883,6 +28064,50 @@ function createFlowService(deps) {
|
|
|
27883
28064
|
});
|
|
27884
28065
|
return { flow, previous, changed };
|
|
27885
28066
|
},
|
|
28067
|
+
async originSet({ cwd, id, kind, reason, quote, source }) {
|
|
28068
|
+
if (!reason?.trim()) {
|
|
28069
|
+
throw new Error('flow origin set requires --reason "<why>"');
|
|
28070
|
+
}
|
|
28071
|
+
validateSingleLineReason(reason);
|
|
28072
|
+
let previous = "unknown";
|
|
28073
|
+
let next = "unknown";
|
|
28074
|
+
let changed = false;
|
|
28075
|
+
let note;
|
|
28076
|
+
const flow = await mutate(cwd, id, async ({ dir, flow: current }) => {
|
|
28077
|
+
const before = readOrigin(current.origin);
|
|
28078
|
+
previous = before?.kind ?? "unknown";
|
|
28079
|
+
let after;
|
|
28080
|
+
if (kind !== "unknown" && !isOriginKind(kind)) {
|
|
28081
|
+
note = `origin kind must be one of: human-request, agent-finding, agent-proposal, unknown (got "${kind}"); the origin is unchanged.`;
|
|
28082
|
+
next = previous;
|
|
28083
|
+
return current;
|
|
28084
|
+
}
|
|
28085
|
+
if (kind !== "unknown") {
|
|
28086
|
+
const resolution = resolveOrigin({
|
|
28087
|
+
kind,
|
|
28088
|
+
quote: quote !== undefined && quote.length > 0 ? quote : before?.quote,
|
|
28089
|
+
source: source !== undefined && source.length > 0 ? source : before?.source
|
|
28090
|
+
});
|
|
28091
|
+
if (resolution.origin === undefined) {
|
|
28092
|
+
note = resolution.note;
|
|
28093
|
+
next = previous;
|
|
28094
|
+
return current;
|
|
28095
|
+
}
|
|
28096
|
+
after = resolution.origin;
|
|
28097
|
+
}
|
|
28098
|
+
next = after?.kind ?? "unknown";
|
|
28099
|
+
if (JSON.stringify(before ?? null) === JSON.stringify(after ?? null)) {
|
|
28100
|
+
return current;
|
|
28101
|
+
}
|
|
28102
|
+
changed = true;
|
|
28103
|
+
if (after === undefined)
|
|
28104
|
+
delete current.origin;
|
|
28105
|
+
else
|
|
28106
|
+
current.origin = after;
|
|
28107
|
+
return save(cwd, dir, current, "origin-set", `${originSummary(before)} -> ${originSummary(after)} (${reason.trim()})`);
|
|
28108
|
+
});
|
|
28109
|
+
return { flow, previous, next, changed, ...note === undefined ? {} : { note } };
|
|
28110
|
+
},
|
|
27886
28111
|
async freeze({ cwd, id }) {
|
|
27887
28112
|
return mutate(cwd, id, async ({ dir, flow }) => {
|
|
27888
28113
|
assertTransition(flow.status, "ready");
|
|
@@ -41023,6 +41248,12 @@ var HELP_GROUPS = [
|
|
|
41023
41248
|
group: "Managed work",
|
|
41024
41249
|
summary: "List doc sections that likely went stale because of the working diff, with Jev."
|
|
41025
41250
|
},
|
|
41251
|
+
{
|
|
41252
|
+
kind: "slash",
|
|
41253
|
+
name: "/flow",
|
|
41254
|
+
group: "Managed work",
|
|
41255
|
+
summary: `Show a flow's origin, or set it with a reason \u2014 /flow origin [<id>] | /flow origin <id> <kind> --reason "...".`
|
|
41256
|
+
},
|
|
41026
41257
|
{
|
|
41027
41258
|
kind: "slash",
|
|
41028
41259
|
name: "/opencomments",
|
|
@@ -41082,7 +41313,7 @@ var HELP_GROUPS = [
|
|
|
41082
41313
|
kind: "cli",
|
|
41083
41314
|
name: "schedule",
|
|
41084
41315
|
group: "Automation",
|
|
41085
|
-
summary: "Scheduled agent tasks in the background: create (with confirmation), list, pause, resume, remove."
|
|
41316
|
+
summary: "Scheduled agent tasks in the background: create (with confirmation), list, pause, resume, remove; `add --digest` makes a GitHub and board digest that `keryx serve` sends to Telegram."
|
|
41086
41317
|
},
|
|
41087
41318
|
{
|
|
41088
41319
|
kind: "cli",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.59",
|
|
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": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"test:client:terminal": "bun test src/tui/ src/commands/shell",
|
|
50
50
|
"test:client:streaming": "bun test src/harness/provider/",
|
|
51
51
|
"test:client:cancel-resume": "bun test src/harness/run/ src/harness/resume/ src/harness/session/ src/session/ src/bus/ src/rewind/ src/remote/ src/docs/ src/commands/sessions",
|
|
52
|
-
"test:client:runtime": "bun test src/harness/ src/mcp-client/ src/mcp-servers/ src/agents/ src/commands/agent src/commands/harness src/commands/providers",
|
|
52
|
+
"test:client:runtime": "bun test src/harness/ src/mcp-client/ src/mcp-servers/ src/agents/ src/commands/agent src/commands/harness src/commands/providers src/scheduler/",
|
|
53
53
|
"test:client": "bun run test:client:terminal && bun run test:client:streaming && bun run test:client:cancel-resume && bun run test:client:runtime",
|
|
54
54
|
"check": "bun run lint && bun run typecheck && bun run typecheck:scripts && bun test",
|
|
55
55
|
"check:core": "bun run lint && bun run typecheck && bun run typecheck:scripts && bun run test:core",
|