@zigrivers/scaffold 3.10.0 → 3.10.1

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 (38) hide show
  1. package/dist/cli/commands/adopt.cli-flags.test.d.ts +2 -0
  2. package/dist/cli/commands/adopt.cli-flags.test.d.ts.map +1 -0
  3. package/dist/cli/commands/adopt.cli-flags.test.js +165 -0
  4. package/dist/cli/commands/adopt.cli-flags.test.js.map +1 -0
  5. package/dist/cli/commands/adopt.config-resolution.test.d.ts +2 -0
  6. package/dist/cli/commands/adopt.config-resolution.test.d.ts.map +1 -0
  7. package/dist/cli/commands/adopt.config-resolution.test.js +217 -0
  8. package/dist/cli/commands/adopt.config-resolution.test.js.map +1 -0
  9. package/dist/cli/commands/adopt.config-write-integration.test.d.ts +2 -0
  10. package/dist/cli/commands/adopt.config-write-integration.test.d.ts.map +1 -0
  11. package/dist/cli/commands/adopt.config-write-integration.test.js +138 -0
  12. package/dist/cli/commands/adopt.config-write-integration.test.js.map +1 -0
  13. package/dist/cli/commands/adopt.d.ts +2 -0
  14. package/dist/cli/commands/adopt.d.ts.map +1 -1
  15. package/dist/cli/commands/adopt.js +5 -4
  16. package/dist/cli/commands/adopt.js.map +1 -1
  17. package/dist/cli/commands/adopt.result-shape.test.d.ts +2 -0
  18. package/dist/cli/commands/adopt.result-shape.test.d.ts.map +1 -0
  19. package/dist/cli/commands/adopt.result-shape.test.js +166 -0
  20. package/dist/cli/commands/adopt.result-shape.test.js.map +1 -0
  21. package/dist/cli/commands/adopt.serialization.test.d.ts +2 -0
  22. package/dist/cli/commands/adopt.serialization.test.d.ts.map +1 -0
  23. package/dist/cli/commands/adopt.serialization.test.js +228 -0
  24. package/dist/cli/commands/adopt.serialization.test.js.map +1 -0
  25. package/dist/cli/commands/adopt.test.js +8 -9
  26. package/dist/cli/commands/adopt.test.js.map +1 -1
  27. package/dist/cli/commands/adopt.windows-crlf.test.d.ts +2 -0
  28. package/dist/cli/commands/adopt.windows-crlf.test.d.ts.map +1 -0
  29. package/dist/cli/commands/adopt.windows-crlf.test.js +102 -0
  30. package/dist/cli/commands/adopt.windows-crlf.test.js.map +1 -0
  31. package/dist/project/detectors/library.d.ts.map +1 -1
  32. package/dist/project/detectors/library.js +6 -1
  33. package/dist/project/detectors/library.js.map +1 -1
  34. package/dist/project/detectors/library.test.js +22 -0
  35. package/dist/project/detectors/library.test.js.map +1 -1
  36. package/dist/types/config.d.ts +9 -9
  37. package/dist/types/config.d.ts.map +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adopt.cli-flags.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.cli-flags.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adopt.cli-flags.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,165 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ // ---------------------------------------------------------------------------
