@lbruton/specflow 3.0.0 → 3.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +34 -26
  3. package/dist/core/__tests__/convention-detector.test.d.ts +2 -0
  4. package/dist/core/__tests__/convention-detector.test.d.ts.map +1 -0
  5. package/dist/core/__tests__/convention-detector.test.js +199 -0
  6. package/dist/core/__tests__/convention-detector.test.js.map +1 -0
  7. package/dist/core/__tests__/security-utils.test.js +2 -2
  8. package/dist/core/__tests__/security-utils.test.js.map +1 -1
  9. package/dist/core/__tests__/template-generator.test.d.ts +2 -0
  10. package/dist/core/__tests__/template-generator.test.d.ts.map +1 -0
  11. package/dist/core/__tests__/template-generator.test.js +167 -0
  12. package/dist/core/__tests__/template-generator.test.js.map +1 -0
  13. package/dist/core/convention-detector.d.ts +36 -0
  14. package/dist/core/convention-detector.d.ts.map +1 -0
  15. package/dist/core/convention-detector.js +298 -0
  16. package/dist/core/convention-detector.js.map +1 -0
  17. package/dist/core/project-registry.d.ts +6 -0
  18. package/dist/core/project-registry.d.ts.map +1 -1
  19. package/dist/core/project-registry.js +17 -1
  20. package/dist/core/project-registry.js.map +1 -1
  21. package/dist/core/security-utils.js +2 -2
  22. package/dist/core/security-utils.js.map +1 -1
  23. package/dist/core/template-generator.d.ts +21 -0
  24. package/dist/core/template-generator.d.ts.map +1 -0
  25. package/dist/core/template-generator.js +217 -0
  26. package/dist/core/template-generator.js.map +1 -0
  27. package/dist/markdown/templates/design-template.md +8 -6
  28. package/dist/markdown/templates/tasks-template.md +23 -20
  29. package/dist/prompts/index.d.ts.map +1 -1
  30. package/dist/prompts/index.js +3 -0
  31. package/dist/prompts/index.js.map +1 -1
  32. package/dist/tools/spec-status.d.ts.map +1 -1
  33. package/dist/tools/spec-status.js +35 -8
  34. package/dist/tools/spec-status.js.map +1 -1
  35. package/dist/tools/spec-workflow-guide.js +25 -15
  36. package/dist/tools/spec-workflow-guide.js.map +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,167 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ // Mock fs/promises before importing the module under test
