aios-core 4.2.14 → 4.3.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 (288) hide show
  1. package/.aios-core/cli/commands/validate/index.js +1 -1
  2. package/.aios-core/core/code-intel/helpers/creation-helper.js +183 -0
  3. package/.aios-core/core/code-intel/helpers/devops-helper.js +166 -0
  4. package/.aios-core/core/code-intel/helpers/planning-helper.js +248 -0
  5. package/.aios-core/core/code-intel/helpers/qa-helper.js +187 -0
  6. package/.aios-core/core/code-intel/helpers/story-helper.js +146 -0
  7. package/.aios-core/core/config/schemas/framework-config.schema.json +155 -7
  8. package/.aios-core/core/config/schemas/project-config.schema.json +329 -15
  9. package/.aios-core/core/config/template-overrides.js +84 -0
  10. package/.aios-core/core/docs/troubleshooting-guide.md +1 -1
  11. package/.aios-core/core/doctor/checks/agent-memory.js +63 -0
  12. package/.aios-core/core/doctor/checks/claude-md.js +56 -0
  13. package/.aios-core/core/doctor/checks/code-intel.js +57 -0
  14. package/.aios-core/core/doctor/checks/commands-count.js +81 -0
  15. package/.aios-core/core/doctor/checks/core-config.js +53 -0
  16. package/.aios-core/core/doctor/checks/entity-registry.js +53 -0
  17. package/.aios-core/core/doctor/checks/git-hooks.js +50 -0
  18. package/.aios-core/core/doctor/checks/graph-dashboard.js +48 -0
  19. package/.aios-core/core/doctor/checks/hooks-claude-count.js +107 -0
  20. package/.aios-core/core/doctor/checks/ide-sync.js +68 -0
  21. package/.aios-core/core/doctor/checks/index.js +46 -0
  22. package/.aios-core/core/doctor/checks/node-version.js +33 -0
  23. package/.aios-core/core/doctor/checks/npm-packages.js +35 -0
  24. package/.aios-core/core/doctor/checks/rules-files.js +61 -0
  25. package/.aios-core/core/doctor/checks/settings-json.js +121 -0
  26. package/.aios-core/core/doctor/checks/skills-count.js +72 -0
  27. package/.aios-core/core/doctor/fix-handler.js +165 -0
  28. package/.aios-core/core/doctor/formatters/json.js +14 -0
  29. package/.aios-core/core/doctor/formatters/text.js +59 -0
  30. package/.aios-core/core/doctor/index.js +94 -0
  31. package/.aios-core/core/graph-dashboard/cli.js +361 -0
  32. package/.aios-core/core/graph-dashboard/data-sources/code-intel-source.js +234 -0
  33. package/.aios-core/core/graph-dashboard/data-sources/metrics-source.js +95 -0
  34. package/.aios-core/core/graph-dashboard/data-sources/registry-source.js +106 -0
  35. package/.aios-core/core/graph-dashboard/formatters/dot-formatter.js +45 -0
  36. package/.aios-core/core/graph-dashboard/formatters/html-formatter.js +1437 -0
  37. package/.aios-core/core/graph-dashboard/formatters/json-formatter.js +13 -0
  38. package/.aios-core/core/graph-dashboard/formatters/mermaid-formatter.js +59 -0
  39. package/.aios-core/core/graph-dashboard/index.js +21 -0
  40. package/.aios-core/core/graph-dashboard/renderers/stats-renderer.js +217 -0
  41. package/.aios-core/core/graph-dashboard/renderers/status-renderer.js +125 -0
  42. package/.aios-core/core/graph-dashboard/renderers/tree-renderer.js +119 -0
  43. package/.aios-core/core/health-check/base-check.js +1 -1
  44. package/.aios-core/core/health-check/check-registry.js +1 -1
  45. package/.aios-core/core/health-check/checks/deployment/build-config.js +1 -1
  46. package/.aios-core/core/health-check/checks/deployment/ci-config.js +1 -1
  47. package/.aios-core/core/health-check/checks/deployment/deployment-readiness.js +1 -1
  48. package/.aios-core/core/health-check/checks/deployment/docker-config.js +1 -1
  49. package/.aios-core/core/health-check/checks/deployment/env-file.js +1 -1
  50. package/.aios-core/core/health-check/checks/deployment/index.js +1 -1
  51. package/.aios-core/core/health-check/checks/index.js +1 -1
  52. package/.aios-core/core/health-check/checks/local/disk-space.js +1 -1
  53. package/.aios-core/core/health-check/checks/local/environment-vars.js +1 -1
  54. package/.aios-core/core/health-check/checks/local/git-install.js +1 -1
  55. package/.aios-core/core/health-check/checks/local/ide-detection.js +1 -1
  56. package/.aios-core/core/health-check/checks/local/index.js +1 -1
  57. package/.aios-core/core/health-check/checks/local/memory.js +1 -1
  58. package/.aios-core/core/health-check/checks/local/network.js +1 -1
  59. package/.aios-core/core/health-check/checks/local/npm-install.js +1 -1
  60. package/.aios-core/core/health-check/checks/local/shell-environment.js +1 -1
  61. package/.aios-core/core/health-check/checks/project/agent-config.js +1 -1
  62. package/.aios-core/core/health-check/checks/project/aios-directory.js +1 -1
  63. package/.aios-core/core/health-check/checks/project/dependencies.js +1 -1
  64. package/.aios-core/core/health-check/checks/project/framework-config.js +1 -1
  65. package/.aios-core/core/health-check/checks/project/index.js +1 -1
  66. package/.aios-core/core/health-check/checks/project/node-version.js +1 -1
  67. package/.aios-core/core/health-check/checks/project/package-json.js +1 -1
  68. package/.aios-core/core/health-check/checks/project/task-definitions.js +1 -1
  69. package/.aios-core/core/health-check/checks/project/workflow-dependencies.js +1 -1
  70. package/.aios-core/core/health-check/checks/repository/branch-protection.js +1 -1
  71. package/.aios-core/core/health-check/checks/repository/commit-history.js +1 -1
  72. package/.aios-core/core/health-check/checks/repository/conflicts.js +1 -1
  73. package/.aios-core/core/health-check/checks/repository/git-repo.js +1 -1
  74. package/.aios-core/core/health-check/checks/repository/git-status.js +1 -1
  75. package/.aios-core/core/health-check/checks/repository/gitignore.js +1 -1
  76. package/.aios-core/core/health-check/checks/repository/index.js +1 -1
  77. package/.aios-core/core/health-check/checks/repository/large-files.js +1 -1
  78. package/.aios-core/core/health-check/checks/repository/lockfile-integrity.js +1 -1
  79. package/.aios-core/core/health-check/checks/services/api-endpoints.js +1 -1
  80. package/.aios-core/core/health-check/checks/services/claude-code.js +1 -1
  81. package/.aios-core/core/health-check/checks/services/gemini-cli.js +1 -1
  82. package/.aios-core/core/health-check/checks/services/github-cli.js +1 -1
  83. package/.aios-core/core/health-check/checks/services/index.js +1 -1
  84. package/.aios-core/core/health-check/checks/services/mcp-integration.js +1 -1
  85. package/.aios-core/core/health-check/engine.js +1 -1
  86. package/.aios-core/core/health-check/healers/backup-manager.js +1 -1
  87. package/.aios-core/core/health-check/healers/index.js +1 -1
  88. package/.aios-core/core/health-check/index.js +9 -2
  89. package/.aios-core/core/health-check/reporters/console.js +1 -1
  90. package/.aios-core/core/health-check/reporters/index.js +1 -1
  91. package/.aios-core/core/health-check/reporters/json.js +1 -1
  92. package/.aios-core/core/health-check/reporters/markdown.js +1 -1
  93. package/.aios-core/core/ids/layer-classifier.js +65 -0
  94. package/.aios-core/core/ids/registry-updater.js +49 -0
  95. package/.aios-core/core/index.esm.js +1 -1
  96. package/.aios-core/core/index.js +1 -1
  97. package/.aios-core/core/session/context-detector.js +2 -7
  98. package/.aios-core/core/synapse/context/context-tracker.js +9 -1
  99. package/.aios-core/core/synapse/engine.js +33 -13
  100. package/.aios-core/core/synapse/runtime/hook-runtime.js +40 -2
  101. package/.aios-core/core/synapse/session/session-manager.js +3 -2
  102. package/.aios-core/core/synapse/utils/atomic-write.js +79 -0
  103. package/.aios-core/core-config.yaml +34 -1
  104. package/.aios-core/data/aios-kb.md +2 -2
  105. package/.aios-core/data/capability-detection.js +290 -0
  106. package/.aios-core/data/entity-registry.yaml +10424 -2127
  107. package/.aios-core/data/mcp-discipline.js +166 -0
  108. package/.aios-core/data/mcp-tool-examples.yaml +215 -0
  109. package/.aios-core/data/tok2-validation.js +168 -0
  110. package/.aios-core/data/tok3-token-comparison.js +123 -0
  111. package/.aios-core/data/tool-registry.yaml +648 -0
  112. package/.aios-core/data/tool-search-validation.js +174 -0
  113. package/.aios-core/development/agents/analyst/MEMORY.md +33 -0
  114. package/.aios-core/development/agents/architect/MEMORY.md +39 -0
  115. package/.aios-core/development/agents/data-engineer/MEMORY.md +32 -0
  116. package/.aios-core/development/agents/dev/MEMORY.md +46 -0
  117. package/.aios-core/development/agents/dev.md +1 -1
  118. package/.aios-core/development/agents/devops/MEMORY.md +39 -0
  119. package/.aios-core/development/agents/devops.md +22 -0
  120. package/.aios-core/development/agents/pm/MEMORY.md +38 -0
  121. package/.aios-core/development/agents/po/MEMORY.md +45 -0
  122. package/.aios-core/development/agents/qa/MEMORY.md +42 -0
  123. package/.aios-core/development/agents/qa.md +1 -1
  124. package/.aios-core/development/agents/sm/MEMORY.md +31 -0
  125. package/.aios-core/development/agents/ux/MEMORY.md +31 -0
  126. package/.aios-core/development/checklists/issue-triage-checklist.md +35 -0
  127. package/.aios-core/development/checklists/memory-audit-checklist.md +53 -0
  128. package/.aios-core/development/scripts/issue-triage.js +171 -0
  129. package/.aios-core/development/scripts/populate-entity-registry.js +412 -19
  130. package/.aios-core/development/scripts/unified-activation-pipeline.js +31 -10
  131. package/.aios-core/development/tasks/analyze-project-structure.md +48 -0
  132. package/.aios-core/development/tasks/brownfield-create-epic.md +41 -0
  133. package/.aios-core/development/tasks/create-doc.md +44 -0
  134. package/.aios-core/development/tasks/create-next-story.md +10 -0
  135. package/.aios-core/development/tasks/dev-develop-story.md +1 -1
  136. package/.aios-core/development/tasks/github-devops-github-pr-automation.md +49 -0
  137. package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +63 -0
  138. package/.aios-core/development/tasks/github-issue-triage.md +118 -0
  139. package/.aios-core/development/tasks/health-check.yaml +206 -171
  140. package/.aios-core/development/tasks/kb-mode-interaction.md +3 -3
  141. package/.aios-core/development/tasks/plan-create-context.md +47 -1
  142. package/.aios-core/development/tasks/plan-create-implementation.md +55 -0
  143. package/.aios-core/development/tasks/pr-automation.md +5 -5
  144. package/.aios-core/development/tasks/qa-gate.md +48 -0
  145. package/.aios-core/development/tasks/qa-review-story.md +24 -1
  146. package/.aios-core/development/tasks/resolve-github-issue.md +608 -0
  147. package/.aios-core/development/tasks/review-contributor-pr.md +152 -0
  148. package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
  149. package/.aios-core/development/tasks/spec-research-dependencies.md +4 -0
  150. package/.aios-core/development/tasks/triage-github-issues.md +356 -0
  151. package/.aios-core/development/tasks/validate-agents.md +4 -0
  152. package/.aios-core/development/tasks/validate-next-story.md +10 -0
  153. package/.aios-core/development/templates/agent-handoff-tmpl.yaml +48 -0
  154. package/.aios-core/development/templates/code-intel-integration-pattern.md +199 -0
  155. package/.aios-core/development/templates/ptc-entity-validation.md +113 -0
  156. package/.aios-core/development/templates/ptc-qa-gate.md +100 -0
  157. package/.aios-core/development/templates/ptc-research-aggregation.md +94 -0
  158. package/.aios-core/development/templates/service-template/README.md.hbs +158 -158
  159. package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -237
  160. package/.aios-core/development/templates/service-template/client.ts.hbs +403 -403
  161. package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -182
  162. package/.aios-core/development/templates/service-template/index.ts.hbs +120 -120
  163. package/.aios-core/development/templates/service-template/package.json.hbs +87 -87
  164. package/.aios-core/development/templates/service-template/types.ts.hbs +145 -145
  165. package/.aios-core/development/templates/squad/agent-template.md +11 -0
  166. package/.aios-core/development/templates/squad/task-template.md +21 -0
  167. package/.aios-core/development/templates/squad-template/LICENSE +21 -21
  168. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +1 -1
  169. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1 -1
  170. package/.aios-core/framework-config.yaml +8 -0
  171. package/.aios-core/index.esm.js +1 -1
  172. package/.aios-core/index.js +1 -1
  173. package/.aios-core/infrastructure/integrations/ai-providers/index.js +1 -1
  174. package/.aios-core/infrastructure/schemas/task-v3-schema.json +6 -0
  175. package/.aios-core/infrastructure/scripts/collect-tool-usage.js +311 -0
  176. package/.aios-core/infrastructure/scripts/generate-optimization-report.js +497 -0
  177. package/.aios-core/infrastructure/scripts/generate-settings-json.js +300 -0
  178. package/.aios-core/infrastructure/scripts/git-config-detector.js +65 -9
  179. package/.aios-core/infrastructure/scripts/ide-sync/index.js +3 -1
  180. package/.aios-core/infrastructure/scripts/ide-sync/transformers/github-copilot.js +184 -0
  181. package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
  182. package/.aios-core/infrastructure/templates/aios-sync.yaml.template +182 -182
  183. package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
  184. package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
  185. package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
  186. package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
  187. package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
  188. package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
  189. package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
  190. package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
  191. package/.aios-core/install-manifest.yaml +541 -249
  192. package/.aios-core/lib/build.json +1 -0
  193. package/.aios-core/local-config.yaml.template +71 -71
  194. package/.aios-core/monitor/hooks/lib/__init__.py +1 -1
  195. package/.aios-core/monitor/hooks/lib/enrich.py +58 -58
  196. package/.aios-core/monitor/hooks/lib/send_event.py +47 -47
  197. package/.aios-core/monitor/hooks/notification.py +29 -29
  198. package/.aios-core/monitor/hooks/post_tool_use.py +45 -45
  199. package/.aios-core/monitor/hooks/pre_compact.py +29 -29
  200. package/.aios-core/monitor/hooks/pre_tool_use.py +40 -40
  201. package/.aios-core/monitor/hooks/stop.py +29 -29
  202. package/.aios-core/monitor/hooks/subagent_stop.py +29 -29
  203. package/.aios-core/monitor/hooks/user_prompt_submit.py +38 -38
  204. package/.aios-core/product/templates/adr.hbs +125 -125
  205. package/.aios-core/product/templates/dbdr.hbs +241 -241
  206. package/.aios-core/product/templates/epic.hbs +212 -212
  207. package/.aios-core/product/templates/ide-rules/claude-rules.md +77 -0
  208. package/.aios-core/product/templates/pmdr.hbs +186 -186
  209. package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
  210. package/.aios-core/product/templates/prd.hbs +201 -201
  211. package/.aios-core/product/templates/story.hbs +263 -263
  212. package/.aios-core/product/templates/task.hbs +170 -170
  213. package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
  214. package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
  215. package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
  216. package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
  217. package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
  218. package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
  219. package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
  220. package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
  221. package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
  222. package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
  223. package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
  224. package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
  225. package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
  226. package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
  227. package/.aios-core/product/templates/tmpl-view.sql +177 -177
  228. package/.aios-core/scripts/pm.sh +0 -0
  229. package/.aios-core/user-guide.md +15 -15
  230. package/.aios-core/utils/filters/constants.js +10 -0
  231. package/.aios-core/utils/filters/content-filter.js +223 -0
  232. package/.aios-core/utils/filters/field-filter.js +126 -0
  233. package/.aios-core/utils/filters/index.js +180 -0
  234. package/.aios-core/utils/filters/schema-filter.js +157 -0
  235. package/.claude/CLAUDE.md +62 -0
  236. package/.claude/hooks/enforce-architecture-first.py +196 -196
  237. package/.claude/hooks/enforce-git-push-authority.sh +33 -0
  238. package/.claude/hooks/mind-clone-governance.py +192 -192
  239. package/.claude/hooks/read-protection.py +151 -151
  240. package/.claude/hooks/slug-validation.py +176 -176
  241. package/.claude/hooks/sql-governance.py +182 -182
  242. package/.claude/hooks/synapse-engine.cjs +28 -5
  243. package/.claude/hooks/write-path-validation.py +194 -194
  244. package/.claude/rules/agent-authority.md +105 -0
  245. package/.claude/rules/agent-handoff.md +97 -0
  246. package/.claude/rules/agent-memory-imports.md +15 -0
  247. package/.claude/rules/coderabbit-integration.md +101 -0
  248. package/.claude/rules/ids-principles.md +119 -0
  249. package/.claude/rules/story-lifecycle.md +145 -0
  250. package/.claude/rules/tool-examples.md +64 -0
  251. package/.claude/rules/tool-response-filtering.md +57 -0
  252. package/.claude/rules/workflow-execution.md +150 -0
  253. package/LICENSE +33 -33
  254. package/bin/aios-graph.js +9 -0
  255. package/bin/aios-init.js +2 -2
  256. package/bin/aios-minimal.js +0 -0
  257. package/bin/aios.js +17 -221
  258. package/bin/utils/detect-fsmonitor.js +70 -0
  259. package/bin/utils/framework-guard.js +238 -0
  260. package/bin/utils/validate-publish.js +108 -0
  261. package/package.json +6 -3
  262. package/packages/aios-install/bin/aios-install.js +0 -0
  263. package/packages/aios-install/bin/edmcp.js +0 -0
  264. package/packages/aios-pro-cli/bin/aios-pro.js +2 -0
  265. package/packages/installer/src/installer/brownfield-upgrader.js +68 -5
  266. package/packages/installer/src/merger/index.js +3 -0
  267. package/packages/installer/src/merger/strategies/index.js +6 -0
  268. package/packages/installer/src/merger/strategies/yaml-merger.js +181 -0
  269. package/packages/installer/src/updater/index.js +4 -4
  270. package/packages/installer/src/wizard/i18n.js +321 -3
  271. package/packages/installer/src/wizard/ide-config-generator.js +152 -25
  272. package/packages/installer/src/wizard/index.js +119 -1
  273. package/packages/installer/src/wizard/pro-setup.js +137 -121
  274. package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +261 -0
  275. package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +192 -0
  276. package/packages/installer/tests/unit/doctor/doctor-checks.test.js +551 -0
  277. package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +134 -0
  278. package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +186 -0
  279. package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +309 -0
  280. package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +230 -0
  281. package/packages/installer/tests/unit/merger/strategies.test.js +2 -2
  282. package/packages/installer/tests/unit/merger/yaml-merger.test.js +327 -0
  283. package/scripts/check-markdown-links.py +352 -352
  284. package/scripts/dashboard-parallel-dev.sh +0 -0
  285. package/scripts/dashboard-parallel-phase3.sh +0 -0
  286. package/scripts/dashboard-parallel-phase4.sh +0 -0
  287. package/scripts/install-monitor-hooks.sh +0 -0
  288. package/scripts/package-synapse.js +2 -1
