@latysh-development/monolith 0.1.0-alpha.0 → 0.1.0-alpha.1

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 (100) hide show
  1. package/README.md +63 -16
  2. package/dist/brief/collect.d.ts.map +1 -1
  3. package/dist/brief/collect.js +41 -1
  4. package/dist/brief/constants.d.ts +2 -0
  5. package/dist/brief/constants.d.ts.map +1 -1
  6. package/dist/brief/constants.js +2 -0
  7. package/dist/brief/render.d.ts +7 -0
  8. package/dist/brief/render.d.ts.map +1 -1
  9. package/dist/brief/render.js +52 -1
  10. package/dist/brief/types.d.ts +17 -1
  11. package/dist/brief/types.d.ts.map +1 -1
  12. package/dist/cli/index.js +33 -0
  13. package/dist/discovery/compose.d.ts +28 -0
  14. package/dist/discovery/compose.d.ts.map +1 -0
  15. package/dist/discovery/compose.js +159 -0
  16. package/dist/discovery/contracts.d.ts +211 -0
  17. package/dist/discovery/contracts.d.ts.map +1 -0
  18. package/dist/discovery/contracts.js +555 -0
  19. package/dist/discovery/docs.d.ts +278 -0
  20. package/dist/discovery/docs.d.ts.map +1 -0
  21. package/dist/discovery/docs.js +1182 -0
  22. package/dist/discovery/facts.d.ts +49 -0
  23. package/dist/discovery/facts.d.ts.map +1 -0
  24. package/dist/discovery/facts.js +541 -0
  25. package/dist/discovery/index.d.ts +8 -0
  26. package/dist/discovery/index.d.ts.map +1 -0
  27. package/dist/discovery/index.js +9 -0
  28. package/dist/discovery/orchestrate.d.ts +35 -0
  29. package/dist/discovery/orchestrate.d.ts.map +1 -0
  30. package/dist/discovery/orchestrate.js +32 -0
  31. package/dist/discovery/render.d.ts +36 -0
  32. package/dist/discovery/render.d.ts.map +1 -0
  33. package/dist/discovery/render.js +278 -0
  34. package/dist/discovery/traverse.d.ts +197 -0
  35. package/dist/discovery/traverse.d.ts.map +1 -0
  36. package/dist/discovery/traverse.js +510 -0
  37. package/dist/durable/errors.d.ts +6 -2
  38. package/dist/durable/errors.d.ts.map +1 -1
  39. package/dist/durable/errors.js +9 -3
  40. package/dist/durable/fs-store.d.ts +21 -0
  41. package/dist/durable/fs-store.d.ts.map +1 -1
  42. package/dist/durable/fs-store.js +103 -3
  43. package/dist/durable/prune-check.d.ts +17 -0
  44. package/dist/durable/prune-check.d.ts.map +1 -1
  45. package/dist/durable/prune-check.js +27 -0
  46. package/dist/durable/runtime.d.ts +5 -3
  47. package/dist/durable/runtime.d.ts.map +1 -1
  48. package/dist/durable/runtime.js +23 -6
  49. package/dist/durable/seams.d.ts +4 -0
  50. package/dist/durable/seams.d.ts.map +1 -1
  51. package/dist/durable/testing.js +2 -2
  52. package/dist/ideas/cli.d.ts +33 -0
  53. package/dist/ideas/cli.d.ts.map +1 -0
  54. package/dist/ideas/cli.js +158 -0
  55. package/dist/ideas/format.d.ts +38 -0
  56. package/dist/ideas/format.d.ts.map +1 -0
  57. package/dist/ideas/format.js +194 -0
  58. package/dist/ideas/index.d.ts +6 -0
  59. package/dist/ideas/index.d.ts.map +1 -0
  60. package/dist/ideas/index.js +3 -0
  61. package/dist/ideas/store.d.ts +55 -0
  62. package/dist/ideas/store.d.ts.map +1 -0
  63. package/dist/ideas/store.js +262 -0
  64. package/dist/ideas/types.d.ts +54 -0
  65. package/dist/ideas/types.d.ts.map +1 -0
  66. package/dist/ideas/types.js +26 -0
  67. package/dist/index.d.ts +1 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +2 -0
  70. package/dist/init/scaffold.d.ts +4 -0
  71. package/dist/init/scaffold.d.ts.map +1 -1
  72. package/dist/init/scaffold.js +6 -2
  73. package/dist/managed/index.d.ts +73 -0
  74. package/dist/managed/index.d.ts.map +1 -0
  75. package/dist/managed/index.js +222 -0
  76. package/dist/root/index.d.ts +7 -0
  77. package/dist/root/index.d.ts.map +1 -1
  78. package/dist/root/index.js +13 -1
  79. package/dist/update/cli.d.ts +8 -0
  80. package/dist/update/cli.d.ts.map +1 -0
  81. package/dist/update/cli.js +115 -0
  82. package/dist/update/index.d.ts +78 -0
  83. package/dist/update/index.d.ts.map +1 -0
  84. package/dist/update/index.js +285 -0
  85. package/dist/version.d.ts +1 -1
  86. package/dist/version.js +1 -1
  87. package/package.json +1 -1
  88. package/templates/default-instance/instruction/.cursorrules +6 -0
  89. package/templates/default-instance/instruction/.windsurfrules +6 -0
  90. package/templates/default-instance/instruction/CLAUDE.md +4 -0
  91. package/templates/default-instance/managed/agent.md +20 -0
  92. package/templates/default-instance/managed/bootstrap.md +7 -0
  93. package/templates/default-instance/managed/index-idea.md +5 -0
  94. package/templates/default-instance/managed/routing-idea.md +14 -0
  95. package/templates/default-instance/monolith/AGENT.md +1 -0
  96. package/templates/default-instance/monolith/context/maps/routing-map.md +4 -0
  97. package/templates/default-instance/monolith/context/maps/semantic-map.md +2 -0
  98. package/templates/default-instance/monolith/skills/INDEX.md +4 -0
  99. package/templates/default-instance/monolith/skills/idea-capture/SKILL.md +157 -0
  100. package/templates/default-instance/projectroot/AGENTS.md +4 -0