6
+ // Hoisted mocks — needed because runAdoption calls detectProjectMode and
7
+ // discoverMetaPrompts. We mock at the paths that adopt.ts imports from.
8
+ // ---------------------------------------------------------------------------
9
+ vi.mock('../../project/detector.js', () => ({
10
+ detectProjectMode: vi.fn(() => ({
11
+ mode: 'brownfield',
12
+ signals: [],
13
+ methodologySuggestion: 'deep',
14
+ sourceFileCount: 10,
15
+ })),
16
+ }));
17
+ vi.mock('../../core/assembly/meta-prompt-loader.js', () => ({
18
+ discoverMetaPrompts: vi.fn(() => new Map()),
19
+ }));
20
+ // ---------------------------------------------------------------------------
21
+ // Imports (after mocks)
22
+ // ---------------------------------------------------------------------------
23
+ import { runAdoption } from '../../project/adopt.js';
24
+ import { buildFlagOverrides, applyFlagFamilyValidation } from '../init-flag-families.js';
25
+ // ---------------------------------------------------------------------------
26
+ // Helpers
27
+ // ---------------------------------------------------------------------------
28
+ function makeTmpProject(files) {
29
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'adopt-flags-'));
30
+ for (const [rel, content] of Object.entries(files)) {
31
+ const full = path.join(dir, rel);
32
+ fs.mkdirSync(path.dirname(full), { recursive: true });
33
+ fs.writeFileSync(full, content);
34
+ }
35
+ return dir;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Tests
39
+ // ---------------------------------------------------------------------------
40
+ describe('adopt CLI flag integration', () => {
41
+ let tmpDirs;
42
+ beforeEach(() => {
43
+ tmpDirs = [];
44
+ });
45
+ afterEach(() => {
46
+ for (const d of tmpDirs) {
47
+ fs.rmSync(d, { recursive: true, force: true });
48
+ }
49
+ });
50
+ function tracked(dir) {
51
+ tmpDirs.push(dir);
52
+ return dir;
53
+ }
54
+ // -------------------------------------------------------------------------
55
+ // buildFlagOverrides unit-level integration
56
+ // -------------------------------------------------------------------------
57
+ it('buildFlagOverrides returns undefined when no family flags present', () => {
58
+ expect(buildFlagOverrides({})).toBeUndefined();
59
+ });
60
+ it('--backend-api-style graphql produces correct override shape', () => {
61
+ const overrides = buildFlagOverrides({ 'backend-api-style': 'graphql' });
62
+ expect(overrides?.type).toBe('backend');
63
+ expect(overrides?.partial).toEqual(expect.objectContaining({ apiStyle: 'graphql' }));
64
+ });
65
+ it('--web-rendering ssr produces web-app override with renderingStrategy', () => {
66
+ const overrides = buildFlagOverrides({ 'web-rendering': 'ssr' });
67
+ expect(overrides?.type).toBe('web-app');
68
+ expect(overrides?.partial).toEqual(expect.objectContaining({ renderingStrategy: 'ssr' }));
69
+ });
70
+ it('--engine unity produces game override with engine', () => {
71
+ const overrides = buildFlagOverrides({ engine: 'unity' });
72
+ expect(overrides?.type).toBe('game');
73
+ expect(overrides?.partial).toEqual(expect.objectContaining({ engine: 'unity' }));
74
+ });
75
+ it('--ml-phase training produces ml override with projectPhase', () => {
76
+ const overrides = buildFlagOverrides({ 'ml-phase': 'training' });
77
+ expect(overrides?.type).toBe('ml');
78
+ expect(overrides?.partial).toEqual(expect.objectContaining({ projectPhase: 'training' }));
79
+ });
80
+ it('--mobile-platform ios produces mobile-app override', () => {
81
+ const overrides = buildFlagOverrides({ 'mobile-platform': 'ios' });
82
+ expect(overrides?.type).toBe('mobile-app');
83
+ expect(overrides?.partial).toEqual(expect.objectContaining({ platform: 'ios' }));
84
+ });
85
+ it('--ext-manifest 3 produces browser-extension override', () => {
86
+ const overrides = buildFlagOverrides({ 'ext-manifest': '3' });
87
+ expect(overrides?.type).toBe('browser-extension');
88
+ expect(overrides?.partial).toEqual(expect.objectContaining({ manifestVersion: '3' }));
89
+ });
90
+ it('--pipeline-processing streaming produces data-pipeline override', () => {
91
+ const overrides = buildFlagOverrides({ 'pipeline-processing': 'streaming' });
92
+ expect(overrides?.type).toBe('data-pipeline');
93
+ expect(overrides?.partial).toEqual(expect.objectContaining({ processingModel: 'streaming' }));
94
+ });
95
+ it('--lib-visibility public produces library override', () => {
96
+ const overrides = buildFlagOverrides({ 'lib-visibility': 'public' });
97
+ expect(overrides?.type).toBe('library');
98
+ expect(overrides?.partial).toEqual(expect.objectContaining({ visibility: 'public' }));
99
+ });
100
+ it('--cli-interactivity hybrid produces cli override', () => {
101
+ const overrides = buildFlagOverrides({ 'cli-interactivity': 'hybrid' });
102
+ expect(overrides?.type).toBe('cli');
103
+ expect(overrides?.partial).toEqual(expect.objectContaining({ interactivity: 'hybrid' }));
104
+ });
105
+ // -------------------------------------------------------------------------
106
+ // Validation — mixed families and project-type mismatches
107
+ // -------------------------------------------------------------------------
108
+ it('mixed family flags throw during validation', () => {
109
+ const argv = { 'web-rendering': 'ssr', 'backend-api-style': 'rest' };
110
+ expect(() => applyFlagFamilyValidation(argv)).toThrow(/Cannot mix flags/);
111
+ });
112
+ it('--web-rendering with --project-type backend throws', () => {
113
+ const argv = { 'project-type': 'backend', 'web-rendering': 'ssr' };
114
+ expect(() => applyFlagFamilyValidation(argv)).toThrow(/--web-\* flags require --project-type web-app/);
115
+ });
116
+ it('--backend-api-style with --project-type web-app throws', () => {
117
+ const argv = { 'project-type': 'web-app', 'backend-api-style': 'rest' };
118
+ expect(() => applyFlagFamilyValidation(argv)).toThrow(/--backend-\* flags require --project-type backend/);
119
+ });
120
+ it('game flags with --project-type cli throws', () => {
121
+ const argv = { 'project-type': 'cli', engine: 'unity' };
122
+ expect(() => applyFlagFamilyValidation(argv)).toThrow(/Game flags .* require --project-type game/);
123
+ });
124
+ // -------------------------------------------------------------------------
125
+ // Flag overrides flow through runAdoption
126
+ // -------------------------------------------------------------------------
127
+ it('--engine unity override flows through to runAdoption result', async () => {
128
+ const dir = tracked(makeTmpProject({
129
+ 'Assets/foo.meta': '',
130
+ }));
131
+ const overrides = buildFlagOverrides({ engine: 'godot' });
132
+ const result = await runAdoption({
133
+ projectRoot: dir,
134
+ metaPromptDir: path.join(dir, '.scaffold'),
135
+ methodology: 'deep',
136
+ dryRun: true,
137
+ auto: true,
138
+ force: true,
139
+ verbose: false,
140
+ explicitProjectType: 'game',
141
+ flagOverrides: overrides,
142
+ });
143
+ // Detection finds unity (Assets/.meta) but flag override says godot
144
+ expect(result.projectType).toBe('game');
145
+ expect(result.detectedConfig?.config?.engine).toBe('godot');
146
+ });
147
+ it('--backend-api-style graphql with --project-type backend sets apiStyle', async () => {
148
+ const dir = tracked(makeTmpProject({}));
149
+ const overrides = buildFlagOverrides({ 'backend-api-style': 'graphql' });
150
+ const result = await runAdoption({
151
+ projectRoot: dir,
152
+ metaPromptDir: path.join(dir, '.scaffold'),
153
+ methodology: 'deep',
154
+ dryRun: true,
155
+ auto: true,
156
+ force: true,
157
+ verbose: false,
158
+ explicitProjectType: 'backend',
159
+ flagOverrides: overrides,
160
+ });
161
+ expect(result.projectType).toBe('backend');
162
+ expect(result.detectedConfig?.config?.apiStyle).toBe('graphql');
163
+ });
164
+ });
165
+ //# sourceMappingURL=adopt.cli-flags.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.cli-flags.test.js","sourceRoot":"","sources":["../../../src/cli/commands/adopt.cli-flags.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adopt.config-resolution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.config-resolution.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adopt.config-resolution.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,217 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ // ---------------------------------------------------------------------------
6
+ // Hoisted mocks
7
+ // ---------------------------------------------------------------------------
8
+ vi.mock('../../project/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 '../../project/adopt.js';
23
+ // ---------------------------------------------------------------------------
24
+ // Helpers
25
+ // ---------------------------------------------------------------------------
26
+ function makeTmpProject(files) {
27
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'adopt-write-'));
28
+ for (const [rel, content] of Object.entries(files)) {
29
+ const full = path.join(dir, rel);
30
+ fs.mkdirSync(path.dirname(full), { recursive: true });
31
+ fs.writeFileSync(full, content);
32
+ }
33
+ return dir;
34
+ }
35
+ // ---------------------------------------------------------------------------
36
+ // Tests
37
+ // ---------------------------------------------------------------------------
38
+ describe('adopt config write', () => {
39
+ let tmpDirs;
40
+ beforeEach(() => {
41
+ tmpDirs = [];
42
+ });
43
+ afterEach(() => {
44
+ for (const d of tmpDirs) {
45
+ fs.rmSync(d, { recursive: true, force: true });
46
+ }
47
+ });
48
+ function tracked(dir) {
49
+ tmpDirs.push(dir);
50
+ return dir;
51
+ }
52
+ it('dry-run produces detectedConfig without writing files', async () => {
53
+ const dir = tracked(makeTmpProject({
54
+ 'Assets/foo.meta': '',
55
+ }));
56
+ const result = await runAdoption({
57
+ projectRoot: dir,
58
+ metaPromptDir: path.join(dir, '.scaffold'),
59
+ methodology: 'deep',
60
+ dryRun: true,
61
+ auto: true,
62
+ force: true,
63
+ verbose: false,
64
+ });
65
+ expect(result.detectedConfig?.type).toBe('game');
66
+ // No .scaffold/config.yml created in dry-run (runAdoption doesn't write files)
67
+ expect(fs.existsSync(path.join(dir, '.scaffold', 'config.yml'))).toBe(false);
68
+ });
69
+ it('merge preserves existing config values over detection', async () => {
70
+ const dir = tracked(makeTmpProject({
71
+ 'Assets/foo.meta': '',
72
+ '.scaffold/config.yml': 'version: 2\nproject:\n projectType: game\n gameConfig:\n engine: unreal\n',
73
+ }));
74
+ const result = await runAdoption({
75
+ projectRoot: dir,
76
+ metaPromptDir: path.join(dir, '.scaffold'),
77
+ methodology: 'deep',
78
+ dryRun: true,
79
+ auto: true,
80
+ force: true,
81
+ verbose: false,
82
+ });
83
+ // Detection finds unity (Assets/.meta), but existing says unreal
84
+ // Existing wins per merge pipeline invariant
85
+ const config = result.detectedConfig?.config;
86
+ expect(config?.engine).toBe('unreal');
87
+ // Should emit field conflict warning
88
+ expect(result.warnings.some(w => w.code === 'ADOPT_FIELD_CONFLICT')).toBe(true);
89
+ });
90
+ it('existing config with bare project: (null scalar) does not crash', async () => {
91
+ const dir = tracked(makeTmpProject({
92
+ 'Assets/foo.meta': '',
93
+ '.scaffold/config.yml': 'version: 2\nproject:\n',
94
+ }));
95
+ const result = await runAdoption({
96
+ projectRoot: dir,
97
+ metaPromptDir: path.join(dir, '.scaffold'),
98
+ methodology: 'deep',
99
+ dryRun: true,
100
+ auto: true,
101
+ force: true,
102
+ verbose: false,
103
+ });
104
+ expect(result.errors).toHaveLength(0);
105
+ expect(result.detectedConfig?.type).toBe('game');
106
+ });
107
+ it('malformed YAML config produces an error', async () => {
108
+ const dir = tracked(makeTmpProject({
109
+ 'Assets/foo.meta': '',
110
+ '.scaffold/config.yml': '{unclosed',
111
+ }));
112
+ const result = await runAdoption({
113
+ projectRoot: dir,
114
+ metaPromptDir: path.join(dir, '.scaffold'),
115
+ methodology: 'deep',
116
+ dryRun: true,
117
+ auto: true,
118
+ force: true,
119
+ verbose: false,
120
+ });
121
+ expect(result.errors.length).toBeGreaterThan(0);
122
+ expect(result.errors[0].code).toBe('CONFIG_PARSE_ERROR');
123
+ });
124
+ it('type conflict without --force returns error', async () => {
125
+ const dir = tracked(makeTmpProject({
126
+ 'Assets/foo.meta': '',
127
+ '.scaffold/config.yml': 'version: 2\nproject:\n projectType: game\n gameConfig:\n engine: unity\n',
128
+ }));
129
+ const result = await runAdoption({
130
+ projectRoot: dir,
131
+ metaPromptDir: path.join(dir, '.scaffold'),
132
+ methodology: 'deep',
133
+ dryRun: true,
134
+ auto: true,
135
+ force: false,
136
+ verbose: false,
137
+ explicitProjectType: 'web-app',
138
+ });
139
+ expect(result.errors.some(e => e.code === 'ADOPT_TYPE_CONFLICT')).toBe(true);
140
+ });
141
+ it('preserves YAML comments in existing config without crashing', async () => {
142
+ const dir = tracked(makeTmpProject({
143
+ 'Assets/foo.meta': '',
144
+ '.scaffold/config.yml': '# My config comment\nversion: 2\nproject:\n projectType: game\n'
145
+ + ' gameConfig:\n engine: unity\n',
146
+ }));
147
+ const result = await runAdoption({
148
+ projectRoot: dir,
149
+ metaPromptDir: path.join(dir, '.scaffold'),
150
+ methodology: 'deep',
151
+ dryRun: true,
152
+ auto: true,
153
+ force: true,
154
+ verbose: false,
155
+ });
156
+ expect(result.errors).toHaveLength(0);
157
+ expect(result.projectType).toBe('game');
158
+ });
159
+ it('re-adoption without --force skips detection and returns ADOPT_DETECTION_INCONCLUSIVE', async () => {
160
+ const dir = tracked(makeTmpProject({
161
+ 'Assets/foo.meta': '',
162
+ '.scaffold/config.yml': 'version: 2\nproject:\n projectType: game\n',
163
+ }));
164
+ const result = await runAdoption({
165
+ projectRoot: dir,
166
+ metaPromptDir: path.join(dir, '.scaffold'),
167
+ methodology: 'deep',
168
+ dryRun: true,
169
+ auto: true,
170
+ force: false,
171
+ verbose: false,
172
+ });
173
+ expect(result.projectType).toBe('game');
174
+ expect(result.detectedConfig).toBeUndefined();
175
+ expect(result.warnings.some(w => w.code === 'ADOPT_DETECTION_INCONCLUSIVE')).toBe(true);
176
+ });
177
+ it('type conflict with --force allows type change and emits ADOPT_TYPE_CHANGED', async () => {
178
+ const dir = tracked(makeTmpProject({
179
+ 'Assets/foo.meta': '',
180
+ '.scaffold/config.yml': 'version: 2\nproject:\n projectType: backend\n backendConfig:\n apiStyle: rest\n',
181
+ }));
182
+ const result = await runAdoption({
183
+ projectRoot: dir,
184
+ metaPromptDir: path.join(dir, '.scaffold'),
185
+ methodology: 'deep',
186
+ dryRun: true,
187
+ auto: true,
188
+ force: true,
189
+ verbose: false,
190
+ });
191
+ // Assets/.meta → detection wins with game
192
+ expect(result.projectType).toBe('game');
193
+ expect(result.errors).toHaveLength(0);
194
+ expect(result.warnings.some(w => w.code === 'ADOPT_TYPE_CHANGED')).toBe(true);
195
+ });
196
+ it('explicit --project-type with matching existing config runs detection', async () => {
197
+ const dir = tracked(makeTmpProject({
198
+ 'Assets/foo.meta': '',
199
+ '.scaffold/config.yml': 'version: 2\nproject:\n projectType: game\n gameConfig:\n engine: unity\n',
200
+ }));
201
+ const result = await runAdoption({
202
+ projectRoot: dir,
203
+ metaPromptDir: path.join(dir, '.scaffold'),
204
+ methodology: 'deep',
205
+ dryRun: true,
206
+ auto: true,
207
+ force: false,
208
+ verbose: false,
209
+ explicitProjectType: 'game',
210
+ });
211
+ // Detection ran because explicit type bypasses re-adoption gating
212
+ expect(result.projectType).toBe('game');
213
+ expect(result.detectedConfig).toBeDefined();
214
+ expect(result.errors).toHaveLength(0);
215
+ });
216
+ });
217
+ //# sourceMappingURL=adopt.config-resolution.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.config-resolution.test.js","sourceRoot":"","sources":["../../../src/cli/commands/adopt.config-resolution.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adopt.config-write-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.config-write-integration.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adopt.config-write-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,138 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { writeOrUpdateConfig } from './adopt.js';
6
+ function makeTmpDir() {
7
+ return fs.mkdtempSync(path.join(os.tmpdir(), 'adopt-write-int-'));
8
+ }
9
+ function makeResult(overrides = {}) {
10
+ return {
11
+ mode: 'brownfield',
12
+ artifactsFound: 0,
13
+ detectedArtifacts: [],
14
+ stepsCompleted: [],
15
+ stepsRemaining: [],
16
+ methodology: 'deep',
17
+ errors: [],
18
+ warnings: [],
19
+ ...overrides,
20
+ };
21
+ }
22
+ describe('writeOrUpdateConfig integration', () => {
23
+ const tmpDirs = [];
24
+ afterEach(() => {
25
+ for (const d of tmpDirs)
26
+ fs.rmSync(d, { recursive: true, force: true });
27
+ tmpDirs.length = 0;
28
+ });
29
+ function tracked(dir) {
30
+ tmpDirs.push(dir);
31
+ return dir;
32
+ }
33
+ it('bootstraps new config.yml when none exists', () => {
34
+ const dir = tracked(makeTmpDir());
35
+ const result = makeResult({
36
+ projectType: 'web-app',
37
+ detectedConfig: {
38
+ type: 'web-app',
39
+ config: { renderingStrategy: 'ssr' },
40
+ },
41
+ });
42
+ writeOrUpdateConfig(dir, result);
43
+ const content = fs.readFileSync(path.join(dir, '.scaffold', 'config.yml'), 'utf8');
44
+ expect(content).toContain('projectType: web-app');
45
+ expect(content).toContain('renderingStrategy: ssr');
46
+ expect(content).toContain('version: 2');
47
+ });
48
+ it('preserves comments in existing config.yml', () => {
49
+ const dir = tracked(makeTmpDir());
50
+ fs.mkdirSync(path.join(dir, '.scaffold'), { recursive: true });
51
+ fs.writeFileSync(path.join(dir, '.scaffold', 'config.yml'), '# My custom comment\nversion: 2\nproject:\n projectType: web-app\n');
52
+ const result = makeResult({
53
+ projectType: 'web-app',
54
+ detectedConfig: {
55
+ type: 'web-app',
56
+ config: { renderingStrategy: 'ssr' },
57
+ },
58
+ });
59
+ writeOrUpdateConfig(dir, result);
60
+ const content = fs.readFileSync(path.join(dir, '.scaffold', 'config.yml'), 'utf8');
61
+ expect(content).toContain('# My custom comment');
62
+ expect(content).toContain('renderingStrategy: ssr');
63
+ });
64
+ it('removes stale config blocks when switching project types', () => {
65
+ const dir = tracked(makeTmpDir());
66
+ fs.mkdirSync(path.join(dir, '.scaffold'), { recursive: true });
67
+ fs.writeFileSync(path.join(dir, '.scaffold', 'config.yml'), 'version: 2\nproject:\n projectType: game\n gameConfig:\n engine: unity\n');
68
+ const result = makeResult({
69
+ projectType: 'web-app',
70
+ detectedConfig: {
71
+ type: 'web-app',
72
+ config: { renderingStrategy: 'ssr' },
73
+ },
74
+ });
75
+ writeOrUpdateConfig(dir, result);
76
+ const content = fs.readFileSync(path.join(dir, '.scaffold', 'config.yml'), 'utf8');
77
+ expect(content).toContain('projectType: web-app');
78
+ expect(content).toContain('webAppConfig');
79
+ expect(content).not.toContain('gameConfig');
80
+ expect(content).not.toContain('engine: unity');
81
+ });
82
+ it('handles bare project: (null scalar) without crashing', () => {
83
+ const dir = tracked(makeTmpDir());
84
+ fs.mkdirSync(path.join(dir, '.scaffold'), { recursive: true });
85
+ fs.writeFileSync(path.join(dir, '.scaffold', 'config.yml'), 'version: 2\nproject:\n');
86
+ const result = makeResult({
87
+ projectType: 'backend',
88
+ detectedConfig: {
89
+ type: 'backend',
90
+ config: { apiStyle: 'rest' },
91
+ },
92
+ });
93
+ expect(() => writeOrUpdateConfig(dir, result)).not.toThrow();
94
+ const content = fs.readFileSync(path.join(dir, '.scaffold', 'config.yml'), 'utf8');
95
+ expect(content).toContain('projectType: backend');
96
+ expect(content).toContain('backendConfig');
97
+ });
98
+ it('throws on malformed YAML', () => {
99
+ const dir = tracked(makeTmpDir());
100
+ fs.mkdirSync(path.join(dir, '.scaffold'), { recursive: true });
101
+ fs.writeFileSync(path.join(dir, '.scaffold', 'config.yml'), '{{{{invalid!');
102
+ const result = makeResult({
103
+ projectType: 'web-app',
104
+ detectedConfig: {
105
+ type: 'web-app',
106
+ config: { renderingStrategy: 'ssr' },
107
+ },
108
+ });
109
+ expect(() => writeOrUpdateConfig(dir, result)).toThrow();
110
+ });
111
+ it('uses atomic tmp+rename write (no partial writes)', () => {
112
+ const dir = tracked(makeTmpDir());
113
+ const result = makeResult({
114
+ projectType: 'cli',
115
+ detectedConfig: {
116
+ type: 'cli',
117
+ config: { interactivity: 'args-only' },
118
+ },
119
+ });
120
+ writeOrUpdateConfig(dir, result);
121
+ const configPath = path.join(dir, '.scaffold', 'config.yml');
122
+ expect(fs.existsSync(configPath)).toBe(true);
123
+ // No tmp file left behind
124
+ const tmpPath = `${configPath}.${process.pid}.tmp`;
125
+ expect(fs.existsSync(tmpPath)).toBe(false);
126
+ });
127
+ it('does nothing when result has no projectType', () => {
128
+ const dir = tracked(makeTmpDir());
129
+ fs.mkdirSync(path.join(dir, '.scaffold'), { recursive: true });
130
+ fs.writeFileSync(path.join(dir, '.scaffold', 'config.yml'), 'version: 2\nproject:\n');
131
+ const result = makeResult(); // no projectType, no detectedConfig
132
+ writeOrUpdateConfig(dir, result);
133
+ const content = fs.readFileSync(path.join(dir, '.scaffold', 'config.yml'), 'utf8');
134
+ // File should be unchanged (no projectType mutation)
135
+ expect(content).not.toContain('projectType:');
136
+ });
137
+ });
138
+ //# sourceMappingURL=adopt.config-write-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.config-write-integration.test.js","sourceRoot":"","sources":["../../../src/cli/commands/adopt.config-write-integration.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { CommandModule } from 'yargs';
2
+ import type { AdoptionResult } from '../../project/adopt.js';
2
3
  interface AdoptArgs {
3
4
  format?: string;
4
5
  auto?: boolean;
@@ -9,6 +10,7 @@ interface AdoptArgs {
9
10
  'project-type'?: string;
10
11
  [key: string]: unknown;
11
12
  }
13
+ export declare function writeOrUpdateConfig(projectRoot: string, result: AdoptionResult): void;
12
14
  declare const adoptCommand: CommandModule<Record<string, unknown>, AdoptArgs>;
13
15
  export default adoptCommand;
14
16
  //# sourceMappingURL=adopt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adopt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAQ,MAAM,OAAO,CAAA;AAwBhD,UAAU,SAAS;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAkHD,QAAA,MAAM,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CA6YnE,CAAA;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adopt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAQ,MAAM,OAAO,CAAA;AAYhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAY5D,UAAU,SAAS;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAYD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,GACrB,IAAI,CAgDN;AAmDD,QAAA,MAAM,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CA8YnE,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -23,7 +23,7 @@ function atomicWriteFileSync(target, content) {
23
23
  fs.writeFileSync(tmpPath, content, 'utf8');
24
24
  fs.renameSync(tmpPath, target);
25
25
  }
