@smartmemory/compose 0.2.58-beta → 0.3.0

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 (99) hide show
  1. package/README.md +2 -2
  2. package/bin/compose.js +55 -54
  3. package/dist/assets/{App-s4CulNkO.js → App-DJ5xk_Wx.js} +218 -218
  4. package/dist/assets/{abnfDiagram-VRR7QNED-CDwzQ5wr.js → abnfDiagram-VRR7QNED-BPWGdCFx.js} +1 -1
  5. package/dist/assets/{arc-kIU8DDth.js → arc-DX5jqmcO.js} +1 -1
  6. package/dist/assets/{architectureDiagram-ZJ3FMSHR-CleorO_0.js → architectureDiagram-ZJ3FMSHR-B6jmNVw7.js} +1 -1
  7. package/dist/assets/{blockDiagram-677ZJIJ3-NvEFfoMk.js → blockDiagram-677ZJIJ3-DAx2i-sB.js} +1 -1
  8. package/dist/assets/{c4Diagram-LMCZKHZV-BcDQdTVB.js → c4Diagram-LMCZKHZV-zmsZCplj.js} +1 -1
  9. package/dist/assets/channel-vsDnTvkh.js +1 -0
  10. package/dist/assets/{chunk-2Q5K7J3B-BseRkpm4.js → chunk-2Q5K7J3B-3QSh6sI7.js} +1 -1
  11. package/dist/assets/{chunk-32BRIVSS-DCHhvgFV.js → chunk-32BRIVSS-BiH5Di_y.js} +1 -1
  12. package/dist/assets/{chunk-5VM5RSS4-DcTpMdJ4.js → chunk-5VM5RSS4-C0EfjFLd.js} +1 -1
  13. package/dist/assets/{chunk-EX3LRPZG-BdN8fvWs.js → chunk-EX3LRPZG-BGyfmVm-.js} +1 -1
  14. package/dist/assets/{chunk-JWPE2WC7-DmZJP-8E.js → chunk-JWPE2WC7-Ba0mrNlg.js} +1 -1
  15. package/dist/assets/{chunk-MOJQB5TN-V74uYM17.js → chunk-MOJQB5TN-D3QO9EzH.js} +1 -1
  16. package/dist/assets/{chunk-RYQCIY6F-CoXUXbn_.js → chunk-RYQCIY6F-D1uvNA6d.js} +1 -1
  17. package/dist/assets/{chunk-V7JOEXUC-DUscIydR.js → chunk-V7JOEXUC-fihlnodT.js} +1 -1
  18. package/dist/assets/{chunk-VR4S4FIN-C4UDHq_a.js → chunk-VR4S4FIN-nmRUEo1H.js} +1 -1
  19. package/dist/assets/{chunk-XXDRQBXY-DIH9i8mZ.js → chunk-XXDRQBXY-CM693yEg.js} +1 -1
  20. package/dist/assets/classDiagram-OUVF2IWQ-DO-wdSFZ.js +1 -0
  21. package/dist/assets/classDiagram-v2-EOCWNBFH-DO-wdSFZ.js +1 -0
  22. package/dist/assets/{cose-bilkent-JH36ORCC-Dn6Gy6l1.js → cose-bilkent-JH36ORCC-CkacPn8W.js} +1 -1
  23. package/dist/assets/{cynefin-VYW2F7L2-C2LW5fzB.js → cynefin-VYW2F7L2-BiHaIptG.js} +1 -1
  24. package/dist/assets/{cynefinDiagram-TSTJHNR4-CGoAq7C9.js → cynefinDiagram-TSTJHNR4-CdKxMmiy.js} +1 -1
  25. package/dist/assets/{dagre-VKFMJZFB-BaOKtuBE.js → dagre-VKFMJZFB-BQLY5y_W.js} +1 -1
  26. package/dist/assets/{diagram-FQU43EPY-BdQwqt4x.js → diagram-FQU43EPY-D7uMBHvq.js} +1 -1
  27. package/dist/assets/{diagram-G47NLZAW-Dkcf0o5z.js → diagram-G47NLZAW-B3Z1cuH7.js} +1 -1
  28. package/dist/assets/{diagram-NH7WQ7WH-C_fDi59r.js → diagram-NH7WQ7WH-BZyRD45e.js} +1 -1
  29. package/dist/assets/{diagram-OA4YK3LP-jaTQcOxt.js → diagram-OA4YK3LP-DcThOTt7.js} +1 -1
  30. package/dist/assets/{diagram-WEI45ONY-dEtqVj3s.js → diagram-WEI45ONY-BcgRAkqY.js} +1 -1
  31. package/dist/assets/{ebnfDiagram-CCIWWBDH-s8ImqsSs.js → ebnfDiagram-CCIWWBDH-CGwfO_xH.js} +1 -1
  32. package/dist/assets/{erDiagram-Q63AITRT-5Zy29-SA.js → erDiagram-Q63AITRT-pV58-Ncc.js} +1 -1
  33. package/dist/assets/{flowDiagram-23GEKE2U-DV74V9he.js → flowDiagram-23GEKE2U-DJ_SqE8h.js} +1 -1
  34. package/dist/assets/{ganttDiagram-NO4QXBWP-BND-CiLO.js → ganttDiagram-NO4QXBWP-Dgy0Iyss.js} +1 -1
  35. package/dist/assets/{gitGraphDiagram-IHSO6WYX-B_-Mf9Jo.js → gitGraphDiagram-IHSO6WYX-CbiZw9fb.js} +1 -1
  36. package/dist/assets/{index-CBWbmG7W.js → index-DZTJEk-y.js} +2 -2
  37. package/dist/assets/{infoDiagram-FWYZ7A6U-Duyz8rZM.js → infoDiagram-FWYZ7A6U-CtsyyEc-.js} +1 -1
  38. package/dist/assets/{ishikawaDiagram-FXEZZL3T-D2Qft0e5.js → ishikawaDiagram-FXEZZL3T-BJilNFkK.js} +1 -1
  39. package/dist/assets/{journeyDiagram-5HDEW3XC-q6rG4Rig.js → journeyDiagram-5HDEW3XC-C2UCMP4t.js} +1 -1
  40. package/dist/assets/{kanban-definition-HUTT4EX6-CsPX7gBL.js → kanban-definition-HUTT4EX6-DmLDJBRy.js} +1 -1
  41. package/dist/assets/{linear-CiccpAAd.js → linear-C1paCqE7.js} +1 -1
  42. package/dist/assets/{mindmap-definition-LN4V7U3C-DRW2njpA.js → mindmap-definition-LN4V7U3C-CX-RxKVn.js} +1 -1
  43. package/dist/assets/{pegDiagram-2B236MQR-DoDgm2S_.js → pegDiagram-2B236MQR-CTU32H2W.js} +1 -1
  44. package/dist/assets/{pieDiagram-ENE6RG2P-CNSYLVAF.js → pieDiagram-ENE6RG2P-D8L1aYoo.js} +1 -1
  45. package/dist/assets/{quadrantDiagram-ABIIQ3AL-8-Nd6ony.js → quadrantDiagram-ABIIQ3AL-hQ3bXosy.js} +1 -1
  46. package/dist/assets/{railroadDiagram-RFXS5EU6-bfdg6Bo4.js → railroadDiagram-RFXS5EU6--_vuYcda.js} +1 -1
  47. package/dist/assets/{requirementDiagram-TGXJPOKE-slDkxCQy.js → requirementDiagram-TGXJPOKE-C6h_m3Az.js} +1 -1
  48. package/dist/assets/{sankeyDiagram-HTMAVEWB-CR3CboiK.js → sankeyDiagram-HTMAVEWB-Dpc7CfIQ.js} +1 -1
  49. package/dist/assets/{sequenceDiagram-DBY2YBRQ-BIXw1JS1.js → sequenceDiagram-DBY2YBRQ-CK5ZzbvJ.js} +1 -1
  50. package/dist/assets/{sizeCapture-X5ZJPWSS-BdKI7JyF.js → sizeCapture-X5ZJPWSS-BAxVvM9G.js} +1 -1
  51. package/dist/assets/{stateDiagram-2N3HPSRC-ktVgpBZS.js → stateDiagram-2N3HPSRC-7j33_2PY.js} +1 -1
  52. package/dist/assets/stateDiagram-v2-6OUMAXLB-GviN0FpJ.js +1 -0
  53. package/dist/assets/{swimlanes-5IMT3BWC-CaXpC3FM.js → swimlanes-5IMT3BWC-CBG2yOob.js} +2 -2
  54. package/dist/assets/swimlanesDiagram-G3AALYLV-D0wMoxl1.js +8 -0
  55. package/dist/assets/{timeline-definition-FHXFAJF6-CKWSlRUl.js → timeline-definition-FHXFAJF6-BOnZkQvc.js} +1 -1
  56. package/dist/assets/{vennDiagram-L72KCM5P-CwOhxDyv.js → vennDiagram-L72KCM5P-D52NhIfj.js} +1 -1
  57. package/dist/assets/{wardleyDiagram-EHGQE667-DGavMpEB.js → wardleyDiagram-EHGQE667-YoPY2ZU-.js} +1 -1
  58. package/dist/assets/{xychartDiagram-FW5EYKEG-CWmnmLZz.js → xychartDiagram-FW5EYKEG-BanNfgtO.js} +1 -1
  59. package/dist/index.html +1 -1
  60. package/lib/build-all.js +0 -5
  61. package/lib/build-stream-schema.js +1 -1
  62. package/lib/build.js +1762 -2614
  63. package/lib/consumer-fanout.js +1317 -0
  64. package/lib/feature-validator.js +6 -4
  65. package/lib/flow-state.js +15 -14
  66. package/lib/gsd-budget.js +48 -10
  67. package/lib/gsd-prompt.js +3 -4
  68. package/lib/gsd-stuck.js +1 -1
  69. package/lib/gsd.js +303 -149
  70. package/lib/local-claude-connector.js +149 -0
  71. package/lib/new.js +162 -307
  72. package/lib/result-normalizer.js +233 -18
  73. package/lib/review-lenses.js +1 -1
  74. package/lib/step-prompt.js +41 -119
  75. package/lib/stratum-engine.js +297 -0
  76. package/lib/stratum-mcp-client.js +224 -213
  77. package/lib/vocabulary-compliance.js +268 -0
  78. package/lib/vocabulary-inject.js +1 -36
  79. package/package.json +2 -1
  80. package/pipelines/build-quick.stratum.yaml +5 -17
  81. package/pipelines/build.profiles.json +11 -0
  82. package/pipelines/build.stratum.yaml +288 -467
  83. package/pipelines/gsd.stratum.yaml +73 -125
  84. package/pipelines/new.stratum.yaml +68 -149
  85. package/server/build-routes.js +4 -1
  86. package/server/design-routes.js +37 -21
  87. package/server/index.js +13 -21
  88. package/server/lifecycle-guard.js +1 -1
  89. package/server/pipeline-routes.js +113 -31
  90. package/server/stratum-client.js +33 -47
  91. package/server/stratum-sync.js +3 -4
  92. package/server/vision-server.js +1 -1
  93. package/dist/assets/channel-DiJkE9og.js +0 -1
  94. package/dist/assets/classDiagram-OUVF2IWQ-DS76VBEL.js +0 -1
  95. package/dist/assets/classDiagram-v2-EOCWNBFH-DS76VBEL.js +0 -1
  96. package/dist/assets/stateDiagram-v2-6OUMAXLB-CzPQnlan.js +0 -1
  97. package/dist/assets/swimlanesDiagram-G3AALYLV-rIDv6EuQ.js +0 -8
  98. package/lib/connector-factory-shim.js +0 -167
  99. package/server/agent-mcp.js +0 -10