@@ -36,7 +36,7 @@ import { dirname, join } from 'path';
36
36
  import { sha256Hex } from './canonical.js';
37
37
  import { LogCorruptError, PruneAttemptLimitError, PruneDecisionCorruptError, RetentionRefusedError, StoreIoError, StoreProtocolError, StoreSecurityError, TaskPrunedError, TombstoneCommittedError, } from './errors.js';
38
38
  import { MAX_REGISTER_BYTES, MAX_WRITE_RESOLVE, PROTOCOL_MARKER_FILE, STAGING_RE, TOMBSTONE_FILE, decisionFile, derivePruneState, encodeDecision, encodePrepare, encodeTombstone, parseDecision, parsePrepare, parseTombstoneFile, prepareFile, sameTombstone, } from './register.js';
39
- import { tombstoneProblem } from './prune-check.js';
39
+ import { committedProblem, tombstoneProblem } from './prune-check.js';
40
40
  import { takeFsSeams } from './seams.js';
41
41
  import { MAX_EVENT_BYTES, ID_PATTERN, parseEvent, serializeEvent } from './log.js';
42
42
  import { MAX_PRUNE_ATTEMPTS } from './types.js';
@@ -48,6 +48,8 @@ const SEGMENT_NAME = /^S(\d{9})-(\d{9})\.jsonl$/;
48
48
  const REF_NAME = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}\.json$/;
49
49
  const TMP_NAME = STAGING_RE;
50
50
  const TOMBSTONE_NAME = TOMBSTONE_FILE;
51
+ /** how often the audit of a committed prune looks at a log with a gap and no tombstone before it refuses (I-1). */
52
+ const AUDIT_PASSES = 3;
51
53
  const MAX_TOMBSTONE_BYTES = 4096;
52
54
  const READ_ATTEMPTS = 8;