@@ -189,7 +189,7 @@ async function runValidation(options) {
189
189
  const possibleSources = [
190
190
  path.join(__dirname, '../../../../..'), // npm package root
191
191
  path.join(projectRoot, 'node_modules/aios-core'),
192
- path.join(projectRoot, 'node_modules/@synkra/aios-core'),
192
+ path.join(projectRoot, 'node_modules/aios-core'),
193
193
  ];
194
194
 
195
195
  for (const src of possibleSources) {
@@ -0,0 +1,183 @@
1
+ 'use strict';
2
+
3
+ const { getEnricher, getClient, isCodeIntelAvailable } = require('../index');
4
+
5
+ /**
6
+ * CreationHelper — Code intelligence helper for squad-creator and artefact creation tasks.
7
+ *
8
+ * All functions return null gracefully when no provider is available.
9
+ * Never throws — safe to call unconditionally in task workflows.
10
+ *
11
+ * Functions:
12
+ * - getCodebaseContext(targetPath) — project structure + conventions for agent creation
13
+ * - checkDuplicateArtefact(name, description) — duplicate detection before artefact creation
14
+ * - enrichRegistryEntry(entityName, entityPath) — pre-populate usedBy/dependencies for entity registry
15
+ */
16
+
17
+ /**
18
+ * Get codebase context for enriching agent/artefact creation.
19
+ * Combines describeProject + getConventions to provide full awareness.
20
+ * Used by squad-creator when creating new agents — advisory, never blocks creation.
21
+ *
22
+ * @param {string} [targetPath='.'] - Path to analyze
23
+ * @returns {Promise<{project: Object, conventions: Object}|null>} Codebase context or null
24
+ */
25
+ async function getCodebaseContext(targetPath) {
26
+ const path = targetPath || '.';
27
+ if (!isCodeIntelAvailable()) return null;
28
+
29
+ try {
30
+ const enricher = getEnricher();
31
+
32
+ // Per-capability try/catch — partial results accepted
33
+ let project = null;
34
+ let conventions = null;
35
+
36
+ try {
37
+ project = await enricher.describeProject(path);
38
+ } catch { /* skip — partial result ok */ }
39
+
40
+ try {
41
+ conventions = await enricher.getConventions(path);
42
+ } catch { /* skip — partial result ok */ }
43
+
44
+ // Return null only if we got nothing at all
45
+ if (!project && !conventions) return null;
46
+
47
+ return {
48
+ project,
49
+ conventions,
50
+ };
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Check for duplicate artefacts before creating a new one.
58
+ * Combines detectDuplicates + findReferences for comprehensive detection.
59
+ * Used by task creation workflows — returns advisory warning, never blocks.
60
+ *
61
+ * @param {string} name - Name of the artefact to create
62
+ * @param {string} description - Description of the artefact
63
+ * @returns {Promise<{duplicates: Array, references: Array, warning: string}|null>} Duplicate info or null
64
+ */
65
+ async function checkDuplicateArtefact(name, description) {
66
+ if (!name && !description) return null;
67
+ if (!isCodeIntelAvailable()) return null;
68
+
69
+ try {
70
+ const enricher = getEnricher();
71
+ const client = getClient();
72
+
73
+ // Per-capability try/catch — partial results accepted
74
+ let dupes = null;
75
+ let refs = null;
76
+
77
+ try {
78
+ const searchText = description || name;
79
+ dupes = await enricher.detectDuplicates(searchText, { path: '.' });
80
+ } catch { /* skip — partial result ok */ }
81
+
82
+ try {
83
+ refs = await client.findReferences(name);
84
+ } catch { /* skip — partial result ok */ }
85
+
86
+ const hasMatches = (dupes && dupes.matches && dupes.matches.length > 0) ||
87
+ (refs && refs.length > 0);
88
+
89
+ if (!hasMatches) return null;
90
+
91
+ return {
92
+ duplicates: dupes ? (dupes.matches || []) : [],
93
+ references: refs || [],
94
+ warning: _formatDuplicateWarning(name, dupes, refs),
95
+ };
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Enrich an entity registry entry with real dependency data.
103
+ * Combines findReferences + analyzeDependencies to pre-populate usedBy/dependencies.
104
+ * Used during entity auto-registration — advisory, registry works without it.
105
+ *
106
+ * @param {string} entityName - Name of the entity being registered
107
+ * @param {string} entityPath - File path of the entity
108
+ * @returns {Promise<{usedBy: Array, dependencies: Object}|null>} Registry enrichment data or null
109
+ */
110
+ async function enrichRegistryEntry(entityName, entityPath) {
111
+ if (!entityName && !entityPath) return null;
112
+ if (!isCodeIntelAvailable()) return null;
113
+
114
+ try {
115
+ const client = getClient();
116
+
117
+ // Per-capability try/catch — partial results accepted
118
+ let usedBy = null;
119
+ let dependencies = null;
120
+
121
+ try {
122
+ const refs = await client.findReferences(entityName);
123
+ if (refs && refs.length > 0) {
124
+ usedBy = refs.map((ref) => ref.file).filter(Boolean);
125
+ // Deduplicate
126
+ usedBy = [...new Set(usedBy)];
127
+ }
128
+ } catch { /* skip — partial result ok */ }
129
+
130
+ try {
131
+ if (entityPath) {
132
+ const deps = await client.analyzeDependencies(entityPath);
133
+ if (deps) {
134
+ dependencies = deps;
135
+ }
136
+ }
137
+ } catch { /* skip — partial result ok */ }
138
+
139
+ // Return null only if we got nothing at all
140
+ if (!usedBy && !dependencies) return null;
141
+
142
+ return {
143
+ usedBy: usedBy || [],
144
+ dependencies: dependencies || { nodes: [], edges: [] },
145
+ };
146
+ } catch {
147
+ return null;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Format a human-readable duplicate warning message.
153
+ * @param {string} name - Artefact name
154
+ * @param {Object|null} dupes - Result from detectDuplicates
155
+ * @param {Array|null} refs - Result from findReferences
156
+ * @returns {string} Formatted warning message
157
+ * @private
158
+ */
159
+ function _formatDuplicateWarning(name, dupes, refs) {
160
+ const parts = [];
161
+
162
+ if (dupes && dupes.matches && dupes.matches.length > 0) {
163
+ const firstMatch = dupes.matches[0];
164
+ const location = firstMatch.file || firstMatch.path || 'unknown';
165
+ parts.push(`Similar artefact exists: ${location}`);
166
+ }
167
+
168
+ if (refs && refs.length > 0) {
169
+ parts.push(`"${name}" already referenced in ${refs.length} location(s)`);
170
+ }
171
+
172
+ parts.push('Consider extending instead of creating new (IDS Article IV-A)');
173
+
174
+ return parts.join('. ') + '.';
175
+ }
176
+
177
+ module.exports = {
178
+ getCodebaseContext,
179
+ checkDuplicateArtefact,
180
+ enrichRegistryEntry,
181
+ // Exposed for testing
182
+ _formatDuplicateWarning,
183
+ };
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ const { getEnricher, isCodeIntelAvailable } = require('../index');
4
+
5
+ /**
6
+ * DevOpsHelper — Code intelligence helper for @devops agent tasks.
7
+ *
8
+ * All functions return null gracefully when no provider is available.
9
+ * Never throws — safe to call unconditionally in task workflows.
10
+ *
11
+ * Functions:
12
+ * - assessPrePushImpact(files) — for @devops pre-push quality gate (blast radius + risk)
13
+ * - generateImpactSummary(files) — for @devops PR automation (impact summary for PR description)
14
+ * - classifyRiskLevel(blastRadius) — pure logic risk classification (LOW/MEDIUM/HIGH)
15
+ * - _formatImpactReport(impact, riskLevel) — private formatting helper
16
+ */
17
+
18
+ /**
19
+ * Assess impact of changed files for the pre-push quality gate.
20
+ * Used by @devops during *pre-push — returns blast radius, risk level, and formatted report.
21
+ *
22
+ * @param {string[]} files - Array of changed file paths
23
+ * @returns {Promise<{impact: Object, riskLevel: string, report: string}|null>} Impact analysis or null
24
+ */
25
+ async function assessPrePushImpact(files) {
26
+ if (!files || files.length === 0) return null;
27
+ if (!isCodeIntelAvailable()) return null;
28
+
29
+ try {
30
+ const enricher = getEnricher();
31
+ const impact = await enricher.assessImpact(files);
32
+
33
+ if (!impact) {
34
+ return {
35
+ impact: null,
36
+ riskLevel: 'LOW',
37
+ report: _formatImpactReport(null, 'LOW'),
38
+ };
39
+ }
40
+
41
+ const riskLevel = classifyRiskLevel(impact.blastRadius);
42
+
43
+ return {
44
+ impact,
45
+ riskLevel,
46
+ report: _formatImpactReport(impact, riskLevel),
47
+ };
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Generate an impact summary for PR description enrichment.
55
+ * Composes assessImpact + findTests to provide summary text and test coverage info.
56
+ * Used by @devops during *create-pr — returns summary for PR body.
57
+ *
58
+ * @param {string[]} files - Array of changed file paths
59
+ * @returns {Promise<{summary: string, testCoverage: Array|null}|null>} Impact summary or null
60
+ */
61
+ async function generateImpactSummary(files) {
62
+ if (!files || files.length === 0) return null;
63
+ if (!isCodeIntelAvailable()) return null;
64
+
65
+ try {
66
+ const enricher = getEnricher();
67
+ const impact = await enricher.assessImpact(files);
68
+
69
+ if (!impact) return null;
70
+
71
+ // Per-capability try/catch — partial results accepted
72
+ let testCoverage = null;
73
+ try {
74
+ const tests = await enricher.findTests(files[0]);
75
+ if (tests) {
76
+ testCoverage = tests;
77
+ }
78
+ } catch { /* skip — partial result ok */ }
79
+
80
+ const riskLevel = classifyRiskLevel(impact.blastRadius);
81
+ const fileCount = impact.references ? impact.references.length : 0;
82
+ const topFiles = (impact.references || [])
83
+ .map((r) => r.file || r.path || 'unknown')
84
+ .slice(0, 10);
85
+
86
+ const summaryLines = [
87
+ `**Blast Radius:** ${impact.blastRadius} files affected`,
88
+ `**Risk Level:** ${riskLevel}`,
89
+ `**Avg Complexity:** ${impact.complexity ? impact.complexity.average.toFixed(1) : 'N/A'}`,
90
+ ];
91
+
92
+ if (topFiles.length > 0) {
93
+ summaryLines.push('', '**Affected Files:**');
94
+ topFiles.forEach((f) => summaryLines.push(`- ${f}`));
95
+ }
96
+
97
+ if (testCoverage && testCoverage.length > 0) {
98
+ summaryLines.push('', `**Related Tests:** ${testCoverage.length} test file(s) found`);
99
+ } else {
100
+ summaryLines.push('', '**Related Tests:** No related tests found');
101
+ }
102
+
103
+ return {
104
+ summary: summaryLines.join('\n'),
105
+ testCoverage,
106
+ };
107
+ } catch {
108
+ return null;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Classify risk level based on blast radius count.
114
+ * Pure logic function — no provider dependency.
115
+ *
116
+ * @param {number} blastRadius - Number of affected files
117
+ * @returns {string} 'LOW' | 'MEDIUM' | 'HIGH'
118
+ */
119
+ function classifyRiskLevel(blastRadius) {
120
+ if (!blastRadius || blastRadius <= 5) return 'LOW';
121
+ if (blastRadius <= 15) return 'MEDIUM';
122
+ return 'HIGH';
123
+ }
124
+
125
+ /**
126
+ * Format a human-readable impact report for pre-push output.
127
+ * @param {Object|null} impact - Impact analysis result from enricher.assessImpact
128
+ * @param {string} riskLevel - Risk level classification
129
+ * @returns {string} Formatted report string
130
+ * @private
131
+ */
132
+ function _formatImpactReport(impact, riskLevel) {
133
+ if (!impact) {
134
+ return '📊 Impact Analysis: No impact data available (code intelligence returned empty result)';
135
+ }
136
+
137
+ const lines = [
138
+ '📊 Impact Analysis:',
139
+ ` Blast Radius: ${impact.blastRadius} files affected`,
140
+ ` Risk Level: ${riskLevel}`,
141
+ ` Avg Complexity: ${impact.complexity ? impact.complexity.average.toFixed(1) : 'N/A'}`,
142
+ ];
143
+
144
+ const topFiles = (impact.references || [])
145
+ .map((r) => r.file || r.path || 'unknown')
146
+ .slice(0, 10);
147
+
148
+ if (topFiles.length > 0) {
149
+ lines.push(' Top affected files:');
150
+ topFiles.forEach((f) => lines.push(` - ${f}`));
151
+ }
152
+
153
+ if (riskLevel === 'HIGH') {
154
+ lines.push('', ` ⚠️ HIGH RISK: ${impact.blastRadius} files affected. Confirm push?`);
155
+ }
156
+
157
+ return lines.join('\n');
158
+ }
159
+
160
+ module.exports = {
161
+ assessPrePushImpact,
162
+ generateImpactSummary,
163
+ classifyRiskLevel,
164
+ // Exposed for testing
165
+ _formatImpactReport,
166
+ };
@@ -0,0 +1,248 @@
1
+ 'use strict';
2
+
3
+ const { getEnricher, getClient, isCodeIntelAvailable } = require('../index');
4
+
5
+ // Risk level thresholds based on blast radius (reference count)
6
+ // Consistent with dev-helper.js and qa-helper.js
7
+ const RISK_THRESHOLDS = {
8
+ LOW_MAX: 4, // 0-4 refs = LOW
9
+ MEDIUM_MAX: 15, // 5-15 refs = MEDIUM
10
+ // >15 refs = HIGH
11
+ };
12
+
13
+ /**
14
+ * PlanningHelper — Code intelligence helper for @pm/@architect agent tasks.
15
+ *
16
+ * All functions return null gracefully when no provider is available.
17
+ * Never throws — safe to call unconditionally in task workflows.
18
+ */
19
+
20
+ /**
21
+ * Get codebase overview with project description and statistics.
22
+ * Used by brownfield-create-epic and create-doc for Codebase Intelligence section.
23
+ *
24
+ * @param {string} path - Path to analyze
25
+ * @returns {Promise<{codebase: Object, stats: Object}|null>}
26
+ */
27
+ async function getCodebaseOverview(path) {
28
+ if (!path) return null;
29
+ if (!isCodeIntelAvailable()) return null;
30
+
31
+ try {
32
+ const enricher = getEnricher();
33
+ const project = await enricher.describeProject(path);
34
+
35
+ if (!project) return null;
36
+
37
+ return {
38
+ codebase: project.codebase || null,
39
+ stats: project.stats || null,
40
+ };
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Get dependency graph summary for a path.
48
+ * Used by brownfield-create-epic and analyze-project-structure for dependency analysis.
49
+ *
50
+ * @param {string} path - Path to analyze dependencies for
51
+ * @returns {Promise<{dependencies: Object, summary: {totalDeps: number, depth: string}}|null>}
52
+ */
53
+ async function getDependencyGraph(path) {
54
+ if (!path) return null;
55
+ if (!isCodeIntelAvailable()) return null;
56
+
57
+ try {
58
+ const client = getClient();
59
+ const deps = await client.analyzeDependencies(path);
60
+
61
+ if (!deps) return null;
62
+
63
+ return {
64
+ dependencies: deps,
65
+ summary: _buildDependencySummary(deps),
66
+ };
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Get complexity analysis for a set of files.
74
+ * Used by analyze-project-structure for complexity metrics per file.
75
+ *
76
+ * @param {string[]} files - Files to analyze complexity for
77
+ * @returns {Promise<{perFile: Array<{file: string, complexity: Object}>, average: number}|null>}
78
+ */
79
+ async function getComplexityAnalysis(files) {
80
+ if (!files || files.length === 0) return null;
81
+ if (!isCodeIntelAvailable()) return null;
82
+
83
+ try {
84
+ const client = getClient();
85
+ const results = await Promise.all(
86
+ files.map(async (file) => {
87
+ try {
88
+ const complexity = await client.analyzeComplexity(file);
89
+ return {
90
+ file,
91
+ complexity: complexity || null,
92
+ };
93
+ } catch {
94
+ return {
95
+ file,
96
+ complexity: null,
97
+ };
98
+ }
99
+ }),
100
+ );
101
+
102
+ const validResults = results.filter((r) => r.complexity !== null);
103
+ const scores = validResults
104
+ .map((r) => r.complexity && typeof r.complexity.score === 'number' ? r.complexity.score : null)
105
+ .filter((s) => s !== null);
106
+ const average = scores.length > 0
107
+ ? scores.reduce((sum, s) => sum + s, 0) / scores.length
108
+ : 0;
109
+
110
+ return {
111
+ perFile: results,
112
+ average,
113
+ };
114
+ } catch {
115
+ return null;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Get implementation context for a set of symbols.
121
+ * Composes findDefinition + analyzeDependencies + findTests for each symbol.
122
+ * Used by plan-create-context for precise implementation context.
123
+ *
124
+ * @param {string[]} symbols - Symbol names to get context for
125
+ * @returns {Promise<{definitions: Array, dependencies: Array, relatedTests: Array}|null>}
126
+ */
127
+ async function getImplementationContext(symbols) {
128
+ if (!symbols || symbols.length === 0) return null;
129
+ if (!isCodeIntelAvailable()) return null;
130
+
131
+ try {
132
+ const client = getClient();
133
+ const enricher = getEnricher();
134
+
135
+ const definitions = [];
136
+ const dependencies = [];
137
+ const relatedTests = [];
138
+
139
+ await Promise.all(
140
+ symbols.map(async (symbol) => {
141
+ // Per-item try/catch — partial results accepted
142
+ try {
143
+ const def = await client.findDefinition(symbol);
144
+ if (def) definitions.push({ symbol, ...def });
145
+ } catch { /* skip */ }
146
+
147
+ try {
148
+ const deps = await client.analyzeDependencies(symbol);
149
+ if (deps) dependencies.push({ symbol, deps });
150
+ } catch { /* skip */ }
151
+
152
+ try {
153
+ const tests = await enricher.findTests(symbol);
154
+ if (tests) relatedTests.push({ symbol, tests });
155
+ } catch { /* skip */ }
156
+ }),
157
+ );
158
+
159
+ return {
160
+ definitions,
161
+ dependencies,
162
+ relatedTests,
163
+ };
164
+ } catch {
165
+ return null;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Get implementation impact analysis for a set of files.
171
+ * Used by plan-create-implementation for blast radius and risk assessment.
172
+ *
173
+ * @param {string[]} files - Files to assess impact for
174
+ * @returns {Promise<{blastRadius: number, riskLevel: string, references: Array}|null>}
175
+ */
176
+ async function getImplementationImpact(files) {
177
+ if (!files || files.length === 0) return null;
178
+ if (!isCodeIntelAvailable()) return null;
179
+
180
+ try {
181
+ const enricher = getEnricher();
182
+ const impact = await enricher.assessImpact(files);
183
+
184
+ if (!impact) return null;
185
+
186
+ return {
187
+ blastRadius: impact.blastRadius,
188
+ riskLevel: _calculateRiskLevel(impact.blastRadius),
189
+ references: impact.references || [],
190
+ };
191
+ } catch {
192
+ return null;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Build a summary from dependency analysis results.
198
+ * @param {Object} deps - Raw dependency graph from analyzeDependencies
199
+ * @returns {{totalDeps: number, depth: string}}
200
+ * @private
201
+ */
202
+ function _buildDependencySummary(deps) {
203
+ if (!deps) return { totalDeps: 0, depth: 'none' };
204
+
205
+ // Handle various shapes of dependency data
206
+ let totalDeps = 0;
207
+ if (Array.isArray(deps)) {
208
+ totalDeps = deps.length;
209
+ } else if (deps.dependencies && Array.isArray(deps.dependencies)) {
210
+ totalDeps = deps.dependencies.length;
211
+ } else if (typeof deps === 'object') {
212
+ totalDeps = Object.keys(deps).length;
213
+ }
214
+
215
+ let depth = 'shallow';
216
+ if (totalDeps > RISK_THRESHOLDS.MEDIUM_MAX) {
217
+ depth = 'deep';
218
+ } else if (totalDeps > RISK_THRESHOLDS.LOW_MAX) {
219
+ depth = 'moderate';
220
+ }
221
+
222
+ return { totalDeps, depth };
223
+ }
224
+
225
+ /**
226
+ * Calculate risk level from blast radius count.
227
+ * Consistent with dev-helper.js and qa-helper.js thresholds.
228
+ * @param {number} blastRadius - Number of references affected
229
+ * @returns {string} 'LOW' | 'MEDIUM' | 'HIGH'
230
+ * @private
231
+ */
232
+ function _calculateRiskLevel(blastRadius) {
233
+ if (blastRadius <= RISK_THRESHOLDS.LOW_MAX) return 'LOW';
234
+ if (blastRadius <= RISK_THRESHOLDS.MEDIUM_MAX) return 'MEDIUM';
235
+ return 'HIGH';
236
+ }
237
+
238
+ module.exports = {
239
+ getCodebaseOverview,
240
+ getDependencyGraph,
241
+ getComplexityAnalysis,
242
+ getImplementationContext,
243
+ getImplementationImpact,
244
+ // Exposed for testing
245
+ _buildDependencySummary,
246
+ _calculateRiskLevel,
247
+ RISK_THRESHOLDS,
248
+ };