agentsys 5.0.3 → 5.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 (264) hide show
  1. package/.claude-plugin/marketplace.json +21 -14
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +2 -1
  4. package/CHANGELOG.md +18 -0
  5. package/README.md +7 -6
  6. package/adapters/codex/skills/agnix/SKILL.md +0 -1
  7. package/adapters/codex/skills/audit-project/SKILL.md +0 -1
  8. package/adapters/codex/skills/audit-project-agents/SKILL.md +0 -1
  9. package/adapters/codex/skills/audit-project-github/SKILL.md +0 -1
  10. package/adapters/codex/skills/consult/SKILL.md +132 -57
  11. package/adapters/codex/skills/debate/SKILL.md +214 -0
  12. package/adapters/codex/skills/delivery-approval/SKILL.md +0 -1
  13. package/adapters/codex/skills/deslop/SKILL.md +0 -1
  14. package/adapters/codex/skills/drift-detect/SKILL.md +0 -1
  15. package/adapters/codex/skills/enhance/SKILL.md +0 -1
  16. package/adapters/codex/skills/learn/SKILL.md +0 -1
  17. package/adapters/codex/skills/next-task/SKILL.md +0 -1
  18. package/adapters/codex/skills/perf/SKILL.md +0 -1
  19. package/adapters/codex/skills/repo-map/SKILL.md +0 -1
  20. package/adapters/codex/skills/ship/SKILL.md +0 -1
  21. package/adapters/codex/skills/ship-ci-review-loop/SKILL.md +0 -1
  22. package/adapters/codex/skills/ship-deployment/SKILL.md +0 -1
  23. package/adapters/codex/skills/ship-error-handling/SKILL.md +0 -1
  24. package/adapters/codex/skills/sync-docs/SKILL.md +0 -1
  25. package/adapters/opencode/agents/agent-enhancer.md +0 -1
  26. package/adapters/opencode/agents/agnix-agent.md +0 -1
  27. package/adapters/opencode/agents/ci-fixer.md +0 -1
  28. package/adapters/opencode/agents/ci-monitor.md +0 -1
  29. package/adapters/opencode/agents/claudemd-enhancer.md +0 -1
  30. package/adapters/opencode/agents/consult-agent.md +122 -30
  31. package/adapters/opencode/agents/cross-file-enhancer.md +0 -1
  32. package/adapters/opencode/agents/debate-orchestrator.md +169 -0
  33. package/adapters/opencode/agents/delivery-validator.md +0 -1
  34. package/adapters/opencode/agents/deslop-agent.md +0 -1
  35. package/adapters/opencode/agents/docs-enhancer.md +0 -1
  36. package/adapters/opencode/agents/exploration-agent.md +0 -1
  37. package/adapters/opencode/agents/hooks-enhancer.md +0 -1
  38. package/adapters/opencode/agents/implementation-agent.md +0 -1
  39. package/adapters/opencode/agents/learn-agent.md +0 -1
  40. package/adapters/opencode/agents/map-validator.md +0 -1
  41. package/adapters/opencode/agents/perf-analyzer.md +0 -1
  42. package/adapters/opencode/agents/perf-code-paths.md +0 -1
  43. package/adapters/opencode/agents/perf-investigation-logger.md +0 -1
  44. package/adapters/opencode/agents/perf-orchestrator.md +0 -1
  45. package/adapters/opencode/agents/perf-theory-gatherer.md +0 -1
  46. package/adapters/opencode/agents/perf-theory-tester.md +0 -1
  47. package/adapters/opencode/agents/plan-synthesizer.md +0 -1
  48. package/adapters/opencode/agents/planning-agent.md +0 -1
  49. package/adapters/opencode/agents/plugin-enhancer.md +0 -1
  50. package/adapters/opencode/agents/prompt-enhancer.md +0 -1
  51. package/adapters/opencode/agents/simple-fixer.md +0 -1
  52. package/adapters/opencode/agents/skills-enhancer.md +0 -1
  53. package/adapters/opencode/agents/sync-docs-agent.md +0 -1
  54. package/adapters/opencode/agents/task-discoverer.md +0 -1
  55. package/adapters/opencode/agents/test-coverage-checker.md +0 -1
  56. package/adapters/opencode/agents/worktree-manager.md +0 -1
  57. package/adapters/opencode/commands/agnix.md +0 -1
  58. package/adapters/opencode/commands/audit-project-agents.md +0 -1
  59. package/adapters/opencode/commands/audit-project-github.md +0 -1
  60. package/adapters/opencode/commands/audit-project.md +0 -1
  61. package/adapters/opencode/commands/consult.md +133 -57
  62. package/adapters/opencode/commands/debate.md +224 -0
  63. package/adapters/opencode/commands/delivery-approval.md +0 -1
  64. package/adapters/opencode/commands/deslop.md +0 -1
  65. package/adapters/opencode/commands/drift-detect.md +0 -1
  66. package/adapters/opencode/commands/enhance.md +0 -1
  67. package/adapters/opencode/commands/learn.md +0 -1
  68. package/adapters/opencode/commands/next-task.md +0 -1
  69. package/adapters/opencode/commands/perf.md +0 -1
  70. package/adapters/opencode/commands/repo-map.md +0 -1
  71. package/adapters/opencode/commands/ship-ci-review-loop.md +0 -1
  72. package/adapters/opencode/commands/ship-deployment.md +0 -1
  73. package/adapters/opencode/commands/ship-error-handling.md +0 -1
  74. package/adapters/opencode/commands/ship.md +0 -1
  75. package/adapters/opencode/commands/sync-docs.md +0 -1
  76. package/adapters/opencode/skills/agnix/SKILL.md +1 -2
  77. package/adapters/opencode/skills/consult/SKILL.md +33 -23
  78. package/adapters/opencode/skills/debate/SKILL.md +245 -0
  79. package/adapters/opencode/skills/deslop/SKILL.md +1 -2
  80. package/adapters/opencode/skills/discover-tasks/SKILL.md +1 -2
  81. package/adapters/opencode/skills/drift-analysis/SKILL.md +1 -2
  82. package/adapters/opencode/skills/enhance-agent-prompts/SKILL.md +1 -2
  83. package/adapters/opencode/skills/enhance-claude-memory/SKILL.md +1 -2
  84. package/adapters/opencode/skills/enhance-cross-file/SKILL.md +1 -2
  85. package/adapters/opencode/skills/enhance-docs/SKILL.md +1 -2
  86. package/adapters/opencode/skills/enhance-hooks/SKILL.md +1 -2
  87. package/adapters/opencode/skills/enhance-orchestrator/SKILL.md +1 -2
  88. package/adapters/opencode/skills/enhance-plugins/SKILL.md +1 -2
  89. package/adapters/opencode/skills/enhance-prompts/SKILL.md +1 -2
  90. package/adapters/opencode/skills/enhance-skills/SKILL.md +1 -2
  91. package/adapters/opencode/skills/learn/SKILL.md +1 -2
  92. package/adapters/opencode/skills/orchestrate-review/SKILL.md +0 -1
  93. package/adapters/opencode/skills/perf-analyzer/SKILL.md +1 -2
  94. package/adapters/opencode/skills/perf-baseline-manager/SKILL.md +1 -2
  95. package/adapters/opencode/skills/perf-benchmarker/SKILL.md +1 -2
  96. package/adapters/opencode/skills/perf-code-paths/SKILL.md +1 -2
  97. package/adapters/opencode/skills/perf-investigation-logger/SKILL.md +1 -2
  98. package/adapters/opencode/skills/perf-profiler/SKILL.md +1 -2
  99. package/adapters/opencode/skills/perf-theory-gatherer/SKILL.md +1 -2
  100. package/adapters/opencode/skills/perf-theory-tester/SKILL.md +1 -2
  101. package/adapters/opencode/skills/repo-mapping/SKILL.md +1 -2
  102. package/adapters/opencode/skills/sync-docs/SKILL.md +1 -2
  103. package/adapters/opencode/skills/validate-delivery/SKILL.md +1 -2
  104. package/lib/adapter-transforms.js +24 -4
  105. package/package.json +1 -1
  106. package/plugins/agnix/.claude-plugin/plugin.json +1 -1
  107. package/plugins/agnix/skills/agnix/SKILL.md +1 -1
  108. package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
  109. package/plugins/audit-project/lib/adapter-transforms.js +24 -4
  110. package/plugins/consult/.claude-plugin/plugin.json +1 -1
  111. package/plugins/consult/agents/consult-agent.md +122 -29
  112. package/plugins/consult/commands/consult.md +135 -58
  113. package/plugins/consult/skills/consult/SKILL.md +31 -20
  114. package/plugins/debate/.claude-plugin/plugin.json +21 -0
  115. package/plugins/debate/agents/debate-orchestrator.md +175 -0
  116. package/plugins/debate/commands/debate.md +221 -0
  117. package/plugins/debate/lib/adapter-transforms.js +298 -0
  118. package/plugins/debate/lib/collectors/codebase.js +392 -0
  119. package/plugins/debate/lib/collectors/docs-patterns.js +713 -0
  120. package/plugins/debate/lib/collectors/documentation.js +219 -0
  121. package/plugins/debate/lib/collectors/github.js +330 -0
  122. package/plugins/debate/lib/collectors/index.js +126 -0
  123. package/plugins/debate/lib/config/index.js +14 -0
  124. package/plugins/debate/lib/cross-platform/index.js +539 -0
  125. package/plugins/debate/lib/discovery/index.js +352 -0
  126. package/plugins/debate/lib/drift-detect/collectors.js +37 -0
  127. package/plugins/debate/lib/enhance/agent-analyzer.js +421 -0
  128. package/plugins/debate/lib/enhance/agent-patterns.js +571 -0
  129. package/plugins/debate/lib/enhance/auto-suppression.js +622 -0
  130. package/plugins/debate/lib/enhance/benchmark.js +417 -0
  131. package/plugins/debate/lib/enhance/cross-file-analyzer.js +930 -0
  132. package/plugins/debate/lib/enhance/cross-file-patterns.js +370 -0
  133. package/plugins/debate/lib/enhance/docs-analyzer.js +325 -0
  134. package/plugins/debate/lib/enhance/docs-patterns.js +671 -0
  135. package/plugins/debate/lib/enhance/fixer.js +721 -0
  136. package/plugins/debate/lib/enhance/hook-analyzer.js +135 -0
  137. package/plugins/debate/lib/enhance/hook-patterns.js +40 -0
  138. package/plugins/debate/lib/enhance/index.js +127 -0
  139. package/plugins/debate/lib/enhance/plugin-analyzer.js +402 -0
  140. package/plugins/debate/lib/enhance/plugin-patterns.js +326 -0
  141. package/plugins/debate/lib/enhance/projectmemory-analyzer.js +551 -0
  142. package/plugins/debate/lib/enhance/projectmemory-patterns.js +617 -0
  143. package/plugins/debate/lib/enhance/prompt-analyzer.js +457 -0
  144. package/plugins/debate/lib/enhance/prompt-patterns.js +1484 -0
  145. package/plugins/debate/lib/enhance/reporter.js +1348 -0
  146. package/plugins/debate/lib/enhance/security-patterns.js +284 -0
  147. package/plugins/debate/lib/enhance/skill-analyzer.js +182 -0
  148. package/plugins/debate/lib/enhance/skill-patterns.js +147 -0
  149. package/plugins/debate/lib/enhance/suppression.js +352 -0
  150. package/plugins/debate/lib/enhance/tool-patterns.js +373 -0
  151. package/plugins/debate/lib/index.js +270 -0
  152. package/plugins/debate/lib/patterns/cli-enhancers.js +611 -0
  153. package/plugins/debate/lib/patterns/pipeline.js +948 -0
  154. package/plugins/debate/lib/patterns/review-patterns.js +558 -0
  155. package/plugins/debate/lib/patterns/slop-analyzers.js +2305 -0
  156. package/plugins/debate/lib/patterns/slop-patterns.js +1187 -0
  157. package/plugins/debate/lib/perf/analyzer/index.js +22 -0
  158. package/plugins/debate/lib/perf/argument-parser.js +105 -0
  159. package/plugins/debate/lib/perf/baseline-comparator.js +50 -0
  160. package/plugins/debate/lib/perf/baseline-store.js +127 -0
  161. package/plugins/debate/lib/perf/benchmark-runner.js +404 -0
  162. package/plugins/debate/lib/perf/breaking-point-finder.js +52 -0
  163. package/plugins/debate/lib/perf/breaking-point-runner.js +60 -0
  164. package/plugins/debate/lib/perf/checkpoint.js +123 -0
  165. package/plugins/debate/lib/perf/code-paths.js +86 -0
  166. package/plugins/debate/lib/perf/consolidation.js +37 -0
  167. package/plugins/debate/lib/perf/constraint-runner.js +71 -0
  168. package/plugins/debate/lib/perf/experiment-runner.js +32 -0
  169. package/plugins/debate/lib/perf/index.js +41 -0
  170. package/plugins/debate/lib/perf/investigation-state.js +874 -0
  171. package/plugins/debate/lib/perf/optimization-runner.js +79 -0
  172. package/plugins/debate/lib/perf/profilers/go.js +22 -0
  173. package/plugins/debate/lib/perf/profilers/index.js +46 -0
  174. package/plugins/debate/lib/perf/profilers/java.js +23 -0
  175. package/plugins/debate/lib/perf/profilers/node.js +27 -0
  176. package/plugins/debate/lib/perf/profilers/python.js +23 -0
  177. package/plugins/debate/lib/perf/profilers/rust.js +23 -0
  178. package/plugins/debate/lib/perf/profiling-runner.js +75 -0
  179. package/plugins/debate/lib/perf/schemas.js +140 -0
  180. package/plugins/debate/lib/platform/detect-platform.js +413 -0
  181. package/plugins/debate/lib/platform/detection-configs.js +93 -0
  182. package/plugins/debate/lib/platform/state-dir.js +132 -0
  183. package/plugins/debate/lib/platform/verify-tools.js +182 -0
  184. package/plugins/debate/lib/repo-map/cache.js +152 -0
  185. package/plugins/debate/lib/repo-map/concurrency.js +29 -0
  186. package/plugins/debate/lib/repo-map/index.js +222 -0
  187. package/plugins/debate/lib/repo-map/installer.js +212 -0
  188. package/plugins/debate/lib/repo-map/queries/go.js +27 -0
  189. package/plugins/debate/lib/repo-map/queries/index.js +100 -0
  190. package/plugins/debate/lib/repo-map/queries/java.js +38 -0
  191. package/plugins/debate/lib/repo-map/queries/javascript.js +55 -0
  192. package/plugins/debate/lib/repo-map/queries/python.js +24 -0
  193. package/plugins/debate/lib/repo-map/queries/rust.js +73 -0
  194. package/plugins/debate/lib/repo-map/queries/typescript.js +38 -0
  195. package/plugins/debate/lib/repo-map/runner.js +1364 -0
  196. package/plugins/debate/lib/repo-map/updater.js +562 -0
  197. package/plugins/debate/lib/repo-map/usage-analyzer.js +407 -0
  198. package/plugins/debate/lib/schemas/plugin-manifest.schema.json +57 -0
  199. package/plugins/debate/lib/schemas/validator.js +247 -0
  200. package/plugins/debate/lib/sources/custom-handler.js +199 -0
  201. package/plugins/debate/lib/sources/policy-questions.js +246 -0
  202. package/plugins/debate/lib/sources/source-cache.js +165 -0
  203. package/plugins/debate/lib/state/workflow-state.js +576 -0
  204. package/plugins/debate/lib/types/agent-frontmatter.d.ts +134 -0
  205. package/plugins/debate/lib/types/command-frontmatter.d.ts +107 -0
  206. package/plugins/debate/lib/types/hook-frontmatter.d.ts +115 -0
  207. package/plugins/debate/lib/types/index.d.ts +84 -0
  208. package/plugins/debate/lib/types/plugin-manifest.d.ts +102 -0
  209. package/plugins/debate/lib/types/skill-frontmatter.d.ts +89 -0
  210. package/plugins/debate/lib/utils/atomic-write.js +94 -0
  211. package/plugins/debate/lib/utils/cache-manager.js +159 -0
  212. package/plugins/debate/lib/utils/command-parser.js +0 -0
  213. package/plugins/debate/lib/utils/context-optimizer.js +300 -0
  214. package/plugins/debate/lib/utils/deprecation.js +37 -0
  215. package/plugins/debate/lib/utils/shell-escape.js +88 -0
  216. package/plugins/debate/lib/utils/state-helpers.js +61 -0
  217. package/plugins/debate/skills/debate/SKILL.md +264 -0
  218. package/plugins/deslop/.claude-plugin/plugin.json +1 -1
  219. package/plugins/deslop/lib/adapter-transforms.js +24 -4
  220. package/plugins/deslop/skills/deslop/SKILL.md +1 -1
  221. package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
  222. package/plugins/drift-detect/lib/adapter-transforms.js +24 -4
  223. package/plugins/drift-detect/skills/drift-analysis/SKILL.md +1 -1
  224. package/plugins/enhance/.claude-plugin/plugin.json +1 -1
  225. package/plugins/enhance/lib/adapter-transforms.js +24 -4
  226. package/plugins/enhance/skills/enhance-agent-prompts/SKILL.md +1 -1
  227. package/plugins/enhance/skills/enhance-claude-memory/SKILL.md +1 -1
  228. package/plugins/enhance/skills/enhance-cross-file/SKILL.md +1 -1
  229. package/plugins/enhance/skills/enhance-docs/SKILL.md +1 -1
  230. package/plugins/enhance/skills/enhance-hooks/SKILL.md +1 -1
  231. package/plugins/enhance/skills/enhance-orchestrator/SKILL.md +1 -1
  232. package/plugins/enhance/skills/enhance-plugins/SKILL.md +1 -1
  233. package/plugins/enhance/skills/enhance-prompts/SKILL.md +1 -1
  234. package/plugins/enhance/skills/enhance-skills/SKILL.md +1 -1
  235. package/plugins/learn/.claude-plugin/plugin.json +1 -1
  236. package/plugins/learn/agents/learn-agent.md +1 -1
  237. package/plugins/learn/lib/adapter-transforms.js +24 -4
  238. package/plugins/learn/skills/learn/SKILL.md +1 -1
  239. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  240. package/plugins/next-task/agents/exploration-agent.md +1 -1
  241. package/plugins/next-task/lib/adapter-transforms.js +24 -4
  242. package/plugins/next-task/skills/discover-tasks/SKILL.md +1 -1
  243. package/plugins/next-task/skills/validate-delivery/SKILL.md +1 -1
  244. package/plugins/perf/.claude-plugin/plugin.json +1 -1
  245. package/plugins/perf/lib/adapter-transforms.js +24 -4
  246. package/plugins/perf/skills/perf-analyzer/SKILL.md +1 -1
  247. package/plugins/perf/skills/perf-baseline-manager/SKILL.md +1 -1
  248. package/plugins/perf/skills/perf-benchmarker/SKILL.md +1 -1
  249. package/plugins/perf/skills/perf-code-paths/SKILL.md +1 -1
  250. package/plugins/perf/skills/perf-investigation-logger/SKILL.md +1 -1
  251. package/plugins/perf/skills/perf-profiler/SKILL.md +1 -1
  252. package/plugins/perf/skills/perf-theory-gatherer/SKILL.md +1 -1
  253. package/plugins/perf/skills/perf-theory-tester/SKILL.md +1 -1
  254. package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
  255. package/plugins/repo-map/lib/adapter-transforms.js +24 -4
  256. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  257. package/plugins/ship/lib/adapter-transforms.js +24 -4
  258. package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
  259. package/plugins/sync-docs/lib/adapter-transforms.js +24 -4
  260. package/plugins/sync-docs/skills/sync-docs/SKILL.md +1 -1
  261. package/scripts/gen-adapters.js +6 -7
  262. package/scripts/generate-docs.js +4 -2
  263. package/scripts/plugins.txt +1 -0
  264. package/site/content.json +6 -6
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Tool Verification System
4
+ * Checks availability and versions of development tools for graceful degradation
5
+ *
6
+ * Usage: node lib/platform/verify-tools.js
7
+ * Output: JSON with tool availability and versions
8
+ *
9
+ * @author Avi Fenesh
10
+ * @license MIT
11
+ */
12
+
13
+ const { spawn } = require('child_process');
14
+
15
+ // Detect Windows platform
16
+ const isWindows = process.platform === 'win32';
17
+
18
+ /**
19
+ * Checks if a tool is available and returns its version
20
+ * Uses safe execution methods to avoid shell injection vulnerabilities
21
+ * @param {string} command - Command to check (e.g., 'git', 'node')
22
+ * @param {string} versionFlag - Flag to get version (default: '--version')
23
+ * @returns {Promise<Object>} { available: boolean, version: string|null }
24
+ */
25
+ function checkTool(command, versionFlag = '--version') {
26
+ return new Promise((resolve) => {
27
+ // Validate command contains only safe characters (alphanumeric, underscore, hyphen)
28
+ if (!/^[a-zA-Z0-9_-]+$/.test(command)) {
29
+ return resolve({ available: false, version: null });
30
+ }
31
+ // Validate versionFlag contains only safe characters
32
+ if (!/^[a-zA-Z0-9_-]+$/.test(versionFlag)) {
33
+ return resolve({ available: false, version: null });
34
+ }
35
+
36
+ let child;
37
+
38
+ if (isWindows) {
39
+ // On Windows, spawn shell directly with command as single argument
40
+ child = spawn('cmd.exe', ['/c', command, versionFlag], {
41
+ stdio: ['pipe', 'pipe', 'ignore'],
42
+ windowsHide: true
43
+ });
44
+ } else {
45
+ // On Unix, spawn directly without shell
46
+ child = spawn(command, [versionFlag], {
47
+ stdio: ['pipe', 'pipe', 'ignore']
48
+ });
49
+ }
50
+
51
+ let stdout = '';
52
+
53
+ // Set timeout
54
+ const timeout = setTimeout(() => {
55
+ child.kill();
56
+ resolve({ available: false, version: null });
57
+ }, 5000);
58
+
59
+ child.stdout.on('data', (data) => {
60
+ try {
61
+ stdout += data.toString();
62
+ } catch {
63
+ // Ignore data conversion errors - will result in empty/partial version string
64
+ }
65
+ });
66
+
67
+ child.on('error', () => {
68
+ clearTimeout(timeout);
69
+ resolve({ available: false, version: null });
70
+ });
71
+
72
+ child.on('close', (code) => {
73
+ clearTimeout(timeout);
74
+ if (code !== 0) {
75
+ return resolve({ available: false, version: null });
76
+ }
77
+ const version = stdout.trim().split('\n')[0];
78
+ resolve({ available: true, version });
79
+ });
80
+ });
81
+ }
82
+
83
+ /**
84
+ * Tool definitions with their version flags
85
+ */
86
+ const TOOL_DEFINITIONS = [
87
+ // Version control
88
+ { name: 'git', flag: '--version' },
89
+ { name: 'gh', flag: '--version' },
90
+
91
+ // Node.js ecosystem
92
+ { name: 'node', flag: '--version' },
93
+ { name: 'npm', flag: '--version' },
94
+ { name: 'pnpm', flag: '--version' },
95
+ { name: 'yarn', flag: '--version' },
96
+ { name: 'bun', flag: '--version' },
97
+
98
+ // Python ecosystem
99
+ { name: 'python', flag: '--version' },
100
+ { name: 'python3', flag: '--version' },
101
+ { name: 'pip', flag: '--version' },
102
+ { name: 'pip3', flag: '--version' },
103
+ { name: 'poetry', flag: '--version' },
104
+
105
+ // Rust ecosystem
106
+ { name: 'cargo', flag: '--version' },
107
+ { name: 'rustc', flag: '--version' },
108
+ { name: 'rustup', flag: '--version' },
109
+
110
+ // Go ecosystem
111
+ { name: 'go', flag: 'version' },
112
+
113
+ // Java ecosystem
114
+ { name: 'java', flag: '--version' },
115
+ { name: 'javac', flag: '--version' },
116
+ { name: 'mvn', flag: '--version' },
117
+ { name: 'gradle', flag: '--version' },
118
+
119
+ // Containerization
120
+ { name: 'docker', flag: '--version' },
121
+
122
+ // Deployment platforms
123
+ { name: 'railway', flag: '--version' },
124
+ { name: 'vercel', flag: '--version' },
125
+ { name: 'netlify', flag: '--version' },
126
+ { name: 'flyctl', flag: 'version' },
127
+
128
+ // CI/CD tools
129
+ { name: 'circleci', flag: 'version' }
130
+ ];
131
+
132
+ /**
133
+ * Verifies all development tools (parallel execution)
134
+ * Runs all tool checks in parallel for fast execution
135
+ * @returns {Promise<Object>} Tool availability map
136
+ */
137
+ async function verifyTools() {
138
+ try {
139
+ const results = await Promise.all(
140
+ TOOL_DEFINITIONS.map(tool => checkTool(tool.name, tool.flag))
141
+ );
142
+
143
+ const toolMap = {};
144
+ TOOL_DEFINITIONS.forEach((tool, index) => {
145
+ toolMap[tool.name] = results[index];
146
+ });
147
+
148
+ return toolMap;
149
+ } catch (error) {
150
+ // Log error for debugging but return empty map for graceful degradation
151
+ console.error(`[WARN] Tool verification failed: ${error.message}`);
152
+ // Return all tools as unavailable rather than throwing
153
+ const toolMap = {};
154
+ TOOL_DEFINITIONS.forEach((tool) => {
155
+ toolMap[tool.name] = { available: false, version: null };
156
+ });
157
+ return toolMap;
158
+ }
159
+ }
160
+
161
+ // When run directly, output JSON
162
+ if (require.main === module) {
163
+ (async () => {
164
+ try {
165
+ const result = await verifyTools();
166
+ console.log(JSON.stringify(result, null, 2));
167
+ } catch (error) {
168
+ console.error(JSON.stringify({
169
+ error: error.message,
170
+ timestamp: new Date().toISOString()
171
+ }, null, 2));
172
+ process.exit(1);
173
+ }
174
+ })();
175
+ }
176
+
177
+ // Export for use as module
178
+ module.exports = {
179
+ verifyTools,
180
+ checkTool,
181
+ TOOL_DEFINITIONS
182
+ };
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Repo map cache management
3
+ *
4
+ * @module lib/repo-map/cache
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { getStateDirPath } = require('../platform/state-dir');
12
+ const { writeJsonAtomic, writeFileAtomic } = require('../utils/atomic-write');
13
+
14
+ const MAP_FILENAME = 'repo-map.json';
15
+ const STALE_FILENAME = 'repo-map.stale';
16
+
17
+ /**
18
+ * Get repo-map path
19
+ * @param {string} basePath - Repository root
20
+ * @returns {string}
21
+ */
22
+ function getMapPath(basePath) {
23
+ return path.join(getStateDirPath(basePath), MAP_FILENAME);
24
+ }
25
+
26
+ /**
27
+ * Get stale marker path
28
+ * @param {string} basePath - Repository root
29
+ * @returns {string}
30
+ */
31
+ function getStalePath(basePath) {
32
+ return path.join(getStateDirPath(basePath), STALE_FILENAME);
33
+ }
34
+
35
+ /**
36
+ * Ensure state directory exists
37
+ * @param {string} basePath - Repository root
38
+ * @returns {string}
39
+ */
40
+ function ensureStateDir(basePath) {
41
+ const stateDir = getStateDirPath(basePath);
42
+ if (!fs.existsSync(stateDir)) {
43
+ fs.mkdirSync(stateDir, { recursive: true });
44
+ }
45
+ return stateDir;
46
+ }
47
+
48
+ /**
49
+ * Load repo-map from cache
50
+ * @param {string} basePath - Repository root
51
+ * @returns {Object|null}
52
+ */
53
+ function load(basePath) {
54
+ const mapPath = getMapPath(basePath);
55
+ if (!fs.existsSync(mapPath)) return null;
56
+
57
+ try {
58
+ const raw = fs.readFileSync(mapPath, 'utf8');
59
+ return JSON.parse(raw);
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Save repo-map to cache
67
+ * @param {string} basePath - Repository root
68
+ * @param {Object} map - Map object
69
+ */
70
+ function save(basePath, map) {
71
+ ensureStateDir(basePath);
72
+ const mapPath = getMapPath(basePath);
73
+
74
+ const output = {
75
+ ...map,
76
+ updated: new Date().toISOString()
77
+ };
78
+
79
+ writeJsonAtomic(mapPath, output);
80
+
81
+ // Clear stale marker if present
82
+ clearStale(basePath);
83
+ }
84
+
85
+ /**
86
+ * Check if repo-map exists
87
+ * @param {string} basePath - Repository root
88
+ * @returns {boolean}
89
+ */
90
+ function exists(basePath) {
91
+ return fs.existsSync(getMapPath(basePath));
92
+ }
93
+
94
+ /**
95
+ * Mark repo-map as stale
96
+ * @param {string} basePath - Repository root
97
+ */
98
+ function markStale(basePath) {
99
+ ensureStateDir(basePath);
100
+ writeFileAtomic(getStalePath(basePath), new Date().toISOString());
101
+ }
102
+
103
+ /**
104
+ * Clear stale marker
105
+ * @param {string} basePath - Repository root
106
+ */
107
+ function clearStale(basePath) {
108
+ const stalePath = getStalePath(basePath);
109
+ if (fs.existsSync(stalePath)) {
110
+ fs.unlinkSync(stalePath);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Check if stale marker exists
116
+ * @param {string} basePath - Repository root
117
+ * @returns {boolean}
118
+ */
119
+ function isMarkedStale(basePath) {
120
+ return fs.existsSync(getStalePath(basePath));
121
+ }
122
+
123
+ /**
124
+ * Get basic status summary
125
+ * @param {string} basePath - Repository root
126
+ * @returns {Object|null}
127
+ */
128
+ function getStatus(basePath) {
129
+ const map = load(basePath);
130
+ if (!map) return null;
131
+
132
+ return {
133
+ generated: map.generated,
134
+ updated: map.updated,
135
+ commit: map.git?.commit,
136
+ branch: map.git?.branch,
137
+ files: Object.keys(map.files || {}).length,
138
+ symbols: map.stats?.totalSymbols || 0,
139
+ languages: map.project?.languages || []
140
+ };
141
+ }
142
+
143
+ module.exports = {
144
+ load,
145
+ save,
146
+ exists,
147
+ getStatus,
148
+ getMapPath,
149
+ markStale,
150
+ clearStale,
151
+ isMarkedStale
152
+ };
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ async function runWithConcurrency(items, limit, worker) {
4
+ if (!Array.isArray(items) || items.length === 0) {
5
+ return [];
6
+ }
7
+
8
+ const maxConcurrency = Math.max(1, Math.min(items.length, Math.floor(limit) || 1));
9
+ const results = new Array(items.length);
10
+ let cursor = 0;
11
+
12
+ async function runWorker() {
13
+ while (true) {
14
+ const index = cursor;
15
+ cursor += 1;
16
+ if (index >= items.length) {
17
+ return;
18
+ }
19
+ results[index] = await worker(items[index], index);
20
+ }
21
+ }
22
+
23
+ await Promise.all(Array.from({ length: maxConcurrency }, () => runWorker()));
24
+ return results;
25
+ }
26
+
27
+ module.exports = {
28
+ runWithConcurrency
29
+ };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Repo Map - AST-based repository symbol mapping
3
+ *
4
+ * Uses ast-grep (sg) for accurate symbol extraction across multiple languages.
5
+ * Generates a cached map of exports, functions, classes, and imports.
6
+ *
7
+ * @module lib/repo-map
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const installer = require('./installer');
13
+ const runner = require('./runner');
14
+ const cache = require('./cache');
15
+ const updater = require('./updater');
16
+ const usageAnalyzer = require('./usage-analyzer');
17
+
18
+ /**
19
+ * Initialize a new repo map (full scan)
20
+ * @param {string} basePath - Repository root path
21
+ * @param {Object} options - Options
22
+ * @param {boolean} options.force - Force rebuild even if map exists
23
+ * @param {string[]} options.languages - Languages to scan (auto-detect if not specified)
24
+ * @returns {Promise<{success: boolean, map?: Object, error?: string}>}
25
+ */
26
+ async function init(basePath, options = {}) {
27
+ // Check if ast-grep is installed
28
+ const installed = await installer.checkInstalled();
29
+ if (!installed.found) {
30
+ return {
31
+ success: false,
32
+ error: 'ast-grep not found',
33
+ installSuggestion: installer.getInstallInstructions()
34
+ };
35
+ }
36
+
37
+ if (!installer.meetsMinimumVersion(installed.version)) {
38
+ return {
39
+ success: false,
40
+ error: `ast-grep version ${installed.version || 'unknown'} is too old. Minimum required: ${installer.getMinimumVersion()}`,
41
+ installSuggestion: installer.getInstallInstructions()
42
+ };
43
+ }
44
+
45
+ // Check if map already exists
46
+ const existing = cache.load(basePath);
47
+ if (existing && !options.force) {
48
+ return {
49
+ success: false,
50
+ error: 'Repo map already exists. Use --force to rebuild or /repo-map update to refresh.',
51
+ existing: cache.getStatus(basePath)
52
+ };
53
+ }
54
+
55
+ // Detect languages in the project
56
+ const languages = options.languages || await runner.detectLanguages(basePath);
57
+ if (languages.length === 0) {
58
+ return {
59
+ success: false,
60
+ error: 'No supported languages detected in repository'
61
+ };
62
+ }
63
+
64
+ // Run full scan
65
+ const startTime = Date.now();
66
+ const map = await runner.fullScan(basePath, languages, {
67
+ fileLimit: options.fileLimit
68
+ });
69
+ map.stats.scanDurationMs = Date.now() - startTime;
70
+
71
+ // Save map
72
+ cache.save(basePath, map);
73
+
74
+ return {
75
+ success: true,
76
+ map,
77
+ summary: {
78
+ files: Object.keys(map.files).length,
79
+ symbols: map.stats.totalSymbols,
80
+ languages: map.project.languages,
81
+ duration: map.stats.scanDurationMs
82
+ }
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Update an existing repo map (incremental)
88
+ * @param {string} basePath - Repository root path
89
+ * @param {Object} options - Options
90
+ * @param {boolean} options.full - Force full rebuild instead of incremental
91
+ * @returns {Promise<{success: boolean, changes?: Object, error?: string}>}
92
+ */
93
+ async function update(basePath, options = {}) {
94
+ // Check if ast-grep is installed
95
+ const installed = await installer.checkInstalled();
96
+ if (!installed.found) {
97
+ return {
98
+ success: false,
99
+ error: 'ast-grep not found',
100
+ installSuggestion: installer.getInstallInstructions()
101
+ };
102
+ }
103
+
104
+ if (!installer.meetsMinimumVersion(installed.version)) {
105
+ return {
106
+ success: false,
107
+ error: `ast-grep version ${installed.version || 'unknown'} is too old. Minimum required: ${installer.getMinimumVersion()}`,
108
+ installSuggestion: installer.getInstallInstructions()
109
+ };
110
+ }
111
+
112
+ // Load existing map
113
+ const existing = cache.load(basePath);
114
+ if (!existing) {
115
+ return {
116
+ success: false,
117
+ error: 'No repo map found. Run /repo-map init first.'
118
+ };
119
+ }
120
+
121
+ // Force full rebuild if requested
122
+ if (options.full) {
123
+ return init(basePath, { force: true });
124
+ }
125
+
126
+ // Incremental update
127
+ const result = await updater.incrementalUpdate(basePath, existing);
128
+
129
+ if (result.success) {
130
+ cache.save(basePath, result.map);
131
+ }
132
+
133
+ return result;
134
+ }
135
+
136
+ /**
137
+ * Get repo map status
138
+ * @param {string} basePath - Repository root path
139
+ * @returns {{exists: boolean, status?: Object}}
140
+ */
141
+ function status(basePath) {
142
+ const map = cache.load(basePath);
143
+ if (!map) {
144
+ return { exists: false };
145
+ }
146
+
147
+ const staleness = updater.checkStaleness(basePath, map);
148
+
149
+ return {
150
+ exists: true,
151
+ status: {
152
+ generated: map.generated,
153
+ updated: map.updated,
154
+ commit: map.git?.commit,
155
+ branch: map.git?.branch,
156
+ files: Object.keys(map.files).length,
157
+ symbols: map.stats?.totalSymbols || 0,
158
+ languages: map.project?.languages || [],
159
+ staleness
160
+ }
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Load repo map (if exists)
166
+ * @param {string} basePath - Repository root path
167
+ * @returns {Object|null} - The map or null if not found
168
+ */
169
+ function load(basePath) {
170
+ return cache.load(basePath);
171
+ }
172
+
173
+ /**
174
+ * Check if ast-grep is installed
175
+ * @returns {Promise<{found: boolean, version?: string, path?: string}>}
176
+ */
177
+ async function checkAstGrepInstalled() {
178
+ return installer.checkInstalled();
179
+ }
180
+
181
+ /**
182
+ * Get install instructions for ast-grep
183
+ * @returns {string}
184
+ */
185
+ function getInstallInstructions() {
186
+ return installer.getInstallInstructions();
187
+ }
188
+
189
+ /**
190
+ * Check if repo map exists
191
+ * @param {string} basePath - Repository root path
192
+ * @returns {boolean}
193
+ */
194
+ function exists(basePath) {
195
+ return cache.exists(basePath);
196
+ }
197
+
198
+ module.exports = {
199
+ init,
200
+ update,
201
+ status,
202
+ load,
203
+ exists,
204
+ checkAstGrepInstalled,
205
+ getInstallInstructions,
206
+
207
+ // Usage analysis functions
208
+ buildUsageIndex: usageAnalyzer.buildUsageIndex,
209
+ findUsages: usageAnalyzer.findUsages,
210
+ findDependents: usageAnalyzer.findDependents,
211
+ findUnusedExports: usageAnalyzer.findUnusedExports,
212
+ findOrphanedInfrastructure: usageAnalyzer.findOrphanedInfrastructure,
213
+ getDependencyGraph: usageAnalyzer.getDependencyGraph,
214
+ findCircularDependencies: usageAnalyzer.findCircularDependencies,
215
+
216
+ // Re-export submodules for advanced usage
217
+ installer,
218
+ runner,
219
+ cache,
220
+ updater,
221
+ usageAnalyzer
222
+ };