@@ -572,14 +572,16 @@ function runArtifactLinkChecks(fctx, ctx, findings) {
572
572
  }
573
573
  // PLANNED / SUPERSEDED / KILLED / PARKED — no finding (expected baseline)
574
574
  }
575
- // MISSING_COMPLETION_REPORT (warning, COMPLETE)
575
+ // MISSING_COMPLETION_REPORT (info, COMPLETE)
576
+ // The report phase is OPTIONAL/skippable (small features legitimately never
577
+ // write one), so a missing report.md is informational, not warning-level debt.
576
578
  // COMP-BUILD-QUICK-1: the quick lifecycle (compose build --quick) omits the
577
579
  // report phase by design and stamps built_via:'build-quick' on feature.json at
578
- // ship. Exempt those features a missing report.md is expected, not debt.
580
+ // ship those stay fully exempt (no finding at all).
579
581
  if (status === 'COMPLETE' && !folder.files.has('report.md') &&
580
582
  featureJson?.built_via !== 'build-quick') {
581
- findings.push(finding('warning', 'MISSING_COMPLETION_REPORT', code,
582
- `Feature is COMPLETE but report.md is missing (current writers do not enforce this; warning only)`));
583
+ findings.push(finding('info', 'MISSING_COMPLETION_REPORT', code,
584
+ `Feature is COMPLETE without report.md — the report phase is optional (skippable for small features); informational only`));
583
585
  }
