create-sdd-project 0.17.1 → 0.17.2
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/lib/scanner.js +54 -18
- package/package.json +1 -1
package/lib/scanner.js
CHANGED
|
@@ -8,18 +8,36 @@ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.n
|
|
|
8
8
|
/**
|
|
9
9
|
* Scan an existing project directory and return detected configuration.
|
|
10
10
|
*
|
|
11
|
-
* v0.17.1: monorepo-aware. If the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* declaration order (pattern outer, lexical inner, deduped by
|
|
15
|
-
* path) and run `detectBackend` / `detectFrontend` per workspace.
|
|
16
|
-
* FIRST workspace returning
|
|
11
|
+
* v0.17.1: monorepo-aware. If the project is a monorepo with
|
|
12
|
+
* `package.json#workspaces` and the root `package.json` does not yield a
|
|
13
|
+
* complete backend/frontend detection, enumerate workspace `package.json`
|
|
14
|
+
* files in declaration order (pattern outer, lexical inner, deduped by
|
|
15
|
+
* normalized path) and run `detectBackend` / `detectFrontend` per workspace.
|
|
16
|
+
* The FIRST workspace returning a framework wins and its result is merged
|
|
17
17
|
* into `result.backend` / `result.frontend` with a `workspaceSource` field
|
|
18
18
|
* recording the detected workspace's relative path (for diagnostics).
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* v0.17.2: the "complete detection" gate uses `framework` presence, not
|
|
21
|
+
* the older `detected` flag. This is because `detectBackend` has a
|
|
22
|
+
* partial-detection fallback (see `detectBackend` lines ~259-261) that
|
|
23
|
+
* sets `detected: true` when only `db` or `orm` is found — commonly
|
|
24
|
+
* triggered by a ROOT `.env.example` declaring `DATABASE_URL` + `PORT`
|
|
25
|
+
* in a monorepo whose real backend stack lives under `packages/api`.
|
|
26
|
+
* Under the v0.17.1 guard, that partial detection blocked the workspace
|
|
27
|
+
* enumeration and left `backend.framework` null → `adaptBackendStandards`
|
|
28
|
+
* produced generic placeholders → `adaptAgentsMd` fell back to the
|
|
29
|
+
* `(DDD, Express, Prisma)` template literal. Gating on `!framework`
|
|
30
|
+
* fires the enumeration in that case and correctly promotes
|
|
31
|
+
* workspace-level framework/orm info while preserving root-level
|
|
32
|
+
* env-derived fields (`db`, `port`) that the workspace didn't detect.
|
|
33
|
+
*
|
|
34
|
+
* Scanner additive invariant: for single-package projects, `isMonorepo`
|
|
35
|
+
* is false and the enumeration block is skipped entirely — same behavior
|
|
36
|
+
* as v0.17.0 and v0.17.1, byte-identical output. For monorepos, the
|
|
37
|
+
* v0.17.2 gate is strictly looser than v0.17.1's, so it runs the
|
|
38
|
+
* enumeration in a strict superset of cases. Enumeration only adds
|
|
39
|
+
* info (framework/orm from workspace), never removes it. Therefore
|
|
40
|
+
* v0.17.2 scan output ⊇ v0.17.1 scan output for the same input.
|
|
23
41
|
*/
|
|
24
42
|
function scan(projectDir) {
|
|
25
43
|
const pkg = readPackageJson(projectDir);
|
|
@@ -28,25 +46,43 @@ function scan(projectDir) {
|
|
|
28
46
|
const frontend = detectFrontend(projectDir, pkg);
|
|
29
47
|
const isMonorepo = detectMonorepo(projectDir, pkg);
|
|
30
48
|
|
|
31
|
-
// v0.17.
|
|
32
|
-
if
|
|
49
|
+
// v0.17.2 monorepo fallback: promote to workspace when root lacks a
|
|
50
|
+
// framework, even if root partial detection set `detected: true`.
|
|
51
|
+
if (isMonorepo && (!backend.framework || !frontend.framework)) {
|
|
33
52
|
const workspaces = enumerateWorkspaces(projectDir, pkg);
|
|
34
53
|
for (const wsRel of workspaces) {
|
|
35
54
|
const wsAbs = path.join(projectDir, ...wsRel.split('/'));
|
|
36
55
|
const wsPkg = readPackageJson(wsAbs);
|
|
37
|
-
if (!backend.
|
|
56
|
+
if (!backend.framework) {
|
|
38
57
|
const wsBackend = detectBackend(wsAbs, wsPkg);
|
|
39
|
-
if (wsBackend.
|
|
40
|
-
|
|
58
|
+
if (wsBackend.framework) {
|
|
59
|
+
// Field-merge: prefer workspace values for fields it detected,
|
|
60
|
+
// preserve root values for fields the workspace didn't (e.g.,
|
|
61
|
+
// a root .env's DATABASE_URL → root.db, which packages/api
|
|
62
|
+
// might not repeat in its own .env). Iterate `Object.keys` so
|
|
63
|
+
// future additions to `detectBackend` are forwarded without
|
|
64
|
+
// requiring a dual-update here (Gemini round-4 finding 1).
|
|
65
|
+
// `workspaceSource` records the winning workspace for diagnostics.
|
|
66
|
+
for (const field of Object.keys(wsBackend)) {
|
|
67
|
+
if (wsBackend[field] !== null && wsBackend[field] !== undefined) {
|
|
68
|
+
backend[field] = wsBackend[field];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
backend.workspaceSource = wsRel;
|
|
41
72
|
}
|
|
42
73
|
}
|
|
43
|
-
if (!frontend.
|
|
74
|
+
if (!frontend.framework) {
|
|
44
75
|
const wsFrontend = detectFrontend(wsAbs, wsPkg);
|
|
45
|
-
if (wsFrontend.
|
|
46
|
-
Object.
|
|
76
|
+
if (wsFrontend.framework) {
|
|
77
|
+
for (const field of Object.keys(wsFrontend)) {
|
|
78
|
+
if (wsFrontend[field] !== null && wsFrontend[field] !== undefined) {
|
|
79
|
+
frontend[field] = wsFrontend[field];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
frontend.workspaceSource = wsRel;
|
|
47
83
|
}
|
|
48
84
|
}
|
|
49
|
-
if (backend.
|
|
85
|
+
if (backend.framework && frontend.framework) break;
|
|
50
86
|
}
|
|
51
87
|
}
|
|
52
88
|
|