bmad-studio 0.2.0 → 1.1.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 (103) hide show
  1. package/README.md +163 -17
  2. package/package.json +12 -3
  3. package/packages/client/dist/assets/index-81ZKe-R8.css +1 -0
  4. package/packages/client/dist/assets/index-DyjtzhqN.js +641 -0
  5. package/packages/client/dist/index.html +2 -2
  6. package/packages/server/dist/app.d.ts +2 -1
  7. package/packages/server/dist/app.d.ts.map +1 -1
  8. package/packages/server/dist/app.js +68 -3
  9. package/packages/server/dist/app.js.map +1 -1
  10. package/packages/server/dist/core/file-store.d.ts +8 -1
  11. package/packages/server/dist/core/file-store.d.ts.map +1 -1
  12. package/packages/server/dist/core/file-store.js +26 -3
  13. package/packages/server/dist/core/file-store.js.map +1 -1
  14. package/packages/server/dist/core/ide-skill-generator.d.ts +58 -0
  15. package/packages/server/dist/core/ide-skill-generator.d.ts.map +1 -0
  16. package/packages/server/dist/core/ide-skill-generator.js +270 -0
  17. package/packages/server/dist/core/ide-skill-generator.js.map +1 -0
  18. package/packages/server/dist/core/ide-skill-generator.test.d.ts +2 -0
  19. package/packages/server/dist/core/ide-skill-generator.test.d.ts.map +1 -0
  20. package/packages/server/dist/core/ide-skill-generator.test.js +257 -0
  21. package/packages/server/dist/core/ide-skill-generator.test.js.map +1 -0
  22. package/packages/server/dist/core/module-installer.d.ts +165 -0
  23. package/packages/server/dist/core/module-installer.d.ts.map +1 -0
  24. package/packages/server/dist/core/module-installer.js +445 -0
  25. package/packages/server/dist/core/module-installer.js.map +1 -0
  26. package/packages/server/dist/core/module-installer.test.d.ts +2 -0
  27. package/packages/server/dist/core/module-installer.test.d.ts.map +1 -0
  28. package/packages/server/dist/core/module-installer.test.js +509 -0
  29. package/packages/server/dist/core/module-installer.test.js.map +1 -0
  30. package/packages/server/dist/core/module-registry.d.ts +5 -0
  31. package/packages/server/dist/core/module-registry.d.ts.map +1 -0
  32. package/packages/server/dist/core/module-registry.js +109 -0
  33. package/packages/server/dist/core/module-registry.js.map +1 -0
  34. package/packages/server/dist/core/module-registry.test.d.ts +2 -0
  35. package/packages/server/dist/core/module-registry.test.d.ts.map +1 -0
  36. package/packages/server/dist/core/module-registry.test.js +280 -0
  37. package/packages/server/dist/core/module-registry.test.js.map +1 -0
  38. package/packages/server/dist/core/write-service.d.ts +20 -0
  39. package/packages/server/dist/core/write-service.d.ts.map +1 -1
  40. package/packages/server/dist/core/write-service.js +113 -1
  41. package/packages/server/dist/core/write-service.js.map +1 -1
  42. package/packages/server/dist/core/write-service.test.js +93 -6
  43. package/packages/server/dist/core/write-service.test.js.map +1 -1
  44. package/packages/server/dist/index.js +85 -1
  45. package/packages/server/dist/index.js.map +1 -1
  46. package/packages/server/dist/parsers/module-yaml-parser.d.ts +16 -0
  47. package/packages/server/dist/parsers/module-yaml-parser.d.ts.map +1 -0
  48. package/packages/server/dist/parsers/module-yaml-parser.js +62 -0
  49. package/packages/server/dist/parsers/module-yaml-parser.js.map +1 -0
  50. package/packages/server/dist/parsers/module-yaml-parser.test.d.ts +2 -0
  51. package/packages/server/dist/parsers/module-yaml-parser.test.d.ts.map +1 -0
  52. package/packages/server/dist/parsers/module-yaml-parser.test.js +156 -0
  53. package/packages/server/dist/parsers/module-yaml-parser.test.js.map +1 -0
  54. package/packages/server/dist/parsers/skill-parser.d.ts.map +1 -1
  55. package/packages/server/dist/parsers/skill-parser.js +41 -4
  56. package/packages/server/dist/parsers/skill-parser.js.map +1 -1
  57. package/packages/server/dist/parsers/skill-parser.test.js +4 -3
  58. package/packages/server/dist/parsers/skill-parser.test.js.map +1 -1
  59. package/packages/server/dist/plugins/agents-plugin.d.ts.map +1 -1
  60. package/packages/server/dist/plugins/agents-plugin.js +60 -1
  61. package/packages/server/dist/plugins/agents-plugin.js.map +1 -1
  62. package/packages/server/dist/plugins/commands-plugin.d.ts.map +1 -1
  63. package/packages/server/dist/plugins/commands-plugin.js +37 -10
  64. package/packages/server/dist/plugins/commands-plugin.js.map +1 -1
  65. package/packages/server/dist/plugins/datasources-plugin.d.ts.map +1 -1
  66. package/packages/server/dist/plugins/datasources-plugin.js +101 -0
  67. package/packages/server/dist/plugins/datasources-plugin.js.map +1 -1
  68. package/packages/server/dist/plugins/modules-plugin.d.ts.map +1 -1
  69. package/packages/server/dist/plugins/modules-plugin.js +905 -100
  70. package/packages/server/dist/plugins/modules-plugin.js.map +1 -1
  71. package/packages/server/dist/plugins/modules-plugin.test.js +1894 -3
  72. package/packages/server/dist/plugins/modules-plugin.test.js.map +1 -1
  73. package/packages/server/dist/plugins/outputs-plugin.d.ts.map +1 -1
  74. package/packages/server/dist/plugins/outputs-plugin.js +111 -0
  75. package/packages/server/dist/plugins/outputs-plugin.js.map +1 -1
  76. package/packages/server/dist/plugins/overview-plugin.d.ts.map +1 -1
  77. package/packages/server/dist/plugins/overview-plugin.js +35 -2
  78. package/packages/server/dist/plugins/overview-plugin.js.map +1 -1
  79. package/packages/server/dist/plugins/search-plugin.d.ts.map +1 -1
  80. package/packages/server/dist/plugins/search-plugin.js +19 -2
  81. package/packages/server/dist/plugins/search-plugin.js.map +1 -1
  82. package/packages/server/dist/plugins/settings-plugin.d.ts.map +1 -1
  83. package/packages/server/dist/plugins/settings-plugin.js +38 -1
  84. package/packages/server/dist/plugins/settings-plugin.js.map +1 -1
  85. package/packages/server/dist/plugins/settings-plugin.test.js +72 -0
  86. package/packages/server/dist/plugins/settings-plugin.test.js.map +1 -1
  87. package/packages/server/dist/plugins/teams-plugin.d.ts.map +1 -1
  88. package/packages/server/dist/plugins/teams-plugin.js +6 -6
  89. package/packages/server/dist/plugins/teams-plugin.js.map +1 -1
  90. package/packages/server/dist/plugins/teams-plugin.test.js +43 -0
  91. package/packages/server/dist/plugins/teams-plugin.test.js.map +1 -1
  92. package/packages/server/dist/plugins/workflows-plugin.d.ts.map +1 -1
  93. package/packages/server/dist/plugins/workflows-plugin.js +14 -6
  94. package/packages/server/dist/plugins/workflows-plugin.js.map +1 -1
  95. package/packages/shared/src/config.ts +26 -0
  96. package/packages/shared/src/events.ts +7 -0
  97. package/packages/shared/src/index.ts +13 -0
  98. package/packages/shared/src/modules.ts +42 -0
  99. package/packages/shared/src/registry.ts +26 -0
  100. package/packages/shared/src/types.test.ts +37 -1
  101. package/packages/shared/src/workflows.ts +27 -0
  102. package/packages/client/dist/assets/index-5nXyrx_3.css +0 -1
  103. package/packages/client/dist/assets/index-DxN3uabX.js +0 -521