26
- function writeOrUpdateConfig(projectRoot, result) {
26
+ export function writeOrUpdateConfig(projectRoot, result) {
27
27
  const configPath = path.join(projectRoot, '.scaffold', 'config.yml');
28
28
  let doc;
29
29
  if (!fs.existsSync(configPath)) {
@@ -394,7 +394,7 @@ const adoptCommand = {
394
394
  if (!projectRoot) {
395
395
  const output = createOutputContext('auto');
396
396
  output.error({ code: 'PROJECT_NOT_INITIALIZED', message: 'No .scaffold/ directory found', exitCode: 1 });
397
- process.exit(1);
397
+ process.exitCode = 1;
398
398
  return;
399
399
  }
400
400
  const outputMode = resolveOutputMode(argv);
@@ -404,7 +404,7 @@ const adoptCommand = {
404
404
  if (!lockResult.acquired) {
405
405
  if (lockResult.error)
406
406
  output.error(lockResult.error);
407
- process.exit(3);
407
+ process.exitCode = 3;
408
408
  return;
409
409
  }
410
410
  try {
@@ -492,7 +492,8 @@ const adoptCommand = {
492
492
  output.success(`Adoption complete: ${adoptResult.artifactsFound} artifacts found, ` +
493
493
  `${adoptResult.stepsCompleted.length} steps completed`);
494
494
  }
495
- process.exit(0);
495
+ process.exitCode = 0;
496
+ return;
496
497
  }
497
498
  finally {
498
499
  releaseLock(projectRoot);