584
586
 
585
587
  // DANGLING_ARTIFACT_LINK + ARTIFACT_OUTSIDE_FEATURE_FOLDER
package/lib/flow-state.js CHANGED
@@ -1,6 +1,8 @@
1
1
  /**
2
- * flow-state.js — small read-only helpers over the persisted Stratum flow state
3
- * (`~/.stratum/flows/<flowId>.json`).
2
+ * flow-state.js — small read-only helpers over persisted Stratum flow state.
3
+ *
4
+ * Reads the TS store (`STRATUM_STATE_ROOT/<flowId>.json` when configured,
5
+ * otherwise `~/.stratum/ts/flows/<flowId>.json`).
4
6
  *
5
7
  * Shared by the gate handlers in build.js and new.js so the gate id can be made
6
8
  * round-aware (COMP-PLAN-GATE-LOOP).
@@ -10,27 +12,26 @@ import { join } from 'node:path';
10
12
  import { homedir } from 'node:os';
11
13
 
12
14
  /**
13
- * Read Stratum's current round for a flow from its persisted state file.
15
+ * Read Stratum's current round for a flow from its persisted state files.
14
16
  *
15
- * The await_gate dispatch Stratum returns does not carry the round, but the
16
- * persisted flow file does. Threading the round into the gate id
17
+ * The TS running response does not carry the round, but the persisted flow
18
+ * file does. Threading the round into the gate id
17
19
  * (`<flowId>:<stepId>:<round>`) makes each gate re-entry after a `revise` a
18
20
  * fresh, pending gate rather than colliding with the prior resolved gate and
19
21
  * replaying its stale outcome.
20
22
  *
21
- * Fail-open: returns 1 (the legacy default) if the file is missing, unreadable,
22
- * or lacks an integer round — a read failure must never block a gate.
23
+ * Fresh TS runs have no `rounds` field and use round 0. A read failure must
24
+ * never block a gate.
23
25
  *
24
26
  * @param {string} flowId
25
27
  * @returns {number}
26
28
  */
