@mrciphersmith/keryx 0.2.47 → 0.2.48

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.
Files changed (2) hide show
  1. package/dist/cli.js +87 -3
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -15225,6 +15225,17 @@ async function writeUnboundCandidateArtifact(dir, trigger, now, grouped, nonEmpt
15225
15225
  await writeFileAtomic(path74.join(archiveDir, filename), `${JSON.stringify(content, null, 2)}
15226
15226
  `);
15227
15227
  }
15228
+ async function writeWrapUpOutcomeArtifact(dir, trigger, now, groups) {
15229
+ try {
15230
+ const archiveDir = path74.join(dir, "slate-archive");
15231
+ await mkdir28(archiveDir, { recursive: true });
15232
+ const nowIso2 = now().toISOString();
15233
+ const filename = `${nowIso2.replace(/[:.]/g, "-")}-wrap-up-outcome.json`;
15234
+ const content = { recordType: "wrap-up-outcome", trigger, generatedAt: nowIso2, groups };
15235
+ await writeFileAtomic(path74.join(archiveDir, filename), `${JSON.stringify(content, null, 2)}
15236
+ `);
15237
+ } catch {}
15238
+ }
15228
15239
  async function proposeOneGroup(params) {
15229
15240
  try {
15230
15241
  const resolved = await resolveMachineWrapUp({
@@ -15293,7 +15304,9 @@ async function runWrapUp(input2) {
15293
15304
  }
15294
15305
  if (input2.slate.workspaceId === undefined) {
15295
15306
  await writeUnboundCandidateArtifact(input2.dir, input2.trigger, now, grouped, nonEmptyKinds);
15296
- return { groups: nonEmptyKinds.map((kind) => ({ kind, outcome: "unbound-candidate" })) };
15307
+ const groups2 = nonEmptyKinds.map((kind) => ({ kind, outcome: "unbound-candidate" }));
15308
+ await writeWrapUpOutcomeArtifact(input2.dir, input2.trigger, now, groups2);
15309
+ return { groups: groups2 };
15297
15310
  }
15298
15311
  const workspaceId = input2.slate.workspaceId;
15299
15312
  const groups = await Promise.all(nonEmptyKinds.map((kind) => proposeOneGroup({
@@ -15306,6 +15319,7 @@ async function runWrapUp(input2) {
15306
15319
  ...input2.providerFactory !== undefined ? { providerFactory: input2.providerFactory } : {},
15307
15320
  ...input2.modelTurnTimeoutMs !== undefined ? { modelTurnTimeoutMs: input2.modelTurnTimeoutMs } : {}
15308
15321
  })));
15322
+ await writeWrapUpOutcomeArtifact(input2.dir, input2.trigger, now, groups);
15309
15323
  return { groups };
15310
15324
  }
15311
15325
  var execFileAsync, WRAP_UP_TTL_MS, DEFAULT_MODEL_TURN_TIMEOUT_MS = 30000;
@@ -49447,7 +49461,7 @@ import { spawnSync as spawnSync2 } from "child_process";
49447
49461
  // package.json
49448
49462
  var package_default = {
49449
49463
  name: "@mrciphersmith/keryx",
49450
- version: "0.2.47",
49464
+ version: "0.2.48",
49451
49465
  description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
49452
49466
  private: false,
49453
49467
  publishConfig: {
@@ -50797,6 +50811,20 @@ async function classifySession(session) {
50797
50811
  item: { type: "unbound-candidate", sessionId: session.id, evidencePath: unboundCandidate.evidencePath, summary: unboundCandidate.summary }
50798
50812
  };
50799
50813
  }
50814
+ const wrapUpOutcome = await readNewestWrapUpOutcome(dir);
50815
+ if (wrapUpOutcome !== undefined && wrapUpOutcome.groups.every(isFailureOutcome)) {
50816
+ const workspaceId2 = (await safeReadSlate(dir))?.workspaceId;
50817
+ return {
50818
+ kind: "unknown",
50819
+ item: {
50820
+ type: "unknown",
50821
+ sessionId: session.id,
50822
+ ...workspaceId2 !== undefined ? { workspaceId: workspaceId2 } : {},
50823
+ lastSeenAt: session.updatedAt,
50824
+ wrapUpOutcome: { trigger: wrapUpOutcome.trigger, generatedAt: wrapUpOutcome.generatedAt, groups: wrapUpOutcome.groups }
50825
+ }
50826
+ };
50827
+ }
50800
50828
  if (!await isSlateEngaged(dir))
50801
50829
  return;
50802
50830
  const workspaceId = (await safeReadSlate(dir))?.workspaceId;
@@ -50883,6 +50911,37 @@ function summarizeUnboundCandidate(groups) {
50883
50911
  const kinds = safeGroups.map((group) => typeof group.kind === "string" ? group.kind : "unknown").join(", ");
50884
50912
  return `${seedCount} untriaged seed(s) across ${safeGroups.length} kind(s) (${kinds})`;
50885
50913
  }
50914
+ function isFailureOutcome(g) {
50915
+ return g.outcome === "error" || g.outcome === "no_credential" || g.outcome === "conflict";
50916
+ }
50917
+ async function readNewestWrapUpOutcome(dir) {
50918
+ const archiveDir = path145.join(dir, "slate-archive");
50919
+ let entries;
50920
+ try {
50921
+ entries = (await readdir24(archiveDir)).filter((name) => name.endsWith("-wrap-up-outcome.json"));
50922
+ } catch {
50923
+ return;
50924
+ }
50925
+ entries.sort();
50926
+ for (let i = entries.length - 1;i >= 0; i--) {
50927
+ const evidencePath = path145.join(archiveDir, entries[i]);
50928
+ const result = readConfigFile(evidencePath);
50929
+ if (!result.ok) {
50930
+ continue;
50931
+ }
50932
+ try {
50933
+ const parsed = JSON.parse(result.text);
50934
+ if (parsed.recordType !== "wrap-up-outcome")
50935
+ continue;
50936
+ if (typeof parsed.trigger !== "string" || typeof parsed.generatedAt !== "string" || !Array.isArray(parsed.groups))
50937
+ continue;
50938
+ return { trigger: parsed.trigger, generatedAt: parsed.generatedAt, groups: parsed.groups };
50939
+ } catch {
50940
+ continue;
50941
+ }
50942
+ }
50943
+ return;
50944
+ }
50886
50945
 
50887
50946
  // src/tui/inspector-sources.ts
50888
50947
  init_slate();
@@ -51650,7 +51709,14 @@ function describeReviewItem(item) {
51650
51709
  `Bind: keryx workspace propose <workspace-id> --kind <kind> --session ${item.sessionId}`
51651
51710
  ];
51652
51711
  case "unknown":
51653
- return [
51712
+ return item.wrapUpOutcome !== undefined ? [
51713
+ `Session ${item.sessionId}${item.workspaceId !== undefined ? ` (workspace ${item.workspaceId})` : ""}`,
51714
+ `Last seen ${item.lastSeenAt}`,
51715
+ `Wrap-up dispatch (${item.wrapUpOutcome.trigger}, ${item.wrapUpOutcome.generatedAt}) did not produce a proposal or unbound-candidate:`,
51716
+ ...item.wrapUpOutcome.groups.map((g) => ` ${g.kind}: ${describeGroupOutcome(g)}`),
51717
+ "",
51718
+ `Investigate: keryx sessions list / keryx shell -r ${item.sessionId}`
51719
+ ] : [
51654
51720
  `Session ${item.sessionId}${item.workspaceId !== undefined ? ` (workspace ${item.workspaceId})` : ""}`,
51655
51721
  `Last seen ${item.lastSeenAt}`,
51656
51722
  "No proposal, terminal state, or unbound-candidate artifact recorded.",
@@ -51659,6 +51725,24 @@ function describeReviewItem(item) {
51659
51725
  ];
51660
51726
  }
51661
51727
  }
51728
+ function describeGroupOutcome(g) {
51729
+ switch (g.outcome) {
51730
+ case "error":
51731
+ return g.message;
51732
+ case "no_credential":
51733
+ return "no model credential available";
51734
+ case "conflict":
51735
+ return "a concurrent proposal already claimed this slot";
51736
+ case "proposed":
51737
+ return `proposed (${g.proposalId})`;
51738
+ case "unbound-candidate":
51739
+ return "unbound candidate";
51740
+ default: {
51741
+ const exhaustive = g;
51742
+ return `unrecognized outcome: ${JSON.stringify(exhaustive)}`;
51743
+ }
51744
+ }
51745
+ }
51662
51746
  function formatReviewDetailLines(item, status) {
51663
51747
  if (item === undefined) {
51664
51748
  return ["No item selected.", "", "Press Enter (or click a row) on the Review tab to view one."];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.47",
3
+ "version": "0.2.48",
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": {