@zigrivers/scaffold 3.9.2 → 3.10.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.
Files changed (190) hide show
  1. package/README.md +39 -8
  2. package/dist/cli/commands/adopt.d.ts +2 -0
  3. package/dist/cli/commands/adopt.d.ts.map +1 -1
  4. package/dist/cli/commands/adopt.js +428 -58
  5. package/dist/cli/commands/adopt.js.map +1 -1
  6. package/dist/cli/commands/adopt.performance.test.d.ts +2 -0
  7. package/dist/cli/commands/adopt.performance.test.d.ts.map +1 -0
  8. package/dist/cli/commands/adopt.performance.test.js +30 -0
  9. package/dist/cli/commands/adopt.performance.test.js.map +1 -0
  10. package/dist/cli/commands/adopt.test.js +18 -6
  11. package/dist/cli/commands/adopt.test.js.map +1 -1
  12. package/dist/cli/commands/init.d.ts.map +1 -1
  13. package/dist/cli/commands/init.js +4 -157
  14. package/dist/cli/commands/init.js.map +1 -1
  15. package/dist/cli/init-flag-families.d.ts +86 -0
  16. package/dist/cli/init-flag-families.d.ts.map +1 -0
  17. package/dist/cli/init-flag-families.js +418 -0
  18. package/dist/cli/init-flag-families.js.map +1 -0
  19. package/dist/cli/init-flag-families.test.d.ts +2 -0
  20. package/dist/cli/init-flag-families.test.d.ts.map +1 -0
  21. package/dist/cli/init-flag-families.test.js +268 -0
  22. package/dist/cli/init-flag-families.test.js.map +1 -0
  23. package/dist/config/schema.d.ts +6 -6
  24. package/dist/config/schema.js +2 -2
  25. package/dist/config/schema.js.map +1 -1
  26. package/dist/config/schema.test.js +10 -4
  27. package/dist/config/schema.test.js.map +1 -1
  28. package/dist/e2e/adopt-multi-type.test.d.ts +2 -0
  29. package/dist/e2e/adopt-multi-type.test.d.ts.map +1 -0
  30. package/dist/e2e/adopt-multi-type.test.js +35 -0
  31. package/dist/e2e/adopt-multi-type.test.js.map +1 -0
  32. package/dist/project/__frozen-schemas__/schema-v3.9.2.d.ts +2891 -0
  33. package/dist/project/__frozen-schemas__/schema-v3.9.2.d.ts.map +1 -0
  34. package/dist/project/__frozen-schemas__/schema-v3.9.2.js +177 -0
  35. package/dist/project/__frozen-schemas__/schema-v3.9.2.js.map +1 -0
  36. package/dist/project/adopt.d.ts +38 -2
  37. package/dist/project/adopt.d.ts.map +1 -1
  38. package/dist/project/adopt.error-messages.test.d.ts +2 -0
  39. package/dist/project/adopt.error-messages.test.d.ts.map +1 -0
  40. package/dist/project/adopt.error-messages.test.js +112 -0
  41. package/dist/project/adopt.error-messages.test.js.map +1 -0
  42. package/dist/project/adopt.forward-compat.test.d.ts +2 -0
  43. package/dist/project/adopt.forward-compat.test.d.ts.map +1 -0
  44. package/dist/project/adopt.forward-compat.test.js +71 -0
  45. package/dist/project/adopt.forward-compat.test.js.map +1 -0
  46. package/dist/project/adopt.js +218 -27
  47. package/dist/project/adopt.js.map +1 -1
  48. package/dist/project/adopt.merge.test.d.ts +2 -0
  49. package/dist/project/adopt.merge.test.d.ts.map +1 -0
  50. package/dist/project/adopt.merge.test.js +62 -0
  51. package/dist/project/adopt.merge.test.js.map +1 -0
  52. package/dist/project/adopt.re-adoption.test.d.ts +2 -0
  53. package/dist/project/adopt.re-adoption.test.d.ts.map +1 -0
  54. package/dist/project/adopt.re-adoption.test.js +222 -0
  55. package/dist/project/adopt.re-adoption.test.js.map +1 -0
  56. package/dist/project/adopt.test.js +72 -27
  57. package/dist/project/adopt.test.js.map +1 -1
  58. package/dist/project/detectors/backend.d.ts +4 -0
  59. package/dist/project/detectors/backend.d.ts.map +1 -0
  60. package/dist/project/detectors/backend.js +199 -0
  61. package/dist/project/detectors/backend.js.map +1 -0
  62. package/dist/project/detectors/backend.test.d.ts +2 -0
  63. package/dist/project/detectors/backend.test.d.ts.map +1 -0
  64. package/dist/project/detectors/backend.test.js +64 -0
  65. package/dist/project/detectors/backend.test.js.map +1 -0
  66. package/dist/project/detectors/browser-extension.d.ts +4 -0
  67. package/dist/project/detectors/browser-extension.d.ts.map +1 -0
  68. package/dist/project/detectors/browser-extension.js +61 -0
  69. package/dist/project/detectors/browser-extension.js.map +1 -0
  70. package/dist/project/detectors/browser-extension.test.d.ts +2 -0
  71. package/dist/project/detectors/browser-extension.test.d.ts.map +1 -0
  72. package/dist/project/detectors/browser-extension.test.js +64 -0
  73. package/dist/project/detectors/browser-extension.test.js.map +1 -0
  74. package/dist/project/detectors/cli.d.ts +4 -0
  75. package/dist/project/detectors/cli.d.ts.map +1 -0
  76. package/dist/project/detectors/cli.js +68 -0
  77. package/dist/project/detectors/cli.js.map +1 -0
  78. package/dist/project/detectors/cli.test.d.ts +2 -0
  79. package/dist/project/detectors/cli.test.d.ts.map +1 -0
  80. package/dist/project/detectors/cli.test.js +70 -0
  81. package/dist/project/detectors/cli.test.js.map +1 -0
  82. package/dist/project/detectors/context.d.ts +105 -0
  83. package/dist/project/detectors/context.d.ts.map +1 -0
  84. package/dist/project/detectors/context.js +652 -0
  85. package/dist/project/detectors/context.js.map +1 -0
  86. package/dist/project/detectors/context.test.d.ts +2 -0
  87. package/dist/project/detectors/context.test.d.ts.map +1 -0
  88. package/dist/project/detectors/context.test.js +240 -0
  89. package/dist/project/detectors/context.test.js.map +1 -0
  90. package/dist/project/detectors/data-pipeline.d.ts +4 -0
  91. package/dist/project/detectors/data-pipeline.d.ts.map +1 -0
  92. package/dist/project/detectors/data-pipeline.js +97 -0
  93. package/dist/project/detectors/data-pipeline.js.map +1 -0
  94. package/dist/project/detectors/data-pipeline.test.d.ts +2 -0
  95. package/dist/project/detectors/data-pipeline.test.d.ts.map +1 -0
  96. package/dist/project/detectors/data-pipeline.test.js +67 -0
  97. package/dist/project/detectors/data-pipeline.test.js.map +1 -0
  98. package/dist/project/detectors/disambiguate.d.ts +12 -0
  99. package/dist/project/detectors/disambiguate.d.ts.map +1 -0
  100. package/dist/project/detectors/disambiguate.js +87 -0
  101. package/dist/project/detectors/disambiguate.js.map +1 -0
  102. package/dist/project/detectors/disambiguate.test.d.ts +2 -0
  103. package/dist/project/detectors/disambiguate.test.d.ts.map +1 -0
  104. package/dist/project/detectors/disambiguate.test.js +114 -0
  105. package/dist/project/detectors/disambiguate.test.js.map +1 -0
  106. package/dist/project/detectors/file-text-match.d.ts +3 -0
  107. package/dist/project/detectors/file-text-match.d.ts.map +1 -0
  108. package/dist/project/detectors/file-text-match.js +60 -0
  109. package/dist/project/detectors/file-text-match.js.map +1 -0
  110. package/dist/project/detectors/file-text-match.test.d.ts +2 -0
  111. package/dist/project/detectors/file-text-match.test.d.ts.map +1 -0
  112. package/dist/project/detectors/file-text-match.test.js +81 -0
  113. package/dist/project/detectors/file-text-match.test.js.map +1 -0
  114. package/dist/project/detectors/game.d.ts +18 -0
  115. package/dist/project/detectors/game.d.ts.map +1 -0
  116. package/dist/project/detectors/game.js +83 -0
  117. package/dist/project/detectors/game.js.map +1 -0
  118. package/dist/project/detectors/game.test.d.ts +2 -0
  119. package/dist/project/detectors/game.test.d.ts.map +1 -0
  120. package/dist/project/detectors/game.test.js +87 -0
  121. package/dist/project/detectors/game.test.js.map +1 -0
  122. package/dist/project/detectors/index.d.ts +5 -0
  123. package/dist/project/detectors/index.d.ts.map +1 -0
  124. package/dist/project/detectors/index.js +29 -0
  125. package/dist/project/detectors/index.js.map +1 -0
  126. package/dist/project/detectors/library.d.ts +4 -0
  127. package/dist/project/detectors/library.d.ts.map +1 -0
  128. package/dist/project/detectors/library.js +117 -0
  129. package/dist/project/detectors/library.js.map +1 -0
  130. package/dist/project/detectors/library.test.d.ts +2 -0
  131. package/dist/project/detectors/library.test.d.ts.map +1 -0
  132. package/dist/project/detectors/library.test.js +73 -0
  133. package/dist/project/detectors/library.test.js.map +1 -0
  134. package/dist/project/detectors/ml.d.ts +4 -0
  135. package/dist/project/detectors/ml.d.ts.map +1 -0
  136. package/dist/project/detectors/ml.js +112 -0
  137. package/dist/project/detectors/ml.js.map +1 -0
  138. package/dist/project/detectors/ml.test.d.ts +2 -0
  139. package/dist/project/detectors/ml.test.d.ts.map +1 -0
  140. package/dist/project/detectors/ml.test.js +75 -0
  141. package/dist/project/detectors/ml.test.js.map +1 -0
  142. package/dist/project/detectors/mobile-app.d.ts +4 -0
  143. package/dist/project/detectors/mobile-app.d.ts.map +1 -0
  144. package/dist/project/detectors/mobile-app.js +58 -0
  145. package/dist/project/detectors/mobile-app.js.map +1 -0
  146. package/dist/project/detectors/mobile-app.test.d.ts +2 -0
  147. package/dist/project/detectors/mobile-app.test.d.ts.map +1 -0
  148. package/dist/project/detectors/mobile-app.test.js +57 -0
  149. package/dist/project/detectors/mobile-app.test.js.map +1 -0
  150. package/dist/project/detectors/required-fields.d.ts +4 -0
  151. package/dist/project/detectors/required-fields.d.ts.map +1 -0
  152. package/dist/project/detectors/required-fields.js +13 -0
  153. package/dist/project/detectors/required-fields.js.map +1 -0
  154. package/dist/project/detectors/required-fields.test.d.ts +2 -0
  155. package/dist/project/detectors/required-fields.test.d.ts.map +1 -0
  156. package/dist/project/detectors/required-fields.test.js +24 -0
  157. package/dist/project/detectors/required-fields.test.js.map +1 -0
  158. package/dist/project/detectors/resolve-detection.d.ts +18 -0
  159. package/dist/project/detectors/resolve-detection.d.ts.map +1 -0
  160. package/dist/project/detectors/resolve-detection.js +184 -0
  161. package/dist/project/detectors/resolve-detection.js.map +1 -0
  162. package/dist/project/detectors/resolve-detection.test.d.ts +2 -0
  163. package/dist/project/detectors/resolve-detection.test.d.ts.map +1 -0
  164. package/dist/project/detectors/resolve-detection.test.js +158 -0
  165. package/dist/project/detectors/resolve-detection.test.js.map +1 -0
  166. package/dist/project/detectors/types.d.ts +56 -0
  167. package/dist/project/detectors/types.d.ts.map +1 -0
  168. package/dist/project/detectors/types.js +9 -0
  169. package/dist/project/detectors/types.js.map +1 -0
  170. package/dist/project/detectors/web-app.d.ts +15 -0
  171. package/dist/project/detectors/web-app.d.ts.map +1 -0
  172. package/dist/project/detectors/web-app.js +228 -0
  173. package/dist/project/detectors/web-app.js.map +1 -0
  174. package/dist/project/detectors/web-app.test.d.ts +2 -0
  175. package/dist/project/detectors/web-app.test.d.ts.map +1 -0
  176. package/dist/project/detectors/web-app.test.js +95 -0
  177. package/dist/project/detectors/web-app.test.js.map +1 -0
  178. package/dist/types/config.d.ts +33 -0
  179. package/dist/types/config.d.ts.map +1 -1
  180. package/dist/types/enums.d.ts +2 -1
  181. package/dist/types/enums.d.ts.map +1 -1
  182. package/dist/types/enums.js +1 -0
  183. package/dist/types/enums.js.map +1 -1
  184. package/dist/utils/errors.d.ts +7 -0
  185. package/dist/utils/errors.d.ts.map +1 -1
  186. package/dist/utils/errors.js +38 -0
  187. package/dist/utils/errors.js.map +1 -1
  188. package/dist/utils/errors.test.js +42 -1
  189. package/dist/utils/errors.test.js.map +1 -1
  190. package/package.json +6 -2