53
55
  export class AppendOutcomeUnknownError extends StoreIoError {
@@ -470,7 +472,7 @@ export class FsEventStore {
470
472
  case 'missing':
471
473
  return new PruneDecisionCorruptError(taskId, 'task-dir-missing');
472
474
  case 'unreadable':
473
- return new StoreIoError(`the prune state of task "${taskId}" cannot be read now (${st.reason ?? 'unknown'}); nothing was changed. Try again.`);
475
+ return new StoreIoError(`the prune state of task "${taskId}" cannot be read now (${st.reason ?? 'unknown'}); this refusal removes and undoes nothing. Try again.`);
474
476
  case 'committed':
475
477
  return new TaskPrunedError(taskId);
476
478
  default:
@@ -670,8 +672,106 @@ export class FsEventStore {
670
672
  }
671
673
  if (committed === null)
672
674
  throw new StoreIoError(`the prune state of task "${taskId}" kept changing; try again.`);
675
+ this.auditCommitted(taskId, committed);
673
676
  return this.rollForward(taskId, committed);
674
677
  }
678
+ /**
679
+ * The events (and covered segment lines) still on disk with `seq <= upTo`, each verified on its own; no gap is an error,
680
+ * because a roll-forward that was interrupted leaves gaps. A segment wins over a loose copy of the same slot (the reader's
681
+ * rule). Anything that cannot be read safely or does not verify throws: the audit then refuses instead of guessing.
682
+ */
683
+ survivingEvents(taskId, upTo) {
684
+ const bySeq = new Map();
685
+ // ORDER MATTERS (F-1), the same as in `readLogImpl`: loose files first, segments second. Compaction publishes a segment
686
+ // BEFORE it removes the loose files it covers and nothing but the roll-forward of a prune ever removes a segment (and that
687
+ // publishes the tombstone first, which `auditCommitted` reads afterwards). So a slot that is missing from the loose
688
+ // files, or whose file vanishes before it is read, was removed after its segment was published, and the segment is in
689
+ // the listing taken afterwards. The other order cannot see a segment that is published between the two listings.
690
+ const eventEntries = this.listDir(this.eventsDir(taskId)) ?? [];
691
+ this.seams.auditHook?.('listed');
692
+ for (const e of eventEntries) {
693
+ const m = EVENT_NAME.exec(e.name);
694
+ if (!m || !e.isFile() || Number(m[1]) > upTo)
695
+ continue; // only regular event files are ever read, and nothing past the head is evidence
696
+ const seq = Number(m[1]);
697
+ const content = this.readManaged(join(this.eventsDir(taskId), e.name), `event ${e.name}`, MAX_EVENT_BYTES + 4096, taskId);
698
+ if (content === null)
699
+ continue; // removed meanwhile: a compaction published its segment first, and it is listed below
700
+ const ev = parseEvent(content.trim(), taskId, seq);
701
+ if (ev.seq !== seq)
702
+ throw new LogCorruptError(taskId, seq, `file ${e.name} holds event ${ev.seq}`);
703
+ bySeq.set(seq, ev);
704
+ }
705
+ const segs = [];
706
+ for (const e of this.listDir(this.segmentsDir(taskId)) ?? []) {
707
+ const m = SEGMENT_NAME.exec(e.name);
708
+ if (m && e.isFile() && Number(m[1]) <= upTo)
709
+ segs.push({ name: e.name, from: Number(m[1]), to: Number(m[2]) });
710
+ }
711
+ for (const g of segs) {
712
+ const content = this.readManaged(join(this.segmentsDir(taskId), g.name), `segment ${g.name}`, MAX_SEGMENT_BYTES, taskId);
713
+ if (content === null)
714
+ continue;
715
+ const lines = content.split('\n').filter((l) => l.length > 0);
716
+ if (lines.length !== g.to - g.from + 1)
717
+ throw new LogCorruptError(taskId, g.from, `segment ${g.name} holds ${lines.length} events, its name says ${g.to - g.from + 1}`);
718
+ lines.forEach((line, i) => {
719
+ const ev = parseEvent(line, taskId, g.from + i);
720
+ if (ev.seq !== g.from + i)
721
+ throw new LogCorruptError(taskId, ev.seq, `segment ${g.name} is not contiguous`);
722
+ if (ev.seq <= upTo)
723
+ bySeq.set(ev.seq, ev);
724
+ });
725
+ }
726
+ return [...bySeq.values()].sort((a, b) => a.seq - b.seq);
727
+ }
728
+ /**
729
+ * O-1: a committed register is not self-proving (its checksum is unkeyed), so the data still on disk must not contradict
730
+ * it before anything is unlinked. See `committedProblem` for what a partly removed log can and cannot prove. Reads only.
731
+ *
732
+ * I-1: the data is read FIRST and `tombstone.json` AFTER it. The roll-forward publishes the tombstone before its first
733
+ * unlink and nothing ever removes it, so a tombstone that is still absent after the data was read proves that no unlink
734
+ * had begun when the data was read (it was absent at every earlier moment too): a gap in the data is then not a removal
735
+ * but a torn observation or real damage. The loose files are read before the segments are listed (see `survivingEvents`), so a
736
+ * compaction that moves events into a segment meanwhile does not tear the observation. Read the
737
+ * other way round, a concurrent pruner that publishes the tombstone and removes events between the two reads is taken
738
+ * for damage. A gap seen without a tombstone is still looked at again a few times before it is refused (a defence in depth,
739
+ * not what F-1 relies on). No lock: a pruner that races this audit only ever turns the verdict
740
+ * from "the whole log must be there" into "a part may be gone", and the roll-forward still checks the tombstone it finds.
741
+ */
742
+ auditCommitted(taskId, tombstone) {
743
+ let problem = null;
744
+ for (let pass = 0; pass < AUDIT_PASSES; pass++) {
745
+ let events = null;
746
+ try {
747
+ events = this.survivingEvents(taskId, tombstone.headSeq);
748
+ }
749
+ catch (err) {
750
+ if (!(err instanceof LogCorruptError))
751
+ throw err;
752
+ problem = err.message; // an event that does not verify on its own does not heal
753
+ break;
754
+ }
755
+ this.seams.auditHook?.('surveyed');
756
+ const published = this.registerIO(taskId).tombstone();
757
+ if (published.k === 'ioerr')
758
+ throw new StoreIoError(`cannot read tombstone.json of task "${taskId}": ${published.reason}; this call removed no task data. Try again.`);
759
+ const deletionStarted = published.k !== 'absent'; // the roll-forward publishes it before its first unlink
760
+ try {
761
+ problem = committedProblem(taskId, events, tombstone, deletionStarted);
762
+ }
763
+ catch (err) {
764
+ if (!(err instanceof LogCorruptError))
765
+ throw err;
766
+ problem = err.message;
767
+ break;
768
+ }
769
+ if (problem === null || deletionStarted)
770
+ break; // with a tombstone the verdict is already the lenient one
771
+ }
772
+ if (problem !== null)
773
+ throw new PruneDecisionCorruptError(taskId, 'commit-audit', null, null, false, problem);
774
+ }
675
775
  /**
676
776
  * Prune cleanup (class C, section 30.3): only for a verified, consistent `COMMITTED`. Publishes `tombstone.json` from the
677
777
  * commit, then removes the data of the task. It never touches the register, `tombstone.json` or the task directory,
@@ -703,7 +803,7 @@ export class FsEventStore {
703
803
  continue;
704
804
  }
705
805
  try {
706
- fs.unlinkSync(join(dir, e.name));
806
+ (this.seams.removeFile ?? fs.unlinkSync)(join(dir, e.name));
707
807
  removed++;
708
808
  }
709
809
  catch (err) {
@@ -14,4 +14,21 @@ export declare function tombstoneFor(state: TaskState, prunedAt: string): Tombst
14
14
  * clock and is not compared.
15
15
  */
16
16
  export declare function tombstoneProblem(taskId: string, events: readonly TaskEvent[], t: Tombstone): string | null;
17
+ /**
18
+ * Why a COMMITTED prune must not be rolled forward over the data that is still on disk, or `null` when it may.
19
+ * `events` are the surviving events with `seq <= t.headSeq`, each verified on its own (`parseEvent`), at most one per seq.
20
+ * Events beyond the committed head are stragglers of appends that lost against the commit (G2 reports them as pruned but
21
+ * leaves the file): they are deleted with the rest and are not evidence either way.
22
+ *
23
+ * What the data can prove depends on whether the roll-forward has begun. It publishes `tombstone.json` BEFORE its first
24
+ * unlink, so a log with a part missing and no `tombstone.json` was not removed by a roll-forward:
25
+ * - `deletionStarted` is false: nothing may be missing. The whole prefix `1..headSeq` must be there and is judged exactly
26
+ * like a prepare (`tombstoneProblem`: a finished task with the tombstone's head). A register forged for an active task,
27
+ * or one that names a head the log does not have, is caught here, before the first unlink;
28
+ * - `deletionStarted` is true: a roll-forward deletes in directory order, so any part of the log may be gone and no check
29
+ * may demand the whole of it. The head slot, if it survives, must be the head the commit names; a complete prefix is
30
+ * judged as above; a partial one has nothing that contradicts the commit, and a part cannot prove the rest.
31
+ * Throws `LogCorruptError` when a complete prefix does not verify.
32
+ */
33
+ export declare function committedProblem(taskId: string, events: readonly TaskEvent[], t: Tombstone, deletionStarted: boolean): string | null;
17
34
  //# sourceMappingURL=prune-check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prune-check.d.ts","sourceRoot":"","sources":["../../src/durable/prune-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAExF,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAGxD;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAK1E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAW1G"}
1
+ {"version":3,"file":"prune-check.d.ts","sourceRoot":"","sources":["../../src/durable/prune-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAExF,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAGxD;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAK1E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAW1G;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOpI"}
@@ -43,3 +43,30 @@ export function tombstoneProblem(taskId, events, t) {
43
43
  return 'the tombstone outcome digest is not the digest of the final outcome';
44
44
  return null;
45
45
  }
46
+ /**
47
+ * Why a COMMITTED prune must not be rolled forward over the data that is still on disk, or `null` when it may.
48
+ * `events` are the surviving events with `seq <= t.headSeq`, each verified on its own (`parseEvent`), at most one per seq.
49
+ * Events beyond the committed head are stragglers of appends that lost against the commit (G2 reports them as pruned but
50
+ * leaves the file): they are deleted with the rest and are not evidence either way.
51
+ *
52
+ * What the data can prove depends on whether the roll-forward has begun. It publishes `tombstone.json` BEFORE its first
53
+ * unlink, so a log with a part missing and no `tombstone.json` was not removed by a roll-forward:
54
+ * - `deletionStarted` is false: nothing may be missing. The whole prefix `1..headSeq` must be there and is judged exactly
55
+ * like a prepare (`tombstoneProblem`: a finished task with the tombstone's head). A register forged for an active task,
56
+ * or one that names a head the log does not have, is caught here, before the first unlink;
57
+ * - `deletionStarted` is true: a roll-forward deletes in directory order, so any part of the log may be gone and no check
58
+ * may demand the whole of it. The head slot, if it survives, must be the head the commit names; a complete prefix is
59
+ * judged as above; a partial one has nothing that contradicts the commit, and a part cannot prove the rest.
60
+ * Throws `LogCorruptError` when a complete prefix does not verify.
61
+ */
62
+ export function committedProblem(taskId, events, t, deletionStarted) {
63
+ if (events.length === 0)
64
+ return deletionStarted ? null : 'the log has no readable events, yet no removal was started';
65
+ const head = events.find((e) => e.seq === t.headSeq);
66
+ if (head && head.hash !== t.headHash)
67
+ return `the surviving event ${t.headSeq} is not the head hash the commit names`;
68
+ const whole = events.length === t.headSeq && events.every((e, i) => e.seq === i + 1);
69
+ if (!whole)
70
+ return deletionStarted ? null : `events of the log are missing (${events.length} of ${t.headSeq} found), yet no removal was started`;
71
+ return tombstoneProblem(taskId, events, t);
72
+ }
@@ -270,7 +270,9 @@ export declare class DurableTasks {
270
270
  * - `live` it exists and carries no tombstone.
271
271
  * - `pending` a tombstone exists, but the prune is unfinished and may still be rolled back, or cannot be examined.
272
272
  * This is a transient state. It is never a reason to cancel anybody.
273
- * - `gone` it never existed, or its removal has started or finished: the prune is committed and irreversible.
273
+ * - `gone` its removal has started or finished: the prune is committed and irreversible.
274
+ * - `missing` its directory is not there and no prune accounts for it (ADR-018 D2). Absence is not proof of a
275
+ * committed prune, so, like `pending`, it blocks execution and is never a reason to cancel anybody.
274
276
  *
275
277
  * Why the tombstone alone proves nothing: a pruner publishes it BEFORE it looks for referrers, and a stopped
276
278
  * (SIGSTOP) or killed pruner leaves it behind with all data in place. Only the data decides:
@@ -282,8 +284,8 @@ export declare class DurableTasks {
282
284
  */
283
285
  private requirementState;
284
286
  /**
285
- * The first task an ACTIVE task requires (`parentTaskId`, `dependsOn`) that is gone, else the first whose prune is
286
- * pending, else `null`. This — not the presence of `task.created` in the log — is what permits execution. Why it
287
+ * The first task an ACTIVE task requires (`parentTaskId`, `dependsOn`) that is gone, else the first that is missing,
288
+ * else the first whose prune is pending, else `null`. This — not the presence of `task.created` in the log — is what permits execution. Why it
287
289
  * is safe without any clock: a pruner publishes its tombstone and only then looks for referrers; this check runs
288
290
  * after the task's `task.created` is published. So either the tombstone is visible here, or the pruner sees the
289
291
  * task and backs off. Once the check has passed, no prune of the required task can succeed while this task is active.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/durable/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/durable/runtime.ts"],"names":[],"mappings":"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"}
@@ -350,7 +350,10 @@ export class DurableTasks {
350
350
  if (!this.store.pinReference)
351
351
  return;
352
352
  for (const r of refs) {
353
- if ((await this.requirementState(r, true)) !== 'gone')
353
+ const st = await this.requirementState(r, true);
354
+ if (st === 'missing')
355
+ throw new ValidationError(`referenced task "${r}" was not found while task "${taskId}" was being created; the new task is not run and is not cancelled (ADR-018 D2).`);
356
+ if (st !== 'gone')
354
357
  continue;
355
358
  await this.quarantine(taskId, r);
356
359
  throw new ValidationError(`referenced task "${r}" was pruned while task "${taskId}" was being created; the new task was cancelled.`);
@@ -361,7 +364,9 @@ export class DurableTasks {
361
364
  * - `live` it exists and carries no tombstone.
362
365
  * - `pending` a tombstone exists, but the prune is unfinished and may still be rolled back, or cannot be examined.
363
366
  * This is a transient state. It is never a reason to cancel anybody.
364
- * - `gone` it never existed, or its removal has started or finished: the prune is committed and irreversible.
367
+ * - `gone` its removal has started or finished: the prune is committed and irreversible.
368
+ * - `missing` its directory is not there and no prune accounts for it (ADR-018 D2). Absence is not proof of a
369
+ * committed prune, so, like `pending`, it blocks execution and is never a reason to cancel anybody.
365
370
  *
366
371
  * Why the tombstone alone proves nothing: a pruner publishes it BEFORE it looks for referrers, and a stopped
367
372
  * (SIGSTOP) or killed pruner leaves it behind with all data in place. Only the data decides:
@@ -379,7 +384,7 @@ export class DurableTasks {
379
384
  }
380
385
  catch (err) {
381
386
  if (err instanceof TaskNotFoundError)
382
- return 'gone';
387
+ return 'missing';
383
388
  if (!(err instanceof TaskPrunedError))
384
389
  throw err;
385
390
  }
@@ -405,8 +410,8 @@ export class DurableTasks {
405
410
  return 'pending';
406
411
  }
407
412
  /**
408
- * The first task an ACTIVE task requires (`parentTaskId`, `dependsOn`) that is gone, else the first whose prune is
409
- * pending, else `null`. This — not the presence of `task.created` in the log — is what permits execution. Why it
413
+ * The first task an ACTIVE task requires (`parentTaskId`, `dependsOn`) that is gone, else the first that is missing,
414
+ * else the first whose prune is pending, else `null`. This — not the presence of `task.created` in the log — is what permits execution. Why it
410
415
  * is safe without any clock: a pruner publishes its tombstone and only then looks for referrers; this check runs
411
416
  * after the task's `task.created` is published. So either the tombstone is visible here, or the pruner sees the
412
417
  * task and backs off. Once the check has passed, no prune of the required task can succeed while this task is active.
@@ -414,15 +419,18 @@ export class DurableTasks {
414
419
  async blockingRequirement(s, recover) {
415
420
  if (s.status !== 'active')
416
421
  return null;
422
+ let missing = null;
417
423
  let pending = null;
418
424
  for (const r of [...(s.parentTaskId ? [s.parentTaskId] : []), ...s.dependsOn]) {
419
425
  const st = await this.requirementState(r, recover);
420
426
  if (st === 'gone')
421
427
  return { id: r, state: 'gone' };
428
+ if (st === 'missing' && missing === null)
429
+ missing = { id: r, state: 'missing' };
422
430
  if (st === 'pending' && pending === null)
423
431
  pending = { id: r, state: 'pending' };
424
432
  }
425
- return pending;
433
+ return missing ?? pending;
426
434
  }
427
435
  /**
428
436
  * Durable, idempotent cleanup of an orphan whose required task is GONE (never for a pending prune):
@@ -542,6 +550,8 @@ export class DurableTasks {
542
550
  await this.quarantine(taskId, blocked.id);
543
551
  throw new TaskOrphanedError(taskId, blocked.id);
544
552
  }
553
+ if (blocked?.state === 'missing')
554
+ throw new TaskOrphanedError(taskId, blocked.id); // refused, but nothing is cancelled (ADR-018 D2)
545
555
  if (blocked)
546
556
  throw new RequiredTaskPendingError(taskId, blocked.id); // fail closed, but not final: nothing is cancelled
547
557
  return this.mutate(taskId, (s) => {
@@ -1006,6 +1016,13 @@ export class DurableTasks {
1006
1016
  reasons: [...a.reasons, { code: 'REQUIRED_TASK_PRUNE_PENDING', severity: 'recovery', detail: `the prune of required task "${blocked.id}" is not settled; the task is not run now and is not cancelled`, refs: [blocked.id] }],
1007
1017
  };
1008
1018
  }
1019
+ if (blocked.state === 'missing') {
1020
+ return {
1021
+ ...a,
1022
+ claimable: false,
1023
+ reasons: [...a.reasons, { code: 'REQUIRED_TASK_GONE', severity: 'recovery', detail: `required task "${blocked.id}" was not found; the task is not run now and is not cancelled`, refs: [blocked.id] }],
1024
+ };
1025
+ }
1009
1026
  await this.quarantine(state.taskId, blocked.id);
1010
1027
  return {
1011
1028
  ...a,
@@ -25,6 +25,10 @@ export interface FsStoreSeams {
25
25
  * writer wins) over logs that are not prunable. Never a production setting.
26
26
  */
27
27
  skipPrunePrecondition?: boolean;
28
+ /** replaces `fs.unlinkSync` in the roll-forward of a committed prune, to stop it after a chosen number of removals. */
29
+ removeFile?: (abs: string) => void;
30
+ /** called by the audit of a committed prune: `listed` after the loose events were listed (nothing read yet, segments not yet listed), `surveyed` after it was read, before `tombstone.json` is. */
31
+ auditHook?: (point: 'listed' | 'surveyed') => void;
28
32
  /** simulate an I/O error on reading a file of the store: return an errno code (`'EIO'`) to fail with, or nothing. */
29
33
  readFault?: (abs: string) => string | null | undefined;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"seams.d.ts","sourceRoot":"","sources":["../../src/durable/seams.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,GAAG,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,uFAAuF;IACvF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,4IAA4I;IAC5I,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wHAAwH;IACxH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAChE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qHAAqH;IACrH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;AAChE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;AAKxE,wBAAgB,WAAW,IAAI,YAAY,CAI1C;AAED,wBAAgB,eAAe,IAAI,gBAAgB,CAIlD"}
1
+ {"version":3,"file":"seams.d.ts","sourceRoot":"","sources":["../../src/durable/seams.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,GAAG,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,uFAAuF;IACvF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,4IAA4I;IAC5I,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wHAAwH;IACxH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAChE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uHAAuH;IACvH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,mMAAmM;IACnM,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,KAAK,IAAI,CAAC;IACnD,qHAAqH;IACrH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;AAChE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;AAKxE,wBAAgB,WAAW,IAAI,YAAY,CAI1C;AAED,wBAAgB,eAAe,IAAI,gBAAgB,CAIlD"}
@@ -5,8 +5,8 @@ import { FsEventStore } from './fs-store.js';
5
5
  import { MemoryEventStore } from './memory-store.js';
6
6
  import { handOver, takeFsSeams, takeMemorySeams } from './seams.js';
7
7
  export function createFsStoreWithSeams(opts) {
8
- const { ops, beforePublish, afterListing, earlyPruneCheck, maxPruneAttempts, registerListing, skipPrunePrecondition, readFault, ...pub } = opts;
9
- handOver('fs', { ops, beforePublish, afterListing, earlyPruneCheck, maxPruneAttempts, registerListing, skipPrunePrecondition, readFault });
8
+ const { ops, beforePublish, afterListing, earlyPruneCheck, maxPruneAttempts, registerListing, skipPrunePrecondition, readFault, removeFile, auditHook, ...pub } = opts;
9
+ handOver('fs', { ops, beforePublish, afterListing, earlyPruneCheck, maxPruneAttempts, registerListing, skipPrunePrecondition, readFault, removeFile, auditHook });
10
10
  try {
11
11
  return new FsEventStore(pub);
12
12
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * `monolith idea ...` command handlers (IDEA-001A).
3
+ *
4
+ * Thin layer: strict flag parsing, store calls, output. No LLM, no network;
5
+ * `add` writes exactly one new file under `<monolithRoot>/memory/long-term/ideas/` and
6
+ * touches no other state (not `active.md`, not `state.json`); `list` and `show` write nothing.
7
+ */
8
+ import type { Readable } from 'stream';
9
+ interface AddFlags {
10
+ title?: string;
11
+ description?: string;
12
+ context?: string;
13
+ descriptionStdin?: boolean;
14
+ }
15
+ /** Strict: every flag needs a value, none may repeat, unknown flags and stray arguments are errors. */
16
+ export declare function parseAddArgs(args: string[]): AddFlags;
17
+ /**
18
+ * Read all of `input` as UTF-8, byte for byte (no trimming, BOM kept). Refuses
19
+ * more than STDIN_MAX_BYTES, invalid UTF-8 and a read error; nothing is
20
+ * interpreted. A terminal is refused instead of waiting for typed input.
21
+ */
22
+ export declare function readStdinText(input?: Readable & {
23
+ isTTY?: boolean;
24
+ }): Promise<string>;
25
+ export declare function runIdeaAdd(args: string[], targetDir?: string, stdin?: Readable & {
26
+ isTTY?: boolean;
27
+ }): Promise<void>;
28
+ export declare function runIdeaList(args: string[], targetDir?: string): Promise<void>;
29
+ export declare function runIdeaShow(args: string[], targetDir?: string): Promise<void>;
30
+ /** Dispatcher used by the CLI entrypoint. */
31
+ export declare function runIdeaCommand(args: string[], targetDir?: string): Promise<void>;
32
+ export {};
33
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/ideas/cli.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAiBvC,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAMD,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,CA4BrD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,KAAK,GAAE,QAAQ,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB1G;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,SAAgB,EAAE,KAAK,GAAE,QAAQ,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhJ;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB1F;AAiBD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1F;AAED,6CAA6C;AAC7C,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAe7F"}
@@ -0,0 +1,158 @@
1
+ /* eslint-disable no-console */
2
+ /**
3
+ * `monolith idea ...` command handlers (IDEA-001A).
4
+ *
5
+ * Thin layer: strict flag parsing, store calls, output. No LLM, no network;
6
+ * `add` writes exactly one new file under `<monolithRoot>/memory/long-term/ideas/` and
7
+ * touches no other state (not `active.md`, not `state.json`); `list` and `show` write nothing.
8
+ */
9
+ import { reportWriteWarning } from '../root/index.js';
10
+ import { addIdea, getIdea, ideaStore, listIdeas } from './store.js';
11
+ import { IDEA_LIMITS, IdeaError } from './types.js';
12
+ const ADD_USAGE = 'Usage: monolith idea add --title "..." (--description "..." | --description-stdin) [--context "..."]';
13
+ /** UTF-8 needs at most 4 bytes per UTF-16 code unit's worth of text; anything larger cannot fit the description limit. */
14
+ const STDIN_MAX_BYTES = IDEA_LIMITS.description * 4;
15
+ const LIST_USAGE = 'Usage: monolith idea list';
16
+ const SHOW_USAGE = 'Usage: monolith idea show <id>';
17
+ /** Escape control characters so project-controlled text cannot forge terminal output. */
18
+ function printable(s) {
19
+ // eslint-disable-next-line no-control-regex
20
+ return s.replace(/[\u0000-\u0009\u000b-\u001f\u007f-\u009f\u2028\u2029]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
21
+ }
22
+ const ADD_FLAGS = ['--title', '--description', '--context'];
23
+ const STDIN_FLAG = '--description-stdin';
24
+ const KNOWN_FLAGS = [...ADD_FLAGS, STDIN_FLAG];
25
+ /** Strict: every flag needs a value, none may repeat, unknown flags and stray arguments are errors. */
26
+ export function parseAddArgs(args) {
27
+ const out = {};
28
+ for (let i = 0; i < args.length; i++) {
29
+ const flag = args[i];
30
+ if (!KNOWN_FLAGS.includes(flag)) {
31
+ throw new IdeaError('IDEA_INVALID_INPUT', `Unexpected argument ${JSON.stringify(printable(flag))}.\n${ADD_USAGE}`);
32
+ }
33
+ if (flag === STDIN_FLAG) {
34
+ if (out.descriptionStdin)
35
+ throw new IdeaError('IDEA_INVALID_INPUT', `${flag} was given more than once.\n${ADD_USAGE}`);
36
+ out.descriptionStdin = true;
37
+ continue;
38
+ }
39
+ const key = flag.slice(2);
40
+ if (key in out)
41
+ throw new IdeaError('IDEA_INVALID_INPUT', `${flag} was given more than once.\n${ADD_USAGE}`);
42
+ const value = args[i + 1];
43
+ if (value === undefined || KNOWN_FLAGS.includes(value)) {
44
+ throw new IdeaError('IDEA_INVALID_INPUT', `${flag} needs a value.\n${ADD_USAGE}`);
45
+ }
46
+ out[key] = value;
47
+ i++;
48
+ }
49
+ if (out.descriptionStdin && out.description !== undefined) {
50
+ throw new IdeaError('IDEA_INVALID_INPUT', `--description and ${STDIN_FLAG} cannot be combined.\n${ADD_USAGE}`);
51
+ }
52
+ if (out.title === undefined || (out.description === undefined && !out.descriptionStdin)) {
53
+ throw new IdeaError('IDEA_INVALID_INPUT', `--title and --description (or ${STDIN_FLAG}) are required.\n${ADD_USAGE}`);
54
+ }
55
+ return out;
56
+ }
57
+ /**
58
+ * Read all of `input` as UTF-8, byte for byte (no trimming, BOM kept). Refuses
59
+ * more than STDIN_MAX_BYTES, invalid UTF-8 and a read error; nothing is
60
+ * interpreted. A terminal is refused instead of waiting for typed input.
61
+ */
62
+ export async function readStdinText(input = process.stdin) {
63
+ if (input.isTTY) {
64
+ throw new IdeaError('IDEA_INVALID_INPUT', `${STDIN_FLAG} needs piped input, but stdin is a terminal.\n${ADD_USAGE}`);
65
+ }
66
+ const chunks = [];
67
+ let total = 0;
68
+ try {
69
+ for await (const chunk of input) {
70
+ const buf = typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : chunk;
71
+ total += buf.length;
72
+ if (total > STDIN_MAX_BYTES) {
73
+ input.destroy();
74
+ throw new IdeaError('IDEA_INVALID_INPUT', `stdin is too large (more than ${STDIN_MAX_BYTES} bytes); nothing was written.`);
75
+ }
76
+ chunks.push(buf);
77
+ }
78
+ }
79
+ catch (err) {
80
+ if (err instanceof IdeaError)
81
+ throw err;
82
+ throw new IdeaError('IDEA_INVALID_INPUT', `could not read stdin: ${err.message}; nothing was written.`, { cause: err });
83
+ }
84
+ try {
85
+ return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(Buffer.concat(chunks));
86
+ }
87
+ catch (err) {
88
+ throw new IdeaError('IDEA_INVALID_INPUT', 'stdin is not valid UTF-8; nothing was written.', { cause: err });
89
+ }
90
+ }
91
+ export async function runIdeaAdd(args, targetDir = process.cwd(), stdin = process.stdin) {
92
+ const flags = parseAddArgs(args);
93
+ const description = flags.descriptionStdin ? await readStdinText(stdin) : flags.description;
94
+ const store = ideaStore(targetDir);
95
+ const { idea, path } = addIdea(store, { title: flags.title, description, context: flags.context }, { onWarning: (w) => reportWriteWarning(w) });
96
+ console.log(`Saved ${idea.id} [${idea.status}]: ${printable(idea.title)}`);
97
+ console.log(` file: ${path}`);
98
+ console.log('Current task and focus are unchanged. Recall with `monolith idea list` / `monolith idea show ' + idea.id + '`.');
99
+ }
100
+ export async function runIdeaList(args, targetDir = process.cwd()) {
101
+ if (args.length > 0)
102
+ throw new IdeaError('IDEA_INVALID_INPUT', `Unexpected argument ${JSON.stringify(printable(args[0]))}.\n${LIST_USAGE}`);
103
+ const entries = listIdeas(ideaStore(targetDir));
104
+ if (entries.length === 0) {
105
+ console.log('No ideas. Capture one with `monolith idea add --title "..." --description "..."`.');
106
+ return;
107
+ }
108
+ console.log(`Ideas (${entries.length}):`);
109
+ let unreadable = 0;
110
+ for (const e of entries) {
111
+ if (e.ok) {
112
+ console.log(` ${e.idea.id} [${e.idea.status}] ${printable(e.idea.title)}`);
113
+ }
114
+ else {
115
+ unreadable++;
116
+ console.log(` ${e.id} [unreadable] ${printable(e.reason)}`);
117
+ }
118
+ }
119
+ if (unreadable > 0) {
120
+ console.error(`${unreadable} idea file(s) could not be read; they were left untouched. Inspect them with \`monolith idea show <id>\`.`);
121
+ process.exitCode = 2;
122
+ }
123
+ }
124
+ function formatIdea(i) {
125
+ const lines = [
126
+ ` id: ${i.id}`,
127
+ ` title: ${printable(i.title)}`,
128
+ ` status: ${i.status}`,
129
+ ` createdAt: ${i.createdAt}`,
130
+ ];
131
+ if (i.tags !== undefined && i.tags.length > 0)
132
+ lines.push(` tags: ${i.tags.map(printable).join(', ')}`);
133
+ lines.push(' context: ' + (i.context === undefined ? '(none)' : ''));
134
+ if (i.context !== undefined)
135
+ lines.push(...i.context.split('\n').map((l) => ` ${l}`));
136
+ lines.push(' description:');
137
+ lines.push(...i.description.split('\n').map((l) => ` ${l}`));
138
+ return lines.join('\n');
139
+ }
140
+ export async function runIdeaShow(args, targetDir = process.cwd()) {
141
+ if (args.length !== 1)
142
+ throw new IdeaError('IDEA_INVALID_INPUT', SHOW_USAGE);
143
+ console.log(formatIdea(getIdea(ideaStore(targetDir), args[0])));
144
+ }
145
+ /** Dispatcher used by the CLI entrypoint. */
146
+ export async function runIdeaCommand(args, targetDir = process.cwd()) {
147
+ const [sub, ...rest] = args;
148
+ switch (sub) {
149
+ case 'add':
150
+ return runIdeaAdd(rest, targetDir);
151
+ case 'list':
152
+ return runIdeaList(rest, targetDir);
153
+ case 'show':
154
+ return runIdeaShow(rest, targetDir);
155
+ default:
156
+ throw new IdeaError('IDEA_INVALID_INPUT', `Unknown idea subcommand: ${sub === undefined ? '(none)' : JSON.stringify(printable(sub))}\n${ADD_USAGE}\n ${LIST_USAGE.slice(7)}\n ${SHOW_USAGE.slice(7)}`);
157
+ }
158
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Idea file format: Markdown with a small frontmatter block.
3
+ *
4
+ * ---
5
+ * type: idea
6
+ * id: "IDEA-001"
7
+ * title: "..." (JSON string: any character survives a round trip)
8
+ * status: inbox
9
+ * createdAt: "2026-..."
10
+ * context: "..." (optional)
11
+ * tags: ["a", "b"] (optional)
12
+ * ---
13
+ *
14
+ * ## Description
15
+ *
16
+ * <description, verbatim>
17
+ *
18
+ * Strings are written as JSON strings, which are also valid YAML double-quoted
19
+ * scalars, so ERG/Scriptorium read the file too. The reader additionally accepts
20
+ * a plain unquoted value, because a person edits these files by hand.
21
+ * The description is the body: no escaping, no trimming.
22
+ */
23
+ import { type Idea, type NewIdea } from './types.js';
24
+ export declare function isIdeaId(value: string): boolean;
25
+ export declare function ideaNumber(id: string): number;
26
+ export declare function formatIdeaId(n: number): string;
27
+ /** `IDEA-007.md` -> `IDEA-007`; anything else (temp files, other documents) -> null. */
28
+ export declare function ideaIdFromFileName(name: string): string | null;
29
+ export declare function ideaFileName(id: string): string;
30
+ /** Validates user input; returns it unchanged (content is never trimmed or rewritten). */
31
+ export declare function validateNewIdea(input: NewIdea): NewIdea;
32
+ export declare function serializeIdea(idea: Idea): string;
33
+ /**
34
+ * Parse an idea file. `expectedId` is the id implied by the file name; a
35
+ * mismatch with the `id:` field is corruption, never silently "fixed".
36
+ */
37
+ export declare function parseIdea(expectedId: string, text: string): Idea;
38
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/ideas/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAyC,KAAK,IAAI,EAAmB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAS7G,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG/C;AAaD,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAmBvD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAahD;AAqBD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA0DhE"}