27
29
  export function readFlowRound(flowId) {
30
+ // TS store — STRATUM_STATE_ROOT-aware; flows are stored flat at the root.
28
31
  try {
29
- const flowFile = join(homedir(), '.stratum', 'flows', `${flowId}.json`);
30
- const state = JSON.parse(readFileSync(flowFile, 'utf-8'));
31
- const r = state?.round;
32
- return Number.isInteger(r) && r >= 0 ? r : 1;
33
- } catch {
34
- return 1;
35
- }
32
+ const tsRoot = process.env.STRATUM_STATE_ROOT || join(homedir(), '.stratum', 'ts', 'flows');
33
+ const state = JSON.parse(readFileSync(join(tsRoot, `${flowId}.json`), 'utf-8'));
34
+ const r = state?.rounds;
35
+ return Number.isInteger(r) && r >= 0 ? r : 0;
36
+ } catch { return 0; }
36
37
  }
package/lib/gsd-budget.js CHANGED
@@ -62,8 +62,8 @@ export function buildBudgetBlock(cfg = {}) {
62
62
  if (Object.keys(budget).length > 0) out.budget = budget;
63
63
 
64
64
  if (cfg.per_task_ms != null) {
65
- // stratum parallel_dispatch per-task timeout is `task_timeout` in SECONDS
66
- // (spec.py:145, schema minimum 1). Convert from ms, floor at 1s.
65
+ // Compose's per-consumer timeout is carried in seconds. Convert from ms and
66
+ // floor at 1s.
67
67
  out.taskTimeoutSec = Math.max(1, Math.ceil(cfg.per_task_ms / 1000));
68
68
  }
69
69
 
@@ -91,8 +91,13 @@ export function buildBudgetBlock(cfg = {}) {
91
91
  */
92
92
  export function injectBudget(specYaml, cfg = {}) {
93
93
  const built = buildBudgetBlock(cfg);
94
- if (!built.budget && built.taskTimeoutSec == null) {
95
- return specYaml; // identitynothing to inject
94
+ // D2(a): per_task_ms is a PER-ITEM wall-clock ceiling enforced compose-side
95
+ // (runConsumerIssuance runs each agent), NOT an engine step budget a step
96
+ // budget on the fanout cannot be per-item (the engine can't know N). So only
97
+ // the honest flow-wide budget is injected here; per_task_ms is threaded to the
98
+ // consumer loop via gsd.budget.per_task_ms.
99
+ if (!built.budget) {
100
+ return specYaml; // identity — nothing to inject into the spec
96
101
  }
97
102
 
98
103
  const parsed = YAML.parse(specYaml);
@@ -102,16 +107,49 @@ export function injectBudget(specYaml, cfg = {}) {
102
107
  throw new Error('injectBudget: spec has no flows.gsd to attach a budget to');
103
108
  }
104
109
 
105
- if (built.budget) flow.budget = built.budget;
106
-
107
- if (built.taskTimeoutSec != null && Array.isArray(flow.steps)) {
108
- const execute = flow.steps.find((s) => s && s.id === 'execute');
109
- if (execute) execute.task_timeout = built.taskTimeoutSec;
110
- }
110
+ flow.budget = parsed.version === 1
111
+ ? {
112
+ ...(built.budget.max_tokens != null ? { tokens: built.budget.max_tokens } : {}),
113
+ ...(built.budget.max_agent_dispatches != null ? { dispatches: built.budget.max_agent_dispatches } : {}),
114
+ ...(built.budget.usd != null ? { usd: built.budget.usd } : {}),
115
+ ...(built.budget.ms != null ? { ms: built.budget.ms } : {}),
116
+ }
117
+ : built.budget;
111
118
 
112
119
  return YAML.stringify(parsed);
113
120
  }
114
121
 
122
+ /**
123
+ * D2(c): adapt the TS engine's terminal `ledger` ({spent, budget}) into the
124
+ * legacy `budget_state` ({caps, consumed}) shape the GSD diagnostics/recording
125
+ * helpers consume. The python terminal envelope carried `budget_state`
126
+ * directly; the TS engine returns a `ledger` with the Budget key names
127
+ * (usd/tokens/dispatches/ms). Returns null for a missing/empty ledger so
128
+ * callers can `response.budget_state ?? budgetStateFromLedger(response.ledger)`.
129
+ *
130
+ * @param {{ spent?: object, budget?: object, limits?: object }} ledger
131
+ * @returns {{ caps: object, consumed: object } | null}
132
+ */
133
+ export function budgetStateFromLedger(ledger) {
134
+ if (!ledger || typeof ledger !== 'object') return null;
135
+ const spent = ledger.spent ?? {};
136
+ const caps = ledger.budget ?? ledger.limits ?? {};
137
+ return {
138
+ caps: {
139
+ ...(caps.tokens != null ? { max_tokens: caps.tokens } : {}),
140
+ ...(caps.dispatches != null ? { max_agent_dispatches: caps.dispatches } : {}),
141
+ ...(caps.usd != null ? { usd: caps.usd } : {}),
142
+ ...(caps.ms != null ? { ms: caps.ms } : {}),
143
+ },
144
+ consumed: {
145
+ tokens: spent.tokens ?? 0,
146
+ dispatches: spent.dispatches ?? 0,
147
+ dollars: spent.usd ?? 0,
148
+ wall_s: (spent.ms ?? 0) / 1000,
149
+ },
150
+ };
151
+ }
152
+
115
153
  // Maps a stratum budget axis → human label for diagnostics.
116
154
  const AXIS_LABEL = {
117
155
  max_tokens: 'tokens',
package/lib/gsd-prompt.js CHANGED
@@ -2,10 +2,9 @@
2
2
  //
3
3
  // COMP-GSD-2 T4: buildTaskDescription — pure string assembly.
4
4
  //
5
- // Stratum's parallel_dispatch only interpolates {task.id|description|
6
- // files_owned|files_read|depends_on|index} and {input.<field>}. Every other
7
- // piece of context — the per-slice produces/consumes contract, the upstream
8
- // tasks summary, the gate commands — must be packed inside `task.description`.
5
+ // TS consumer fanout renders each item, but richer per-slice context — the
6
+ // produces/consumes contract, upstream summary, and gate commands — is packed
7
+ // inside `task.description`.
9
8
  //
10
9
  // This module produces the rich `description` string. It is also used by
11
10
  // runGsd as a deterministic fallback when the decompose_gsd agent failed to
package/lib/gsd-stuck.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * no-progress are the only new bookkeeping.
16
16
  *
17
17
  * Consumes BuildStreamEvents from stratum.onEvent inside
18
- * executeParallelDispatchServer, keyed by event.task_id. gsd runs the execute
18
+ * the TS consumer runner, keyed by event.task_id. GSD runs the execute
19
19
  * step max_concurrent:1, so per-task state is unambiguous. Telemetry contract
20
20
  * (schema 0.2.7, STRAT-PAR-STREAM-TOOLDETAIL):
21
21
  * tool_use_summary.metadata = { tool, summary, ok, duration_ms, input, tool_use_id }