@@ -1,13 +1,56 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { parseDocument, isMap, isScalar } from 'yaml';
4
+ import { z } from 'zod';
5
+ import { assertNever } from './detectors/types.js';
3
6
  import { detectProjectMode } from './detector.js';
4
7
  import { discoverMetaPrompts } from '../core/assembly/meta-prompt-loader.js';
8
+ import { createSignalContext } from './detectors/context.js';
9
+ import { runDetectors } from './detectors/index.js';
10
+ import { resolveDetection } from './detectors/resolve-detection.js';
11
+ import { WebAppConfigSchema, BackendConfigSchema, CliConfigSchema, LibraryConfigSchema, MobileAppConfigSchema, DataPipelineConfigSchema, MlConfigSchema, BrowserExtensionConfigSchema, GameConfigSchema, } from '../config/schema.js';
12
+ import { ExitCode } from '../types/enums.js';
13
+ import { configParseError, configNotObject } from '../utils/errors.js';
14
+ // CRITICAL: project-type → typed-config-key mapping. Do NOT derive via string transforms
15
+ // — `'web-app'.replace('-','')` produces 'webapp', not 'webApp'.
16
+ const TYPE_KEY = {
17
+ 'web-app': 'webAppConfig',
18
+ 'mobile-app': 'mobileAppConfig',
19
+ 'backend': 'backendConfig',
20
+ 'cli': 'cliConfig',
21
+ 'library': 'libraryConfig',
22
+ 'game': 'gameConfig',
23
+ 'data-pipeline': 'dataPipelineConfig',
24
+ 'ml': 'mlConfig',
25
+ 'browser-extension': 'browserExtensionConfig',
26
+ };
27
+ // Exported for use by CLI handler's writeOrUpdateConfig
28
+ export { TYPE_KEY };
29
+ // Map project type to its Zod schema for parse/validation
30
+ function schemaForType(type) {
31
+ switch (type) {
32
+ case 'web-app': return WebAppConfigSchema;
33
+ case 'backend': return BackendConfigSchema;
34
+ case 'cli': return CliConfigSchema;
35
+ case 'library': return LibraryConfigSchema;
36
+ case 'mobile-app': return MobileAppConfigSchema;
37
+ case 'data-pipeline': return DataPipelineConfigSchema;
38
+ case 'ml': return MlConfigSchema;
39
+ case 'browser-extension': return BrowserExtensionConfigSchema;
40
+ case 'game': return GameConfigSchema;
41
+ default: return assertNever(type);
42
+ }
43
+ }
5
44
  /**
6
45
  * Scan projectRoot for existing artifacts, match to pipeline steps,
7
46
  * and pre-populate state.json.
8
47
  */
