@nerviq/cli 1.0.0 → 1.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 (48) hide show
  1. package/bin/cli.js +170 -73
  2. package/package.json +3 -5
  3. package/src/activity.js +20 -0
  4. package/src/aider/domain-packs.js +27 -2
  5. package/src/aider/mcp-packs.js +231 -0
  6. package/src/aider/techniques.js +3210 -1397
  7. package/src/audit.js +290 -9
  8. package/src/catalog.js +18 -2
  9. package/src/codex/domain-packs.js +23 -1
  10. package/src/codex/mcp-packs.js +254 -0
  11. package/src/codex/techniques.js +4738 -3257
  12. package/src/copilot/domain-packs.js +23 -1
  13. package/src/copilot/mcp-packs.js +254 -0
  14. package/src/copilot/techniques.js +3433 -1936
  15. package/src/cursor/domain-packs.js +23 -1
  16. package/src/cursor/mcp-packs.js +257 -0
  17. package/src/cursor/techniques.js +3697 -1869
  18. package/src/deprecation.js +98 -0
  19. package/src/domain-pack-expansion.js +571 -0
  20. package/src/domain-packs.js +25 -2
  21. package/src/formatters/otel.js +151 -0
  22. package/src/gemini/domain-packs.js +23 -1
  23. package/src/gemini/mcp-packs.js +257 -0
  24. package/src/gemini/techniques.js +3734 -2238
  25. package/src/integrations.js +194 -0
  26. package/src/mcp-packs.js +233 -0
  27. package/src/opencode/domain-packs.js +23 -1
  28. package/src/opencode/mcp-packs.js +231 -0
  29. package/src/opencode/techniques.js +3500 -1687
  30. package/src/org.js +68 -0
  31. package/src/source-urls.js +410 -260
  32. package/src/stack-checks.js +565 -0
  33. package/src/supplemental-checks.js +767 -0
  34. package/src/techniques.js +2929 -1449
  35. package/src/telemetry.js +160 -0
  36. package/src/windsurf/domain-packs.js +23 -1
  37. package/src/windsurf/mcp-packs.js +257 -0
  38. package/src/windsurf/techniques.js +3647 -1834
  39. package/src/workspace.js +233 -0
  40. package/CHANGELOG.md +0 -198
  41. package/content/case-study-template.md +0 -91
  42. package/content/claims-governance.md +0 -37
  43. package/content/claude-code/audit-repo/SKILL.md +0 -20
  44. package/content/claude-native-integration.md +0 -60
  45. package/content/devto-article.json +0 -9
  46. package/content/launch-posts.md +0 -226
  47. package/content/pilot-rollout-kit.md +0 -30
  48. package/content/release-checklist.md +0 -31