3
+ vi.mock('fs/promises', () => ({
4
+ readFile: vi.fn(),
5
+ mkdir: vi.fn(),
6
+ writeFile: vi.fn(),
7
+ stat: vi.fn(),
8
+ }));
9
+ import { readFile, mkdir, writeFile, stat } from 'fs/promises';
10
+ import { generateUserTemplates, writeUserTemplates } from '../template-generator.js';
11
+ const mockReadFile = vi.mocked(readFile);
12
+ const mockMkdir = vi.mocked(mkdir);
13
+ const mockWriteFile = vi.mocked(writeFile);
14
+ const mockStat = vi.mocked(stat);
15
+ /** Helper: create a fake Stats for a file. */
16
+ function fakeFileStat() {
17
+ return { isFile: () => true, isDirectory: () => false };
18
+ }
19
+ /** Minimal design template with a Testing Strategy section. */
20
+ const MOCK_DESIGN_TEMPLATE = `# Design
21
+
22
+ ## Architecture
23
+ [Architecture details]
24
+
25
+ ## Testing Strategy
26
+ [Default testing strategy placeholder]
27
+
28
+ ## Rollback Plan
29
+ [Rollback details]
30
+ `;
31
+ /** Minimal tasks template with a Standard Closing Tasks section. */
32
+ const MOCK_TASKS_TEMPLATE = `# Tasks
33
+
34
+ - [ ] 1. First task
35
+ - Do the thing
36
+
37
+ ## Standard Closing Tasks
38
+
39
+ - [ ] 6. Default closing task
40
+ - Default details
41
+ `;
42
+ /** Build a conventions object with sensible defaults and overrides. */
43
+ function makeConventions(overrides = {}) {
44
+ return {
45
+ schemaVersion: 1,
46
+ detectedAt: '2026-04-03T00:00:00.000Z',
47
+ testing: {
48
+ framework: null,
49
+ command: null,
50
+ configFile: null,
51
+ testDir: null,
52
+ hasBrowserbase: false,
53
+ ...overrides.testing,
54
+ },
55
+ versioning: {
56
+ hasVersionLock: false,
57
+ lockFile: null,
58
+ packageVersion: null,
59
+ userDeclinedSetup: false,
60
+ ...overrides.versioning,
61
+ },
62
+ changelog: {
63
+ hasChangelog: false,
64
+ file: null,
65
+ format: null,
66
+ docvaultFallback: false,
67
+ ...overrides.changelog,
68
+ },
69
+ };
70
+ }
71
+ beforeEach(() => {
72
+ vi.resetAllMocks();
73
+ const enoent = Object.assign(new Error('ENOENT'), { code: 'ENOENT' });
74
+ mockStat.mockRejectedValue(enoent);
75
+ mockReadFile.mockRejectedValue(enoent);
76
+ });
77
+ /**
78
+ * Set up readFile to serve mock templates.
79
+ * readDefaultTemplate checks project .spec-workflow/templates/ first, then bundled.
80
+ * We simulate the bundled fallback by matching on the path containing 'markdown/templates/'.
81
+ */
82
+ function setupTemplateReads() {
83
+ mockReadFile.mockImplementation(async (p) => {
84
+ const path = String(p);
85
+ if (path.includes('markdown/templates/design-template.md'))
86
+ return MOCK_DESIGN_TEMPLATE;
87
+ if (path.includes('markdown/templates/tasks-template.md'))
88
+ return MOCK_TASKS_TEMPLATE;
89
+ throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' });
90
+ });
91
+ }
92
+ describe('generateUserTemplates', () => {
93
+ it('should generate browserbase-specific templates', async () => {
94
+ setupTemplateReads();
95
+ const conventions = makeConventions({
96
+ testing: { hasBrowserbase: true, framework: 'bb-test', testDir: 'tests/runbook/' },
97
+ });
98
+ const result = await generateUserTemplates('/fake/project', conventions);
99
+ // Design template should contain Runbook E2E Tests section
100
+ expect(result.designTemplate).toContain('Runbook E2E Tests');
101
+ expect(result.designTemplate).toContain('tests/runbook/');
102
+ // Tasks template should contain /bb-test references
103
+ expect(result.tasksTemplate).toContain('/bb-test');
104
+ expect(result.tasksTemplate).toContain('runbook');
105
+ });
106
+ it('should generate vitest-specific templates', async () => {
107
+ setupTemplateReads();
108
+ const conventions = makeConventions({
109
+ testing: { framework: 'vitest', command: 'npx vitest', configFile: 'vitest.config.ts' },
110
+ });
111
+ const result = await generateUserTemplates('/fake/project', conventions);
112
+ // Should reference vitest
113
+ expect(result.designTemplate).toContain('vitest');
114
+ expect(result.tasksTemplate).toContain('npx vitest');
115
+ // Should NOT contain browserbase references
116
+ expect(result.designTemplate).not.toContain('bb-test');
117
+ expect(result.designTemplate).not.toContain('runbook');
118
+ expect(result.tasksTemplate).not.toContain('bb-test');
119
+ expect(result.tasksTemplate).not.toContain('Runbook');
120
+ });
121
+ it('should use generic fallbacks when all testing fields are null', async () => {
122
+ setupTemplateReads();
123
+ const conventions = makeConventions(); // all defaults (null)
124
+ const result = await generateUserTemplates('/fake/project', conventions);
125
+ // Should use generic fallback values
126
+ expect(result.designTemplate).toContain('npm test');
127
+ expect(result.designTemplate).toContain('tests/');
128
+ expect(result.tasksTemplate).toContain('npm test');
129
+ // Should NOT contain browserbase references
130
+ expect(result.designTemplate).not.toContain('bb-test');
131
+ expect(result.tasksTemplate).not.toContain('bb-test');
132
+ });
133
+ });
134
+ describe('writeUserTemplates', () => {
135
+ it('should not overwrite existing user-template files', async () => {
136
+ // Simulate that the design template already exists
137
+ mockStat.mockImplementation(async (p) => {
138
+ const path = String(p);
139
+ if (path.endsWith('user-templates/design-template.md'))
140
+ return fakeFileStat();
141
+ throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' });
142
+ });
143
+ const templates = {
144
+ designTemplate: '# New design',
145
+ tasksTemplate: '# New tasks',
146
+ };
147
+ await writeUserTemplates('/fake/project', templates);
148
+ // Should NOT have written anything since a user-template already exists
149
+ expect(mockWriteFile).not.toHaveBeenCalled();
150
+ expect(mockMkdir).not.toHaveBeenCalled();
151
+ });
152
+ it('should write templates when no user-templates exist', async () => {
153
+ // All stat calls reject (no existing files) — default from beforeEach
154
+ mockMkdir.mockResolvedValue(undefined);
155
+ mockWriteFile.mockResolvedValue(undefined);
156
+ const templates = {
157
+ designTemplate: '# Generated design',
158
+ tasksTemplate: '# Generated tasks',
159
+ };
160
+ await writeUserTemplates('/fake/project', templates);
161
+ expect(mockMkdir).toHaveBeenCalledWith('/fake/project/.spec-workflow/user-templates', { recursive: true });
162
+ expect(mockWriteFile).toHaveBeenCalledTimes(2);
163
+ expect(mockWriteFile).toHaveBeenCalledWith('/fake/project/.spec-workflow/user-templates/design-template.md', '# Generated design', 'utf-8');
164
+ expect(mockWriteFile).toHaveBeenCalledWith('/fake/project/.spec-workflow/user-templates/tasks-template.md', '# Generated tasks', 'utf-8');
165
+ });
166
+ });
167
+ //# sourceMappingURL=template-generator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-generator.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/template-generator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface ProjectConventions {
2
+ schemaVersion: 1;
3
+ detectedAt: string;
4
+ testing: {
5
+ framework: string | null;
6
+ command: string | null;
7
+ configFile: string | null;
8
+ testDir: string | null;
9
+ hasBrowserbase: boolean;
10
+ };
11
+ versioning: {
12
+ hasVersionLock: boolean;
13
+ lockFile: string | null;
14
+ packageVersion: string | null;
15
+ userDeclinedSetup: boolean;
16
+ };
17
+ changelog: {
18
+ hasChangelog: boolean;
19
+ file: string | null;
20
+ format: string | null;
21
+ docvaultFallback: boolean;
22
+ };
23
+ }
24
+ /**
25
+ * Scan a project directory and detect its testing, versioning, and changelog conventions.
26
+ *
27
+ * All filesystem errors are handled gracefully — missing files produce null values, never throw.
28
+ * Works on any project directory, including empty ones.
29
+ */
30
+ export declare function detectConventions(projectPath: string): Promise<ProjectConventions>;
31
+ /**
32
+ * Write detected conventions to `.spec-workflow/project-conventions.json`.
33
+ * Creates the `.spec-workflow` directory if it does not exist.
34
+ */
35
+ export declare function writeConventions(projectPath: string, conventions: ProjectConventions): Promise<void>;
36
+ //# sourceMappingURL=convention-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convention-detector.d.ts","sourceRoot":"","sources":["../../src/core/convention-detector.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,CAAC,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,UAAU,EAAE;QACV,cAAc,EAAE,OAAO,CAAC;QACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,iBAAiB,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF,SAAS,EAAE;QACT,YAAY,EAAE,OAAO,CAAC;QACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,gBAAgB,EAAE,OAAO,CAAC;KAC3B,CAAC;CACH;AAyRD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAcxF;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS1G"}
@@ -0,0 +1,298 @@
1
+ import { readFile, readdir, stat, mkdir, writeFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ /** Safely read a file, returning null on any error. */
4
+ async function safeReadFile(filePath) {
5
+ try {
6
+ return await readFile(filePath, 'utf-8');
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ /** Check if a path exists and is a directory. */
13
+ async function isDirectory(dirPath) {
14
+ try {
15
+ const s = await stat(dirPath);
16
+ return s.isDirectory();
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ /** Check if a file exists. */
23
+ async function fileExists(filePath) {
24
+ try {
25
+ const s = await stat(filePath);
26
+ return s.isFile();
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /** Find the first existing file from a list of candidates. Returns the relative path or null. */
33
+ async function findFirstFile(projectPath, candidates) {
34
+ for (const candidate of candidates) {
35
+ if (await fileExists(join(projectPath, candidate))) {
36
+ return candidate;
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+ /** Detect testing framework, command, config file, test directory, and browserbase usage. */
42
+ async function detectTesting(projectPath) {
43
+ let framework = null;
44
+ let command = null;
45
+ let configFile = null;
46
+ let testDir = null;
47
+ let hasBrowserbase = false;
48
+ // --- Framework detection (priority order) ---
49
+ // Vitest
50
+ const vitestConfigs = [
51
+ 'vitest.config.ts', 'vitest.config.js', 'vitest.config.mts', 'vitest.config.mjs',
52
+ ];
53
+ const vitestConfig = await findFirstFile(projectPath, vitestConfigs);
54
+ if (vitestConfig) {
55
+ framework = 'vitest';
56
+ command = 'npx vitest';
57
+ configFile = vitestConfig;
58
+ }
59
+ // Jest (only if vitest not found)
60
+ if (!framework) {
61
+ const jestConfigs = [
62
+ 'jest.config.ts', 'jest.config.js', 'jest.config.mjs', 'jest.config.cjs', 'jest.config.json',
63
+ ];
64
+ const jestConfig = await findFirstFile(projectPath, jestConfigs);
65
+ if (jestConfig) {
66
+ framework = 'jest';
67
+ command = 'npx jest';
68
+ configFile = jestConfig;
69
+ }
70
+ }
71
+ // Pytest
72
+ if (!framework) {
73
+ const pytestConfigs = ['pytest.ini', 'pyproject.toml', 'setup.cfg'];
74
+ for (const candidate of pytestConfigs) {
75
+ const content = await safeReadFile(join(projectPath, candidate));
76
+ if (content !== null) {
77
+ // For pyproject.toml and setup.cfg, check for pytest section
78
+ if (candidate === 'pytest.ini') {
79
+ framework = 'pytest';
80
+ command = 'pytest';
81
+ configFile = candidate;
82
+ break;
83
+ }
84
+ if (candidate === 'pyproject.toml' && content.includes('[tool.pytest')) {
85
+ framework = 'pytest';
86
+ command = 'pytest';
87
+ configFile = candidate;
88
+ break;
89
+ }
90
+ if (candidate === 'setup.cfg' && content.includes('[tool:pytest]')) {
91
+ framework = 'pytest';
92
+ command = 'pytest';
93
+ configFile = candidate;
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ // Mocha (check package.json devDependencies or config files)
100
+ if (!framework) {
101
+ const mochaConfigs = ['.mocharc.yml', '.mocharc.yaml', '.mocharc.js', '.mocharc.json', '.mocharc.cjs'];
102
+ const mochaConfig = await findFirstFile(projectPath, mochaConfigs);
103
+ if (mochaConfig) {
104
+ framework = 'mocha';
105
+ command = 'npx mocha';
106
+ configFile = mochaConfig;
107
+ }
108
+ }
109
+ // package.json scripts.test fallback
110
+ if (!framework) {
111
+ const pkgContent = await safeReadFile(join(projectPath, 'package.json'));
112
+ if (pkgContent) {
113
+ try {
114
+ const pkg = JSON.parse(pkgContent);
115
+ const testScript = pkg?.scripts?.test;
116
+ if (testScript) {
117
+ // Infer framework from test script content
118
+ if (testScript.includes('vitest')) {
119
+ framework = 'vitest';
120
+ configFile = 'package.json';
121
+ }
122
+ else if (testScript.includes('jest')) {
123
+ framework = 'jest';
124
+ configFile = 'package.json';
125
+ }
126
+ else if (testScript.includes('mocha')) {
127
+ framework = 'mocha';
128
+ configFile = 'package.json';
129
+ }
130
+ else if (testScript.includes('pytest')) {
131
+ framework = 'pytest';
132
+ configFile = 'package.json';
133
+ }
134
+ command = testScript.startsWith('npm') ? testScript : `npm test`;
135
+ }
136
+ }
137
+ catch {
138
+ // Invalid JSON — ignore
139
+ }
140
+ }
141
+ }
142
+ // --- Browserbase / bb-test detection ---
143
+ const runbookDir = join(projectPath, 'tests', 'runbook');
144
+ if (await isDirectory(runbookDir)) {
145
+ hasBrowserbase = true;
146
+ if (!framework) {
147
+ framework = 'bb-test';
148
+ testDir = 'tests/runbook/';
149
+ // Count runbook sections for the command hint
150
+ try {
151
+ const entries = await readdir(runbookDir);
152
+ const sections = entries.filter(e => !e.startsWith('.')).length;
153
+ command = `/bb-test sections=${sections}`;
154
+ }
155
+ catch {
156
+ command = '/bb-test';
157
+ }
158
+ }
159
+ }
160
+ // Check CLAUDE.md for bb-test references
161
+ if (!hasBrowserbase) {
162
+ const claudeMd = await safeReadFile(join(projectPath, 'CLAUDE.md'));
163
+ if (claudeMd && (claudeMd.includes('/bb-test') || claudeMd.includes('bb-test'))) {
164
+ hasBrowserbase = true;
165
+ }
166
+ }
167
+ // --- Test directory detection ---
168
+ if (!testDir) {
169
+ const testDirCandidates = [
170
+ 'src/__tests__',
171
+ 'tests/',
172
+ 'test/',
173
+ '__tests__/',
174
+ ];
175
+ for (const candidate of testDirCandidates) {
176
+ const candidatePath = join(projectPath, candidate.replace(/\/$/, ''));
177
+ if (await isDirectory(candidatePath)) {
178
+ testDir = candidate;
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ return { framework, command, configFile, testDir, hasBrowserbase };
184
+ }
185
+ /** Detect versioning conventions. */
186
+ async function detectVersioning(projectPath) {
187
+ let hasVersionLock = false;
188
+ let lockFile = null;
189
+ let packageVersion = null;
190
+ const userDeclinedSetup = false;
191
+ // Check devops/version.lock
192
+ const versionLockPath = join(projectPath, 'devops', 'version.lock');
193
+ if (await fileExists(versionLockPath)) {
194
+ hasVersionLock = true;
195
+ lockFile = 'devops/version.lock';
196
+ }
197
+ // Check package.json version
198
+ const pkgContent = await safeReadFile(join(projectPath, 'package.json'));
199
+ if (pkgContent) {
200
+ try {
201
+ const pkg = JSON.parse(pkgContent);
202
+ if (pkg?.version && typeof pkg.version === 'string') {
203
+ packageVersion = pkg.version;
204
+ }
205
+ }
206
+ catch {
207
+ // Invalid JSON — ignore
208
+ }
209
+ }
210
+ // Check .version file
211
+ if (!hasVersionLock && !packageVersion) {
212
+ const dotVersionPath = join(projectPath, '.version');
213
+ const dotVersion = await safeReadFile(dotVersionPath);
214
+ if (dotVersion !== null) {
215
+ hasVersionLock = true;
216
+ lockFile = '.version';
217
+ }
218
+ }
219
+ return { hasVersionLock, lockFile, packageVersion, userDeclinedSetup };
220
+ }
221
+ /** Detect changelog presence and format. */
222
+ async function detectChangelog(projectPath) {
223
+ let hasChangelog = false;
224
+ let file = null;
225
+ let format = null;
226
+ const docvaultFallback = false;
227
+ const changelogCandidates = ['CHANGELOG.md', 'CHANGES.md', 'HISTORY.md'];
228
+ for (const candidate of changelogCandidates) {
229
+ const content = await safeReadFile(join(projectPath, candidate));
230
+ if (content !== null) {
231
+ hasChangelog = true;
232
+ file = candidate;
233
+ format = detectChangelogFormat(content);
234
+ break;
235
+ }
236
+ }
237
+ return { hasChangelog, file, format, docvaultFallback };
238
+ }
239
+ /** Detect changelog format from file content (reads first ~20 lines). */
240
+ function detectChangelogFormat(content) {
241
+ const lines = content.split('\n').slice(0, 20);
242
+ const header = lines.join('\n');
243
+ // keepachangelog: has ## [Unreleased] or ## [X.Y.Z] with Added/Changed/Fixed sections
244
+ const hasVersionHeaders = /## \[(Unreleased|\d+\.\d+\.\d+)]/i.test(header);
245
+ const hasSections = /(### (Added|Changed|Deprecated|Removed|Fixed|Security))/i.test(header);
246
+ if (hasVersionHeaders && hasSections) {
247
+ return 'keepachangelog';
248
+ }
249
+ // Also match keepachangelog if just the version header pattern is present with the right title
250
+ if (hasVersionHeaders && /keep.?a.?changelog/i.test(header)) {
251
+ return 'keepachangelog';
252
+ }
253
+ // conventional-changelog: typically starts with # followed by version + date and has commit-style entries
254
+ if (/^#+ \d+\.\d+\.\d+/m.test(header) && /\* \*\*\w+:\*\*/m.test(header)) {
255
+ return 'conventional';
256
+ }
257
+ // If it has version headers but doesn't match the above patterns
258
+ if (hasVersionHeaders) {
259
+ return 'keepachangelog';
260
+ }
261
+ return 'custom';
262
+ }
263
+ /**
264
+ * Scan a project directory and detect its testing, versioning, and changelog conventions.
265
+ *
266
+ * All filesystem errors are handled gracefully — missing files produce null values, never throw.
267
+ * Works on any project directory, including empty ones.
268
+ */
269
+ export async function detectConventions(projectPath) {
270
+ const [testing, versioning, changelog] = await Promise.all([
271
+ detectTesting(projectPath),
272
+ detectVersioning(projectPath),
273
+ detectChangelog(projectPath),
274
+ ]);
275
+ return {
276
+ schemaVersion: 1,
277
+ detectedAt: new Date().toISOString(),
278
+ testing,
279
+ versioning,
280
+ changelog,
281
+ };
282
+ }
283
+ /**
284
+ * Write detected conventions to `.spec-workflow/project-conventions.json`.
285
+ * Creates the `.spec-workflow` directory if it does not exist.
286
+ */
287
+ export async function writeConventions(projectPath, conventions) {
288
+ const dir = join(projectPath, '.spec-workflow');
289
+ try {
290
+ await mkdir(dir, { recursive: true });
291
+ }
292
+ catch {
293
+ // Directory may already exist — ignore
294
+ }
295
+ const filePath = join(dir, 'project-conventions.json');
296
+ await writeFile(filePath, JSON.stringify(conventions, null, 2) + '\n', 'utf-8');
297
+ }
298
+ //# sourceMappingURL=convention-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convention-detector.js","sourceRoot":"","sources":["../../src/core/convention-detector.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,12 @@ export declare class ProjectRegistry {
48
48
  * so we assume processes are alive if path translation is enabled.
49
49
  */
50
50
  private isProcessAlive;
51
+ /**
52
+ * Check if a path is under one of the configured project roots.
53
+ * SPEC_WORKFLOW_PROJECT_ROOT accepts colon-separated paths.
54
+ * Returns true (allow) when no root is configured.
55
+ */
56
+ private isUnderProjectRoot;
51
57
  /**
52
58
  * Register a project in the global registry
53
59
  * Self-healing: If a project exists with dead PIDs, cleans them up and adds new PID
@@ -1 +1 @@
1
- {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../src/core/project-registry.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CASlG;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;;IAO7C;;OAEG;YACW,iBAAiB;IAkB/B;;;OAGG;YACW,YAAY;IA0D1B;;OAEG;YACW,aAAa;IAY3B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;;OAIG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;IAyC9G;;;;OAIG;IACG,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBzE;;OAEG;IACG,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAKvD;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAO3E;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAK7E;;;;OAIG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IA6B7C;;OAEG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOhE;;OAEG;IACH,eAAe,IAAI,MAAM;CAG1B"}
1
+ {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../src/core/project-registry.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CASlG;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;;IAO7C;;OAEG;YACW,iBAAiB;IAkB/B;;;OAGG;YACW,YAAY;IA0D1B;;OAEG;YACW,aAAa;IAY3B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;;OAIG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;IA8C9G;;;;OAIG;IACG,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBzE;;OAEG;IACG,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAKvD;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAO3E;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAK7E;;;;OAIG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IA6B7C;;OAEG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOhE;;OAEG;IACH,eAAe,IAAI,MAAM;CAG1B"}
@@ -147,14 +147,30 @@ export class ProjectRegistry {
147
147
  return false;
148
148
  }
149
149
  }
150
+ /**
151
+ * Check if a path is under one of the configured project roots.
152
+ * SPEC_WORKFLOW_PROJECT_ROOT accepts colon-separated paths.
153
+ * Returns true (allow) when no root is configured.
154
+ */
155
+ isUnderProjectRoot(absolutePath) {
156
+ const rootEnv = process.env.SPEC_WORKFLOW_PROJECT_ROOT;
157
+ if (!rootEnv)
158
+ return true;
159
+ const roots = rootEnv.split(':').map(r => resolve(r.trim())).filter(Boolean);
160
+ return roots.some(root => absolutePath.startsWith(root));
161
+ }
150
162
  /**
151
163
  * Register a project in the global registry
152
164
  * Self-healing: If a project exists with dead PIDs, cleans them up and adds new PID
153
165
  * Multi-instance: Allows unlimited MCP server instances per project
154
166
  */
155
167
  async registerProject(projectPath, pid, options = {}) {
156
- const registry = await this.readRegistry();
157
168
  const workspacePath = resolve(projectPath);
169
+ // Skip registration for paths outside configured project root(s)
170
+ if (!this.isUnderProjectRoot(workspacePath)) {
171
+ return generateProjectId(workspacePath);
172
+ }
173
+ const registry = await this.readRegistry();
158
174
  const workflowRootPath = resolve(options.workflowRootPath || projectPath);
159
175
  const projectId = generateProjectId(workspacePath);
160
176
  const projectName = options.projectName || generateProjectDisplayName(workspacePath, workflowRootPath);
@@ -1 +1 @@
1
- {"version":3,"file":"project-registry.js","sourceRoot":"","sources":["../../src/core/project-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-registry.js","sourceRoot":"","sources":["../../src/core/project-registry.ts"],"names":[],"mappings":"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"}
@@ -217,7 +217,7 @@ export class AuditLogger {
217
217
  export function createSecurityHeadersMiddleware(port) {
218
218
  const actualPort = port || DEFAULT_DASHBOARD_PORT;
219
219
  // Build connect-src directive with WebSocket endpoints
220
- let connectSrc = `'self' ws://localhost:${actualPort} ws://127.0.0.1:${actualPort} wss://specdash.lbruton.cc https://api.staktrakr.com`;
220
+ let connectSrc = `'self' ws://localhost:${actualPort} ws://127.0.0.1:${actualPort} wss://specdash.lbruton.cc`;
221
221
  // In non-production environments, also allow Vite dev server connections
222
222
  if (process.env.NODE_ENV !== 'production') {
223
223
  connectSrc += ` ws://localhost:${VITE_DEV_PORT} ws://127.0.0.1:${VITE_DEV_PORT}`;
@@ -231,7 +231,7 @@ export function createSecurityHeadersMiddleware(port) {
231
231
  // CSP for dashboard
232
232
  // Note: cdn.jsdelivr.net is required for highlight.js stylesheets used by the MDX editor
233
233
  // connect-src allows WebSocket connections to the dashboard on the actual port
234
- reply.header('Content-Security-Policy', `default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data:; connect-src ${connectSrc}; frame-src https://polldash.lbruton.cc https://beta.staktrakr.com http://127.0.0.1:9778;`);
234
+ reply.header('Content-Security-Policy', `default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data:; connect-src ${connectSrc}; frame-src https://polldash.lbruton.cc;`);
235
235
  };
236
236
  }
237
237
  /**