@smartmemory/compose 0.1.7-beta → 0.1.9-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.
- package/README.md +32 -5
- package/bin/compose.js +294 -34
- package/bin/git-hooks/post-commit.template +2 -1
- package/bin/git-hooks/pre-push.template +2 -1
- package/dist/assets/{_baseUniq-D-avYfn5.js → _baseUniq-3jW4HAOf.js} +1 -1
- package/dist/assets/{arc-BC4dfQ-X.js → arc-DzzDimyd.js} +1 -1
- package/dist/assets/{architectureDiagram-Q4EWVU46-BZmFXnGI.js → architectureDiagram-Q4EWVU46-CtAgwORz.js} +1 -1
- package/dist/assets/{blockDiagram-DXYQGD6D-DlfWSuux.js → blockDiagram-DXYQGD6D-Bryby0c_.js} +1 -1
- package/dist/assets/{c4Diagram-AHTNJAMY-Y__uJrRx.js → c4Diagram-AHTNJAMY-C7N9RTJ8.js} +1 -1
- package/dist/assets/channel-DDkv7DUd.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-BfMePfTp.js → chunk-4BX2VUAB-wijkFgZY.js} +1 -1
- package/dist/assets/{chunk-4TB4RGXK-BdlMSdEA.js → chunk-4TB4RGXK-zdSZGRS2.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-vrQHZTdv.js → chunk-55IACEB6-6zqzTZQQ.js} +1 -1
- package/dist/assets/{chunk-EDXVE4YY-B8wioVlW.js → chunk-EDXVE4YY-frd1Vwf-.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-Cd6Hrux2.js → chunk-FMBD7UC4-CdkRK5Hx.js} +1 -1
- package/dist/assets/{chunk-OYMX7WX6-CfrhdQXY.js → chunk-OYMX7WX6-C6bMB0cf.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-B9JQerOU.js → chunk-QZHKN3VN-4vsxN3jq.js} +1 -1
- package/dist/assets/{chunk-YZCP3GAM-DFN9X99H.js → chunk-YZCP3GAM-DbNARKip.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-J6ZTeCbW.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-J6ZTeCbW.js +1 -0
- package/dist/assets/clone-5MVZ89iV.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-BAn0ap_E.js → cose-bilkent-S5V4N54A-BpXeV7Vj.js} +1 -1
- package/dist/assets/{dagre-KV5264BT-DyxnVq1g.js → dagre-KV5264BT-DQLu_W8r.js} +1 -1
- package/dist/assets/{diagram-5BDNPKRD-XCrzqski.js → diagram-5BDNPKRD-skaOoe5A.js} +1 -1
- package/dist/assets/{diagram-G4DWMVQ6-MBCAXft_.js → diagram-G4DWMVQ6-DezlfFH4.js} +1 -1
- package/dist/assets/{diagram-MMDJMWI5-DbtB2yS6.js → diagram-MMDJMWI5-BUu-v-wT.js} +1 -1
- package/dist/assets/{diagram-TYMM5635-Bb5NzX61.js → diagram-TYMM5635-CziQ6LPs.js} +1 -1
- package/dist/assets/{erDiagram-SMLLAGMA-CpIeCOh2.js → erDiagram-SMLLAGMA-BsAyOVTI.js} +1 -1
- package/dist/assets/{flowDiagram-DWJPFMVM-CHyoKnhW.js → flowDiagram-DWJPFMVM-CbYWJOLq.js} +1 -1
- package/dist/assets/{ganttDiagram-T4ZO3ILL-DErKteO_.js → ganttDiagram-T4ZO3ILL-CAwgDkLl.js} +1 -1
- package/dist/assets/{gitGraphDiagram-UUTBAWPF-KFVAtj2F.js → gitGraphDiagram-UUTBAWPF-DK4RlkjO.js} +1 -1
- package/dist/assets/{graph-CRnO_ifT.js → graph-orv1XHGx.js} +1 -1
- package/dist/assets/{index-DkRKLuNr.js → index-Ceywghsu.js} +143 -143
- package/dist/assets/{infoDiagram-42DDH7IO-BZFnuSp5.js → infoDiagram-42DDH7IO-DQyA75sK.js} +1 -1
- package/dist/assets/{ishikawaDiagram-UXIWVN3A-4Xe2Szde.js → ishikawaDiagram-UXIWVN3A-C-F_5q4k.js} +1 -1
- package/dist/assets/{journeyDiagram-VCZTEJTY-CZRByfS-.js → journeyDiagram-VCZTEJTY-Bj8UIvK-.js} +1 -1
- package/dist/assets/{kanban-definition-6JOO6SKY-B95sk6Fk.js → kanban-definition-6JOO6SKY-DZYr8Dp1.js} +1 -1
- package/dist/assets/{layout-BqNQzxWT.js → layout-CBaTKjpX.js} +1 -1
- package/dist/assets/{linear-CUh7qb64.js → linear-j1sI_SiN.js} +1 -1
- package/dist/assets/{min-wXgOS3ig.js → min-DtJISjld.js} +1 -1
- package/dist/assets/{mindmap-definition-QFDTVHPH-DB6iaAbO.js → mindmap-definition-QFDTVHPH-Bulb64RS.js} +1 -1
- package/dist/assets/{pieDiagram-DEJITSTG-CHkZHrTW.js → pieDiagram-DEJITSTG-D11keQxr.js} +1 -1
- package/dist/assets/{quadrantDiagram-34T5L4WZ-DoTEO8e3.js → quadrantDiagram-34T5L4WZ-BEcWQiEG.js} +1 -1
- package/dist/assets/{requirementDiagram-MS252O5E-Dn8peXYp.js → requirementDiagram-MS252O5E-Cbp23uDf.js} +1 -1
- package/dist/assets/{sankeyDiagram-XADWPNL6-DRXs6Ipb.js → sankeyDiagram-XADWPNL6-Dae1hMc5.js} +1 -1
- package/dist/assets/{sequenceDiagram-FGHM5R23-wBBYZ0aq.js → sequenceDiagram-FGHM5R23-C16abORi.js} +1 -1
- package/dist/assets/{stateDiagram-FHFEXIEX-DPlBNGmf.js → stateDiagram-FHFEXIEX-CbEtfhbx.js} +1 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-CyY84hEA.js +1 -0
- package/dist/assets/{timeline-definition-GMOUNBTQ-CbbyTlHk.js → timeline-definition-GMOUNBTQ-BV7JTNMI.js} +1 -1
- package/dist/assets/{vennDiagram-DHZGUBPP-Bj4GaFfj.js → vennDiagram-DHZGUBPP-DBZiT48j.js} +1 -1
- package/dist/assets/{wardley-RL74JXVD-RtNzq8KU.js → wardley-RL74JXVD-Cc8uoiL3.js} +37 -37
- package/dist/assets/{wardleyDiagram-NUSXRM2D-CDfE3zSj.js → wardleyDiagram-NUSXRM2D-DEYcWGo5.js} +1 -1
- package/dist/assets/{xychartDiagram-5P7HB3ND-CZXHHYD5.js → xychartDiagram-5P7HB3ND-bFhLXv2b.js} +1 -1
- package/dist/index.html +1 -1
- package/lib/build.js +193 -19
- package/lib/completion-writer.js +7 -4
- package/lib/deps.js +17 -6
- package/lib/discover-workspaces.js +109 -0
- package/lib/feature-events.js +3 -0
- package/lib/feature-writer.js +34 -22
- package/lib/followup-writer.js +556 -0
- package/lib/mcp-enforcement.js +173 -0
- package/lib/migrate-roadmap.js +4 -1
- package/lib/project-paths.js +36 -0
- package/lib/resolve-workspace.js +166 -0
- package/lib/review-lenses.js +23 -8
- package/lib/review-normalize.js +42 -3
- package/lib/roadmap-drift.js +54 -0
- package/lib/roadmap-gen.js +297 -27
- package/lib/roadmap-preservers.js +353 -0
- package/lib/step-prompt.js +15 -0
- package/lib/triage.js +2 -1
- package/lib/version-check.js +110 -0
- package/package.json +1 -2
- package/server/compose-mcp-tools.js +44 -8
- package/server/compose-mcp.js +66 -1
- package/server/project-root.js +4 -0
- package/server/vision-routes.js +51 -2
- package/templates/ROADMAP.md +6 -0
- package/dist/assets/channel-LRG9kHqJ.js +0 -1
- package/dist/assets/classDiagram-6PBFFD2Q-BC9a6pDE.js +0 -1
- package/dist/assets/classDiagram-v2-HSJHXN6E-BC9a6pDE.js +0 -1
- package/dist/assets/clone-dRxgFrBv.js +0 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-BW0ezXb4.js +0 -1
package/server/compose-mcp.js
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
toolLinkFeatures,
|
|
51
51
|
toolGetFeatureArtifacts,
|
|
52
52
|
toolGetFeatureLinks,
|
|
53
|
+
toolProposeFollowup,
|
|
53
54
|
toolAddChangelogEntry,
|
|
54
55
|
toolGetChangelogEntries,
|
|
55
56
|
toolWriteJournalEntry,
|
|
@@ -58,7 +59,12 @@ import {
|
|
|
58
59
|
toolGetCompletions,
|
|
59
60
|
toolValidateFeature,
|
|
60
61
|
toolValidateProject,
|
|
62
|
+
toolSetWorkspace,
|
|
63
|
+
toolGetWorkspace,
|
|
64
|
+
_getBinding,
|
|
61
65
|
} from './compose-mcp-tools.js';
|
|
66
|
+
import { switchProject, getTargetRoot } from './project-root.js';
|
|
67
|
+
import { resolveWorkspace } from '../lib/resolve-workspace.js';
|
|
62
68
|
|
|
63
69
|
// ---------------------------------------------------------------------------
|
|
64
70
|
// Tool definitions
|
|
@@ -150,6 +156,20 @@ const TOOLS = [
|
|
|
150
156
|
required: ['featureCode'],
|
|
151
157
|
},
|
|
152
158
|
},
|
|
159
|
+
{
|
|
160
|
+
name: 'set_workspace',
|
|
161
|
+
description: 'Bind this MCP session to a workspace. Required when cwd contains multiple workspaces. Lives in process memory; lost on MCP restart.',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
required: ['workspaceId'],
|
|
165
|
+
properties: { workspaceId: { type: 'string', description: 'Workspace ID (kebab-case)' } },
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'get_workspace',
|
|
170
|
+
description: 'Get the current MCP workspace binding plus all candidates discovered from cwd.',
|
|
171
|
+
inputSchema: { type: 'object', properties: {} },
|
|
172
|
+
},
|
|
153
173
|
{
|
|
154
174
|
name: 'get_feature_lifecycle',
|
|
155
175
|
description: 'Get the lifecycle state of a feature: current phase, phase history, artifacts, warnings.',
|
|
@@ -175,11 +195,15 @@ const TOOLS = [
|
|
|
175
195
|
},
|
|
176
196
|
{
|
|
177
197
|
name: 'complete_feature',
|
|
178
|
-
description: 'Mark a feature as complete. Only callable from the ship phase.',
|
|
198
|
+
description: 'Mark a feature as complete. Only callable from the ship phase. When commit_sha is provided, the lifecycle endpoint also writes a commit-bound completion record via record_completion (which atomically flips feature.status to COMPLETE and regenerates ROADMAP.md). Without commit_sha, the lifecycle transitions but no completion record is written; a `cockpit_completion_skipped` decision event explains the skip.',
|
|
179
199
|
inputSchema: {
|
|
180
200
|
type: 'object',
|
|
181
201
|
properties: {
|
|
182
202
|
id: { type: 'string', description: 'Item ID' },
|
|
203
|
+
commit_sha: { type: 'string', description: 'Full 40-char commit SHA. Required to write a completion record.' },
|
|
204
|
+
tests_pass: { type: 'boolean', description: 'Defaults to true when commit_sha is provided.' },
|
|
205
|
+
files_changed: { type: 'array', items: { type: 'string' }, description: 'Repo-relative paths committed in the SHA.' },
|
|
206
|
+
notes: { type: 'string', description: 'One-line note for the completion record.' },
|
|
183
207
|
},
|
|
184
208
|
required: ['id'],
|
|
185
209
|
},
|
|
@@ -348,6 +372,23 @@ const TOOLS = [
|
|
|
348
372
|
},
|
|
349
373
|
},
|
|
350
374
|
},
|
|
375
|
+
{
|
|
376
|
+
name: 'propose_followup',
|
|
377
|
+
description: 'File a follow-up feature against a parent. Auto-numbers the next code in the parent\'s namespace (parent_code-N), adds the ROADMAP row, links surfaced_by from new → parent, and scaffolds design.md with a "## Why" rationale block. Idempotent on (parent_code, idempotency_key); resumes across partial failures via an inflight ledger.',
|
|
378
|
+
inputSchema: {
|
|
379
|
+
type: 'object',
|
|
380
|
+
required: ['parent_code', 'description', 'rationale'],
|
|
381
|
+
properties: {
|
|
382
|
+
parent_code: { type: 'string', description: 'Parent feature code (e.g. "COMP-MCP-MIGRATION"). Must exist; must not be KILLED/SUPERSEDED.' },
|
|
383
|
+
description: { type: 'string', description: 'One-line description for the ROADMAP cell.' },
|
|
384
|
+
rationale: { type: 'string', description: 'Why this follow-up exists. Persisted as a "## Why" block in the new design.md and in the audit event.' },
|
|
385
|
+
complexity: { type: 'string', enum: ['S', 'M', 'L', 'XL'] },
|
|
386
|
+
phase: { type: 'string', description: 'Phase heading. Defaults to the parent\'s phase if omitted.' },
|
|
387
|
+
status: { type: 'string', enum: ['PLANNED', 'IN_PROGRESS', 'PARTIAL', 'COMPLETE', 'BLOCKED', 'KILLED', 'PARKED', 'SUPERSEDED'] },
|
|
388
|
+
idempotency_key: { type: 'string', description: 'Optional retry-safety key. Without it, repeated calls allocate new codes.' },
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
},
|
|
351
392
|
|
|
352
393
|
// -------------------------------------------------------------------------
|
|
353
394
|
// Linker — COMP-MCP-ARTIFACT-LINKER
|
|
@@ -548,7 +589,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
548
589
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
549
590
|
const { name, arguments: args = {} } = request.params;
|
|
550
591
|
|
|
592
|
+
const WORKSPACE_EXEMPT = new Set(['set_workspace', 'get_workspace']);
|
|
593
|
+
|
|
551
594
|
try {
|
|
595
|
+
if (!WORKSPACE_EXEMPT.has(name)) {
|
|
596
|
+
const ws = resolveWorkspace({ getBinding: _getBinding });
|
|
597
|
+
if (ws.root !== getTargetRoot()) switchProject(ws.root);
|
|
598
|
+
}
|
|
552
599
|
let result;
|
|
553
600
|
switch (name) {
|
|
554
601
|
case 'get_vision_items': result = toolGetVisionItems(args); break;
|
|
@@ -557,6 +604,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
557
604
|
case 'get_blocked_items': result = toolGetBlockedItems(); break;
|
|
558
605
|
case 'get_current_session': result = await toolGetCurrentSession(args); break;
|
|
559
606
|
case 'bind_session': result = await toolBindSession(args); break;
|
|
607
|
+
case 'set_workspace': result = toolSetWorkspace(args); break;
|
|
608
|
+
case 'get_workspace': result = toolGetWorkspace(); break;
|
|
560
609
|
case 'get_feature_lifecycle': result = toolGetFeatureLifecycle(args); break;
|
|
561
610
|
case 'kill_feature': result = await toolKillFeature(args); break;
|
|
562
611
|
case 'complete_feature': result = await toolCompleteFeature(args); break;
|
|
@@ -582,6 +631,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
582
631
|
case 'get_completions': result = await toolGetCompletions(args); break;
|
|
583
632
|
case 'validate_feature': result = await toolValidateFeature(args); break;
|
|
584
633
|
case 'validate_project': result = await toolValidateProject(args); break;
|
|
634
|
+
case 'propose_followup': result = await toolProposeFollowup(args); break;
|
|
585
635
|
// agent_run removed — STRAT-DEDUP-AGENTRUN v1. Use mcp__stratum__stratum_agent_run.
|
|
586
636
|
default:
|
|
587
637
|
return {
|
|
@@ -601,6 +651,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
601
651
|
let text = err && err.code
|
|
602
652
|
? `Error [${err.code}]: ${err.message}`
|
|
603
653
|
: `Error: ${err.message}`;
|
|
654
|
+
// For workspace ambiguity, include the candidate list and the call to fix it
|
|
655
|
+
// so Claude can prompt the user without a follow-up tool call.
|
|
656
|
+
if (err && err.code === 'WorkspaceAmbiguous' && Array.isArray(err.candidates)) {
|
|
657
|
+
text += '\n\nCandidates:';
|
|
658
|
+
for (const c of err.candidates) text += `\n - ${c.id} (${c.root})`;
|
|
659
|
+
text += '\n\nNext step: call set_workspace({"workspaceId": "<id>"}) and retry.';
|
|
660
|
+
}
|
|
661
|
+
if (err && err.code === 'WorkspaceIdCollision' && Array.isArray(err.roots)) {
|
|
662
|
+
text += `\n\nworkspaceId "${err.id}" is used by multiple roots:`;
|
|
663
|
+
for (const r of err.roots) text += `\n - ${r}`;
|
|
664
|
+
text += '\n\nFix: set an explicit workspaceId in each .compose/compose.json.';
|
|
665
|
+
}
|
|
666
|
+
if (err && err.code === 'WorkspaceUnset') {
|
|
667
|
+
text += '\n\nNo .compose/ workspace was found. Run `compose init` to scaffold one.';
|
|
668
|
+
}
|
|
604
669
|
if (err && err.cause && typeof err.cause.message === 'string') {
|
|
605
670
|
text += err.cause.code
|
|
606
671
|
? `\n Caused by [${err.cause.code}]: ${err.cause.message}`
|
package/server/project-root.js
CHANGED
|
@@ -48,6 +48,10 @@ export function getTargetRoot() { return _targetRoot; }
|
|
|
48
48
|
/** Data directory for Compose state. Lives in the target project. */
|
|
49
49
|
export function getDataDir() { return _dataDir; }
|
|
50
50
|
|
|
51
|
+
let _currentWorkspaceId = null;
|
|
52
|
+
export function getCurrentWorkspaceId() { return _currentWorkspaceId; }
|
|
53
|
+
export function setCurrentWorkspaceId(id) { _currentWorkspaceId = id; }
|
|
54
|
+
|
|
51
55
|
// ---------------------------------------------------------------------------
|
|
52
56
|
// Switch project at runtime
|
|
53
57
|
// ---------------------------------------------------------------------------
|
package/server/vision-routes.js
CHANGED
|
@@ -338,7 +338,7 @@ export function attachVisionRoutes(app, { store, scheduleBroadcast, broadcastMes
|
|
|
338
338
|
}
|
|
339
339
|
});
|
|
340
340
|
|
|
341
|
-
app.post('/api/vision/items/:id/lifecycle/complete', (req, res) => {
|
|
341
|
+
app.post('/api/vision/items/:id/lifecycle/complete', async (req, res) => {
|
|
342
342
|
try {
|
|
343
343
|
const item = store.items.get(req.params.id);
|
|
344
344
|
if (!item?.lifecycle) return res.status(404).json({ error: 'No lifecycle on this item' });
|
|
@@ -360,7 +360,56 @@ export function attachVisionRoutes(app, { store, scheduleBroadcast, broadcastMes
|
|
|
360
360
|
emitDriftAxes(broadcastMessage, store, item, projectRoot, now);
|
|
361
361
|
// COMP-OBS-STATUS: emit status snapshot after lifecycle transition (complete)
|
|
362
362
|
emitStatusSnapshot(broadcastMessage, store, item.lifecycle.featureCode, now);
|
|
363
|
-
|
|
363
|
+
|
|
364
|
+
// COMP-MCP-MIGRATION: reconcile cockpit complete with record_completion
|
|
365
|
+
// (commit-bound completion writer). Best-effort: failures emit a decision
|
|
366
|
+
// event but never roll back the lifecycle transition.
|
|
367
|
+
const featureCode = item.lifecycle.featureCode;
|
|
368
|
+
const completionResult = { partial: false };
|
|
369
|
+
if (featureCode) {
|
|
370
|
+
const { commit_sha, tests_pass, files_changed, notes } = req.body || {};
|
|
371
|
+
if (commit_sha) {
|
|
372
|
+
try {
|
|
373
|
+
const { recordCompletion } = await import('../lib/completion-writer.js');
|
|
374
|
+
await recordCompletion(projectRoot, {
|
|
375
|
+
feature_code: featureCode,
|
|
376
|
+
commit_sha,
|
|
377
|
+
tests_pass: tests_pass ?? true,
|
|
378
|
+
files_changed: files_changed ?? [],
|
|
379
|
+
notes: notes ?? `cockpit lifecycle: ${featureCode} complete`,
|
|
380
|
+
});
|
|
381
|
+
} catch (err) {
|
|
382
|
+
completionResult.partial = true;
|
|
383
|
+
const eventType = err.code === 'STATUS_FLIP_AFTER_COMPLETION_RECORDED'
|
|
384
|
+
? 'cockpit_completion_partial_status_flip'
|
|
385
|
+
: 'cockpit_completion_failed';
|
|
386
|
+
completionResult.completion_failed = err.code || 'UNKNOWN';
|
|
387
|
+
completionResult.message = err.message;
|
|
388
|
+
try {
|
|
389
|
+
emitDecisionEvent(broadcastMessage, {
|
|
390
|
+
type: eventType,
|
|
391
|
+
featureCode,
|
|
392
|
+
timestamp: now,
|
|
393
|
+
error: { code: err.code, message: err.message },
|
|
394
|
+
});
|
|
395
|
+
} catch { /* decision event emit best-effort */ }
|
|
396
|
+
// eslint-disable-next-line no-console
|
|
397
|
+
console.warn(`[lifecycle/complete] record_completion ${eventType} for ${featureCode}: ${err.message}`);
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
// No SHA — emit a skip event so validate_feature can flag drift later
|
|
401
|
+
try {
|
|
402
|
+
emitDecisionEvent(broadcastMessage, {
|
|
403
|
+
type: 'cockpit_completion_skipped',
|
|
404
|
+
featureCode,
|
|
405
|
+
timestamp: now,
|
|
406
|
+
reason: 'no_commit_sha',
|
|
407
|
+
});
|
|
408
|
+
} catch { /* decision event emit best-effort */ }
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
res.json({ completedAt: now, ...completionResult });
|
|
364
413
|
} catch (err) {
|
|
365
414
|
const status = err.message.includes('not found') ? 404 : 400;
|
|
366
415
|
res.status(status).json({ error: err.message });
|
package/templates/ROADMAP.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
<!-- preserved-section: roadmap-conventions -->
|
|
8
9
|
## Roadmap Conventions
|
|
9
10
|
|
|
10
11
|
- **Status:** `PLANNED` | `IN_PROGRESS` | `PARTIAL` | `COMPLETE` | `SUPERSEDED` | `PARKED`
|
|
@@ -12,6 +13,8 @@
|
|
|
12
13
|
- Items are numbered sequentially across all phases — never reuse a number.
|
|
13
14
|
- Cross-reference stable IDs (e.g. `FEAT-1`, `Phase 2`) not section headings.
|
|
14
15
|
|
|
16
|
+
<!-- /preserved-section -->
|
|
17
|
+
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
## Phase 1: Foundation — PLANNED
|
|
@@ -37,6 +40,7 @@ Bootstrap: establish the core structure and first working milestone.
|
|
|
37
40
|
|
|
38
41
|
---
|
|
39
42
|
|
|
43
|
+
<!-- preserved-section: dogfooding-milestones -->
|
|
40
44
|
## Dogfooding Milestones
|
|
41
45
|
|
|
42
46
|
| Milestone | Description | Status |
|
|
@@ -44,3 +48,5 @@ Bootstrap: establish the core structure and first working milestone.
|
|
|
44
48
|
| D0: Bootstrap | Manual, out-of-band. | PLANNED |
|
|
45
49
|
| D1: [First self-use milestone] | [Description] | PLANNED |
|
|
46
50
|
| D2: [Second self-use milestone] | [Description] | PLANNED |
|
|
51
|
+
|
|
52
|
+
<!-- /preserved-section -->
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{aq as o,ar as n}from"./index-DkRKLuNr.js";const t=(r,a)=>o.lang.round(n.parse(r)[a]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-BdlMSdEA.js";import{_ as i}from"./index-DkRKLuNr.js";import"./chunk-FMBD7UC4-Cd6Hrux2.js";import"./chunk-YZCP3GAM-DFN9X99H.js";import"./chunk-55IACEB6-vrQHZTdv.js";import"./chunk-EDXVE4YY-B8wioVlW.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-BdlMSdEA.js";import{_ as i}from"./index-DkRKLuNr.js";import"./chunk-FMBD7UC4-Cd6Hrux2.js";import"./chunk-YZCP3GAM-DFN9X99H.js";import"./chunk-55IACEB6-vrQHZTdv.js";import"./chunk-EDXVE4YY-B8wioVlW.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as r}from"./graph-CRnO_ifT.js";var e=4;function a(o){return r(o,e)}export{a as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as t,b as r,a,S as s}from"./chunk-OYMX7WX6-CfrhdQXY.js";import{_ as i}from"./index-DkRKLuNr.js";import"./chunk-55IACEB6-vrQHZTdv.js";import"./chunk-EDXVE4YY-B8wioVlW.js";var l={parser:a,get db(){return new s(2)},renderer:r,styles:t,init:i(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")};export{l as diagram};
|