@@ -0,0 +1,109 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import yaml from 'js-yaml';
4
+ import { downloadGithubTarball, parseGithubSource } from './module-installer.js';
5
+ import { parseModuleYaml } from '../parsers/module-yaml-parser.js';
6
+ const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
7
+ function cacheFilePath(studioDir, owner, repo) {
8
+ return path.join(studioDir, 'cache', `registry-${owner}-${repo}.json`);
9
+ }
10
+ export function readCachedRegistryIndex(studioDir, owner, repo) {
11
+ const file = cacheFilePath(studioDir, owner, repo);
12
+ if (!fs.existsSync(file))
13
+ return null;
14
+ try {
15
+ return JSON.parse(fs.readFileSync(file, 'utf-8'));
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ export function isRegistryCacheStale(index) {
22
+ const fetched = new Date(index.fetchedAt).getTime();
23
+ return Date.now() - fetched > CACHE_TTL_MS;
24
+ }
25
+ export async function fetchAndCacheRegistryIndex(studioDir, repoString, branch) {
26
+ const ghSource = parseGithubSource(`${repoString}@${branch}`);
27
+ const { extractedRoot, tmpDir } = await downloadGithubTarball(ghSource);
28
+ try {
29
+ // Optional index.yaml at the repo root
30
+ let indexMeta = null;
31
+ let indexYamlError;
32
+ const indexYamlPath = path.join(extractedRoot, 'index.yaml');
33
+ if (fs.existsSync(indexYamlPath)) {
34
+ try {
35
+ indexMeta = yaml.load(fs.readFileSync(indexYamlPath, 'utf-8'));
36
+ }
37
+ catch (err) {
38
+ indexYamlError = err instanceof Error ? err.message : String(err);
39
+ }
40
+ }
41
+ const modules = [];
42
+ for (const entry of fs.readdirSync(extractedRoot, { withFileTypes: true })) {
43
+ if (!entry.isDirectory())
44
+ continue;
45
+ if (entry.name.startsWith('.') || entry.name.startsWith('_'))
46
+ continue;
47
+ const moduleDir = path.join(extractedRoot, entry.name);
48
+ const hasModuleYaml = fs.existsSync(path.join(moduleDir, 'module.yaml'));
49
+ const hasEntities = ['agents', 'skills', 'workflows', 'tasks'].some((sub) => fs.existsSync(path.join(moduleDir, sub)));
50
+ if (!hasModuleYaml && !hasEntities)
51
+ continue;
52
+ const parsed = parseModuleYaml(moduleDir);
53
+ if (!parsed.ok)
54
+ continue;
55
+ const agentCount = fs.existsSync(path.join(moduleDir, 'agents'))
56
+ ? fs
57
+ .readdirSync(path.join(moduleDir, 'agents'))
58
+ .filter((f) => f.endsWith('.md') || f.endsWith('.yaml')).length
59
+ : 0;
60
+ const workflowCount = fs.existsSync(path.join(moduleDir, 'workflows'))
61
+ ? fs
62
+ .readdirSync(path.join(moduleDir, 'workflows'), { withFileTypes: true })
63
+ .filter((e) => e.isDirectory()).length
64
+ : 0;
65
+ const taskCount = fs.existsSync(path.join(moduleDir, 'tasks'))
66
+ ? fs
67
+ .readdirSync(path.join(moduleDir, 'tasks'), { withFileTypes: true })
68
+ .filter((e) => e.isDirectory()).length
69
+ : 0;
70
+ const indexEntry = indexMeta?.modules?.[parsed.data.code];
71
+ modules.push({
72
+ code: parsed.data.code,
73
+ name: parsed.data.name ?? parsed.data.code,
74
+ version: parsed.data.version ?? '1.0.0',
75
+ description: parsed.data.description ?? '',
76
+ agentCount,
77
+ workflowCount,
78
+ taskCount,
79
+ tags: indexEntry?.tags,
80
+ status: indexEntry?.status,
81
+ category: indexEntry?.category,
82
+ rawModuleYaml: hasModuleYaml ? parsed.data : null,
83
+ });
84
+ }
85
+ modules.sort((a, b) => a.name.localeCompare(b.name));
86
+ const index = {
87
+ owner: ghSource.owner,
88
+ repo: ghSource.repo,
89
+ branch: ghSource.branch ?? branch,
90
+ fetchedAt: new Date().toISOString(),
91
+ modules,
92
+ ...(indexYamlError !== undefined ? { indexYamlError } : {}),
93
+ };
94
+ // Write cache
95
+ const cacheFile = cacheFilePath(studioDir, ghSource.owner, ghSource.repo);
96
+ fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
97
+ fs.writeFileSync(cacheFile, JSON.stringify(index, null, 2), 'utf-8');
98
+ return index;
99
+ }
100
+ finally {
101
+ try {
102
+ fs.rmSync(tmpDir, { recursive: true, force: true });
103
+ }
104
+ catch {
105
+ // ignore cleanup errors
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=module-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-registry.js","sourceRoot":"","sources":["../../src/core/module-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=module-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-registry.test.d.ts","sourceRoot":"","sources":["../../src/core/module-registry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,280 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { execSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import yaml from 'js-yaml';
7
+ import { createApp } from '../app.js';
8
+ import { fetchAndCacheRegistryIndex, isRegistryCacheStale, readCachedRegistryIndex, } from './module-registry.js';
9
+ // ─── Fixture tarball helpers ────────────────────────────────────────────────
10
+ /**
11
+ * Build a fixture tarball that mimics GitHub's tarball format. GitHub tarballs
12
+ * always extract to a single wrapper directory like {owner}-{repo}-{shortsha}/.
13
+ */
14
+ function buildFixtureTarball(wrapperName, contentBuilder) {
15
+ const stagingRoot = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'bmad-registry-fixture-')));
16
+ try {
17
+ const wrapperDir = path.join(stagingRoot, wrapperName);
18
+ fs.mkdirSync(wrapperDir, { recursive: true });
19
+ contentBuilder(wrapperDir);
20
+ const tarballPath = path.join(stagingRoot, 'fixture.tar.gz');
21
+ execSync(`tar -czf "${tarballPath}" -C "${stagingRoot}" "${wrapperName}"`, { stdio: 'pipe' });
22
+ return fs.readFileSync(tarballPath);
23
+ }
24
+ finally {
25
+ fs.rmSync(stagingRoot, { recursive: true, force: true });
26
+ }
27
+ }
28
+ function mockTarballResponse(bytes) {
29
+ return new Response(bytes, {
30
+ status: 200,
31
+ statusText: 'OK',
32
+ headers: { 'Content-Type': 'application/gzip' },
33
+ });
34
+ }
35
+ function mockUnauthorizedResponse() {
36
+ return new Response('Unauthorized', { status: 401, statusText: 'Unauthorized' });
37
+ }
38
+ // A registry with two modules and an index.yaml
39
+ const REGISTRY_WITH_INDEX = buildFixtureTarball('owner-modules-abc1234', (wrapper) => {
40
+ // Module alpha
41
+ fs.mkdirSync(path.join(wrapper, 'alpha', 'agents'), { recursive: true });
42
+ fs.mkdirSync(path.join(wrapper, 'alpha', 'workflows'), { recursive: true });
43
+ fs.writeFileSync(path.join(wrapper, 'alpha', 'agents', 'agent.md'), '# Agent\n');
44
+ fs.writeFileSync(path.join(wrapper, 'alpha', 'module.yaml'), yaml.dump({
45
+ code: 'alpha',
46
+ name: 'Alpha Module',
47
+ version: '2.0.0',
48
+ description: 'An alpha module',
49
+ }));
50
+ // Module beta (tasks only)
51
+ fs.mkdirSync(path.join(wrapper, 'beta', 'tasks', 'my-task'), { recursive: true });
52
+ fs.writeFileSync(path.join(wrapper, 'beta', 'tasks', 'my-task', 'SKILL.md'), '# Task\n');
53
+ fs.writeFileSync(path.join(wrapper, 'beta', 'module.yaml'), yaml.dump({ code: 'beta', name: 'Beta Module', version: '1.5.0', description: 'A beta module' }));
54
+ // index.yaml with metadata for alpha
55
+ fs.writeFileSync(path.join(wrapper, 'index.yaml'), yaml.dump({
56
+ modules: {
57
+ alpha: { tags: ['analytics', 'reporting'], status: 'stable', category: 'data' },
58
+ },
59
+ }));
60
+ // Hidden dir and underscore dir — must be excluded
61
+ fs.mkdirSync(path.join(wrapper, '.hidden'), { recursive: true });
62
+ fs.mkdirSync(path.join(wrapper, '_internal'), { recursive: true });
63
+ });
64
+ // A registry with no index.yaml
65
+ const REGISTRY_NO_INDEX = buildFixtureTarball('owner-modules-abc1234', (wrapper) => {
66
+ fs.mkdirSync(path.join(wrapper, 'gamma', 'agents'), { recursive: true });
67
+ fs.writeFileSync(path.join(wrapper, 'gamma', 'agents', 'g.md'), '# G\n');
68
+ fs.writeFileSync(path.join(wrapper, 'gamma', 'module.yaml'), yaml.dump({ code: 'gamma', name: 'Gamma Module', version: '0.9.0', description: '' }));
69
+ });
70
+ // A registry with malformed index.yaml
71
+ const REGISTRY_BAD_INDEX = buildFixtureTarball('owner-modules-abc1234', (wrapper) => {
72
+ fs.mkdirSync(path.join(wrapper, 'delta', 'agents'), { recursive: true });
73
+ fs.writeFileSync(path.join(wrapper, 'delta', 'agents', 'd.md'), '# D\n');
74
+ fs.writeFileSync(path.join(wrapper, 'delta', 'module.yaml'), yaml.dump({ code: 'delta', name: 'Delta Module', version: '1.0.0', description: '' }));
75
+ // Malformed YAML
76
+ fs.writeFileSync(path.join(wrapper, 'index.yaml'), '{ not: valid: yaml: :::');
77
+ });
78
+ // ─── Unit tests for module-registry.ts ──────────────────────────────────────
79
+ describe('module-registry — unit', () => {
80
+ let tmpDir;
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ let fetchSpy;
83
+ beforeEach(() => {
84
+ tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'module-registry-test-')));
85
+ fs.mkdirSync(path.join(tmpDir, '.bmad-studio'), { recursive: true });
86
+ fetchSpy = vi.spyOn(globalThis, 'fetch');
87
+ });
88
+ afterEach(() => {
89
+ fs.rmSync(tmpDir, { recursive: true, force: true });
90
+ vi.restoreAllMocks();
91
+ });
92
+ const studioDir = () => path.join(tmpDir, '.bmad-studio');
93
+ it('AC-16.2.2 — fetches index with two modules and applies index.yaml metadata', async () => {
94
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
95
+ const index = await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
96
+ expect(index.owner).toBe('owner');
97
+ expect(index.repo).toBe('modules');
98
+ expect(index.branch).toBe('main');
99
+ expect(index.fetchedAt).toMatch(/^\d{4}-\d{2}-\d{2}/);
100
+ // AC-16.2.3, AC-16.2.4 — sorted alphabetically, metadata present
101
+ expect(index.modules).toHaveLength(2);
102
+ expect(index.modules[0].code).toBe('alpha');
103
+ expect(index.modules[1].code).toBe('beta');
104
+ const alpha = index.modules[0];
105
+ expect(alpha.name).toBe('Alpha Module');
106
+ expect(alpha.version).toBe('2.0.0');
107
+ expect(alpha.agentCount).toBe(1);
108
+ expect(alpha.workflowCount).toBe(0);
109
+ expect(alpha.tags).toEqual(['analytics', 'reporting']);
110
+ expect(alpha.status).toBe('stable');
111
+ expect(alpha.category).toBe('data');
112
+ expect(alpha.rawModuleYaml).not.toBeNull();
113
+ const beta = index.modules[1];
114
+ expect(beta.taskCount).toBe(1);
115
+ expect(beta.tags).toBeUndefined();
116
+ });
117
+ it('AC-16.2.5 — excludes dot and underscore directories', async () => {
118
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
119
+ const index = await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
120
+ const codes = index.modules.map((m) => m.code);
121
+ expect(codes).not.toContain('.hidden');
122
+ expect(codes).not.toContain('_internal');
123
+ });
124
+ it('AC-16.2.6 — writes cache to .bmad-studio/cache/registry-{owner}-{repo}.json', async () => {
125
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
126
+ await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
127
+ const cachePath = path.join(studioDir(), 'cache', 'registry-owner-modules.json');
128
+ expect(fs.existsSync(cachePath)).toBe(true);
129
+ const cached = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
130
+ expect(cached.modules).toHaveLength(2);
131
+ });
132
+ it('AC-16.2.7 — readCachedRegistryIndex returns null when no cache exists', () => {
133
+ const result = readCachedRegistryIndex(studioDir(), 'owner', 'modules');
134
+ expect(result).toBeNull();
135
+ });
136
+ it('AC-16.2.7 — readCachedRegistryIndex returns cached index', async () => {
137
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
138
+ await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
139
+ const cached = readCachedRegistryIndex(studioDir(), 'owner', 'modules');
140
+ expect(cached).not.toBeNull();
141
+ expect(cached.modules).toHaveLength(2);
142
+ });
143
+ it('isRegistryCacheStale — false for fresh cache', () => {
144
+ const index = {
145
+ owner: 'o',
146
+ repo: 'r',
147
+ branch: 'main',
148
+ fetchedAt: new Date().toISOString(),
149
+ modules: [],
150
+ };
151
+ expect(isRegistryCacheStale(index)).toBe(false);
152
+ });
153
+ it('isRegistryCacheStale — true after 1 hour + 1ms', () => {
154
+ const index = {
155
+ owner: 'o',
156
+ repo: 'r',
157
+ branch: 'main',
158
+ fetchedAt: new Date(Date.now() - 60 * 60 * 1000 - 1).toISOString(),
159
+ modules: [],
160
+ };
161
+ expect(isRegistryCacheStale(index)).toBe(true);
162
+ });
163
+ it('without index.yaml — modules parsed, indexYamlError undefined', async () => {
164
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_NO_INDEX));
165
+ const index = await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
166
+ expect(index.modules).toHaveLength(1);
167
+ expect(index.modules[0].code).toBe('gamma');
168
+ expect(index.indexYamlError).toBeUndefined();
169
+ });
170
+ it('AC-16.2.9 — malformed index.yaml sets indexYamlError, modules still returned', async () => {
171
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_BAD_INDEX));
172
+ const index = await fetchAndCacheRegistryIndex(studioDir(), 'owner/modules', 'main');
173
+ expect(index.modules).toHaveLength(1);
174
+ expect(index.modules[0].code).toBe('delta');
175
+ expect(index.indexYamlError).toBeDefined();
176
+ expect(typeof index.indexYamlError).toBe('string');
177
+ });
178
+ });
179
+ // ─── API endpoint tests (via modules-plugin) ────────────────────────────────
180
+ function makeProject(tmpDir) {
181
+ return {
182
+ projectRoot: tmpDir,
183
+ bmadVersion: '6.2.0',
184
+ versionSupported: true,
185
+ modules: [],
186
+ ideDirectories: [],
187
+ };
188
+ }
189
+ describe('modules-plugin — Story 16.2 registry endpoints', () => {
190
+ let tmpDir;
191
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
192
+ let fetchSpy;
193
+ beforeEach(() => {
194
+ tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'registry-plugin-test-')));
195
+ const configDir = path.join(tmpDir, '_bmad', '_config');
196
+ fs.mkdirSync(configDir, { recursive: true });
197
+ fs.writeFileSync(path.join(configDir, 'manifest.yaml'), yaml.dump({
198
+ installation: {
199
+ version: '6.2.0',
200
+ installDate: '2026-01-01T00:00:00.000Z',
201
+ lastUpdated: '2026-01-01T00:00:00.000Z',
202
+ },
203
+ modules: [],
204
+ }));
205
+ fs.mkdirSync(path.join(tmpDir, '.bmad-studio'), { recursive: true });
206
+ fetchSpy = vi.spyOn(globalThis, 'fetch');
207
+ });
208
+ afterEach(() => {
209
+ fs.rmSync(tmpDir, { recursive: true, force: true });
210
+ vi.restoreAllMocks();
211
+ });
212
+ it('AC-16.2.1 — GET /api/registry returns configured:false when no settings file', async () => {
213
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
214
+ const resp = await app.inject({ method: 'GET', url: '/api/registry' });
215
+ expect(resp.statusCode).toBe(200);
216
+ const body = JSON.parse(resp.body);
217
+ expect(body.ok).toBe(false);
218
+ expect(body.configured).toBe(false);
219
+ await app.close();
220
+ });
221
+ it('AC-16.2.1 — GET /api/registry returns configured:false when settings has no registry block', async () => {
222
+ fs.writeFileSync(path.join(tmpDir, '.bmad-studio', 'settings.json'), JSON.stringify({ port: 4040, theme: 'dark' }));
223
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
224
+ const resp = await app.inject({ method: 'GET', url: '/api/registry' });
225
+ expect(resp.statusCode).toBe(200);
226
+ const body = JSON.parse(resp.body);
227
+ expect(body.ok).toBe(false);
228
+ expect(body.configured).toBe(false);
229
+ await app.close();
230
+ });
231
+ it('AC-16.2.2 — GET /api/registry fetches and returns index when configured', async () => {
232
+ fs.writeFileSync(path.join(tmpDir, '.bmad-studio', 'settings.json'), JSON.stringify({ registry: { repo: 'owner/modules', branch: 'main' } }));
233
+ fetchSpy.mockImplementationOnce(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
234
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
235
+ const resp = await app.inject({ method: 'GET', url: '/api/registry' });
236
+ expect(resp.statusCode).toBe(200);
237
+ const body = JSON.parse(resp.body);
238
+ expect(body.ok).toBe(true);
239
+ expect(body.configured).toBe(true);
240
+ expect(body.index.owner).toBe('owner');
241
+ expect(body.index.modules).toHaveLength(2);
242
+ await app.close();
243
+ });
244
+ it('AC-16.2.7 — second GET /api/registry within TTL uses cache, no second fetch', async () => {
245
+ fs.writeFileSync(path.join(tmpDir, '.bmad-studio', 'settings.json'), JSON.stringify({ registry: { repo: 'owner/modules', branch: 'main' } }));
246
+ fetchSpy.mockImplementation(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
247
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
248
+ await app.inject({ method: 'GET', url: '/api/registry' });
249
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
250
+ await app.inject({ method: 'GET', url: '/api/registry' });
251
+ expect(fetchSpy).toHaveBeenCalledTimes(1); // still 1 — served from cache
252
+ await app.close();
253
+ });
254
+ it('AC-16.2.8 — POST /api/registry/refresh always re-fetches', async () => {
255
+ fs.writeFileSync(path.join(tmpDir, '.bmad-studio', 'settings.json'), JSON.stringify({ registry: { repo: 'owner/modules', branch: 'main' } }));
256
+ fetchSpy.mockImplementation(async () => mockTarballResponse(REGISTRY_WITH_INDEX));
257
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
258
+ // First populate the cache
259
+ await app.inject({ method: 'GET', url: '/api/registry' });
260
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
261
+ // Refresh should always re-fetch
262
+ const resp = await app.inject({ method: 'POST', url: '/api/registry/refresh' });
263
+ expect(resp.statusCode).toBe(200);
264
+ const body = JSON.parse(resp.body);
265
+ expect(body.ok).toBe(true);
266
+ expect(fetchSpy).toHaveBeenCalledTimes(2);
267
+ await app.close();
268
+ });
269
+ it('AC-16.2.10 — unauthorized GitHub repo surfaces error', async () => {
270
+ fs.writeFileSync(path.join(tmpDir, '.bmad-studio', 'settings.json'), JSON.stringify({ registry: { repo: 'private/repo', branch: 'main' } }));
271
+ fetchSpy.mockImplementationOnce(async () => mockUnauthorizedResponse());
272
+ const app = await createApp({ logger: false, serveStatic: false, project: makeProject(tmpDir) });
273
+ const resp = await app.inject({ method: 'GET', url: '/api/registry' });
274
+ expect(resp.statusCode).toBe(422);
275
+ const body = JSON.parse(resp.body);
276
+ expect(body.error.message).toContain('private/repo');
277
+ await app.close();
278
+ });
279
+ });
280
+ //# sourceMappingURL=module-registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-registry.test.js","sourceRoot":"","sources":["../../src/core/module-registry.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ export declare const TEXT_FILE_EXTENSIONS: ReadonlySet<string>;
2
+ export declare function isLikelyText(filePath: string): boolean;
1
3
  export type WriteResult = {
2
4
  ok: true;
3
5
  filePath: string;
@@ -8,5 +10,23 @@ export type WriteResult = {
8
10
  filePath: string;
9
11
  };
10
12
  export declare function writeFile(filePath: string, content: string, studioDir: string): WriteResult;
13
+ /**
14
+ * Delete a single file. Snapshots TEXT content to history/ before unlink.
15
+ * Binary files (per `isLikelyText`) are unlinked directly without a snapshot —
16
+ * recovery for binary content is "re-install the module" per TD-16.
17
+ *
18
+ * Returns `{ ok: false }` (does NOT throw) on missing paths so callers can
19
+ * handle absence gracefully.
20
+ */
21
+ export declare function deleteFile(filePath: string, studioDir: string): WriteResult;
22
+ /**
23
+ * Recursively delete a directory. Walks the tree, deletes each file via
24
+ * `deleteFile` (which snapshots text files), then unlinks the (now-empty)
25
+ * directory tree.
26
+ *
27
+ * On partial failure mid-walk, the directory is left in its current state —
28
+ * some files deleted, some not. The caller decides whether to retry.
29
+ */
30
+ export declare function deleteDirectory(dirPath: string, studioDir: string): WriteResult;
11
31
  export declare function getHistory(studioDir: string): string[];
12
32
  //# sourceMappingURL=write-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-service.d.ts","sourceRoot":"","sources":["../../src/core/write-service.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CA0C3F;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAItD"}
1
+ {"version":3,"file":"write-service.d.ts","sourceRoot":"","sources":["../../src/core/write-service.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAyBnD,CAAA;AAEF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD;AAmBD,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CA0C3F;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAwB3E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CA8B/E;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAItD"}
@@ -1,6 +1,45 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- const HISTORY_CAP = 50;
3
+ // Sized for module-scale operations (one install can write 60+ files).
4
+ // Average snapshot ~5KB → ~2.5MB max disk budget. Raised from 50 in Story 15.7
5
+ // (TD-17) so module installs/removes don't prune themselves mid-operation.
6
+ const HISTORY_CAP = 500;
7
+ // Files with these extensions are routed through WriteService snapshots
8
+ // (text content). Binary files bypass snapshots — recovery for binaries is
9
+ // "re-install the module" per TD-16.
10
+ //
11
+ // CONSERVATIVE list — false positives (treating binary as text) corrupt the
12
+ // file via utf-8 round-trip; false negatives (text as binary) just skip the
13
+ // snapshot. When in doubt, leave OFF the list.
14
+ export const TEXT_FILE_EXTENSIONS = new Set([
15
+ '.md',
16
+ '.markdown',
17
+ '.yaml',
18
+ '.yml',
19
+ '.json',
20
+ '.csv',
21
+ '.txt',
22
+ '.ts',
23
+ '.tsx',
24
+ '.js',
25
+ '.jsx',
26
+ '.mjs',
27
+ '.cjs',
28
+ '.html',
29
+ '.htm',
30
+ '.css',
31
+ '.scss',
32
+ '.toml',
33
+ '.xml',
34
+ '.svg',
35
+ '.sh',
36
+ '.bash',
37
+ '.zsh',
38
+ '.fish',
39
+ ]);
40
+ export function isLikelyText(filePath) {
41
+ return TEXT_FILE_EXTENSIONS.has(path.extname(filePath).toLowerCase());
42
+ }
4
43
  function ensureDir(dir) {
5
44
  if (!fs.existsSync(dir)) {
6
45
  fs.mkdirSync(dir, { recursive: true });
@@ -52,6 +91,79 @@ export function writeFile(filePath, content, studioDir) {
52
91
  return { ok: false, error: `Write failed: ${message}`, filePath };
53
92
  }
54
93
  }
94
+ /**
95
+ * Delete a single file. Snapshots TEXT content to history/ before unlink.
96
+ * Binary files (per `isLikelyText`) are unlinked directly without a snapshot —
97
+ * recovery for binary content is "re-install the module" per TD-16.
98
+ *
99
+ * Returns `{ ok: false }` (does NOT throw) on missing paths so callers can
100
+ * handle absence gracefully.
101
+ */
102
+ export function deleteFile(filePath, studioDir) {
103
+ const historyDir = path.join(studioDir, 'history');
104
+ try {
105
+ if (!fs.existsSync(filePath)) {
106
+ return { ok: false, error: 'File does not exist', filePath };
107
+ }
108
+ let snapshotPath = null;
109
+ if (isLikelyText(filePath)) {
110
+ const previousContent = fs.readFileSync(filePath, 'utf-8');
111
+ ensureDir(historyDir);
112
+ const timestamp = Date.now();
113
+ const basename = path.basename(filePath);
114
+ snapshotPath = path.join(historyDir, `${timestamp}-${basename}`);
115
+ fs.writeFileSync(snapshotPath, previousContent, 'utf-8');
116
+ }
117
+ fs.unlinkSync(filePath);
118
+ pruneHistory(historyDir);
119
+ return { ok: true, filePath, snapshotPath };
120
+ }
121
+ catch (err) {
122
+ const message = err instanceof Error ? err.message : String(err);
123
+ return { ok: false, error: `Delete failed: ${message}`, filePath };
124
+ }
125
+ }
126
+ /**
127
+ * Recursively delete a directory. Walks the tree, deletes each file via
128
+ * `deleteFile` (which snapshots text files), then unlinks the (now-empty)
129
+ * directory tree.
130
+ *
131
+ * On partial failure mid-walk, the directory is left in its current state —
132
+ * some files deleted, some not. The caller decides whether to retry.
133
+ */
134
+ export function deleteDirectory(dirPath, studioDir) {
135
+ try {
136
+ if (!fs.existsSync(dirPath)) {
137
+ return { ok: false, error: 'Directory does not exist', filePath: dirPath };
138
+ }
139
+ const walk = (dir) => {
140
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
141
+ const full = path.join(dir, entry.name);
142
+ if (entry.isDirectory()) {
143
+ walk(full);
144
+ }
145
+ else if (entry.isSymbolicLink()) {
146
+ // Symlinks (dangling or otherwise) are unlinked directly — no content to snapshot.
147
+ // fs.existsSync follows symlinks, so a dangling symlink would fool deleteFile into
148
+ // returning { ok: false, 'File does not exist' } and aborting the entire walk.
149
+ fs.unlinkSync(full);
150
+ }
151
+ else {
152
+ const result = deleteFile(full, studioDir);
153
+ if (!result.ok)
154
+ throw new Error(result.error);
155
+ }
156
+ }
157
+ };
158
+ walk(dirPath);
159
+ fs.rmSync(dirPath, { recursive: true, force: true });
160
+ return { ok: true, filePath: dirPath, snapshotPath: null };
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : String(err);
164
+ return { ok: false, error: `Directory delete failed: ${message}`, filePath: dirPath };
165
+ }
166
+ }
55
167
  export function getHistory(studioDir) {
56
168
  const historyDir = path.join(studioDir, 'history');
57
169
  if (!fs.existsSync(historyDir))
@@ -1 +1 @@
1
- {"version":3,"file":"write-service.js","sourceRoot":"","sources":["../../src/core/write-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,WAAW,GAAG,EAAE,CAAA;AAEtB,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAM;IAEtC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;IAE/C,OAAO,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAG,CAAA;QAC7B,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe,EAAE,SAAiB;IAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAClD,IAAI,YAAY,GAAkB,IAAI,CAAA;IAEtC,IAAI,CAAC;QACH,qDAAqD;QACrD,IAAI,eAAe,GAAkB,IAAI,CAAA;QACzC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACtD,CAAC;QAED,8BAA8B;QAC9B,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAC7B,SAAS,CAAC,UAAU,CAAC,CAAA;YACrB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACxC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAA;YAChE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;QAC1D,CAAC;QAED,6BAA6B;QAC7B,MAAM,OAAO,GAAG,GAAG,QAAQ,MAAM,CAAA;QACjC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QACjC,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QAE3C,wBAAwB;QACxB,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAEhC,iBAAiB;QACjB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,6CAA6C,EAAE,QAAQ,EAAE,CAAA;QACtF,CAAC;QAED,wBAAwB;QACxB,YAAY,CAAC,UAAU,CAAC,CAAA;QAExB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAA;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAA;IACzC,OAAO,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;AACpD,CAAC"}
1
+ {"version":3,"file":"write-service.js","sourceRoot":"","sources":["../../src/core/write-service.ts"],"names":[],"mappings":"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"}