@smartmemory/compose 0.2.36-beta → 0.2.38-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/dist/assets/App-BD4lfyhF.js +686 -0
- package/dist/assets/{arc-DIXitrAQ.js → arc-fd_r6IIl.js} +1 -1
- package/dist/assets/{architectureDiagram-3BPJPVTR-Cj7dBJg7.js → architectureDiagram-3BPJPVTR-UehcfvE8.js} +1 -1
- package/dist/assets/{blockDiagram-GPEHLZMM-Cl9S3jDb.js → blockDiagram-GPEHLZMM-Dm-THFZ6.js} +1 -1
- package/dist/assets/{c4Diagram-AAUBKEIU-BhXknY2V.js → c4Diagram-AAUBKEIU-CIZ7QDGR.js} +1 -1
- package/dist/assets/channel-C0cFeemU.js +1 -0
- package/dist/assets/{chunk-2J33WTMH-D9br4z7_.js → chunk-2J33WTMH-COBZ5eyU.js} +1 -1
- package/dist/assets/{chunk-4BX2VUAB-BUm--OlR.js → chunk-4BX2VUAB-w3bqdoNF.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-BPBvBDq8.js → chunk-55IACEB6-D18v8dR4.js} +1 -1
- package/dist/assets/{chunk-727SXJPM-D-k0AVv9.js → chunk-727SXJPM-2MAwFz_9.js} +1 -1
- package/dist/assets/{chunk-AQP2D5EJ-DbrnuPhd.js → chunk-AQP2D5EJ-Dp_jdVPB.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-CArhG5bz.js → chunk-FMBD7UC4-mPSIpSeS.js} +1 -1
- package/dist/assets/{chunk-ND2GUHAM-BMqJF8Yq.js → chunk-ND2GUHAM-gkRIeuOg.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-xEVO-BnU.js → chunk-QZHKN3VN-DJ7h7c2i.js} +1 -1
- package/dist/assets/classDiagram-4FO5ZUOK-7kNnlTD1.js +1 -0
- package/dist/assets/classDiagram-v2-Q7XG4LA2-7kNnlTD1.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-D8YuuIpy.js → cose-bilkent-S5V4N54A-BC5rkVLI.js} +1 -1
- package/dist/assets/{dagre-BM42HDAG-DAFO7F2u.js → dagre-BM42HDAG-DBwRZbPz.js} +1 -1
- package/dist/assets/{diagram-2AECGRRQ-BwnnQC9d.js → diagram-2AECGRRQ-CmljsTYt.js} +1 -1
- package/dist/assets/{diagram-5GNKFQAL-DBEb2BhO.js → diagram-5GNKFQAL-Pcdh-Hev.js} +1 -1
- package/dist/assets/{diagram-KO2AKTUF-BMIv-hqj.js → diagram-KO2AKTUF-CrEqfa_s.js} +1 -1
- package/dist/assets/{diagram-LMA3HP47-B_BQfoht.js → diagram-LMA3HP47-pmYhkUAj.js} +1 -1
- package/dist/assets/{diagram-OG6HWLK6-CGX5WRJy.js → diagram-OG6HWLK6-1mWNdTnP.js} +1 -1
- package/dist/assets/{erDiagram-TEJ5UH35-BA3HXlzl.js → erDiagram-TEJ5UH35-BuNJLn2I.js} +1 -1
- package/dist/assets/{flowDiagram-I6XJVG4X-DqCc80Gc.js → flowDiagram-I6XJVG4X-D84i8zUb.js} +1 -1
- package/dist/assets/{ganttDiagram-6RSMTGT7-2JYlowTb.js → ganttDiagram-6RSMTGT7-DW_1tH7v.js} +1 -1
- package/dist/assets/{gitGraphDiagram-PVQCEYII-DeFaU-B5.js → gitGraphDiagram-PVQCEYII-Mo99IrfD.js} +1 -1
- package/dist/assets/{index-BUEdsF82.js → index-DfocQEE0.js} +2 -2
- package/dist/assets/index-vDKys15R.css +1 -0
- package/dist/assets/{infoDiagram-5YYISTIA-Denratb4.js → infoDiagram-5YYISTIA-BJvJda4j.js} +1 -1
- package/dist/assets/{ishikawaDiagram-YF4QCWOH-DmYnlEGM.js → ishikawaDiagram-YF4QCWOH-Dl7ib9vb.js} +1 -1
- package/dist/assets/{journeyDiagram-JHISSGLW-XCrNbncG.js → journeyDiagram-JHISSGLW-DmgxLRyA.js} +1 -1
- package/dist/assets/{kanban-definition-UN3LZRKU-tdCgL_BJ.js → kanban-definition-UN3LZRKU-DV6cN2Fc.js} +1 -1
- package/dist/assets/{linear-CQCcdMrA.js → linear-ChPnBFTg.js} +1 -1
- package/dist/assets/{mindmap-definition-RKZ34NQL-DtZJzpjH.js → mindmap-definition-RKZ34NQL-C0dgdrrD.js} +1 -1
- package/dist/assets/{pieDiagram-4H26LBE5-BFeercFA.js → pieDiagram-4H26LBE5-N-HzAPPi.js} +1 -1
- package/dist/assets/{quadrantDiagram-W4KKPZXB-BCX6XEvx.js → quadrantDiagram-W4KKPZXB-YEX6PyFG.js} +1 -1
- package/dist/assets/{requirementDiagram-4Y6WPE33-Cbby1ELs.js → requirementDiagram-4Y6WPE33-CCpgQqwO.js} +1 -1
- package/dist/assets/{sankeyDiagram-5OEKKPKP-CoGrYNGu.js → sankeyDiagram-5OEKKPKP-BSUvtggj.js} +1 -1
- package/dist/assets/{sequenceDiagram-3UESZ5HK-Ppn3RRuA.js → sequenceDiagram-3UESZ5HK-Dh8UHRBI.js} +1 -1
- package/dist/assets/{stateDiagram-AJRCARHV-z3isZwb4.js → stateDiagram-AJRCARHV-DKvZ4fLX.js} +1 -1
- package/dist/assets/stateDiagram-v2-BHNVJYJU-DF_adEfb.js +1 -0
- package/dist/assets/{timeline-definition-PNZ67QCA-MzpbvgHe.js → timeline-definition-PNZ67QCA-qunNDnlH.js} +1 -1
- package/dist/assets/{vennDiagram-CIIHVFJN-Bsvlh8Xw.js → vennDiagram-CIIHVFJN-D5a-gmIU.js} +1 -1
- package/dist/assets/{wardley-L42UT6IY-VWT3qdBy.js → wardley-L42UT6IY-akIUfw-F.js} +1 -1
- package/dist/assets/{wardleyDiagram-YWT4CUSO-DhsQvXBN.js → wardleyDiagram-YWT4CUSO-R1zmVC27.js} +1 -1
- package/dist/assets/{xychartDiagram-2RQKCTM6-DvmK5-UN.js → xychartDiagram-2RQKCTM6-Do2YVGeZ.js} +1 -1
- package/dist/index.html +2 -2
- package/lib/build-history.js +62 -0
- package/lib/build.js +27 -0
- package/lib/discover-workspaces.js +28 -5
- package/lib/resolve-workspace.js +50 -3
- package/package.json +1 -1
- package/server/build-routes.js +14 -0
- package/dist/assets/App-CpdZk3aa.js +0 -681
- package/dist/assets/channel-llllBK4h.js +0 -1
- package/dist/assets/classDiagram-4FO5ZUOK-BEiB5jyR.js +0 -1
- package/dist/assets/classDiagram-v2-Q7XG4LA2-BEiB5jyR.js +0 -1
- package/dist/assets/index-jqUffYBL.css +0 -1
- package/dist/assets/stateDiagram-v2-BHNVJYJU-CU-EnGpI.js +0 -1
package/lib/resolve-workspace.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* 1. explicit hint.workspaceId (cheap upward walk first; falls back to discovery)
|
|
6
6
|
* 2. COMPOSE_TARGET env (absolute path bypasses discovery; id routes through it)
|
|
7
7
|
* 3. hint.getBinding() (MCP binding)
|
|
8
|
-
* 4. discovery (auto-pick when exactly one candidate; throws otherwise)
|
|
8
|
+
* 4. discovery (auto-pick when exactly one candidate; throws otherwise) —
|
|
9
|
+
* degrades to the nearest-enclosing workspace if the subtree is too broad
|
|
10
|
+
* to enumerate within the visit bound.
|
|
9
11
|
*
|
|
10
12
|
* Throws structured errors with `.code`: WorkspaceUnknown, WorkspaceAmbiguous,
|
|
11
13
|
* WorkspaceIdCollision, WorkspaceUnset. The CLI's dieOnWorkspaceError consumes them.
|
|
@@ -13,6 +15,14 @@
|
|
|
13
15
|
* Design intent: explicit-flag path uses findWorkspaceById (cheap upward walk)
|
|
14
16
|
* BEFORE invoking discoverWorkspaces — this lets users escape WorkspaceDiscoveryTooBroad
|
|
15
17
|
* by passing --workspace=<ancestor-id>. A descendant id still routes through discovery.
|
|
18
|
+
*
|
|
19
|
+
* The no-hint path mirrors that instinct only when the descendant scan can't
|
|
20
|
+
* enumerate the subtree (WorkspaceDiscoveryTooBroad): rather than failing, it
|
|
21
|
+
* falls back to the nearest enclosing `.compose` ancestor (upward walk), so
|
|
22
|
+
* running from a large workspace root resolves instead of dying. A tractable
|
|
23
|
+
* tree is still enumerated in full — genuine nested-workspace ambiguity (a
|
|
24
|
+
* parent workspace with a child below it) deliberately surfaces and forces an
|
|
25
|
+
* explicit --workspace.
|
|
16
26
|
*/
|
|
17
27
|
import path from 'node:path';
|
|
18
28
|
import fs from 'node:fs';
|
|
@@ -96,8 +106,26 @@ export function resolveWorkspace(hint = {}) {
|
|
|
96
106
|
}
|
|
97
107
|
}
|
|
98
108
|
|
|
99
|
-
// 4. Discovery —
|
|
100
|
-
|
|
109
|
+
// 4. Discovery — fan out under the anchor; collisions/ambiguity matter
|
|
110
|
+
// because we're auto-picking. A normal tree enumerates fine, so genuine
|
|
111
|
+
// nested-workspace ambiguity (e.g. a parent workspace with a child below)
|
|
112
|
+
// still surfaces as WorkspaceAmbiguous and forces an explicit --workspace.
|
|
113
|
+
let candidates;
|
|
114
|
+
try {
|
|
115
|
+
({ candidates } = discoverWorkspaces(cwd));
|
|
116
|
+
} catch (err) {
|
|
117
|
+
// The subtree was too large to enumerate within the visit bound. That cap
|
|
118
|
+
// is a cost guard, not a verdict — if cwd is itself inside a workspace, the
|
|
119
|
+
// nearest enclosing `.compose` ancestor is the unambiguous answer, so we
|
|
120
|
+
// degrade to it instead of failing (best-effort, same philosophy as the
|
|
121
|
+
// scan silently skipping EACCES subtrees). Only when cwd is inside NO
|
|
122
|
+
// workspace must the caller disambiguate explicitly — then we rethrow.
|
|
123
|
+
if (err.code === 'WorkspaceDiscoveryTooBroad') {
|
|
124
|
+
const enclosing = findEnclosingWorkspace(cwd);
|
|
125
|
+
if (enclosing) return { ...deriveId({ root: enclosing }), source: 'discovery' };
|
|
126
|
+
}
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
101
129
|
detectCollisions(candidates);
|
|
102
130
|
if (candidates.length === 0) throw new WorkspaceUnset();
|
|
103
131
|
if (candidates.length === 1) return { ...candidates[0], source: 'discovery' };
|
|
@@ -124,6 +152,25 @@ function findWorkspaceById(startDir, targetId) {
|
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Cheap upward-only lookup: walk ancestors from startDir and return the first
|
|
157
|
+
* directory containing a `.compose/` marker, or null if none exists before the
|
|
158
|
+
* filesystem root. This is the no-hint "nearest enclosing workspace" resolver —
|
|
159
|
+
* identical walk to findWorkspaceById but id-agnostic (returns the closest
|
|
160
|
+
* workspace regardless of its derived id).
|
|
161
|
+
*/
|
|
162
|
+
function findEnclosingWorkspace(startDir) {
|
|
163
|
+
let dir = path.resolve(startDir);
|
|
164
|
+
const { root } = path.parse(dir);
|
|
165
|
+
while (true) {
|
|
166
|
+
if (fs.existsSync(path.join(dir, '.compose'))) return dir;
|
|
167
|
+
if (dir === root) return null;
|
|
168
|
+
const parent = path.dirname(dir);
|
|
169
|
+
if (parent === dir) return null;
|
|
170
|
+
dir = parent;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
127
174
|
function resolveByIdScopedCollisionCheck(id, candidates, source) {
|
|
128
175
|
const matching = candidates.filter((c) => c.id === id);
|
|
129
176
|
if (matching.length === 0) throw new WorkspaceUnknown(id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartmemory/compose",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.38-beta",
|
|
4
4
|
"description": "Structured AI dev pipeline — goal-to-product orchestration with gates, iteration loops, and feature lifecycle management.",
|
|
5
5
|
"author": "SmartMemory",
|
|
6
6
|
"license": "MIT",
|
package/server/build-routes.js
CHANGED
|
@@ -16,12 +16,26 @@
|
|
|
16
16
|
import { runBuild as defaultRunBuild, abortBuild as defaultAbortBuild } from '../lib/build.js';
|
|
17
17
|
import { requireSensitiveToken } from './security.js';
|
|
18
18
|
import { getDataDir as defaultGetDataDir } from './project-root.js';
|
|
19
|
+
import { readBuildHistory } from '../lib/build-history.js';
|
|
19
20
|
|
|
20
21
|
export function attachBuildRoutes(app, deps = {}) {
|
|
21
22
|
const runBuild = deps.runBuild || defaultRunBuild;
|
|
22
23
|
const abortBuild = deps.abortBuild || defaultAbortBuild;
|
|
23
24
|
const getDataDir = deps.getDataDir || defaultGetDataDir;
|
|
24
25
|
|
|
26
|
+
// COMP-COCKPIT-3: read-only past-builds history. No sensitive token —
|
|
27
|
+
// mirrors GET /api/build/state (read-only, no secrets in the records).
|
|
28
|
+
app.get('/api/builds', (req, res) => {
|
|
29
|
+
try {
|
|
30
|
+
const raw = parseInt(req.query.limit, 10);
|
|
31
|
+
const limit = Number.isFinite(raw) ? Math.min(Math.max(raw, 1), 200) : 50;
|
|
32
|
+
const builds = readBuildHistory(getDataDir(), { limit });
|
|
33
|
+
res.json({ builds });
|
|
34
|
+
} catch (err) {
|
|
35
|
+
res.status(500).json({ error: err.message || String(err) });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
25
39
|
app.post('/api/build/start', requireSensitiveToken, async (req, res) => {
|
|
26
40
|
const body = req.body || {};
|
|
27
41
|
const { featureCode, mode = 'feature', description = '' } = body;
|