@smartmemory/compose 0.1.6-beta → 0.1.8-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 +353 -60
- package/bin/git-hooks/pre-push.template +26 -0
- package/contracts/feature-json.schema.json +115 -0
- package/contracts/roadmap-row.schema.json +23 -0
- package/contracts/vision-state.schema.json +64 -0
- 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 +8 -6
- package/lib/deps.js +17 -6
- package/lib/feature-code.js +29 -0
- package/lib/feature-events.js +3 -0
- package/lib/feature-validator.js +629 -0
- package/lib/feature-writer.js +35 -23
- package/lib/followup-writer.js +556 -0
- package/lib/journal-writer.js +1 -1
- package/lib/mcp-enforcement.js +173 -0
- package/lib/migrate-roadmap.js +4 -1
- package/lib/project-paths.js +36 -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 -1
- package/server/compose-mcp-tools.js +34 -2
- package/server/compose-mcp.js +52 -1
- package/server/schema-validator.js +50 -9
- 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
|
@@ -5,26 +5,43 @@ import Ajv from 'ajv';
|
|
|
5
5
|
import addFormats from 'ajv-formats';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const
|
|
8
|
+
const DEFAULT_SCHEMA_PATH = resolve(__dirname, '../contracts/comp-obs-contract.schema.json');
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// Per-path cache. Each entry: { schema, ajv }.
|
|
11
|
+
const cache = new Map();
|
|
11
12
|
|
|
12
|
-
function load() {
|
|
13
|
-
if (
|
|
14
|
-
const schema = JSON.parse(readFileSync(
|
|
13
|
+
function load(schemaPath = DEFAULT_SCHEMA_PATH) {
|
|
14
|
+
if (cache.has(schemaPath)) return cache.get(schemaPath);
|
|
15
|
+
const schema = JSON.parse(readFileSync(schemaPath, 'utf8'));
|
|
15
16
|
const ajv = new Ajv({ strict: false, allErrors: true });
|
|
16
17
|
addFormats(ajv);
|
|
17
18
|
ajv.addSchema(schema);
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const entry = { schema, ajv };
|
|
20
|
+
cache.set(schemaPath, entry);
|
|
21
|
+
return entry;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Load (and cache) a schema by absolute path. Returns `{ schema, ajv }`.
|
|
26
|
+
* Used by code that wants to compile arbitrary `$ref`s against the schema
|
|
27
|
+
* without going through the SchemaValidator class.
|
|
28
|
+
*/
|
|
29
|
+
export function loadSchema(schemaPath) {
|
|
30
|
+
return load(schemaPath);
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
export class SchemaValidator {
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} [schemaPath] Absolute path to a JSON Schema file.
|
|
36
|
+
* Default is the comp-obs-contract schema (back-compat for existing
|
|
37
|
+
* callers that pass no args).
|
|
38
|
+
*/
|
|
39
|
+
constructor(schemaPath = DEFAULT_SCHEMA_PATH) {
|
|
40
|
+
const { schema, ajv } = load(schemaPath);
|
|
25
41
|
this.schema = schema;
|
|
26
42
|
this.ajv = ajv;
|
|
27
43
|
this._validators = new Map();
|
|
44
|
+
this._rootValidator = null;
|
|
28
45
|
}
|
|
29
46
|
|
|
30
47
|
_getValidator(defName) {
|
|
@@ -39,11 +56,35 @@ export class SchemaValidator {
|
|
|
39
56
|
return v;
|
|
40
57
|
}
|
|
41
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Validate `obj` against `schema.definitions[defName]`. Used by the
|
|
61
|
+
* comp-obs-contract code paths.
|
|
62
|
+
*/
|
|
42
63
|
validate(defName, obj) {
|
|
43
64
|
const v = this._getValidator(defName);
|
|
44
65
|
const valid = v(obj);
|
|
45
66
|
return { valid: !!valid, errors: valid ? [] : (v.errors || []) };
|
|
46
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Validate `obj` against the schema's root (no $defs/$ref indirection).
|
|
71
|
+
* Used by feature-json / vision-state / roadmap-row schemas, which are
|
|
72
|
+
* top-level shapes without nested definitions.
|
|
73
|
+
*/
|
|
74
|
+
validateRoot(obj) {
|
|
75
|
+
if (!this._rootValidator) {
|
|
76
|
+
// ajv.getSchema by $id returns the root validator if the schema was
|
|
77
|
+
// added via addSchema (which load() does).
|
|
78
|
+
let v = this.schema.$id ? this.ajv.getSchema(this.schema.$id) : null;
|
|
79
|
+
if (!v) v = this.ajv.compile(this.schema);
|
|
80
|
+
this._rootValidator = v;
|
|
81
|
+
}
|
|
82
|
+
const v = this._rootValidator;
|
|
83
|
+
const valid = v(obj);
|
|
84
|
+
return { valid: !!valid, errors: valid ? [] : (v.errors || []) };
|
|
85
|
+
}
|
|
47
86
|
}
|
|
48
87
|
|
|
88
|
+
// Back-compat export — points at the comp-obs schema version. Existing
|
|
89
|
+
// callers consuming SCHEMA_VERSION continue to work unchanged.
|
|
49
90
|
export const SCHEMA_VERSION = load().schema.version;
|
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};
|