@hivehub/rulebook 3.3.1 → 4.0.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 (162) hide show
  1. package/.claude/commands/continue.md +33 -0
  2. package/.claude-plugin/marketplace.json +28 -29
  3. package/.claude-plugin/plugin.json +8 -8
  4. package/README.md +32 -144
  5. package/dist/agents/ralph-parser.d.ts +44 -5
  6. package/dist/agents/ralph-parser.d.ts.map +1 -1
  7. package/dist/agents/ralph-parser.js +218 -26
  8. package/dist/agents/ralph-parser.js.map +1 -1
  9. package/dist/cli/commands.d.ts +65 -0
  10. package/dist/cli/commands.d.ts.map +1 -1
  11. package/dist/cli/commands.js +841 -175
  12. package/dist/cli/commands.js.map +1 -1
  13. package/dist/core/agent-manager.d.ts +12 -32
  14. package/dist/core/agent-manager.d.ts.map +1 -1
  15. package/dist/core/agent-manager.js +150 -220
  16. package/dist/core/agent-manager.js.map +1 -1
  17. package/dist/core/claude-mcp.d.ts +17 -0
  18. package/dist/core/claude-mcp.d.ts.map +1 -1
  19. package/dist/core/claude-mcp.js +90 -6
  20. package/dist/core/claude-mcp.js.map +1 -1
  21. package/dist/core/cli-bridge.js +1 -1
  22. package/dist/core/cli-bridge.js.map +1 -1
  23. package/dist/core/config-manager.d.ts.map +1 -1
  24. package/dist/core/config-manager.js +40 -0
  25. package/dist/core/config-manager.js.map +1 -1
  26. package/dist/core/cursor-mdc-generator.d.ts +30 -0
  27. package/dist/core/cursor-mdc-generator.d.ts.map +1 -0
  28. package/dist/core/cursor-mdc-generator.js +98 -0
  29. package/dist/core/cursor-mdc-generator.js.map +1 -0
  30. package/dist/core/detector.d.ts +25 -1
  31. package/dist/core/detector.d.ts.map +1 -1
  32. package/dist/core/detector.js +321 -1
  33. package/dist/core/detector.js.map +1 -1
  34. package/dist/core/generator.d.ts +10 -0
  35. package/dist/core/generator.d.ts.map +1 -1
  36. package/dist/core/generator.js +182 -9
  37. package/dist/core/generator.js.map +1 -1
  38. package/dist/core/github-issues-importer.d.ts +82 -0
  39. package/dist/core/github-issues-importer.d.ts.map +1 -0
  40. package/dist/core/github-issues-importer.js +161 -0
  41. package/dist/core/github-issues-importer.js.map +1 -0
  42. package/dist/core/health-scorer.d.ts +39 -0
  43. package/dist/core/health-scorer.d.ts.map +1 -1
  44. package/dist/core/health-scorer.js +256 -13
  45. package/dist/core/health-scorer.js.map +1 -1
  46. package/dist/core/iteration-tracker.d.ts +28 -0
  47. package/dist/core/iteration-tracker.d.ts.map +1 -1
  48. package/dist/core/iteration-tracker.js +86 -0
  49. package/dist/core/iteration-tracker.js.map +1 -1
  50. package/dist/core/logger.js +1 -1
  51. package/dist/core/logger.js.map +1 -1
  52. package/dist/core/migrator.js +1 -1
  53. package/dist/core/migrator.js.map +1 -1
  54. package/dist/core/modern-console.d.ts +1 -2
  55. package/dist/core/modern-console.d.ts.map +1 -1
  56. package/dist/core/modern-console.js +6 -18
  57. package/dist/core/modern-console.js.map +1 -1
  58. package/dist/core/multi-tool-generator.d.ts +59 -0
  59. package/dist/core/multi-tool-generator.d.ts.map +1 -0
  60. package/dist/core/multi-tool-generator.js +157 -0
  61. package/dist/core/multi-tool-generator.js.map +1 -0
  62. package/dist/core/override-manager.d.ts +23 -0
  63. package/dist/core/override-manager.d.ts.map +1 -0
  64. package/dist/core/override-manager.js +82 -0
  65. package/dist/core/override-manager.js.map +1 -0
  66. package/dist/core/plans-manager.d.ts +46 -0
  67. package/dist/core/plans-manager.d.ts.map +1 -0
  68. package/dist/core/plans-manager.js +158 -0
  69. package/dist/core/plans-manager.js.map +1 -0
  70. package/dist/core/prd-generator.d.ts +12 -0
  71. package/dist/core/prd-generator.d.ts.map +1 -1
  72. package/dist/core/prd-generator.js +91 -2
  73. package/dist/core/prd-generator.js.map +1 -1
  74. package/dist/core/ralph-manager.d.ts +81 -1
  75. package/dist/core/ralph-manager.d.ts.map +1 -1
  76. package/dist/core/ralph-manager.js +214 -4
  77. package/dist/core/ralph-manager.js.map +1 -1
  78. package/dist/core/ralph-parallel.d.ts +55 -0
  79. package/dist/core/ralph-parallel.d.ts.map +1 -0
  80. package/dist/core/ralph-parallel.js +201 -0
  81. package/dist/core/ralph-parallel.js.map +1 -0
  82. package/dist/core/ralph-plan-checkpoint.d.ts +58 -0
  83. package/dist/core/ralph-plan-checkpoint.d.ts.map +1 -0
  84. package/dist/core/ralph-plan-checkpoint.js +154 -0
  85. package/dist/core/ralph-plan-checkpoint.js.map +1 -0
  86. package/dist/core/ralph-scripts.d.ts +12 -0
  87. package/dist/core/ralph-scripts.d.ts.map +1 -0
  88. package/dist/core/ralph-scripts.js +49 -0
  89. package/dist/core/ralph-scripts.js.map +1 -0
  90. package/dist/core/review-manager.d.ts +74 -0
  91. package/dist/core/review-manager.d.ts.map +1 -0
  92. package/dist/core/review-manager.js +371 -0
  93. package/dist/core/review-manager.js.map +1 -0
  94. package/dist/core/task-manager.d.ts +1 -1
  95. package/dist/core/task-manager.js +1 -1
  96. package/dist/core/workflow-generator.js +1 -1
  97. package/dist/core/workflow-generator.js.map +1 -1
  98. package/dist/index.js +96 -4
  99. package/dist/index.js.map +1 -1
  100. package/dist/mcp/rulebook-server.d.ts.map +1 -1
  101. package/dist/mcp/rulebook-server.js +300 -164
  102. package/dist/mcp/rulebook-server.js.map +1 -1
  103. package/dist/memory/memory-store.d.ts.map +1 -1
  104. package/dist/memory/memory-store.js +4 -0
  105. package/dist/memory/memory-store.js.map +1 -1
  106. package/dist/types.d.ts +55 -34
  107. package/dist/types.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/templates/agents/implementer.md +35 -0
  110. package/templates/agents/researcher.md +34 -0
  111. package/templates/agents/team-lead.md +34 -0
  112. package/templates/agents/tester.md +42 -0
  113. package/templates/ci/rulebook-review.yml +26 -0
  114. package/templates/core/AGENTS_LEAN.md +25 -0
  115. package/templates/core/AGENTS_OVERRIDE.md +16 -0
  116. package/templates/core/MULTI_AGENT.md +74 -0
  117. package/templates/core/PLANS.md +28 -0
  118. package/templates/core/RALPH.md +45 -4
  119. package/templates/ides/CONTINUE_RULES.md +16 -0
  120. package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -0
  121. package/templates/ides/GEMINI_RULES.md +17 -0
  122. package/templates/ides/WINDSURF_RULES.md +14 -0
  123. package/templates/ides/cursor-mdc/go.mdc +24 -0
  124. package/templates/ides/cursor-mdc/python.mdc +24 -0
  125. package/templates/ides/cursor-mdc/quality.mdc +25 -0
  126. package/templates/ides/cursor-mdc/ralph.mdc +39 -0
  127. package/templates/ides/cursor-mdc/rulebook.mdc +38 -0
  128. package/templates/ides/cursor-mdc/rust.mdc +24 -0
  129. package/templates/ides/cursor-mdc/typescript.mdc +25 -0
  130. package/templates/modules/sequential-thinking.md +42 -0
  131. package/templates/ralph/ralph-history.bat +4 -0
  132. package/templates/ralph/ralph-history.sh +5 -0
  133. package/templates/ralph/ralph-init.bat +5 -0
  134. package/templates/ralph/ralph-init.sh +5 -0
  135. package/templates/ralph/ralph-pause.bat +5 -0
  136. package/templates/ralph/ralph-pause.sh +5 -0
  137. package/templates/ralph/ralph-run.bat +5 -0
  138. package/templates/ralph/ralph-run.sh +5 -0
  139. package/templates/ralph/ralph-status.bat +4 -0
  140. package/templates/ralph/ralph-status.sh +5 -0
  141. package/templates/services/DATADOG.md +26 -0
  142. package/templates/services/DOCKER.md +124 -0
  143. package/templates/services/DOCKER_COMPOSE.md +168 -0
  144. package/templates/services/HELM.md +194 -0
  145. package/templates/services/KUBERNETES.md +208 -0
  146. package/templates/services/OPENTELEMETRY.md +25 -0
  147. package/templates/services/PINO.md +24 -0
  148. package/templates/services/PROMETHEUS.md +33 -0
  149. package/templates/services/SENTRY.md +23 -0
  150. package/templates/services/WINSTON.md +30 -0
  151. package/dist/core/openspec-manager.d.ts +0 -133
  152. package/dist/core/openspec-manager.d.ts.map +0 -1
  153. package/dist/core/openspec-manager.js +0 -596
  154. package/dist/core/openspec-manager.js.map +0 -1
  155. package/dist/core/openspec-migrator.d.ts +0 -27
  156. package/dist/core/openspec-migrator.d.ts.map +0 -1
  157. package/dist/core/openspec-migrator.js +0 -262
  158. package/dist/core/openspec-migrator.js.map +0 -1
  159. package/dist/core/test-task-manager.d.ts +0 -49
  160. package/dist/core/test-task-manager.d.ts.map +0 -1
  161. package/dist/core/test-task-manager.js +0 -121
  162. package/dist/core/test-task-manager.js.map +0 -1
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Cursor MDC Rules Generator
3
+ *
4
+ * Generates .cursor/rules/*.mdc files for Cursor IDE v0.45+.
5
+ * The new .mdc format replaces the deprecated .cursorrules file and supports:
6
+ * - YAML frontmatter (description, globs, alwaysApply)
7
+ * - Multiple scoped rule files
8
+ * - On-demand loading based on file globs
9
+ */
10
+ export interface CursorMdcOptions {
11
+ languages: string[];
12
+ ralphEnabled: boolean;
13
+ rulebookDir?: string;
14
+ }
15
+ export interface CursorMdcResult {
16
+ generated: string[];
17
+ skipped: string[];
18
+ }
19
+ /**
20
+ * Check if Cursor IDE is being used in the project.
21
+ * Detects: .cursor/ directory, .cursorrules, .cursor/mcp.json
22
+ */
23
+ export declare function isCursorInstalled(projectRoot: string): boolean;
24
+ /**
25
+ * Generate .cursor/rules/*.mdc files for the project.
26
+ * Always generates: rulebook.mdc, quality.mdc
27
+ * Conditionally generates: ralph.mdc (if Ralph enabled), <language>.mdc
28
+ */
29
+ export declare function generateCursorMdcRules(projectRoot: string, options: CursorMdcOptions): Promise<CursorMdcResult>;
30
+ //# sourceMappingURL=cursor-mdc-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-mdc-generator.d.ts","sourceRoot":"","sources":["../../src/core/cursor-mdc-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA4C1B"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Cursor MDC Rules Generator
3
+ *
4
+ * Generates .cursor/rules/*.mdc files for Cursor IDE v0.45+.
5
+ * The new .mdc format replaces the deprecated .cursorrules file and supports:
6
+ * - YAML frontmatter (description, globs, alwaysApply)
7
+ * - Multiple scoped rule files
8
+ * - On-demand loading based on file globs
9
+ */
10
+ import path from 'path';
11
+ import { existsSync } from 'fs';
12
+ import { readFile as fsReadFile, writeFile, mkdir } from 'fs/promises';
13
+ import { fileURLToPath } from 'url';
14
+ import { dirname } from 'path';
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ // Language → .mdc template name
18
+ const LANGUAGE_MDC_MAP = {
19
+ typescript: 'typescript',
20
+ javascript: 'typescript', // share the TS template for JS projects
21
+ python: 'python',
22
+ rust: 'rust',
23
+ go: 'go',
24
+ };
25
+ /**
26
+ * Check if Cursor IDE is being used in the project.
27
+ * Detects: .cursor/ directory, .cursorrules, .cursor/mcp.json
28
+ */
29
+ export function isCursorInstalled(projectRoot) {
30
+ return (existsSync(path.join(projectRoot, '.cursor')) ||
31
+ existsSync(path.join(projectRoot, '.cursorrules')));
32
+ }
33
+ /**
34
+ * Generate .cursor/rules/*.mdc files for the project.
35
+ * Always generates: rulebook.mdc, quality.mdc
36
+ * Conditionally generates: ralph.mdc (if Ralph enabled), <language>.mdc
37
+ */
38
+ export async function generateCursorMdcRules(projectRoot, options) {
39
+ const rulesDir = path.join(projectRoot, '.cursor', 'rules');
40
+ await mkdir(rulesDir, { recursive: true });
41
+ const result = { generated: [], skipped: [] };
42
+ const templatesDir = getTemplatesDir();
43
+ // Always-generate files: rulebook.mdc, quality.mdc
44
+ const alwaysFiles = ['rulebook', 'quality'];
45
+ for (const name of alwaysFiles) {
46
+ const wrote = await writeMdcFile(rulesDir, name, templatesDir);
47
+ if (wrote) {
48
+ result.generated.push(`${name}.mdc`);
49
+ }
50
+ else {
51
+ result.skipped.push(`${name}.mdc`);
52
+ }
53
+ }
54
+ // Ralph directives (only if ralph is enabled in config)
55
+ if (options.ralphEnabled) {
56
+ const wrote = await writeMdcFile(rulesDir, 'ralph', templatesDir);
57
+ if (wrote) {
58
+ result.generated.push('ralph.mdc');
59
+ }
60
+ else {
61
+ result.skipped.push('ralph.mdc');
62
+ }
63
+ }
64
+ // Language-specific files
65
+ const writtenLangTemplates = new Set();
66
+ for (const lang of options.languages) {
67
+ const templateName = LANGUAGE_MDC_MAP[lang.toLowerCase()];
68
+ if (!templateName || writtenLangTemplates.has(templateName))
69
+ continue;
70
+ writtenLangTemplates.add(templateName);
71
+ const wrote = await writeMdcFile(rulesDir, templateName, templatesDir);
72
+ if (wrote) {
73
+ result.generated.push(`${templateName}.mdc`);
74
+ }
75
+ else {
76
+ result.skipped.push(`${templateName}.mdc`);
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ // ─── Helpers ────────────────────────────────────────────────────────────────
82
+ function getTemplatesDir() {
83
+ return path.join(__dirname, '..', '..', 'templates', 'ides', 'cursor-mdc');
84
+ }
85
+ /**
86
+ * Write a single .mdc file from template. Returns true if file was written.
87
+ */
88
+ async function writeMdcFile(rulesDir, name, templatesDir) {
89
+ const templatePath = path.join(templatesDir, `${name}.mdc`);
90
+ if (!existsSync(templatePath)) {
91
+ return false;
92
+ }
93
+ const content = await fsReadFile(templatePath, 'utf-8');
94
+ const destPath = path.join(rulesDir, `${name}.mdc`);
95
+ await writeFile(destPath, content, 'utf-8');
96
+ return true;
97
+ }
98
+ //# sourceMappingURL=cursor-mdc-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-mdc-generator.js","sourceRoot":"","sources":["../../src/core/cursor-mdc-generator.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,27 @@
1
- import type { DetectionResult } from '../types.js';
1
+ import type { DetectionResult, MonorepoDetection } from '../types.js';
2
2
  export declare function detectProject(cwd?: string): Promise<DetectionResult>;
3
+ /**
4
+ * Detect Cursor IDE presence and configuration status.
5
+ */
6
+ export declare function detectCursor(cwd: string): Promise<DetectionResult['cursor']>;
7
+ /**
8
+ * Detect Gemini CLI presence by checking for GEMINI.md in the project root.
9
+ */
10
+ export declare function detectGeminiCli(cwd: string): Promise<NonNullable<DetectionResult['geminiCli']>>;
11
+ /**
12
+ * Detect Continue.dev IDE extension by checking for the .continue/ directory.
13
+ */
14
+ export declare function detectContinueDev(cwd: string): Promise<NonNullable<DetectionResult['continueDev']>>;
15
+ /**
16
+ * Detect Windsurf IDE by checking for .windsurfrules in the project root.
17
+ */
18
+ export declare function detectWindsurf(cwd: string): Promise<NonNullable<DetectionResult['windsurf']>>;
19
+ /**
20
+ * Detect GitHub Copilot by checking for .github/copilot-instructions.md.
21
+ */
22
+ export declare function detectGithubCopilot(cwd: string): Promise<NonNullable<DetectionResult['githubCopilot']>>;
23
+ /**
24
+ * Detect monorepo structure: Turborepo, Nx, pnpm workspaces, Lerna, or manual.
25
+ */
26
+ export declare function detectMonorepo(cwd: string): Promise<MonorepoDetection>;
3
27
  //# sourceMappingURL=detector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/core/detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EAShB,MAAM,aAAa,CAAC;AAErB,wBAAsB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBzF"}
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/core/detector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EASf,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB,wBAAsB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CA4BzF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAoBlF;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAIpD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,CAKtD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAInD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,CAIxD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgC5E"}
@@ -1,4 +1,6 @@
1
1
  import path from 'path';
2
+ import { existsSync } from 'fs';
3
+ import { readdir } from 'fs/promises';
2
4
  import { fileExists, findFiles, readFile, readJsonFile } from '../utils/file-system.js';
3
5
  export async function detectProject(cwd = process.cwd()) {
4
6
  const languages = await detectLanguages(cwd);
@@ -7,6 +9,12 @@ export async function detectProject(cwd = process.cwd()) {
7
9
  const services = await detectServices(cwd);
8
10
  const existingAgents = await detectExistingAgents(cwd);
9
11
  const gitHooks = await detectGitHooks(cwd);
12
+ const monorepo = await detectMonorepo(cwd);
13
+ const cursor = await detectCursor(cwd);
14
+ const geminiCli = await detectGeminiCli(cwd);
15
+ const continueDev = await detectContinueDev(cwd);
16
+ const windsurf = await detectWindsurf(cwd);
17
+ const githubCopilot = await detectGithubCopilot(cwd);
10
18
  return {
11
19
  languages,
12
20
  modules,
@@ -14,8 +22,127 @@ export async function detectProject(cwd = process.cwd()) {
14
22
  services,
15
23
  existingAgents,
16
24
  gitHooks,
25
+ monorepo,
26
+ cursor,
27
+ geminiCli,
28
+ continueDev,
29
+ windsurf,
30
+ githubCopilot,
17
31
  };
18
32
  }
33
+ /**
34
+ * Detect Cursor IDE presence and configuration status.
35
+ */
36
+ export async function detectCursor(cwd) {
37
+ const cursorDir = path.join(cwd, '.cursor');
38
+ const cursorrules = path.join(cwd, '.cursorrules');
39
+ const rulesDir = path.join(cursorDir, 'rules');
40
+ const hasCursorDir = existsSync(cursorDir);
41
+ const hasCursorrules = existsSync(cursorrules);
42
+ const detected = hasCursorDir || hasCursorrules;
43
+ let hasMdcRules = false;
44
+ if (existsSync(rulesDir)) {
45
+ try {
46
+ const files = await readdir(rulesDir);
47
+ hasMdcRules = files.some((f) => f.endsWith('.mdc'));
48
+ }
49
+ catch {
50
+ // ignore
51
+ }
52
+ }
53
+ return { detected, hasCursorrules, hasMdcRules };
54
+ }
55
+ /**
56
+ * Detect Gemini CLI presence by checking for GEMINI.md in the project root.
57
+ */
58
+ export async function detectGeminiCli(cwd) {
59
+ const geminiMd = path.join(cwd, 'GEMINI.md');
60
+ const detected = existsSync(geminiMd);
61
+ return { detected };
62
+ }
63
+ /**
64
+ * Detect Continue.dev IDE extension by checking for the .continue/ directory.
65
+ */
66
+ export async function detectContinueDev(cwd) {
67
+ const continueDir = path.join(cwd, '.continue');
68
+ const rulesDir = path.join(continueDir, 'rules');
69
+ const detected = existsSync(continueDir);
70
+ return { detected, rulesDir };
71
+ }
72
+ /**
73
+ * Detect Windsurf IDE by checking for .windsurfrules in the project root.
74
+ */
75
+ export async function detectWindsurf(cwd) {
76
+ const windsurfrules = path.join(cwd, '.windsurfrules');
77
+ const detected = existsSync(windsurfrules);
78
+ return { detected };
79
+ }
80
+ /**
81
+ * Detect GitHub Copilot by checking for .github/copilot-instructions.md.
82
+ */
83
+ export async function detectGithubCopilot(cwd) {
84
+ const copilotInstructions = path.join(cwd, '.github', 'copilot-instructions.md');
85
+ const detected = existsSync(copilotInstructions);
86
+ return { detected };
87
+ }
88
+ /**
89
+ * Detect monorepo structure: Turborepo, Nx, pnpm workspaces, Lerna, or manual.
90
+ */
91
+ export async function detectMonorepo(cwd) {
92
+ // Turborepo
93
+ if (existsSync(path.join(cwd, 'turbo.json'))) {
94
+ const packages = await discoverPackages(cwd);
95
+ return { detected: true, tool: 'turborepo', packages };
96
+ }
97
+ // Nx
98
+ if (existsSync(path.join(cwd, 'nx.json'))) {
99
+ const packages = await discoverPackages(cwd);
100
+ return { detected: true, tool: 'nx', packages };
101
+ }
102
+ // pnpm workspaces
103
+ if (existsSync(path.join(cwd, 'pnpm-workspace.yaml'))) {
104
+ const packages = await discoverPackages(cwd);
105
+ return { detected: true, tool: 'pnpm', packages };
106
+ }
107
+ // Lerna
108
+ if (existsSync(path.join(cwd, 'lerna.json'))) {
109
+ const packages = await discoverPackages(cwd);
110
+ return { detected: true, tool: 'lerna', packages };
111
+ }
112
+ // Manual monorepo — packages/ or apps/ directory with multiple package.json files
113
+ const packages = await discoverPackages(cwd);
114
+ if (packages.length >= 2) {
115
+ return { detected: true, tool: 'manual', packages };
116
+ }
117
+ return { detected: false, tool: null, packages: [] };
118
+ }
119
+ /**
120
+ * Discover package directories by looking for package.json in packages/ and apps/.
121
+ */
122
+ async function discoverPackages(cwd) {
123
+ const packageDirs = [];
124
+ const searchDirs = ['packages', 'apps', 'libs', 'services'];
125
+ for (const searchDir of searchDirs) {
126
+ const absDir = path.join(cwd, searchDir);
127
+ if (!existsSync(absDir))
128
+ continue;
129
+ try {
130
+ const entries = await readdir(absDir, { withFileTypes: true });
131
+ for (const entry of entries) {
132
+ if (!entry.isDirectory())
133
+ continue;
134
+ const pkgJson = path.join(absDir, entry.name, 'package.json');
135
+ if (existsSync(pkgJson)) {
136
+ packageDirs.push(`${searchDir}/${entry.name}`);
137
+ }
138
+ }
139
+ }
140
+ catch {
141
+ // ignore unreadable dirs
142
+ }
143
+ }
144
+ return packageDirs;
145
+ }
19
146
  async function detectLanguages(cwd) {
20
147
  const detections = [];
21
148
  // Detect Rust
@@ -762,6 +889,21 @@ async function detectModules(cwd) {
762
889
  source: mcpPath,
763
890
  });
764
891
  }
892
+ // Check for Sequential Thinking MCP Server (various key names)
893
+ const seqKeys = ['sequential-thinking', 'sequential_thinking', 'sequentialThinking'];
894
+ const hasSeqThinking = seqKeys.some((k) => config.mcpServers?.[k] || config.servers?.[k]) ||
895
+ Object.entries(config.mcpServers ?? {}).some(([, v]) => typeof v === 'object' &&
896
+ v !== null &&
897
+ 'args' in v &&
898
+ Array.isArray(v.args) &&
899
+ v.args.some((a) => typeof a === 'string' && a.includes('sequential-thinking')));
900
+ if (hasSeqThinking) {
901
+ modules.push({
902
+ module: 'sequential_thinking',
903
+ detected: true,
904
+ source: mcpPath,
905
+ });
906
+ }
765
907
  }
766
908
  }
767
909
  catch {
@@ -771,7 +913,15 @@ async function detectModules(cwd) {
771
913
  }
772
914
  // Add undetected modules
773
915
  const detectedModules = new Set(modules.map((m) => m.module));
774
- const allModules = ['vectorizer', 'synap', 'context7', 'github', 'playwright', 'rulebook_mcp'];
916
+ const allModules = [
917
+ 'vectorizer',
918
+ 'synap',
919
+ 'context7',
920
+ 'github',
921
+ 'playwright',
922
+ 'rulebook_mcp',
923
+ 'sequential_thinking',
924
+ ];
775
925
  for (const module of allModules) {
776
926
  if (!detectedModules.has(module)) {
777
927
  modules.push({
@@ -1044,6 +1194,75 @@ async function detectServices(cwd) {
1044
1194
  source: packageJson,
1045
1195
  });
1046
1196
  }
1197
+ // Sentry
1198
+ if (allDeps['@sentry/node'] ||
1199
+ allDeps['@sentry/react'] ||
1200
+ allDeps['@sentry/nextjs'] ||
1201
+ allDeps['@sentry/browser']) {
1202
+ services.push({
1203
+ service: 'sentry',
1204
+ detected: true,
1205
+ confidence: 0.9,
1206
+ indicators: ['@sentry/node', '@sentry/react', '@sentry/nextjs', '@sentry/browser'].filter((dep) => allDeps[dep]),
1207
+ source: packageJson,
1208
+ });
1209
+ }
1210
+ // OpenTelemetry
1211
+ if (allDeps['@opentelemetry/sdk-node'] ||
1212
+ allDeps['@opentelemetry/api'] ||
1213
+ allDeps['@opentelemetry/auto-instrumentations-node']) {
1214
+ services.push({
1215
+ service: 'opentelemetry',
1216
+ detected: true,
1217
+ confidence: 0.9,
1218
+ indicators: [
1219
+ '@opentelemetry/sdk-node',
1220
+ '@opentelemetry/api',
1221
+ '@opentelemetry/auto-instrumentations-node',
1222
+ ].filter((dep) => allDeps[dep]),
1223
+ source: packageJson,
1224
+ });
1225
+ }
1226
+ // Datadog
1227
+ if (allDeps['dd-trace'] || allDeps['datadog-lambda-js']) {
1228
+ services.push({
1229
+ service: 'datadog',
1230
+ detected: true,
1231
+ confidence: 0.9,
1232
+ indicators: ['dd-trace', 'datadog-lambda-js'].filter((dep) => allDeps[dep]),
1233
+ source: packageJson,
1234
+ });
1235
+ }
1236
+ // Pino
1237
+ if (allDeps['pino'] || allDeps['pino-http']) {
1238
+ services.push({
1239
+ service: 'pino',
1240
+ detected: true,
1241
+ confidence: 0.9,
1242
+ indicators: ['pino', 'pino-http'].filter((dep) => allDeps[dep]),
1243
+ source: packageJson,
1244
+ });
1245
+ }
1246
+ // Winston
1247
+ if (allDeps['winston'] || allDeps['winston-transport']) {
1248
+ services.push({
1249
+ service: 'winston',
1250
+ detected: true,
1251
+ confidence: 0.9,
1252
+ indicators: ['winston', 'winston-transport'].filter((dep) => allDeps[dep]),
1253
+ source: packageJson,
1254
+ });
1255
+ }
1256
+ // Prometheus
1257
+ if (allDeps['prom-client'] || allDeps['express-prometheus-middleware']) {
1258
+ services.push({
1259
+ service: 'prometheus',
1260
+ detected: true,
1261
+ confidence: 0.9,
1262
+ indicators: ['prom-client', 'express-prometheus-middleware'].filter((dep) => allDeps[dep]),
1263
+ source: packageJson,
1264
+ });
1265
+ }
1047
1266
  }
1048
1267
  catch {
1049
1268
  // Ignore JSON parse errors
@@ -1404,6 +1623,97 @@ async function detectServices(cwd) {
1404
1623
  }
1405
1624
  }
1406
1625
  }
1626
+ // Detect container/orchestration services (Docker, Docker Compose, Kubernetes, Helm)
1627
+ const dockerfile = path.join(cwd, 'Dockerfile');
1628
+ const dockerignore = path.join(cwd, '.dockerignore');
1629
+ const k8sDir = path.join(cwd, 'k8s');
1630
+ const kubernetesDir = path.join(cwd, 'kubernetes');
1631
+ const chartYaml = path.join(cwd, 'Chart.yaml');
1632
+ const chartsDir = path.join(cwd, 'charts');
1633
+ // Docker
1634
+ if ((await fileExists(dockerfile)) || (await fileExists(dockerignore))) {
1635
+ const indicators = [];
1636
+ if (await fileExists(dockerfile))
1637
+ indicators.push('Dockerfile');
1638
+ if (await fileExists(dockerignore))
1639
+ indicators.push('.dockerignore');
1640
+ services.push({
1641
+ service: 'docker',
1642
+ detected: true,
1643
+ confidence: 0.95,
1644
+ indicators,
1645
+ source: indicators[0],
1646
+ });
1647
+ }
1648
+ // Docker Compose
1649
+ if ((await fileExists(dockerCompose)) || (await fileExists(dockerComposeYaml))) {
1650
+ const indicators = [];
1651
+ if (await fileExists(dockerCompose))
1652
+ indicators.push('docker-compose.yml');
1653
+ if (await fileExists(dockerComposeYaml))
1654
+ indicators.push('docker-compose.yaml');
1655
+ services.push({
1656
+ service: 'docker-compose',
1657
+ detected: true,
1658
+ confidence: 0.95,
1659
+ indicators,
1660
+ source: indicators[0],
1661
+ });
1662
+ }
1663
+ // Kubernetes
1664
+ const k8sDirExists = existsSync(k8sDir);
1665
+ const kubernetesDirExists = existsSync(kubernetesDir);
1666
+ let k8sYamlDetected = false;
1667
+ if (!k8sDirExists && !kubernetesDirExists) {
1668
+ // Scan root-level YAML files for Kubernetes resource kinds
1669
+ try {
1670
+ const rootFiles = await readdir(cwd);
1671
+ const yamlFiles = rootFiles.filter((f) => f.endsWith('.yml') || f.endsWith('.yaml'));
1672
+ for (const yamlFile of yamlFiles) {
1673
+ const content = await readFile(path.join(cwd, yamlFile));
1674
+ if (content.includes('kind: Deployment') ||
1675
+ content.includes('kind: Service') ||
1676
+ content.includes('kind: Ingress')) {
1677
+ k8sYamlDetected = true;
1678
+ break;
1679
+ }
1680
+ }
1681
+ }
1682
+ catch {
1683
+ // Ignore read errors
1684
+ }
1685
+ }
1686
+ if (k8sDirExists || kubernetesDirExists || k8sYamlDetected) {
1687
+ const indicators = [];
1688
+ if (k8sDirExists)
1689
+ indicators.push('k8s/ directory');
1690
+ if (kubernetesDirExists)
1691
+ indicators.push('kubernetes/ directory');
1692
+ if (k8sYamlDetected)
1693
+ indicators.push('YAML with kind: Deployment/Service/Ingress');
1694
+ services.push({
1695
+ service: 'kubernetes',
1696
+ detected: true,
1697
+ confidence: 0.9,
1698
+ indicators,
1699
+ });
1700
+ }
1701
+ // Helm
1702
+ const chartYamlExists = await fileExists(chartYaml);
1703
+ const chartsDirExists = existsSync(chartsDir);
1704
+ if (chartYamlExists || chartsDirExists) {
1705
+ const indicators = [];
1706
+ if (chartYamlExists)
1707
+ indicators.push('Chart.yaml');
1708
+ if (chartsDirExists)
1709
+ indicators.push('charts/ directory');
1710
+ services.push({
1711
+ service: 'helm',
1712
+ detected: true,
1713
+ confidence: 0.9,
1714
+ indicators,
1715
+ });
1716
+ }
1407
1717
  // Add undetected services (for manual selection)
1408
1718
  const detectedServices = new Set(services.map((s) => s.service));
1409
1719
  const allServices = [
@@ -1427,6 +1737,16 @@ async function detectServices(cwd) {
1427
1737
  'azure_blob',
1428
1738
  'gcs',
1429
1739
  'minio',
1740
+ 'docker',
1741
+ 'docker-compose',
1742
+ 'kubernetes',
1743
+ 'helm',
1744
+ 'sentry',
1745
+ 'opentelemetry',
1746
+ 'datadog',
1747
+ 'pino',
1748
+ 'winston',
1749
+ 'prometheus',
1430
1750
  ];
1431
1751
  for (const service of allServices) {
1432
1752
  if (!detectedServices.has(service)) {