9
- export function runAdoption(options) {
48
+ export async function runAdoption(options) {
10
49
  const { projectRoot, metaPromptDir, methodology } = options;
50
+ const auto = options.auto ?? false;
51
+ const force = options.force ?? false;
52
+ const explicitProjectType = options.explicitProjectType;
53
+ const flagOverrides = options.flagOverrides;
11
54
  // 1. Detect project mode
12
55
  const detection = detectProjectMode(projectRoot);
13
56
  // 2. Discover meta-prompts to get expected outputs per step
@@ -35,29 +78,6 @@ export function runAdoption(options) {
35
78
  stepsRemaining.push(slug);
36
79
  }
37
80
  }
38
- // 4. Game engine detection
39
- let detectedEngine;
40
- if (fs.existsSync(path.join(projectRoot, 'Assets'))) {
41
- try {
42
- const assets = fs.readdirSync(path.join(projectRoot, 'Assets'));
43
- if (assets.some(f => f.endsWith('.meta'))) {
44
- detectedEngine = 'unity';
45
- }
46
- }
47
- catch { /* ignore read errors */ }
48
- }
49
- if (!detectedEngine) {
50
- try {
51
- const files = fs.readdirSync(projectRoot);
52
- if (files.some(f => f.endsWith('.uproject'))) {
53
- detectedEngine = 'unreal';
54
- }
55
- }
56
- catch { /* ignore */ }
57
- }
58
- if (!detectedEngine && fs.existsSync(path.join(projectRoot, 'project.godot'))) {
59
- detectedEngine = 'godot';
60
- }
61
81
  const result = {
62
82
  mode: detection.mode,
63
83
  artifactsFound: detectedArtifacts.length,
@@ -68,10 +88,181 @@ export function runAdoption(options) {
68
88
  errors: [],
69
89
  warnings: [],
70
90
  };
71
- if (detectedEngine) {
72
- result.projectType = 'game';
73
- result.gameConfig = { engine: detectedEngine };
91
+ // 4. Project-type detection via SignalContext-backed detectors + resolveDetection pipeline.
92
+ // Build SignalContext + run detectors
93
+ const ctx = createSignalContext(projectRoot);
94
+ const detectorMatches = runDetectors(ctx);
95
+ // Re-adoption: read existing config.yml (if any) BEFORE Case A-G resolves
96
+ const configPath = path.join(projectRoot, '.scaffold', 'config.yml');
97
+ let existingDoc;
98
+ let existingProjectType;
99
+ let existingTypedConfigRaw;
100
+ if (fs.existsSync(configPath)) {
101
+ const text = fs.readFileSync(configPath, 'utf8');
102
+ existingDoc = parseDocument(text);
103
+ if (existingDoc.errors.length > 0) {
104
+ result.errors.push(configParseError(configPath, existingDoc.errors[0].message));
105
+ return result;
106
+ }
107
+ const projectNode = existingDoc.get('project', true);
108
+ // A null Scalar (YAML `project:` with no value) is fine — treated as empty project
109
+ if (projectNode !== undefined && !isMap(projectNode) && !isScalar(projectNode)) {
110
+ result.errors.push(configNotObject(configPath));
111
+ return result;
112
+ }
113
+ const projectJs = existingDoc.toJS()?.project;
114
+ existingProjectType = projectJs?.projectType;
115
+ if (existingProjectType) {
116
+ existingTypedConfigRaw = projectJs?.[TYPE_KEY[existingProjectType]];
117
+ }
118
+ }
119
+ // Re-adoption gating
120
+ if (existingProjectType && !force && !explicitProjectType) {
121
+ // SKIP detection — just re-run artifact scan (existing behavior)
122
+ result.warnings.push({
123
+ code: 'ADOPT_DETECTION_INCONCLUSIVE',
124
+ message: `Project already adopted as '${existingProjectType}'. `
125
+ + 'Pass --force to re-detect, or --project-type to switch.',
126
+ });
127
+ result.projectType = existingProjectType;
128
+ // Carry through context warnings
129
+ result.warnings.push(...ctx.warnings);
130
+ return result;
131
+ }
132
+ // Project-type conflict check
133
+ if (existingProjectType && explicitProjectType
134
+ && explicitProjectType !== existingProjectType
135
+ && !force) {
136
+ result.errors.push({
137
+ code: 'ADOPT_TYPE_CONFLICT',
138
+ message: `Existing projectType is '${existingProjectType}' but `
139
+ + `--project-type=${explicitProjectType} was passed. `
140
+ + 'Re-run with --force to overwrite.',
141
+ exitCode: ExitCode.Ambiguous,
142
+ });
143
+ return result;
144
+ }
145
+ const decision = await resolveDetection({
146
+ matches: detectorMatches,
147
+ explicitProjectType,
148
+ opts: {
149
+ interactive: !auto,
150
+ acceptLowConfidence: force,
151
+ },
152
+ });
153
+ result.warnings.push(...ctx.warnings, ...decision.warnings);
154
+ if (decision.error) {
155
+ result.errors.push(decision.error);
156
+ return result;
157
+ }
158
+ if (decision.chosen) {
159
+ // Type-changed warning if re-adoption picked a different type
160
+ if (existingProjectType && existingProjectType !== decision.chosen.projectType) {
161
+ result.warnings.push({
162
+ code: 'ADOPT_TYPE_CHANGED',
163
+ message: `Re-adoption changed projectType from '${existingProjectType}' to '${decision.chosen.projectType}'`,
164
+ context: { from: existingProjectType, to: decision.chosen.projectType },
165
+ });
166
+ }
167
+ try {
168
+ const finalized = finalizeConfigFromMatch(decision.chosen, flagOverrides,
169
+ // Only pass existing raw if same type (avoids merging across types)
170
+ existingProjectType === decision.chosen.projectType ? existingTypedConfigRaw : undefined);
171
+ // Emit field-conflict warnings from the merge
172
+ if (finalized.conflicts.length > 0) {
173
+ result.warnings.push(...emitFieldConflictWarnings(finalized.conflicts, TYPE_KEY[decision.chosen.projectType]));
174
+ }
175
+ result.projectType = decision.chosen.projectType;
176
+ result.detectedConfig = {
177
+ type: decision.chosen.projectType,
178
+ config: finalized.config,
179
+ };
180
+ result.detectionEvidence = decision.chosen.evidence;
181
+ result.detectionConfidence = decision.chosen.confidence;
182
+ // Dual-emit gameConfig (deprecation alias, removed v4.0)
183
+ if (decision.chosen.projectType === 'game') {
184
+ result.gameConfig = finalized.config;
185
+ result.warnings.push({
186
+ code: 'ADOPT_GAME_CONFIG_DEPRECATED',
187
+ message: 'The \'gameConfig\' field is deprecated. '
188
+ + 'Use \'detectedConfig\' (when type === \'game\'). Removed in v4.0.',
189
+ });
190
+ }
191
+ }
192
+ catch (err) {
193
+ if (err instanceof z.ZodError) {
194
+ const missing = err.errors.map(e => e.path.join('.')).join(', ');
195
+ result.errors.push({
196
+ code: 'ADOPT_MISSING_REQUIRED_FIELDS',
197
+ message: `Schema validation failed for ${decision.chosen.projectType}: `
198
+ + `missing or invalid fields [${missing}]. `
199
+ + 'Run \'scaffold init --help\' to see the available flags.',
200
+ exitCode: ExitCode.ValidationError,
201
+ context: { type: decision.chosen.projectType, missing },
202
+ });
203
+ return result;
204
+ }
205
+ throw err;
206
+ }
74
207
  }
75
208
  return result;
76
209
  }
210
+ function finalizeConfigFromMatch(match, flagOverrides, existingTypedConfigRaw) {
211
+ // Step 1: pre-parse merge — existing wins over detected
212
+ const { merged, conflicts } = mergeRawConfig(match.partialConfig, existingTypedConfigRaw);
213
+ // Step 2: apply flag overrides — flags replace whatever survived step 1
214
+ const overridePartial = flagOverrides?.type === match.projectType
215
+ ? flagOverrides.partial
216
+ : undefined;
217
+ const flagged = applyFlagOverrides(merged, overridePartial);
218
+ // Step 3: Zod.parse — applies defaults to fields still unset
219
+ const schema = schemaForType(match.projectType);
220
+ const config = schema.parse(flagged);
221
+ return { config, conflicts };
222
+ }
223
+ /**
224
+ * Shallow merge: existing values win on overlap, detected fills gaps.
225
+ * Returns the merged object plus a list of FieldConflict records for any field
226
+ * where detected and existing disagree (caller emits ADOPT_FIELD_CONFLICT warnings).
227
+ *
228
+ * Uses JSON.stringify for value equality so arrays and (future) nested objects
229
+ * are compared by content, not reference.
230
+ */
231
+ export function mergeRawConfig(detected, existing) {
232
+ const conflicts = [];
233
+ const merged = { ...detected };
234
+ if (existing) {
235
+ for (const [key, existingVal] of Object.entries(existing)) {
236
+ const detectedVal = detected[key];
237
+ if (detectedVal !== undefined) {
238
+ // Compare by serialized form so arrays/objects aren't always "different"
239
+ const detectedSerialized = JSON.stringify(detectedVal);
240
+ const existingSerialized = JSON.stringify(existingVal);
241
+ if (detectedSerialized !== existingSerialized) {
242
+ conflicts.push({ field: key, existing: existingVal, detected: detectedVal });
243
+ }
244
+ }
245
+ merged[key] = existingVal; // existing wins
246
+ }
247
+ }
248
+ return { merged, conflicts };
249
+ }
250
+ export function applyFlagOverrides(base, overrides) {
251
+ if (!overrides)
252
+ return base;
253
+ return { ...base, ...overrides }; // flag values replace whatever was there
254
+ }
255
+ /**
256
+ * Convert FieldConflict[] into ADOPT_FIELD_CONFLICT warnings for the orchestrator
257
+ * to push onto result.warnings.
258
+ */
259
+ export function emitFieldConflictWarnings(conflicts, configKey) {
260
+ return conflicts.map(c => ({
261
+ code: 'ADOPT_FIELD_CONFLICT',
262
+ message: `${configKey}.${c.field}: existing value ` +
263
+ `'${JSON.stringify(c.existing)}' wins over detected ` +
264
+ `'${JSON.stringify(c.detected)}'. Pass --force --project-type <type> --<flag> to override.`,
265
+ context: { field: c.field, existing: String(c.existing), detected: String(c.detected) },
266
+ }));
267
+ }
77
268
  //# sourceMappingURL=adopt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/project/adopt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/project/adopt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adopt.merge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.merge.test.d.ts","sourceRoot":"","sources":["../../src/project/adopt.merge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { mergeRawConfig, applyFlagOverrides, emitFieldConflictWarnings } from './adopt.js';
3
+ describe('mergeRawConfig', () => {
4
+ it('returns detected when existing is undefined', () => {
5
+ const result = mergeRawConfig({ a: 1, b: 2 }, undefined);
6
+ expect(result.merged).toEqual({ a: 1, b: 2 });
7
+ expect(result.conflicts).toEqual([]);
8
+ });
9
+ it('existing wins on overlap (scalar values)', () => {
10
+ const result = mergeRawConfig({ a: 1, b: 2 }, { a: 99 });
11
+ expect(result.merged).toEqual({ a: 99, b: 2 });
12
+ expect(result.conflicts).toEqual([{ field: 'a', existing: 99, detected: 1 }]);
13
+ });
14
+ it('no conflict when detected and existing agree', () => {
15
+ const result = mergeRawConfig({ a: 1 }, { a: 1 });
16
+ expect(result.merged).toEqual({ a: 1 });
17
+ expect(result.conflicts).toEqual([]);
18
+ });
19
+ it('detected fills in fields existing does not set', () => {
20
+ const result = mergeRawConfig({ a: 1, b: 2 }, { c: 3 });
21
+ expect(result.merged).toEqual({ a: 1, b: 2, c: 3 });
22
+ expect(result.conflicts).toEqual([]);
23
+ });
24
+ it('handles arrays as opaque values via JSON.stringify comparison', () => {
25
+ const result = mergeRawConfig({ dataStore: ['relational', 'redis'] }, { dataStore: ['relational'] });
26
+ expect(result.merged.dataStore).toEqual(['relational']); // existing wins entirely
27
+ expect(result.conflicts).toEqual([{
28
+ field: 'dataStore',
29
+ existing: ['relational'],
30
+ detected: ['relational', 'redis'],
31
+ }]);
32
+ });
33
+ it('NO conflict when arrays are structurally equal', () => {
34
+ const result = mergeRawConfig({ dataStore: ['relational'] }, { dataStore: ['relational'] });
35
+ expect(result.conflicts).toEqual([]);
36
+ });
37
+ });
38
+ describe('emitFieldConflictWarnings', () => {
39
+ it('produces one ADOPT_FIELD_CONFLICT per conflict', () => {
40
+ const warnings = emitFieldConflictWarnings([{ field: 'renderingStrategy', existing: 'ssr', detected: 'spa' }], 'webAppConfig');
41
+ expect(warnings).toHaveLength(1);
42
+ expect(warnings[0].code).toBe('ADOPT_FIELD_CONFLICT');
43
+ expect(warnings[0].message).toContain('webAppConfig.renderingStrategy');
44
+ expect(warnings[0].message).toContain('\'"ssr"\'');
45
+ });
46
+ });
47
+ describe('applyFlagOverrides', () => {
48
+ it('returns base when overrides is undefined', () => {
49
+ expect(applyFlagOverrides({ a: 1 }, undefined)).toEqual({ a: 1 });
50
+ });
51
+ it('overrides replace base values', () => {
52
+ expect(applyFlagOverrides({ a: 1, b: 2 }, { a: 99 })).toEqual({ a: 99, b: 2 });
53
+ });
54
+ it('full precedence: flag overrides existing + detected merge result', () => {
55
+ // Step 1: merge
56
+ const { merged } = mergeRawConfig({ a: 'detected', b: 'detected' }, { a: 'existing' });
57
+ // Step 2: flag overrides
58
+ const final = applyFlagOverrides(merged, { a: 'flag' });
59
+ expect(final).toEqual({ a: 'flag', b: 'detected' });
60
+ });
61
+ });
62
+ //# sourceMappingURL=adopt.merge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.merge.test.js","sourceRoot":"","sources":["../../src/project/adopt.merge.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adopt.re-adoption.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.re-adoption.test.d.ts","sourceRoot":"","sources":["../../src/project/adopt.re-adoption.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,222 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ // ---------------------------------------------------------------------------
6
+ // Hoisted mocks
7
+ // ---------------------------------------------------------------------------
8
+ vi.mock('./detector.js', () => ({
9
+ detectProjectMode: vi.fn(() => ({
10
+ mode: 'brownfield',
11
+ signals: [],
12
+ methodologySuggestion: 'deep',
13
+ sourceFileCount: 10,
14
+ })),
15
+ }));
16
+ vi.mock('../core/assembly/meta-prompt-loader.js', () => ({
17
+ discoverMetaPrompts: vi.fn(() => new Map()),
18
+ }));
19
+ // ---------------------------------------------------------------------------
20
+ // Imports (after mocks)
21
+ // ---------------------------------------------------------------------------
22
+ import { runAdoption } from './adopt.js';
23
+ // ---------------------------------------------------------------------------
24
+ // Helpers
25
+ // ---------------------------------------------------------------------------
26
+ function makeTempDir() {
27
+ return fs.mkdtempSync(path.join(os.tmpdir(), 'scaffold-readopt-'));
28
+ }
29
+ function seedGameProject(dir) {
30
+ const assetsDir = path.join(dir, 'Assets');
31
+ fs.mkdirSync(assetsDir, { recursive: true });
32
+ fs.writeFileSync(path.join(assetsDir, 'foo.meta'), '');
33
+ }
34
+ function seedConfig(dir, content) {
35
+ const scaffoldDir = path.join(dir, '.scaffold');
36
+ fs.mkdirSync(scaffoldDir, { recursive: true });
37
+ fs.writeFileSync(path.join(scaffoldDir, 'config.yml'), content, 'utf8');
38
+ }
39
+ function baseOpts(dir) {
40
+ return {
41
+ projectRoot: dir,
42
+ metaPromptDir: path.join(dir, 'content', 'pipeline'),
43
+ methodology: 'deep',
44
+ dryRun: true,
45
+ auto: true,
46
+ };
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Tests
50
+ // ---------------------------------------------------------------------------
51
+ describe('re-adoption gating', () => {
52
+ let tmpDir;
53
+ beforeEach(() => {
54
+ tmpDir = makeTempDir();
55
+ });
56
+ afterEach(() => {
57
+ fs.rmSync(tmpDir, { recursive: true, force: true });
58
+ vi.restoreAllMocks();
59
+ });
60
+ // -----------------------------------------------------------------------
61
+ // No existing projectType (fresh adoption)
62
+ // -----------------------------------------------------------------------
63
+ it('fresh adoption: detects game without existing config', async () => {
64
+ seedGameProject(tmpDir);
65
+ const result = await runAdoption({ ...baseOpts(tmpDir) });
66
+ expect(result.projectType).toBe('game');
67
+ expect(result.errors).toHaveLength(0);
68
+ expect(result.warnings.every(w => w.code !== 'ADOPT_DETECTION_INCONCLUSIVE')).toBe(true);
69
+ });
70
+ it('fresh adoption with explicit --project-type + required flag works', async () => {
71
+ const result = await runAdoption({
72
+ ...baseOpts(tmpDir),
73
+ explicitProjectType: 'backend',
74
+ flagOverrides: { type: 'backend', partial: { apiStyle: 'rest' } },
75
+ });
76
+ expect(result.projectType).toBe('backend');
77
+ expect(result.errors).toHaveLength(0);
78
+ expect(result.detectedConfig?.type).toBe('backend');
79
+ });
80
+ it('fresh adoption with explicit --project-type missing required field: MISSING_REQUIRED', async () => {
81
+ const result = await runAdoption({
82
+ ...baseOpts(tmpDir),
83
+ explicitProjectType: 'backend',
84
+ });
85
+ expect(result.errors).toHaveLength(1);
86
+ expect(result.errors[0].code).toBe('ADOPT_MISSING_REQUIRED_FIELDS');
87
+ expect(result.errors[0].message).toContain('apiStyle');
88
+ });
89
+ // -----------------------------------------------------------------------
90
+ // Existing matching projectType
91
+ // -----------------------------------------------------------------------
92
+ it('re-adoption of matching type without --force: skips detection', async () => {
93
+ seedGameProject(tmpDir);
94
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n');
95
+ const result = await runAdoption({ ...baseOpts(tmpDir) });
96
+ expect(result.projectType).toBe('game');
97
+ expect(result.warnings.some(w => w.code === 'ADOPT_DETECTION_INCONCLUSIVE')).toBe(true);
98
+ // Detection skipped, so no detectedConfig
99
+ expect(result.detectedConfig).toBeUndefined();
100
+ });
101
+ it('re-adoption of matching type with --force: runs detection', async () => {
102
+ seedGameProject(tmpDir);
103
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n');
104
+ const result = await runAdoption({
105
+ ...baseOpts(tmpDir),
106
+ force: true,
107
+ });
108
+ expect(result.projectType).toBe('game');
109
+ expect(result.detectedConfig).toBeDefined();
110
+ expect(result.errors).toHaveLength(0);
111
+ // No ADOPT_DETECTION_INCONCLUSIVE since we forced
112
+ expect(result.warnings.every(w => w.code !== 'ADOPT_DETECTION_INCONCLUSIVE')).toBe(true);
113
+ });
114
+ it('re-adoption with --project-type same as existing: runs detection', async () => {
115
+ seedGameProject(tmpDir);
116
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n'
117
+ + ' gameConfig:\n engine: unity\n');
118
+ const result = await runAdoption({
119
+ ...baseOpts(tmpDir),
120
+ explicitProjectType: 'game',
121
+ });
122
+ expect(result.projectType).toBe('game');
123
+ // Detection ran because explicit type bypasses re-adoption gating
124
+ expect(result.detectedConfig).toBeDefined();
125
+ expect(result.errors).toHaveLength(0);
126
+ });
127
+ // -----------------------------------------------------------------------
128
+ // Existing mismatching projectType
129
+ // -----------------------------------------------------------------------
130
+ it('re-adoption with mismatching --project-type (no --force): TYPE_CONFLICT', async () => {
131
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n');
132
+ const result = await runAdoption({
133
+ ...baseOpts(tmpDir),
134
+ explicitProjectType: 'backend',
135
+ });
136
+ expect(result.errors).toHaveLength(1);
137
+ expect(result.errors[0].code).toBe('ADOPT_TYPE_CONFLICT');
138
+ expect(result.errors[0].message).toContain('game');
139
+ expect(result.errors[0].message).toContain('backend');
140
+ });
141
+ it('re-adoption with mismatching --project-type + --force: succeeds', async () => {
142
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n');
143
+ const result = await runAdoption({
144
+ ...baseOpts(tmpDir),
145
+ explicitProjectType: 'backend',
146
+ force: true,
147
+ // backend requires apiStyle — supply it via flag overrides
148
+ flagOverrides: { type: 'backend', partial: { apiStyle: 'rest' } },
149
+ });
150
+ expect(result.projectType).toBe('backend');
151
+ expect(result.errors).toHaveLength(0);
152
+ // ADOPT_TYPE_CHANGED warning emitted
153
+ expect(result.warnings.some(w => w.code === 'ADOPT_TYPE_CHANGED')).toBe(true);
154
+ });
155
+ // -----------------------------------------------------------------------
156
+ // Merge pipeline: existing values win
157
+ // -----------------------------------------------------------------------
158
+ it('existing config values win over detected during merge', async () => {
159
+ seedGameProject(tmpDir);
160
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n'
161
+ + ' gameConfig:\n engine: unreal\n');
162
+ const result = await runAdoption({
163
+ ...baseOpts(tmpDir),
164
+ force: true,
165
+ });
166
+ // Detection finds unity (Assets/.meta), but existing says unreal
167
+ // Existing wins per merge pipeline invariant
168
+ expect(result.projectType).toBe('game');
169
+ expect(result.detectedConfig?.config).toEqual(expect.objectContaining({ engine: 'unreal' }));
170
+ // Conflict warning emitted
171
+ expect(result.warnings.some(w => w.code === 'ADOPT_FIELD_CONFLICT'
172
+ && w.message.includes('engine'))).toBe(true);
173
+ });
174
+ // -----------------------------------------------------------------------
175
+ // Flag overrides win over everything
176
+ // -----------------------------------------------------------------------
177
+ it('flag overrides win over existing and detected values', async () => {
178
+ seedGameProject(tmpDir);
179
+ seedConfig(tmpDir, 'version: 2\nproject:\n projectType: game\n'
180
+ + ' gameConfig:\n engine: unreal\n');
181
+ const result = await runAdoption({
182
+ ...baseOpts(tmpDir),
183
+ force: true,
184
+ flagOverrides: {
185
+ type: 'game',
186
+ partial: { engine: 'godot' },
187
+ },
188
+ });
189
+ expect(result.projectType).toBe('game');
190
+ // Flag override (godot) wins over existing (unreal) and detected (unity)
191
+ expect(result.detectedConfig?.config).toEqual(expect.objectContaining({ engine: 'godot' }));
192
+ });
193
+ // -----------------------------------------------------------------------
194
+ // Game deprecation alias
195
+ // -----------------------------------------------------------------------
196
+ it('game detection emits ADOPT_GAME_CONFIG_DEPRECATED warning', async () => {
197
+ seedGameProject(tmpDir);
198
+ const result = await runAdoption({ ...baseOpts(tmpDir) });
199
+ expect(result.projectType).toBe('game');
200
+ expect(result.gameConfig).toBeDefined();
201
+ expect(result.warnings.some(w => w.code === 'ADOPT_GAME_CONFIG_DEPRECATED')).toBe(true);
202
+ });
203
+ // -----------------------------------------------------------------------
204
+ // Config parse error
205
+ // -----------------------------------------------------------------------
206
+ it('returns CONFIG_PARSE_ERROR when config.yml is malformed YAML', async () => {
207
+ seedConfig(tmpDir, '{unclosed');
208
+ const result = await runAdoption({ ...baseOpts(tmpDir) });
209
+ expect(result.errors).toHaveLength(1);
210
+ expect(result.errors[0].code).toBe('CONFIG_PARSE_ERROR');
211
+ });
212
+ // -----------------------------------------------------------------------
213
+ // No detection match
214
+ // -----------------------------------------------------------------------
215
+ it('returns no projectType when empty dir and no explicit type', async () => {
216
+ const result = await runAdoption({ ...baseOpts(tmpDir) });
217
+ expect(result.projectType).toBeUndefined();
218
+ expect(result.detectedConfig).toBeUndefined();
219
+ expect(result.errors).toHaveLength(0);
220
+ });
221
+ });
222
+ //# sourceMappingURL=adopt.re-adoption.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.re-adoption.test.js","sourceRoot":"","sources":["../../src/project/adopt.re-adoption.test.ts"],"names":[],"mappings":"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"}