@smartmemory/compose 0.1.1-beta → 0.1.2-beta

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 (124) hide show
  1. package/.claude/skills/bug-fix/SKILL.md +143 -0
  2. package/.claude/skills/compose/SKILL.md +604 -0
  3. package/.compose-deps.json +89 -0
  4. package/README.md +14 -3
  5. package/bin/compose.js +473 -0
  6. package/contracts/comp-obs-contract.schema.json +362 -0
  7. package/contracts/cross-model-review-result.json +78 -0
  8. package/contracts/review-result.json +126 -0
  9. package/dist/assets/{_baseUniq-CQwX6VLz.js → _baseUniq-D-avYfn5.js} +1 -1
  10. package/dist/assets/{arc-SxJ2J1sh.js → arc-BC4dfQ-X.js} +1 -1
  11. package/dist/assets/{architectureDiagram-Q4EWVU46-BykunY1F.js → architectureDiagram-Q4EWVU46-BZmFXnGI.js} +1 -1
  12. package/dist/assets/{blockDiagram-DXYQGD6D-ohAKBOUw.js → blockDiagram-DXYQGD6D-DlfWSuux.js} +1 -1
  13. package/dist/assets/{c4Diagram-AHTNJAMY-DBDC3ENB.js → c4Diagram-AHTNJAMY-Y__uJrRx.js} +1 -1
  14. package/dist/assets/channel-LRG9kHqJ.js +1 -0
  15. package/dist/assets/{chunk-4BX2VUAB-Cv93Z7uM.js → chunk-4BX2VUAB-BfMePfTp.js} +1 -1
  16. package/dist/assets/{chunk-4TB4RGXK-DE0WBDkj.js → chunk-4TB4RGXK-BdlMSdEA.js} +1 -1
  17. package/dist/assets/{chunk-55IACEB6-CE1EXenG.js → chunk-55IACEB6-vrQHZTdv.js} +1 -1
  18. package/dist/assets/{chunk-EDXVE4YY-DA7Ana6H.js → chunk-EDXVE4YY-B8wioVlW.js} +1 -1
  19. package/dist/assets/{chunk-FMBD7UC4-CTDIPA3p.js → chunk-FMBD7UC4-Cd6Hrux2.js} +1 -1
  20. package/dist/assets/{chunk-OYMX7WX6-uGBaPaTX.js → chunk-OYMX7WX6-CfrhdQXY.js} +1 -1
  21. package/dist/assets/{chunk-QZHKN3VN-CYlnXuUO.js → chunk-QZHKN3VN-B9JQerOU.js} +1 -1
  22. package/dist/assets/{chunk-YZCP3GAM-ojGkzcZK.js → chunk-YZCP3GAM-DFN9X99H.js} +1 -1
  23. package/dist/assets/classDiagram-6PBFFD2Q-BC9a6pDE.js +1 -0
  24. package/dist/assets/classDiagram-v2-HSJHXN6E-BC9a6pDE.js +1 -0
  25. package/dist/assets/clone-dRxgFrBv.js +1 -0
  26. package/dist/assets/{cose-bilkent-S5V4N54A-Bktn9hL-.js → cose-bilkent-S5V4N54A-BAn0ap_E.js} +1 -1
  27. package/dist/assets/{dagre-KV5264BT-DFaSzuRF.js → dagre-KV5264BT-DyxnVq1g.js} +1 -1
  28. package/dist/assets/{diagram-5BDNPKRD-DnfmDzEm.js → diagram-5BDNPKRD-XCrzqski.js} +1 -1
  29. package/dist/assets/{diagram-G4DWMVQ6-Bm8W9YnG.js → diagram-G4DWMVQ6-MBCAXft_.js} +1 -1
  30. package/dist/assets/{diagram-MMDJMWI5-B5-TSKvp.js → diagram-MMDJMWI5-DbtB2yS6.js} +1 -1
  31. package/dist/assets/{diagram-TYMM5635-ls4rqlky.js → diagram-TYMM5635-Bb5NzX61.js} +1 -1
  32. package/dist/assets/{erDiagram-SMLLAGMA-giG6WO-r.js → erDiagram-SMLLAGMA-CpIeCOh2.js} +1 -1
  33. package/dist/assets/{flowDiagram-DWJPFMVM-XvlUuz-7.js → flowDiagram-DWJPFMVM-CHyoKnhW.js} +1 -1
  34. package/dist/assets/{ganttDiagram-T4ZO3ILL-hLBV57oV.js → ganttDiagram-T4ZO3ILL-DErKteO_.js} +1 -1
  35. package/dist/assets/{gitGraphDiagram-UUTBAWPF-BHu3s_Gn.js → gitGraphDiagram-UUTBAWPF-KFVAtj2F.js} +1 -1
  36. package/dist/assets/{graph-D0Cfv00Y.js → graph-CRnO_ifT.js} +1 -1
  37. package/dist/assets/index-DKBsEUJ-.css +1 -0
  38. package/dist/assets/index-DkRKLuNr.js +1144 -0
  39. package/dist/assets/{infoDiagram-42DDH7IO-DbqRsOo3.js → infoDiagram-42DDH7IO-BZFnuSp5.js} +1 -1
  40. package/dist/assets/{ishikawaDiagram-UXIWVN3A-DnCdx7zb.js → ishikawaDiagram-UXIWVN3A-4Xe2Szde.js} +1 -1
  41. package/dist/assets/{journeyDiagram-VCZTEJTY-CfD7eNcP.js → journeyDiagram-VCZTEJTY-CZRByfS-.js} +1 -1
  42. package/dist/assets/{kanban-definition-6JOO6SKY-BYaO9-mK.js → kanban-definition-6JOO6SKY-B95sk6Fk.js} +1 -1
  43. package/dist/assets/{layout-Bj72wOEB.js → layout-BqNQzxWT.js} +1 -1
  44. package/dist/assets/{linear-BRFo114D.js → linear-CUh7qb64.js} +1 -1
  45. package/dist/assets/{min-GCHnKlJS.js → min-wXgOS3ig.js} +1 -1
  46. package/dist/assets/{mindmap-definition-QFDTVHPH-n0PMebY4.js → mindmap-definition-QFDTVHPH-DB6iaAbO.js} +1 -1
  47. package/dist/assets/{pieDiagram-DEJITSTG-pN4CljHF.js → pieDiagram-DEJITSTG-CHkZHrTW.js} +1 -1
  48. package/dist/assets/{quadrantDiagram-34T5L4WZ-DNoAy8-D.js → quadrantDiagram-34T5L4WZ-DoTEO8e3.js} +1 -1
  49. package/dist/assets/{requirementDiagram-MS252O5E-BhtY05PT.js → requirementDiagram-MS252O5E-Dn8peXYp.js} +1 -1
  50. package/dist/assets/{sankeyDiagram-XADWPNL6-B6AD-16A.js → sankeyDiagram-XADWPNL6-DRXs6Ipb.js} +1 -1
  51. package/dist/assets/{sequenceDiagram-FGHM5R23-DShHM-uk.js → sequenceDiagram-FGHM5R23-wBBYZ0aq.js} +1 -1
  52. package/dist/assets/{stateDiagram-FHFEXIEX-DMxn7HTo.js → stateDiagram-FHFEXIEX-DPlBNGmf.js} +1 -1
  53. package/dist/assets/stateDiagram-v2-QKLJ7IA2-BW0ezXb4.js +1 -0
  54. package/dist/assets/{timeline-definition-GMOUNBTQ-Cdu6uq52.js → timeline-definition-GMOUNBTQ-CbbyTlHk.js} +1 -1
  55. package/dist/assets/{vennDiagram-DHZGUBPP-CpK29iRe.js → vennDiagram-DHZGUBPP-Bj4GaFfj.js} +1 -1
  56. package/dist/assets/{wardley-RL74JXVD-BQgSkdcO.js → wardley-RL74JXVD-RtNzq8KU.js} +55 -55
  57. package/dist/assets/{wardleyDiagram-NUSXRM2D-DJHYev6O.js → wardleyDiagram-NUSXRM2D-CDfE3zSj.js} +1 -1
  58. package/dist/assets/{xychartDiagram-5P7HB3ND-1d75pbaO.js → xychartDiagram-5P7HB3ND-CZXHHYD5.js} +1 -1
  59. package/dist/index.html +2 -2
  60. package/lib/budget-ledger.js +45 -0
  61. package/lib/bug-bisect.js +292 -0
  62. package/lib/bug-checkpoint.js +191 -0
  63. package/lib/bug-escalation.js +306 -0
  64. package/lib/bug-index-gen.js +136 -0
  65. package/lib/bug-ledger.js +126 -0
  66. package/lib/build-stream-schema.js +176 -0
  67. package/lib/build-stream-writer.js +3 -1
  68. package/lib/build.js +854 -284
  69. package/lib/connector-factory-shim.js +167 -0
  70. package/lib/constants.js +18 -0
  71. package/lib/debug-discipline.js +176 -27
  72. package/lib/deps.js +205 -0
  73. package/lib/health-score.js +4 -4
  74. package/lib/import.js +26 -13
  75. package/lib/inject-schema.js +21 -0
  76. package/lib/new.js +27 -53
  77. package/lib/result-normalizer.js +160 -144
  78. package/lib/review-lenses.js +5 -5
  79. package/lib/review-normalize.js +413 -0
  80. package/lib/review-prompt.js +163 -0
  81. package/lib/sections.js +325 -0
  82. package/lib/step-prompt.js +21 -1
  83. package/lib/step-validator.js +5 -3
  84. package/lib/stratum-mcp-client.js +172 -7
  85. package/package.json +14 -3
  86. package/pipelines/bug-fix.stratum.yaml +39 -1
  87. package/pipelines/build.stratum.yaml +28 -45
  88. package/pipelines/review-fix.stratum.yaml +1 -1
  89. package/presets/team-review.stratum.yaml +21 -14
  90. package/server/build-stream-bridge.js +28 -0
  91. package/server/cc-session-feature-resolver.js +111 -0
  92. package/server/cc-session-reader.js +327 -0
  93. package/server/cc-session-watcher.js +318 -0
  94. package/server/compose-mcp-tools.js +0 -125
  95. package/server/compose-mcp.js +2 -4
  96. package/server/contract-diff.js +192 -0
  97. package/server/decision-event-emit.js +175 -0
  98. package/server/decision-event-id.js +64 -0
  99. package/server/decision-events-snapshot.js +166 -0
  100. package/server/design-routes.js +92 -49
  101. package/server/drift-axes.js +365 -0
  102. package/server/drift-emit.js +121 -0
  103. package/server/gate-log-store.js +102 -0
  104. package/server/lifecycle-phase-history.js +44 -0
  105. package/server/open-loops-store.js +102 -0
  106. package/server/schema-validator.js +49 -0
  107. package/server/status-emit.js +27 -0
  108. package/server/status-snapshot.js +218 -0
  109. package/server/vision-routes.js +332 -4
  110. package/server/vision-server.js +104 -12
  111. package/server/vision-store.js +21 -0
  112. package/dist/assets/channel-DGElom1e.js +0 -1
  113. package/dist/assets/classDiagram-6PBFFD2Q-KqWP9wWZ.js +0 -1
  114. package/dist/assets/classDiagram-v2-HSJHXN6E-KqWP9wWZ.js +0 -1
  115. package/dist/assets/clone-DUJKJXd7.js +0 -1
  116. package/dist/assets/index-CUd6pFGF.css +0 -1
  117. package/dist/assets/index-DReRlzZI.js +0 -1144
  118. package/dist/assets/stateDiagram-v2-QKLJ7IA2-o6PnCs4e.js +0 -1
  119. package/server/connectors/agent-connector.js +0 -78
  120. package/server/connectors/claude-sdk-connector.js +0 -198
  121. package/server/connectors/codex-connector.js +0 -240
  122. package/server/connectors/connector-discovery.js +0 -18
  123. package/server/connectors/connector-runtime.js +0 -13
  124. package/server/connectors/opencode-connector.js +0 -200
