@smartmemory/compose 0.1.44-beta → 0.2.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.
- package/bin/compose.js +71 -35
- package/dist/assets/App-VU2lfA8m.js +770 -0
- package/dist/assets/{arc-N74_SuiS.js → arc-CIeqpX37.js} +1 -1
- package/dist/assets/{architectureDiagram-3BPJPVTR-DHOb5xas.js → architectureDiagram-3BPJPVTR-itmOSZLE.js} +1 -1
- package/dist/assets/{blockDiagram-GPEHLZMM-DR9b_xXC.js → blockDiagram-GPEHLZMM-N7MotI_5.js} +8 -8
- package/dist/assets/{c4Diagram-AAUBKEIU-EXIx4J1v.js → c4Diagram-AAUBKEIU-DRKW39LH.js} +1 -1
- package/dist/assets/channel-DugSMLKi.js +1 -0
- package/dist/assets/{chunk-2J33WTMH-CyZqa6ub.js → chunk-2J33WTMH-CF6iSwEb.js} +1 -1
- package/dist/assets/{chunk-4BX2VUAB-SjPmvNaj.js → chunk-4BX2VUAB-BTe-QE0R.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-Cnu3mdms.js → chunk-55IACEB6-E2hHEsl9.js} +1 -1
- package/dist/assets/{chunk-727SXJPM-DNj5i6fj.js → chunk-727SXJPM-CBRmkSvh.js} +1 -1
- package/dist/assets/{chunk-AQP2D5EJ-BIVskOlI.js → chunk-AQP2D5EJ-BdtQ63fN.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-BWlLU-hh.js → chunk-FMBD7UC4-DfYQ2YmB.js} +1 -1
- package/dist/assets/{chunk-ND2GUHAM-DQEknadH.js → chunk-ND2GUHAM-CDrOVOW5.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-CUYnhnAB.js → chunk-QZHKN3VN-DwjqJ9xB.js} +1 -1
- package/dist/assets/classDiagram-4FO5ZUOK-D2RRwp7J.js +1 -0
- package/dist/assets/classDiagram-v2-Q7XG4LA2-D2RRwp7J.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-X3n23b12.js → cose-bilkent-S5V4N54A-MHpsrtBZ.js} +1 -1
- package/dist/assets/{dagre-BM42HDAG-C0SrhQ_X.js → dagre-BM42HDAG-DaPz_mPt.js} +1 -1
- package/dist/assets/{diagram-2AECGRRQ-Bc3qx6pJ.js → diagram-2AECGRRQ-DIdstuOm.js} +1 -1
- package/dist/assets/{diagram-5GNKFQAL-UiCrD06F.js → diagram-5GNKFQAL-DbkTGVES.js} +1 -1
- package/dist/assets/{diagram-KO2AKTUF-B9Vn5KyO.js → diagram-KO2AKTUF-BPalYJed.js} +1 -1
- package/dist/assets/{diagram-LMA3HP47-DLOYeLM3.js → diagram-LMA3HP47-vnySSoyd.js} +1 -1
- package/dist/assets/{diagram-OG6HWLK6-CXjh2miZ.js → diagram-OG6HWLK6-Dv3BUJft.js} +1 -1
- package/dist/assets/{erDiagram-TEJ5UH35-EmDzXNsM.js → erDiagram-TEJ5UH35-B3OLgtKK.js} +1 -1
- package/dist/assets/{flowDiagram-I6XJVG4X-vk6E_ebo.js → flowDiagram-I6XJVG4X-DdpxVf-5.js} +1 -1
- package/dist/assets/{ganttDiagram-6RSMTGT7-DYYSAjNx.js → ganttDiagram-6RSMTGT7-QALT_Lj9.js} +4 -4
- package/dist/assets/{gitGraphDiagram-PVQCEYII-CWPZVbhV.js → gitGraphDiagram-PVQCEYII-nITcPPED.js} +1 -1
- package/dist/assets/{graph-uO5hwVZK.js → graph-DnLKqSPg.js} +2 -2
- package/dist/assets/{index-BYYTTzUT.js → index-CLb8RFcn.js} +3 -3
- package/dist/assets/index-jqUffYBL.css +1 -0
- package/dist/assets/{infoDiagram-5YYISTIA-Dsu-eeJm.js → infoDiagram-5YYISTIA-CjlRce3x.js} +1 -1
- package/dist/assets/{ishikawaDiagram-YF4QCWOH-BP1SP8WA.js → ishikawaDiagram-YF4QCWOH-OyKVgxOz.js} +1 -1
- package/dist/assets/{journeyDiagram-JHISSGLW-DkE5By_R.js → journeyDiagram-JHISSGLW-3FaFyfLR.js} +1 -1
- package/dist/assets/{kanban-definition-UN3LZRKU-Cf_230xs.js → kanban-definition-UN3LZRKU-DUPnRo3q.js} +1 -1
- package/dist/assets/{linear-B-paxRBQ.js → linear-BeL8i3rv.js} +1 -1
- package/dist/assets/{mindmap-definition-RKZ34NQL-DAp6uJ_b.js → mindmap-definition-RKZ34NQL-C0CwWNdR.js} +1 -1
- package/dist/assets/mobile-qvdJ5p0m.js +17 -0
- package/dist/assets/{pieDiagram-4H26LBE5-CbYY5KL0.js → pieDiagram-4H26LBE5-DaU2jPjX.js} +1 -1
- package/dist/assets/{quadrantDiagram-W4KKPZXB-D5S4_ac5.js → quadrantDiagram-W4KKPZXB-HFtjZSAT.js} +1 -1
- package/dist/assets/{requirementDiagram-4Y6WPE33-BrPWCnHz.js → requirementDiagram-4Y6WPE33-CX_Mz3gv.js} +1 -1
- package/dist/assets/{sankeyDiagram-5OEKKPKP-CP8j1mcl.js → sankeyDiagram-5OEKKPKP-BR2_eTy9.js} +1 -1
- package/dist/assets/{sequenceDiagram-3UESZ5HK-c8DuhvUj.js → sequenceDiagram-3UESZ5HK-CtHp0Qnp.js} +1 -1
- package/dist/assets/{stateDiagram-AJRCARHV-KO9G1Jrm.js → stateDiagram-AJRCARHV-DmiEmD6G.js} +1 -1
- package/dist/assets/stateDiagram-v2-BHNVJYJU-7rdO1Tgp.js +1 -0
- package/dist/assets/{timeline-definition-PNZ67QCA-Cs2HLlbG.js → timeline-definition-PNZ67QCA-GSHqrJ3A.js} +1 -1
- package/dist/assets/{vennDiagram-CIIHVFJN-rcSRidqI.js → vennDiagram-CIIHVFJN-CNxhQnCU.js} +1 -1
- package/dist/assets/{wardley-L42UT6IY-BsajGfii.js → wardley-L42UT6IY-Bf-gQIFY.js} +1 -1
- package/dist/assets/{wardleyDiagram-YWT4CUSO-CSWALc_m.js → wardleyDiagram-YWT4CUSO-RGxoapr7.js} +1 -1
- package/dist/assets/{xychartDiagram-2RQKCTM6-jC4Q0GvG.js → xychartDiagram-2RQKCTM6-1_H1qVde.js} +1 -1
- package/dist/index.html +3 -3
- package/lib/build.js +3 -2
- package/lib/feature-code.js +14 -4
- package/lib/feature-json.js +33 -2
- package/lib/feature-validator.js +135 -11
- package/lib/feature-writer.js +83 -3
- package/lib/migrate-roadmap.js +16 -2
- package/lib/project-paths.js +16 -0
- package/lib/roadmap-config.js +50 -0
- package/lib/roadmap-gen.js +46 -31
- package/lib/roadmap-heading.js +85 -0
- package/lib/roadmap-parser.js +69 -18
- package/lib/roadmap-preservers.js +60 -19
- package/lib/roadmap-roundtrip.js +137 -0
- package/lib/vision-writer.js +42 -14
- package/lib/xref-sync.js +160 -0
- package/package.json +1 -1
- package/server/compose-mcp.js +2 -1
- package/server/vision-store.js +1 -1
- package/dist/assets/App-CdP799CF.js +0 -768
- package/dist/assets/channel-yPY0IE15.js +0 -1
- package/dist/assets/classDiagram-4FO5ZUOK-SGKYXTP4.js +0 -1
- package/dist/assets/classDiagram-v2-Q7XG4LA2-SGKYXTP4.js +0 -1
- package/dist/assets/index-Dh2rRpBR.css +0 -1
- package/dist/assets/mobile-BwduHUEq.js +0 -17
- package/dist/assets/stateDiagram-v2-BHNVJYJU-eVyb8_R4.js +0 -1
package/bin/compose.js
CHANGED
|
@@ -119,6 +119,7 @@ if (!cmd || cmd === '--help' || cmd === '-h') {
|
|
|
119
119
|
console.log(' roadmap generate Regenerate ROADMAP.md from feature.json files')
|
|
120
120
|
console.log(' roadmap migrate Extract ROADMAP.md entries into feature.json files')
|
|
121
121
|
console.log(' roadmap check Verify feature.json and ROADMAP.md are in sync')
|
|
122
|
+
console.log(' roadmap xref-sync Pull-reconcile feature.json external links to live state')
|
|
122
123
|
console.log(' items List vision items from local state (no server)')
|
|
123
124
|
console.log(' items show <id> Show detail for a specific vision item')
|
|
124
125
|
console.log(' triage Analyze a feature and recommend build profile')
|
|
@@ -1036,22 +1037,47 @@ _This is a seed design doc created by \`compose feature\`. The \`compose build\`
|
|
|
1036
1037
|
if (cmd === 'roadmap') {
|
|
1037
1038
|
const subcmd = args[0]
|
|
1038
1039
|
|
|
1039
|
-
// compose roadmap generate — regenerate ROADMAP.md from feature.json files
|
|
1040
|
+
// compose roadmap generate — regenerate ROADMAP.md from feature.json files,
|
|
1041
|
+
// converging to a fixed point before finishing.
|
|
1040
1042
|
if (subcmd === 'generate' || subcmd === 'gen') {
|
|
1041
1043
|
const { writeRoadmap } = await import('../lib/roadmap-gen.js')
|
|
1044
|
+
const { checkRoundtrip } = await import('../lib/roadmap-roundtrip.js')
|
|
1045
|
+
const { listFeatures } = await import('../lib/feature-json.js')
|
|
1046
|
+
const { loadExternalPrefixes } = await import('../lib/project-paths.js')
|
|
1047
|
+
const { isNarrativeOwned } = await import('../lib/roadmap-config.js')
|
|
1042
1048
|
const { root: cwd } = resolveCwdWithWorkspace(args)
|
|
1049
|
+
// Narrative-owned workspaces (#39): ROADMAP.md is hand-authored, not a render
|
|
1050
|
+
// of feature.json. writeRoadmap already no-ops, but the canonicalization pass
|
|
1051
|
+
// below would still overwrite the file (or crash if it's absent) — skip the
|
|
1052
|
+
// whole generate path here so the hand-authored file is never touched.
|
|
1053
|
+
if (isNarrativeOwned(cwd)) {
|
|
1054
|
+
console.log('narrative-owned workspace (roadmap.narrative=true) — ROADMAP.md is hand-authored; generate skipped.')
|
|
1055
|
+
process.exit(0)
|
|
1056
|
+
}
|
|
1043
1057
|
const path = writeRoadmap(cwd)
|
|
1044
|
-
|
|
1058
|
+
const externalPrefixes = loadExternalPrefixes(cwd)
|
|
1059
|
+
// checkRoundtrip's now:'0000-00-00' is only used to detect/canonicalize
|
|
1060
|
+
// structural non-convergence — once the file has headings, readPreamble
|
|
1061
|
+
// preserves the existing preamble date verbatim, so no sentinel date leaks.
|
|
1062
|
+
const rt = checkRoundtrip(readFileSync(path, 'utf-8'), listFeatures(cwd), { now: '0000-00-00', externalPrefixes })
|
|
1063
|
+
if (!rt.fixedPoint) {
|
|
1064
|
+
writeFileSync(path, rt.canonical)
|
|
1065
|
+
console.log(`Generated ${path} (canonicalized over ${rt.passes} passes)`)
|
|
1066
|
+
} else {
|
|
1067
|
+
console.log(`Generated ${path} from feature.json files`)
|
|
1068
|
+
}
|
|
1045
1069
|
process.exit(0)
|
|
1046
1070
|
}
|
|
1047
1071
|
|
|
1048
1072
|
// compose roadmap migrate — extract ROADMAP.md entries into feature.json files
|
|
1049
1073
|
if (subcmd === 'migrate') {
|
|
1050
1074
|
const { migrateRoadmap } = await import('../lib/migrate-roadmap.js')
|
|
1075
|
+
const { loadExternalPrefixes } = await import('../lib/project-paths.js')
|
|
1051
1076
|
const { root: cwd } = resolveCwdWithWorkspace(args)
|
|
1052
1077
|
const dryRun = args.includes('--dry-run')
|
|
1053
1078
|
const overwrite = args.includes('--overwrite')
|
|
1054
|
-
const
|
|
1079
|
+
const externalPrefixes = loadExternalPrefixes(cwd)
|
|
1080
|
+
const result = migrateRoadmap(cwd, { dryRun, overwrite, externalPrefixes })
|
|
1055
1081
|
if (!dryRun) {
|
|
1056
1082
|
console.log(`Created: ${result.created.length} feature.json files`)
|
|
1057
1083
|
if (result.created.length > 0) console.log(` ${result.created.join(', ')}`)
|
|
@@ -1059,6 +1085,9 @@ if (cmd === 'roadmap') {
|
|
|
1059
1085
|
if (result.updated.length > 0) console.log(` ${result.updated.join(', ')}`)
|
|
1060
1086
|
console.log(`Skipped: ${result.skipped.length} (already exist, use --overwrite to replace)`)
|
|
1061
1087
|
if (result.skipped.length > 0) console.log(` ${result.skipped.join(', ')}`)
|
|
1088
|
+
const ext = result.skippedExternal ?? []
|
|
1089
|
+
console.log(`Skipped (external, cross-project refs): ${ext.length}`)
|
|
1090
|
+
if (ext.length > 0) console.log(` ${ext.join(', ')}`)
|
|
1062
1091
|
}
|
|
1063
1092
|
process.exit(0)
|
|
1064
1093
|
}
|
|
@@ -1066,49 +1095,56 @@ if (cmd === 'roadmap') {
|
|
|
1066
1095
|
// compose roadmap check — verify feature.json ↔ ROADMAP.md consistency
|
|
1067
1096
|
if (subcmd === 'check') {
|
|
1068
1097
|
const { listFeatures } = await import('../lib/feature-json.js')
|
|
1069
|
-
const {
|
|
1098
|
+
const { checkRoundtrip, describeLossyDiff } = await import('../lib/roadmap-roundtrip.js')
|
|
1099
|
+
const { loadExternalPrefixes } = await import('../lib/project-paths.js')
|
|
1070
1100
|
const { root: cwd } = resolveCwdWithWorkspace(args)
|
|
1071
1101
|
const roadmapPath = join(cwd, 'ROADMAP.md')
|
|
1072
1102
|
if (!existsSync(roadmapPath)) {
|
|
1073
1103
|
console.error('No ROADMAP.md found. Run: compose roadmap generate')
|
|
1074
1104
|
process.exit(1)
|
|
1075
1105
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
const
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
for (const f of features) {
|
|
1084
|
-
if (!roadmapCodes.has(f.code)) {
|
|
1085
|
-
console.log(`MISSING from ROADMAP.md: ${f.code}`)
|
|
1086
|
-
clean = false
|
|
1087
|
-
}
|
|
1106
|
+
// Narrative-owned workspaces (#39): ROADMAP.md is hand-authored, not a render
|
|
1107
|
+
// of feature.json — the roundtrip would always report false drift. The file
|
|
1108
|
+
// must still EXIST (checked above); we only skip the drift comparison.
|
|
1109
|
+
const { isNarrativeOwned } = await import('../lib/roadmap-config.js')
|
|
1110
|
+
if (isNarrativeOwned(cwd)) {
|
|
1111
|
+
console.log('narrative-owned workspace (roadmap.narrative=true) — ROADMAP.md is hand-authored; roundtrip check skipped.')
|
|
1112
|
+
process.exit(0)
|
|
1088
1113
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
clean = false
|
|
1095
|
-
}
|
|
1114
|
+
const externalPrefixes = loadExternalPrefixes(cwd)
|
|
1115
|
+
const rt = checkRoundtrip(readFileSync(roadmapPath, 'utf-8'), listFeatures(cwd), { now: '0000-00-00', externalPrefixes })
|
|
1116
|
+
if (rt.fixedPoint && rt.lossless) {
|
|
1117
|
+
console.log('feature.json and ROADMAP.md are in sync (fixed point, lossless).')
|
|
1118
|
+
process.exit(0)
|
|
1096
1119
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
clean = false
|
|
1104
|
-
}
|
|
1120
|
+
if (!rt.fixedPoint) {
|
|
1121
|
+
const d = rt.diffs.find(x => x.kind === 'FIXED_POINT_DIVERGENCE')
|
|
1122
|
+
console.log(`NOT A FIXED POINT: ${d?.detail ?? 'ROADMAP.md changes on regen'}`)
|
|
1123
|
+
}
|
|
1124
|
+
for (const d of rt.diffs.filter(x => x.kind.startsWith('LOSSLESS_'))) {
|
|
1125
|
+
console.log(describeLossyDiff(d))
|
|
1105
1126
|
}
|
|
1127
|
+
console.log('\nRun `compose roadmap generate` to regenerate ROADMAP.md from feature.json.')
|
|
1128
|
+
process.exit(1)
|
|
1129
|
+
}
|
|
1106
1130
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1131
|
+
// compose roadmap xref-sync — pull-reconcile feature.json external links'
|
|
1132
|
+
// expect= to live target state (COMP-ROADMAP-XREF-SYNC v1). Never writes external.
|
|
1133
|
+
if (subcmd === 'xref-sync') {
|
|
1134
|
+
const { syncExternalRefs } = await import('../lib/xref-sync.js')
|
|
1135
|
+
const { root: cwd } = resolveCwdWithWorkspace(args)
|
|
1136
|
+
const dryRun = args.includes('--dry-run')
|
|
1137
|
+
const res = await syncExternalRefs(cwd, { dryRun })
|
|
1138
|
+
const verb = dryRun ? 'would update' : 'updated'
|
|
1139
|
+
if (res.synced.length === 0) {
|
|
1140
|
+
console.log(`No external-link drift to reconcile (${res.scanned} resolvable link(s) checked, ${res.unchanged} already in sync).`)
|
|
1109
1141
|
} else {
|
|
1110
|
-
console.log(
|
|
1111
|
-
|
|
1142
|
+
console.log(`${dryRun ? 'Would reconcile' : 'Reconciled'} ${res.synced.length} external link(s):`)
|
|
1143
|
+
for (const s of res.synced) console.log(` ${s.code} ${s.provider} ${s.target}: expect ${s.from} → ${s.to} (${verb})`)
|
|
1144
|
+
}
|
|
1145
|
+
if (res.skipped.length > 0) {
|
|
1146
|
+
console.log(`\nSkipped ${res.skipped.length} unresolved link(s):`)
|
|
1147
|
+
for (const s of res.skipped) console.log(` ${s.code} ${s.provider} ${s.target}: ${s.reason}`)
|
|
1112
1148
|
}
|
|
1113
1149
|
process.exit(0)
|
|
1114
1150
|
}
|