@@ -0,0 +1,98 @@
1
+ const DEPRECATION_NOTICE_CATALOG = [
2
+ {
3
+ feature: 'legacy-claude-api-patterns',
4
+ message: 'Legacy Claude prompt patterns are deprecated in v1.x audits.',
5
+ removedIn: '2.0.0',
6
+ alternative: 'Use current Messages API conventions and modern CLAUDE.md patterns.',
7
+ match: /human_prompt|assistant_prompt|deprecated api patterns/i,
8
+ },
9
+ {
10
+ feature: 'legacy-codex-config',
11
+ message: 'Deprecated Codex config and workflow patterns are flagged in v1.x.',
12
+ removedIn: '2.0.0',
13
+ alternative: 'Use the current Codex config schema and current workflow notes.',
14
+ match: /deprecated codex|approval_policy|full_auto_error_mode|send_to_server|removed from the official codex config schema/i,
15
+ },
16
+ {
17
+ feature: 'legacy-gemini-flags',
18
+ message: 'Deprecated Gemini flags and config keys are flagged in v1.x.',
19
+ removedIn: '2.0.0',
20
+ alternative: 'Use current Gemini CLI settings, policy files, and output flags.',
21
+ match: /deprecated gemini|--json|--allowed-tools|sandbox_mode|max_tokens|mcp_servers/i,
22
+ },
23
+ {
24
+ feature: 'legacy-cursor-rule-surface',
25
+ message: 'Legacy Cursor rule surfaces are deprecated in agent-mode audits.',
26
+ removedIn: '2.0.0',
27
+ alternative: 'Use `.cursor/rules/*.mdc` instead of `.cursorrules` for modern Cursor flows.',
28
+ match: /\.cursorrules|legacy cursor/i,
29
+ },
30
+ {
31
+ feature: 'legacy-windsurf-rule-surface',
32
+ message: 'Legacy Windsurf rule surfaces are deprecated in modern Cascade flows.',
33
+ removedIn: '2.0.0',
34
+ alternative: 'Use `.windsurf/rules/*.md` instead of `.windsurfrules` for modern Windsurf flows.',
35
+ match: /\.windsurfrules|legacy windsurf/i,
36
+ },
37
+ ];
38
+
39
+ function parseVersion(version) {
40
+ const match = String(version || '0.0.0').match(/^(\d+)\.(\d+)\.(\d+)/);
41
+ return match ? match.slice(1).map(Number) : [0, 0, 0];
42
+ }
43
+
44
+ function compareVersions(left, right) {
45
+ const a = parseVersion(left);
46
+ const b = parseVersion(right);
47
+ for (let index = 0; index < 3; index++) {
48
+ if (a[index] > b[index]) return 1;
49
+ if (a[index] < b[index]) return -1;
50
+ }
51
+ return 0;
52
+ }
53
+
54
+ function deprecationWarnings(version) {
55
+ return DEPRECATION_NOTICE_CATALOG.filter((notice) => compareVersions(version, '1.0.0') >= 0 && compareVersions(version, notice.removedIn) < 0)
56
+ .map(({ match, ...notice }) => ({ ...notice }));
57
+ }
58
+
59
+ function detectDeprecationWarnings(results, version) {
60
+ const notices = deprecationWarnings(version);
61
+ const haystack = Array.isArray(results) ? results.filter((item) => item && item.passed === false) : [];
62
+ const matched = [];
63
+
64
+ for (const notice of DEPRECATION_NOTICE_CATALOG) {
65
+ if (compareVersions(version, '1.0.0') < 0 || compareVersions(version, notice.removedIn) >= 0) {
66
+ continue;
67
+ }
68
+
69
+ const hit = haystack.find((item) => notice.match.test(`${item.key || ''}\n${item.name || ''}\n${item.fix || ''}`));
70
+ if (hit) {
71
+ matched.push({
72
+ feature: notice.feature,
73
+ message: notice.message,
74
+ removedIn: notice.removedIn,
75
+ alternative: hit.fix || notice.alternative,
76
+ });
77
+ }
78
+ }
79
+
80
+ if (matched.length > 0) {
81
+ return matched;
82
+ }
83
+
84
+ return haystack
85
+ .filter((item) => /deprecated|legacy|removed/i.test(`${item.name || ''}\n${item.fix || ''}`))
86
+ .slice(0, 5)
87
+ .map((item) => ({
88
+ feature: item.key,
89
+ message: item.name,
90
+ removedIn: '2.0.0',
91
+ alternative: item.fix,
92
+ }));
93
+ }
94
+
95
+ module.exports = {
96
+ deprecationWarnings,
97
+ detectDeprecationWarnings,
98
+ };
@@ -0,0 +1,571 @@
1
+ const PACK_BLUEPRINTS = [
2
+ {
3
+ key: 'blockchain',
4
+ label: 'Blockchain',
5
+ useWhen: 'Repos with smart contracts, wallet logic, chain integrations, or on-chain deployment tooling.',
6
+ adoption: 'Recommended when contract review, deployment safety, and chain-specific build workflows are core to the repo.',
7
+ recommendedModules: ['Contract review guide', 'Wallet and secret safety', 'Deployment verification'],
8
+ benchmarkFocus: ['contract-aware verification', 'wallet and secret safety', 'deployment review'],
9
+ },
10
+ {
11
+ key: 'realtime',
12
+ label: 'Realtime',
13
+ useWhen: 'Repos centered on websockets, live collaboration, presence, or push-driven event flows.',
14
+ adoption: 'Recommended when event delivery, connection lifecycle, and concurrency behavior matter as much as CRUD flows.',
15
+ recommendedModules: ['Event flow guide', 'Connection lifecycle checks', 'Delivery and retry posture'],
16
+ benchmarkFocus: ['live event safety', 'connection lifecycle review', 'delivery resilience'],
17
+ },
18
+ {
19
+ key: 'graphql',
20
+ label: 'GraphQL',
21
+ useWhen: 'Repos with GraphQL schemas, resolvers, or GraphQL-first clients and services.',
22
+ adoption: 'Recommended when schema contracts and resolver changes need stronger review and verification loops.',
23
+ recommendedModules: ['Schema contract guide', 'Resolver verification', 'Client-server contract checks'],
24
+ benchmarkFocus: ['schema safety', 'resolver correctness', 'contract review'],
25
+ },
26
+ {
27
+ key: 'serverless',
28
+ label: 'Serverless',
29
+ useWhen: 'Repos built around functions, lambdas, edge handlers, or platform-managed deployment surfaces.',
30
+ adoption: 'Recommended when deployment packaging, environment isolation, and runtime constraints drive the workflow.',
31
+ recommendedModules: ['Function deployment guide', 'Cold-start aware verification', 'Environment isolation checklist'],
32
+ benchmarkFocus: ['deployment safety', 'runtime fit', 'environment isolation'],
33
+ },
34
+ {
35
+ key: 'microservices',
36
+ label: 'Microservices',
37
+ useWhen: 'Repos coordinating several services, contracts, or inter-service boundaries across a shared system.',
38
+ adoption: 'Recommended when service boundaries, orchestration, and contract compatibility need stronger guardrails.',
39
+ recommendedModules: ['Service boundary guide', 'Contract and proto review', 'Multi-service orchestration checks'],
40
+ benchmarkFocus: ['service-boundary safety', 'contract review', 'multi-service coordination'],
41
+ },
42
+ {
43
+ key: 'cli-tool',
44
+ label: 'CLI Tool',
45
+ useWhen: 'Repos whose primary product surface is a terminal command, scaffolder, or developer-facing CLI.',
46
+ adoption: 'Recommended when command UX, flags, help text, and packaging are part of the product contract.',
47
+ recommendedModules: ['CLI UX guide', 'Flag and help contract', 'Distribution checklist'],
48
+ benchmarkFocus: ['command UX quality', 'flag safety', 'distribution readiness'],
49
+ },
50
+ {
51
+ key: 'browser-ext',
52
+ label: 'Browser Extension',
53
+ useWhen: 'Repos shipping browser extensions, add-ons, or extension-like surfaces with manifest-driven permissions.',
54
+ adoption: 'Recommended when manifest review, permission minimization, and cross-browser packaging are central concerns.',
55
+ recommendedModules: ['Extension manifest guide', 'Permission review', 'Store packaging checklist'],
56
+ benchmarkFocus: ['manifest safety', 'permission posture', 'store packaging readiness'],
57
+ },
58
+ {
59
+ key: 'desktop',
60
+ label: 'Desktop App',
61
+ useWhen: 'Repos shipping desktop software through Electron, Tauri, or similar native-shell frameworks.',
62
+ adoption: 'Recommended when native bridges, packaging, and OS-specific release workflows shape the repo.',
63
+ recommendedModules: ['Desktop packaging guide', 'Native bridge safety', 'Cross-platform release checks'],
64
+ benchmarkFocus: ['native-surface safety', 'packaging quality', 'cross-platform release readiness'],
65
+ },
66
+ {
67
+ key: 'game-dev',
68
+ label: 'Game Development',
69
+ useWhen: 'Repos focused on gameplay loops, rendering, scenes, or asset-heavy interactive experiences.',
70
+ adoption: 'Recommended when performance, asset pipelines, and engine-specific workflows dominate the repo.',
71
+ recommendedModules: ['Asset pipeline guide', 'Render loop safety', 'Performance regression checks'],
72
+ benchmarkFocus: ['render-loop safety', 'asset pipeline quality', 'performance regressions'],
73
+ },
74
+ {
75
+ key: 'data-viz',
76
+ label: 'Data Visualization',
77
+ useWhen: 'Repos centered on charts, dashboards, visual analytics, or data-heavy rendering surfaces.',
78
+ adoption: 'Recommended when chart correctness, data transforms, and rendering fidelity are core product risks.',
79
+ recommendedModules: ['Chart correctness guide', 'Dataset transformation review', 'Render performance checks'],
80
+ benchmarkFocus: ['visual correctness', 'data-transform review', 'render performance'],
81
+ },
82
+ {
83
+ key: 'cms',
84
+ label: 'CMS',
85
+ useWhen: 'Repos driven by structured content, headless CMS models, authoring flows, or publishing pipelines.',
86
+ adoption: 'Recommended when content modeling, preview, and publish behavior need stronger workflow guidance.',
87
+ recommendedModules: ['Content model guide', 'Authoring workflow review', 'Preview and publish checks'],
88
+ benchmarkFocus: ['content-model safety', 'authoring workflow quality', 'publish readiness'],
89
+ },
90
+ {
91
+ key: 'testing-framework',
92
+ label: 'Testing Framework',
93
+ useWhen: 'Repos where the main engineering loop is defined by a first-class test runner and CI test discipline.',
94
+ adoption: 'Recommended when test ergonomics, coverage, and CI parity are foundational to the repo workflow.',
95
+ recommendedModules: ['Test runner baseline', 'Coverage and flake control', 'CI test parity'],
96
+ benchmarkFocus: ['test-loop quality', 'coverage posture', 'CI parity'],
97
+ },
98
+ {
99
+ key: 'devtools',
100
+ label: 'Developer Tools',
101
+ useWhen: 'Repos building plugins, editor extensions, bundler plugins, or other developer-facing tooling.',
102
+ adoption: 'Recommended when extension APIs, integration contracts, and distribution workflows matter to product quality.',
103
+ recommendedModules: ['Developer-tool integration guide', 'Extension/plugin API review', 'Distribution checks'],
104
+ benchmarkFocus: ['integration safety', 'API compatibility', 'distribution readiness'],
105
+ },
106
+ {
107
+ key: 'auth-service',
108
+ label: 'Auth Service',
109
+ useWhen: 'Repos centered on authentication, identity, session issuance, or user access management.',
110
+ adoption: 'Recommended when auth boundaries, token handling, and identity-provider integrations are primary concerns.',
111
+ recommendedModules: ['Auth boundary guide', 'Session/token review', 'Identity-provider integration checks'],
112
+ benchmarkFocus: ['auth-boundary safety', 'session and token review', 'identity-provider fit'],
113
+ },
114
+ {
115
+ key: 'payments',
116
+ label: 'Payments',
117
+ useWhen: 'Repos where billing, subscriptions, checkout, or payment-provider integrations are the core workflow.',
118
+ adoption: 'Recommended when money movement, webhooks, and retry semantics are product-critical.',
119
+ recommendedModules: ['Payment flow guide', 'Webhook and retry review', 'Financial safety checks'],
120
+ benchmarkFocus: ['payment-flow safety', 'webhook correctness', 'financial guardrails'],
121
+ },
122
+ {
123
+ key: 'notifications',
124
+ label: 'Notifications',
125
+ useWhen: 'Repos whose product flows depend on email, SMS, push, or multi-channel user notifications.',
126
+ adoption: 'Recommended when delivery channels, templates, and retry policies drive the system behavior.',
127
+ recommendedModules: ['Delivery channel guide', 'Template lifecycle review', 'Retry and rate-limit checks'],
128
+ benchmarkFocus: ['delivery reliability', 'template quality', 'retry posture'],
129
+ },
130
+ {
131
+ key: 'search',
132
+ label: 'Search',
133
+ useWhen: 'Repos built around search indexing, query relevance, or external search infrastructure.',
134
+ adoption: 'Recommended when indexing, ranking, and synchronization between source data and search need stronger review.',
135
+ recommendedModules: ['Indexing guide', 'Query relevance review', 'Sync and backfill checks'],
136
+ benchmarkFocus: ['indexing safety', 'relevance quality', 'sync correctness'],
137
+ },
138
+ {
139
+ key: 'queue-worker',
140
+ label: 'Queue Worker',
141
+ useWhen: 'Repos organized around job queues, background workers, retries, or asynchronous orchestration.',
142
+ adoption: 'Recommended when idempotency, retries, and worker operational safety define the workflow.',
143
+ recommendedModules: ['Queue processing guide', 'Retry and idempotency review', 'Worker scaling checks'],
144
+ benchmarkFocus: ['job safety', 'retry correctness', 'worker scalability'],
145
+ },
146
+ {
147
+ key: 'observability',
148
+ label: 'Observability',
149
+ useWhen: 'Repos where logs, traces, metrics, or platform telemetry are a first-class operating surface.',
150
+ adoption: 'Recommended when log quality, telemetry coverage, and alertability are central to production readiness.',
151
+ recommendedModules: ['Logging and telemetry guide', 'Error-tracing review', 'Alertability checks'],
152
+ benchmarkFocus: ['telemetry coverage', 'traceability', 'alert readiness'],
153
+ },
154
+ {
155
+ key: 'i18n',
156
+ label: 'Internationalization',
157
+ useWhen: 'Repos with locale files, translation workflows, or runtime language switching as a product feature.',
158
+ adoption: 'Recommended when fallback behavior, message keys, and translation coverage shape the user experience.',
159
+ recommendedModules: ['Locale and message guide', 'Fallback coverage', 'Translation workflow checks'],
160
+ benchmarkFocus: ['translation coverage', 'fallback safety', 'message-key consistency'],
161
+ },
162
+ {
163
+ key: 'static-site',
164
+ label: 'Static Site',
165
+ useWhen: 'Repos generating static documentation, marketing, blog, or content-first sites.',
166
+ adoption: 'Recommended when content builds, routing, and publishing pipelines dominate the workflow.',
167
+ recommendedModules: ['Content build guide', 'Template and routing review', 'Publish pipeline checks'],
168
+ benchmarkFocus: ['build correctness', 'routing safety', 'publish readiness'],
169
+ },
170
+ {
171
+ key: 'api-gateway',
172
+ label: 'API Gateway',
173
+ useWhen: 'Repos built around gateway routing, proxying, traffic policy, or service aggregation layers.',
174
+ adoption: 'Recommended when upstream contracts, routing rules, and auth policy at the edge are major concerns.',
175
+ recommendedModules: ['Gateway routing guide', 'Policy and auth review', 'Upstream contract checks'],
176
+ benchmarkFocus: ['routing safety', 'policy correctness', 'upstream compatibility'],
177
+ },
178
+ {
179
+ key: 'ml-ops',
180
+ label: 'ML Ops',
181
+ useWhen: 'Repos focused on experiment tracking, data lineage, model artifacts, or promotion workflows.',
182
+ adoption: 'Recommended when model lifecycle and experiment traceability matter as much as the model code itself.',
183
+ recommendedModules: ['Experiment tracking guide', 'Artifact lifecycle review', 'Model promotion checks'],
184
+ benchmarkFocus: ['artifact traceability', 'experiment hygiene', 'promotion safety'],
185
+ },
186
+ {
187
+ key: 'embedded-iot',
188
+ label: 'Embedded / IoT',
189
+ useWhen: 'Repos integrating with hardware devices, MQTT-like messaging, or embedded runtime constraints.',
190
+ adoption: 'Recommended when device messaging, firmware safety, and hardware integration dominate the repo.',
191
+ recommendedModules: ['Hardware integration guide', 'Device messaging review', 'Firmware safety checks'],
192
+ benchmarkFocus: ['device-surface safety', 'messaging reliability', 'firmware guardrails'],
193
+ },
194
+ ];
195
+
196
+ const PLATFORM_DEFAULTS = {
197
+ claude: {
198
+ recommendedModules: ['CLAUDE.md baseline'],
199
+ recommendedProposalFamilies: ['claude-md', 'commands', 'rules'],
200
+ recommendedSurfaces: ['CLAUDE.md', '.claude/settings.json', '.github/workflows/'],
201
+ recommendedMcpPacks: ['context7-docs'],
202
+ },
203
+ codex: {
204
+ recommendedModules: ['AGENTS.md baseline', 'Codex config baseline'],
205
+ recommendedProposalFamilies: ['codex-agents-md', 'codex-config', 'codex-ci-review'],
206
+ recommendedSurfaces: ['AGENTS.md', '.codex/config.toml', '.github/workflows/'],
207
+ },
208
+ gemini: {
209
+ recommendedModules: ['GEMINI.md baseline', 'Gemini settings baseline'],
210
+ recommendedProposalFamilies: ['gemini-md', 'gemini-settings', 'gemini-hooks'],
211
+ recommendedSurfaces: ['GEMINI.md', '.gemini/settings.json', '.github/workflows/'],
212
+ },
213
+ copilot: {
214
+ recommendedModules: ['copilot-instructions baseline', 'VS Code settings baseline'],
215
+ recommendedProposalFamilies: ['copilot-instructions', 'copilot-vscode-settings', 'copilot-ci-review'],
216
+ recommendedSurfaces: ['.github/copilot-instructions.md', '.vscode/settings.json', '.github/workflows/'],
217
+ },
218
+ cursor: {
219
+ recommendedModules: ['.cursor/rules baseline', 'Cursor MCP baseline'],
220
+ recommendedProposalFamilies: ['cursor-rules', 'cursor-mcp', 'cursor-ci-review'],
221
+ recommendedSurfaces: ['.cursor/rules/', '.cursor/mcp.json', '.github/workflows/'],
222
+ },
223
+ windsurf: {
224
+ recommendedModules: ['.windsurf/rules baseline', 'Windsurf MCP baseline'],
225
+ recommendedProposalFamilies: ['windsurf-rules', 'windsurf-mcp', 'windsurf-ci-review'],
226
+ recommendedSurfaces: ['.windsurf/rules/', '.windsurf/mcp.json', '.github/workflows/'],
227
+ },
228
+ aider: {
229
+ recommendedModules: ['.aider.conf.yml baseline', 'Convention file starter'],
230
+ recommendedProposalFamilies: ['aider-conf-yml', 'aider-conventions', 'aider-ci'],
231
+ recommendedSurfaces: ['.aider.conf.yml', 'CONVENTIONS.md', '.github/workflows/'],
232
+ },
233
+ opencode: {
234
+ recommendedModules: ['AGENTS.md baseline', 'OpenCode config baseline'],
235
+ recommendedProposalFamilies: ['opencode-agents-md', 'opencode-config', 'opencode-ci'],
236
+ recommendedSurfaces: ['AGENTS.md', 'opencode.json', '.github/workflows/'],
237
+ },
238
+ };
239
+
240
+ function depMapKeys(deps) {
241
+ return Object.keys(deps || {}).map((key) => key.toLowerCase());
242
+ }
243
+
244
+ function hasDependency(depKeys, matchers) {
245
+ return depKeys.some((key) => matchers.some((matcher) => {
246
+ if (typeof matcher === 'string') return key === matcher.toLowerCase();
247
+ return matcher.test(key);
248
+ }));
249
+ }
250
+
251
+ function hasAnyFile(files, pattern) {
252
+ return files.some((file) => pattern.test(file));
253
+ }
254
+
255
+ function getFileContent(ctx, filePath) {
256
+ return typeof ctx.fileContent === 'function' ? (ctx.fileContent(filePath) || '') : '';
257
+ }
258
+
259
+ function countComposeServices(content) {
260
+ if (!content || !/^\s*services\s*:\s*$/m.test(content)) return 0;
261
+ const lines = content.split(/\r?\n/);
262
+ let inServices = false;
263
+ let count = 0;
264
+
265
+ for (const line of lines) {
266
+ if (!inServices) {
267
+ if (/^\s*services\s*:\s*$/.test(line)) {
268
+ inServices = true;
269
+ }
270
+ continue;
271
+ }
272
+
273
+ if (!line.trim()) continue;
274
+ if (/^\S/.test(line)) break;
275
+ if (/^\s{2}[A-Za-z0-9_.-]+\s*:\s*$/.test(line)) count += 1;
276
+ }
277
+
278
+ return count;
279
+ }
280
+
281
+ function getManifestInfo(ctx, files) {
282
+ const manifestPath = files.find((file) => /(^|\/)manifest\.json$/i.test(file));
283
+ if (!manifestPath) return { path: null, content: '' };
284
+ return { path: manifestPath, content: getFileContent(ctx, manifestPath) };
285
+ }
286
+
287
+ function getComposeInfo(ctx, files) {
288
+ const composePath = files.find((file) => /(^|\/)(docker-compose|compose)\.ya?ml$/i.test(file));
289
+ if (!composePath) return { path: null, services: 0 };
290
+ const content = getFileContent(ctx, composePath);
291
+ return { path: composePath, services: countComposeServices(content) };
292
+ }
293
+
294
+ function buildAdditionalDomainPacks(platform, options = {}) {
295
+ const defaults = PLATFORM_DEFAULTS[platform];
296
+ if (!defaults) {
297
+ throw new Error(`Unknown domain-pack expansion platform '${platform}'`);
298
+ }
299
+
300
+ const existingKeys = options.existingKeys || new Set();
301
+
302
+ return PACK_BLUEPRINTS
303
+ .filter((pack) => !existingKeys.has(pack.key))
304
+ .map((pack) => ({
305
+ key: pack.key,
306
+ label: pack.label,
307
+ useWhen: pack.useWhen,
308
+ adoption: pack.adoption,
309
+ recommendedModules: [...defaults.recommendedModules, ...pack.recommendedModules.slice(0, 2)],
310
+ recommendedProposalFamilies: defaults.recommendedProposalFamilies.slice(0, 3),
311
+ recommendedSurfaces: defaults.recommendedSurfaces.slice(0, 3),
312
+ benchmarkFocus: pack.benchmarkFocus.slice(0, 3),
313
+ ...(defaults.recommendedMcpPacks ? { recommendedMcpPacks: defaults.recommendedMcpPacks.slice(0, 3) } : {}),
314
+ }));
315
+ }
316
+
317
+ function detectAdditionalDomainPacks(options) {
318
+ const {
319
+ ctx,
320
+ pkg = {},
321
+ deps = {},
322
+ stackKeys = new Set(),
323
+ addMatch,
324
+ hasBackend = false,
325
+ hasFrontend = false,
326
+ hasInfra = false,
327
+ hasCi = false,
328
+ } = options;
329
+
330
+ const files = Array.isArray(ctx.files) ? ctx.files : [];
331
+ const depKeys = depMapKeys(deps);
332
+ const pkgBin = pkg && pkg.bin;
333
+ const hasBinField = typeof pkgBin === 'string' || (pkgBin && typeof pkgBin === 'object' && Object.keys(pkgBin).length > 0);
334
+ const manifest = getManifestInfo(ctx, files);
335
+ const compose = getComposeInfo(ctx, files);
336
+ const vercelConfig = getFileContent(ctx, 'vercel.json');
337
+
338
+ if (
339
+ hasAnyFile(files, /(^|\/)(hardhat\.config\.(js|ts)|truffle-config\.js|foundry\.toml)$/i) ||
340
+ hasAnyFile(files, /\.sol$/i) ||
341
+ hasDependency(depKeys, [/^hardhat$/i, /^truffle$/i, /^ethers$/i, /^viem$/i, /^@openzeppelin\//i])
342
+ ) {
343
+ addMatch('blockchain', [
344
+ hasAnyFile(files, /\.sol$/i) ? 'Smart-contract source files detected.' : 'Blockchain toolchain files detected.',
345
+ hasAnyFile(files, /foundry\.toml$/i) ? 'Foundry config detected.' : null,
346
+ hasDependency(depKeys, [/^hardhat$/i]) ? 'Hardhat dependency detected.' : null,
347
+ ]);
348
+ }
349
+
350
+ if (hasDependency(depKeys, [/^socket\.io$/i, /^socket\.io-client$/i, /^ws$/i, /^ably/i, /^pusher/i])) {
351
+ addMatch('realtime', [
352
+ 'Realtime communication dependencies detected.',
353
+ hasDependency(depKeys, [/^socket\.io$/i, /^socket\.io-client$/i]) ? 'Socket.IO dependency detected.' : null,
354
+ hasDependency(depKeys, [/^ws$/i]) ? 'WebSocket dependency detected.' : null,
355
+ ]);
356
+ }
357
+
358
+ if (
359
+ hasAnyFile(files, /(^|\/)(schema\.graphql|schema\.gql|.*\.graphqlrc(\.(json|ya?ml))?)$/i) ||
360
+ hasDependency(depKeys, [/^graphql$/i, /^@apollo\//i, /^apollo-/i, /^urql$/i, /^relay/i])
361
+ ) {
362
+ addMatch('graphql', [
363
+ hasAnyFile(files, /\.graphql$/i) ? 'GraphQL schema files detected.' : 'GraphQL tooling detected.',
364
+ hasAnyFile(files, /\.graphqlrc/i) ? '.graphqlrc detected.' : null,
365
+ hasDependency(depKeys, [/^@apollo\//i, /^apollo-/i]) ? 'Apollo dependency detected.' : null,
366
+ ]);
367
+ }
368
+
369
+ if (
370
+ hasAnyFile(files, /(^|\/)(serverless\.ya?ml|sam\.ya?ml)$/i) ||
371
+ /"functions"\s*:\s*\{/i.test(vercelConfig) ||
372
+ (hasInfra && hasAnyFile(files, /vercel\.json$/i))
373
+ ) {
374
+ addMatch('serverless', [
375
+ hasAnyFile(files, /serverless\.ya?ml$/i) ? 'Serverless framework config detected.' : 'Function deployment config detected.',
376
+ hasAnyFile(files, /sam\.ya?ml$/i) ? 'AWS SAM config detected.' : null,
377
+ /"functions"\s*:\s*\{/i.test(vercelConfig) ? 'Vercel functions config detected.' : null,
378
+ ]);
379
+ }
380
+
381
+ if (compose.services >= 3 || hasAnyFile(files, /\.proto$/i)) {
382
+ addMatch('microservices', [
383
+ compose.services >= 3 ? `Compose file defines ${compose.services} services.` : 'Protocol buffer contracts detected.',
384
+ hasAnyFile(files, /\.proto$/i) ? 'Proto files detected.' : null,
385
+ compose.path ? `${compose.path} detected.` : null,
386
+ ]);
387
+ }
388
+
389
+ if (hasBinField && hasDependency(depKeys, [/^commander$/i, /^yargs$/i, /^oclif/i, /^cac$/i])) {
390
+ addMatch('cli-tool', [
391
+ 'CLI bin entry and command-parser dependencies detected.',
392
+ hasDependency(depKeys, [/^commander$/i]) ? 'Commander dependency detected.' : null,
393
+ hasDependency(depKeys, [/^yargs$/i]) ? 'Yargs dependency detected.' : null,
394
+ ]);
395
+ }
396
+
397
+ if (manifest.path && /browser_specific_settings/i.test(manifest.content)) {
398
+ addMatch('browser-ext', [
399
+ 'Browser extension manifest detected.',
400
+ `${manifest.path} contains browser_specific_settings.`,
401
+ null,
402
+ ]);
403
+ }
404
+
405
+ if (
406
+ hasDependency(depKeys, [/^electron$/i, /^electron-builder$/i, /^@tauri-apps\//i, /^tauri$/i]) ||
407
+ files.includes('tauri.conf.json') ||
408
+ ctx.hasDir('src-tauri')
409
+ ) {
410
+ addMatch('desktop', [
411
+ 'Desktop application framework signals detected.',
412
+ ctx.hasDir('src-tauri') ? 'src-tauri directory detected.' : null,
413
+ hasDependency(depKeys, [/^electron$/i]) ? 'Electron dependency detected.' : null,
414
+ ]);
415
+ }
416
+
417
+ if (hasDependency(depKeys, [/^phaser$/i, /^three$/i, /^three\.js$/i, /^pixi\.js$/i, /^@pixi\//i])) {
418
+ addMatch('game-dev', [
419
+ 'Game-development rendering dependencies detected.',
420
+ hasDependency(depKeys, [/^phaser$/i]) ? 'Phaser dependency detected.' : null,
421
+ hasDependency(depKeys, [/^three$/i, /^three\.js$/i]) ? 'Three.js dependency detected.' : null,
422
+ ]);
423
+ }
424
+
425
+ if (hasDependency(depKeys, [/^d3/i, /^chart\.js$/i, /^plotly/i, /^recharts$/i, /^visx/i])) {
426
+ addMatch('data-viz', [
427
+ 'Data-visualization dependencies detected.',
428
+ hasDependency(depKeys, [/^d3/i]) ? 'D3 dependency detected.' : null,
429
+ hasDependency(depKeys, [/^chart\.js$/i]) ? 'Chart.js dependency detected.' : null,
430
+ ]);
431
+ }
432
+
433
+ if (hasDependency(depKeys, [/^strapi/i, /^contentful$/i, /^contentful-/i, /^sanity$/i, /^@sanity\//i])) {
434
+ addMatch('cms', [
435
+ 'CMS or content-platform dependencies detected.',
436
+ hasDependency(depKeys, [/^strapi/i]) ? 'Strapi dependency detected.' : null,
437
+ hasDependency(depKeys, [/^contentful/i]) ? 'Contentful dependency detected.' : null,
438
+ ]);
439
+ }
440
+
441
+ if (
442
+ hasDependency(depKeys, [/^jest$/i, /^vitest$/i, /^@playwright\/test$/i, /^playwright$/i]) ||
443
+ hasAnyFile(files, /(^|\/)(jest\.config|vitest\.config|playwright\.config)\./i)
444
+ ) {
445
+ addMatch('testing-framework', [
446
+ 'Primary test-framework signals detected.',
447
+ hasDependency(depKeys, [/^jest$/i]) ? 'Jest dependency detected.' : null,
448
+ hasDependency(depKeys, [/^vitest$/i]) ? 'Vitest dependency detected.' : null,
449
+ ]);
450
+ }
451
+
452
+ if (
453
+ hasDependency(depKeys, [/^vscode$/i, /^@types\/vscode$/i, /^webpack$/i, /^rollup$/i]) &&
454
+ (pkg.engines && pkg.engines.vscode || hasAnyFile(files, /(^|\/)(extension\.(ts|js)|webpack\..*plugin\.(ts|js))$/i))
455
+ ) {
456
+ addMatch('devtools', [
457
+ 'Developer-tooling integration signals detected.',
458
+ pkg.engines && pkg.engines.vscode ? 'VS Code extension engine declared.' : null,
459
+ hasAnyFile(files, /extension\.(ts|js)$/i) ? 'Extension entrypoint detected.' : null,
460
+ ]);
461
+ }
462
+
463
+ if (hasDependency(depKeys, [/^passport$/i, /^passport-/i, /^auth0$/i, /^@auth0\//i, /^@clerk\//i, /^clerk$/i])) {
464
+ addMatch('auth-service', [
465
+ 'Authentication-platform dependencies detected.',
466
+ hasDependency(depKeys, [/^passport$/i, /^passport-/i]) ? 'Passport dependency detected.' : null,
467
+ hasDependency(depKeys, [/^@clerk\//i, /^clerk$/i]) ? 'Clerk dependency detected.' : null,
468
+ ]);
469
+ }
470
+
471
+ if (
472
+ hasDependency(depKeys, [/^stripe$/i, /^@stripe\//i, /^paypal$/i, /^@paypal\//i, /^braintree$/i]) ||
473
+ ctx.hasDir('payments')
474
+ ) {
475
+ addMatch('payments', [
476
+ 'Payment-platform signals detected.',
477
+ hasDependency(depKeys, [/^stripe$/i, /^@stripe\//i]) ? 'Stripe dependency detected.' : null,
478
+ hasDependency(depKeys, [/^paypal$/i, /^@paypal\//i]) ? 'PayPal dependency detected.' : null,
479
+ ]);
480
+ }
481
+
482
+ if (hasDependency(depKeys, [/^@sendgrid\//i, /^nodemailer$/i, /^ses$/i, /^@aws-sdk\/client-ses$/i, /^twilio$/i])) {
483
+ addMatch('notifications', [
484
+ 'Notification-channel dependencies detected.',
485
+ hasDependency(depKeys, [/^@sendgrid\//i]) ? 'SendGrid dependency detected.' : null,
486
+ hasDependency(depKeys, [/^twilio$/i]) ? 'Twilio dependency detected.' : null,
487
+ ]);
488
+ }
489
+
490
+ if (hasDependency(depKeys, [/^@elastic\/elasticsearch$/i, /^elasticsearch$/i, /^algoliasearch$/i, /^meilisearch$/i])) {
491
+ addMatch('search', [
492
+ 'Search-platform dependencies detected.',
493
+ hasDependency(depKeys, [/^@elastic\/elasticsearch$/i, /^elasticsearch$/i]) ? 'Elasticsearch dependency detected.' : null,
494
+ hasDependency(depKeys, [/^algoliasearch$/i]) ? 'Algolia dependency detected.' : null,
495
+ ]);
496
+ }
497
+
498
+ if (hasDependency(depKeys, [/^bull$/i, /^bullmq$/i, /^amqplib$/i, /^rabbitmq$/i, /^@aws-sdk\/client-sqs$/i, /^sqs-consumer$/i])) {
499
+ addMatch('queue-worker', [
500
+ 'Queue or worker dependencies detected.',
501
+ hasDependency(depKeys, [/^bull$/i, /^bullmq$/i]) ? 'Bull/BullMQ dependency detected.' : null,
502
+ hasDependency(depKeys, [/^amqplib$/i, /^rabbitmq$/i]) ? 'RabbitMQ dependency detected.' : null,
503
+ ]);
504
+ }
505
+
506
+ if (hasDependency(depKeys, [/^winston$/i, /^pino$/i, /^datadog$/i, /^dd-trace$/i, /^@datadog\//i])) {
507
+ addMatch('observability', [
508
+ 'Observability dependencies detected.',
509
+ hasDependency(depKeys, [/^winston$/i]) ? 'Winston dependency detected.' : null,
510
+ hasDependency(depKeys, [/^pino$/i]) ? 'Pino dependency detected.' : null,
511
+ ]);
512
+ }
513
+
514
+ if (hasDependency(depKeys, [/^i18next$/i, /^react-intl$/i, /^formatjs$/i, /^next-intl$/i]) || ctx.hasDir('locales')) {
515
+ addMatch('i18n', [
516
+ 'Internationalization signals detected.',
517
+ ctx.hasDir('locales') ? 'Locales directory detected.' : null,
518
+ hasDependency(depKeys, [/^i18next$/i]) ? 'i18next dependency detected.' : null,
519
+ ]);
520
+ }
521
+
522
+ if (
523
+ hasDependency(depKeys, [/^gatsby$/i, /^@11ty\/eleventy$/i, /^hugo-bin$/i, /^jekyll$/i]) ||
524
+ hasAnyFile(files, /(^|\/)(hugo\.toml|_config\.yml|_config\.yaml|gatsby-config\.(js|ts)|eleventy\.config\.(js|cjs|mjs))$/i)
525
+ ) {
526
+ addMatch('static-site', [
527
+ 'Static-site generator signals detected.',
528
+ hasDependency(depKeys, [/^gatsby$/i]) ? 'Gatsby dependency detected.' : null,
529
+ hasAnyFile(files, /(^|\/)(hugo\.toml|_config\.yml|_config\.yaml)$/i) ? 'Static-site config detected.' : null,
530
+ ]);
531
+ }
532
+
533
+ if (
534
+ hasDependency(depKeys, [/^kong$/i, /^express-gateway$/i]) ||
535
+ hasAnyFile(files, /(^|\/)(kong\.ya?ml|gateway\.config\.(json|ya?ml))$/i)
536
+ ) {
537
+ addMatch('api-gateway', [
538
+ 'API-gateway signals detected.',
539
+ hasDependency(depKeys, [/^express-gateway$/i]) ? 'express-gateway dependency detected.' : null,
540
+ hasAnyFile(files, /kong\.ya?ml$/i) ? 'Kong config detected.' : null,
541
+ ]);
542
+ }
543
+
544
+ if (
545
+ hasDependency(depKeys, [/^mlflow$/i, /^wandb$/i, /^dvc$/i]) ||
546
+ hasAnyFile(files, /(^|\/)(dvc\.yaml|dvc\.yml|mlruns\/|wandb\/)/i)
547
+ ) {
548
+ addMatch('ml-ops', [
549
+ 'ML Ops tracking or artifact signals detected.',
550
+ hasDependency(depKeys, [/^mlflow$/i]) ? 'MLflow dependency detected.' : null,
551
+ hasDependency(depKeys, [/^wandb$/i]) ? 'Weights & Biases dependency detected.' : null,
552
+ ]);
553
+ }
554
+
555
+ if (
556
+ hasDependency(depKeys, [/^johnny-five$/i, /^mqtt$/i, /^particle-/i, /^particle$/i]) ||
557
+ hasAnyFile(files, /\.ino$/i)
558
+ ) {
559
+ addMatch('embedded-iot', [
560
+ 'Embedded or device-integration signals detected.',
561
+ hasDependency(depKeys, [/^mqtt$/i]) ? 'MQTT dependency detected.' : null,
562
+ hasDependency(depKeys, [/^johnny-five$/i]) ? 'Johnny-Five dependency detected.' : null,
563
+ ]);
564
+ }
565
+ }
566
+
567
+ module.exports = {
568
+ PACK_BLUEPRINTS,
569
+ buildAdditionalDomainPacks,
570
+ detectAdditionalDomainPacks,
571
+ };