@@ -1,200 +0,0 @@
1
- /**
2
- * OpencodeConnector — spawns `opencode run` for each prompt.
3
- *
4
- * Model-agnostic base for any non-Anthropic agent running through OpenCode.
5
- * NOT exposed as an MCP tool directly — subclasses (e.g. CodexConnector)
6
- * are exposed after constraining to a specific provider/model set.
7
- *
8
- * Uses `opencode run --format json` which streams structured JSON events
9
- * (step_start, text, tool_use, step_finish) to stdout. This is more reliable
10
- * than the SDK's serve mode which has event stream issues.
11
- */
12
-
13
- import { spawn } from 'node:child_process';
14
- import { createInterface } from 'node:readline';
15
- import { AgentConnector, injectSchema } from './agent-connector.js';
16
-
17
- // ---------------------------------------------------------------------------
18
- // OpencodeConnector
19
- // ---------------------------------------------------------------------------
20
-
21
- export class OpencodeConnector extends AgentConnector {
22
- // ── Discovery ──────────────────────────────────────────────────────────────
23
- // No overrides — inherits stubs from AgentConnector. See agent-connector.js.
24
-
25
- _defaultProviderID;
26
- _defaultModelID;
27
- _cwd;
28
- _agentName;
29
- #proc = null;
30
-
31
- /**
32
- * @param {object} opts
33
- * @param {string} opts.providerID — OpenCode provider ID (e.g. 'openai')
34
- * @param {string} opts.modelID — model ID (e.g. 'gpt-5.4')
35
- * @param {string} [opts.cwd] — default working directory
36
- * @param {string} [opts.agentName] — label used in system messages
37
- */
38
- constructor({ providerID, modelID, cwd = process.cwd(), agentName = 'opencode' }) {
39
- super();
40
- this._defaultProviderID = providerID;
41
- this._defaultModelID = modelID;
42
- this._cwd = cwd;
43
- this._agentName = agentName;
44
- }
45
-
46
- // ── Runtime ────────────────────────────────────────────────────────────────
47
-
48
- async *run(prompt, { schema, modelID, providerID, cwd } = {}) {
49
- if (this.#proc) {
50
- throw new Error(`${this._agentName}: run() already active. Call interrupt() first.`);
51
- }
52
-
53
- const resolvedProviderID = providerID ?? this._defaultProviderID;
54
- const resolvedModelID = modelID ?? this._defaultModelID;
55
- const resolvedCwd = cwd ?? this._cwd;
56
- const actualPrompt = schema ? injectSchema(prompt, schema) : prompt;
57
-
58
- yield {
59
- type: 'system', subtype: 'init',
60
- agent: this._agentName, model: `${resolvedProviderID}/${resolvedModelID}`,
61
- };
62
-
63
- // Build clean env: remove OPENAI_API_KEY so opencode uses OAuth
64
- // (API key overrides OAuth and may lack Codex model access)
65
- const cleanEnv = { ...process.env };
66
- delete cleanEnv.OPENAI_API_KEY;
67
-
68
- const proc = spawn('opencode', [
69
- 'run',
70
- '-m', `${resolvedProviderID}/${resolvedModelID}`,
71
- '--format', 'json',
72
- actualPrompt,
73
- ], {
74
- cwd: resolvedCwd,
75
- stdio: ['ignore', 'pipe', 'pipe'],
76
- env: cleanEnv,
77
- });
78
- this.#proc = proc;
79
-
80
- // Read JSON events line-by-line from stdout
81
- const rl = createInterface({ input: proc.stdout, crlfDelay: Infinity });
82
-
83
- const textParts = [];
84
- let stderrChunks = [];
85
-
86
- // Stream stderr live — detect rate-limit, auth, and quota errors immediately
87
- proc.stderr.on('data', chunk => {
88
- stderrChunks.push(chunk);
89
- const text = chunk.toString();
90
- const lower = text.toLowerCase();
91
- // Check for actionable errors that should surface immediately
92
- if (lower.includes('rate limit') || lower.includes('rate_limit') ||
93
- lower.includes('quota') || lower.includes('insufficient_quota') ||
94
- lower.includes('unauthorized') || lower.includes('401') ||
95
- lower.includes('403') || lower.includes('authentication') ||
96
- lower.includes('auth') || lower.includes('billing') ||
97
- lower.includes('exceeded') || lower.includes('capacity')) {
98
- process.stderr.write(`\n⚠ ${this._agentName}: ${text.trim()}\n`);
99
- process.stderr.write(` → Check account: opencode auth status\n`);
100
- process.stderr.write(` → Switch account: opencode auth login\n\n`);
101
- }
102
- });
103
-
104
- // Stall detection — warn if no stdout events for 120s
105
- let lastEventAt = Date.now();
106
- const stallTimer = setInterval(() => {
107
- const silent = Math.round((Date.now() - lastEventAt) / 1000);
108
- if (silent >= 120) {
109
- process.stderr.write(`\n⚠ ${this._agentName}: no response for ${silent}s — may be stalled or rate-limited\n`);
110
- process.stderr.write(` → Press s to skip, or Ctrl+C to abort\n\n`);
111
- }
112
- }, 30_000);
113
-
114
- try {
115
- for await (const line of rl) {
116
- if (!line.trim()) continue;
117
- lastEventAt = Date.now();
118
-
119
- let event;
120
- try {
121
- event = JSON.parse(line);
122
- } catch {
123
- continue; // skip non-JSON lines
124
- }
125
-
126
- if (event.type === 'text') {
127
- const text = event.part?.text ?? '';
128
- if (text) {
129
- textParts.push(text);
130
- yield { type: 'assistant', content: text };
131
- }
132
- } else if (event.type === 'tool_use') {
133
- const tool = event.part?.tool ?? event.part?.state?.input?.command ? 'bash' : 'unknown';
134
- const input = event.part?.state?.input ?? {};
135
- yield { type: 'tool_use', tool, input };
136
-
137
- // If tool has output, yield a summary
138
- const output = event.part?.state?.output;
139
- if (output && typeof output === 'string') {
140
- const short = output.length > 80 ? output.slice(0, 77) + '...' : output;
141
- yield { type: 'tool_use_summary', summary: short, output: output.slice(0, 2048) };
142
- }
143
- } else if (event.type === 'step_finish') {
144
- // step_finish includes cost and token info — forward as usage event
145
- const part = event.part;
146
- if (part && (part.cost != null || part.tokens != null)) {
147
- if (process.env.COMPOSE_DEBUG) {
148
- process.stderr.write(` [${this._agentName}] cost=$${(part.cost ?? 0).toFixed(4)} tokens=${part.tokens?.total}\n`);
149
- }
150
- yield {
151
- type: 'usage',
152
- input_tokens: part.tokens?.input ?? 0,
153
- output_tokens: part.tokens?.output ?? 0,
154
- cache_creation_input_tokens: part.tokens?.cache_write ?? 0,
155
- cache_read_input_tokens: part.tokens?.cache_read ?? 0,
156
- cost_usd: part.cost ?? 0,
157
- model: resolvedModelID,
158
- };
159
- }
160
- }
161
- // step_start is ignored (already yielded init)
162
- }
163
-
164
- // Wait for process to exit
165
- const exitCode = await new Promise((resolve) => {
166
- proc.on('close', resolve);
167
- });
168
-
169
- if (exitCode !== 0 && textParts.length === 0) {
170
- const stderr = Buffer.concat(stderrChunks).toString();
171
- yield { type: 'error', message: stderr || `opencode exited with code ${exitCode}` };
172
- } else {
173
- // Yield the full concatenated text as a result
174
- const fullText = textParts.join('');
175
- if (fullText) {
176
- yield { type: 'result', content: fullText };
177
- }
178
- yield { type: 'system', subtype: 'complete', agent: this._agentName };
179
- }
180
- } catch (err) {
181
- if (err?.name !== 'AbortError') {
182
- yield { type: 'error', message: err.message || String(err) };
183
- }
184
- } finally {
185
- clearInterval(stallTimer);
186
- this.#proc = null;
187
- }
188
- }
189
-
190
- interrupt() {
191
- if (this.#proc) {
192
- try { this.#proc.kill('SIGTERM'); } catch { /* ignore */ }
193
- this.#proc = null;
194
- }
195
- }
196
-
197
- get isRunning() {
198
- return this.#proc !== null;
199
- }
200
- }