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
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Doctor Check: settings.json
3
+ *
4
+ * Validates .claude/settings.json exists, deny rules count >= 40,
5
+ * and compares against core-config.yaml boundary paths.
6
+ *
7
+ * @module aios-core/doctor/checks/settings-json
8
+ * @story INS-4.1
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+
14
+ const name = 'settings-json';
15
+
16
+ /**
17
+ * Checks that core-config.yaml boundary.protected paths are covered by deny rules.
18
+ * Returns array of unprotected boundary paths.
19
+ */
20
+ function checkBoundaryAlignment(context, denyRules) {
21
+ const configPath = path.join(context.projectRoot, '.aios-core', 'core-config.yaml');
22
+ if (!fs.existsSync(configPath)) return []; // No config = skip boundary check
23
+
24
+ let content;
25
+ try {
26
+ content = fs.readFileSync(configPath, 'utf8');
27
+ } catch {
28
+ return [];
29
+ }
30
+
31
+ // Extract boundary.protected paths from YAML (simple line parsing)
32
+ const lines = content.split('\n');
33
+ const protectedPaths = [];
34
+ let inProtected = false;
35
+
36
+ for (const line of lines) {
37
+ if (/^\s+protected:\s*$/.test(line)) {
38
+ inProtected = true;
39
+ continue;
40
+ }
41
+ if (inProtected) {
42
+ const match = line.match(/^\s+-\s+(.+)$/);
43
+ if (match) {
44
+ protectedPaths.push(match[1].trim());
45
+ } else if (/^\s+\w/.test(line) && !line.match(/^\s+-/)) {
46
+ inProtected = false;
47
+ }
48
+ }
49
+ }
50
+
51
+ if (protectedPaths.length === 0) return [];
52
+
53
+ // Check each boundary path has at least one matching deny rule
54
+ const denyStr = denyRules.join('\n');
55
+ const unprotected = protectedPaths.filter((bp) => {
56
+ // Strip glob suffixes for base path matching
57
+ const basePath = bp.replace(/\/\*\*$/, '').replace(/\/\*$/, '');
58
+ return !denyStr.includes(basePath);
59
+ });
60
+
61
+ return unprotected;
62
+ }
63
+
64
+ async function run(context) {
65
+ const settingsPath = path.join(context.projectRoot, '.claude', 'settings.json');
66
+
67
+ if (!fs.existsSync(settingsPath)) {
68
+ return {
69
+ check: name,
70
+ status: 'FAIL',
71
+ message: 'settings.json not found',
72
+ fixCommand: 'npx aios-core install --force',
73
+ };
74
+ }
75
+
76
+ let settings;
77
+ try {
78
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
79
+ } catch {
80
+ return {
81
+ check: name,
82
+ status: 'FAIL',
83
+ message: 'settings.json is invalid JSON',
84
+ fixCommand: 'npx aios-core install --force',
85
+ };
86
+ }
87
+
88
+ const denyRules = settings.permissions?.deny || [];
89
+ const allowRules = settings.permissions?.allow || [];
90
+ const denyCount = denyRules.length;
91
+ const allowCount = allowRules.length;
92
+
93
+ if (denyCount < 40) {
94
+ return {
95
+ check: name,
96
+ status: 'WARN',
97
+ message: `Deny rules below threshold (${denyCount} rules, expected >= 40)`,
98
+ fixCommand: 'aios doctor --fix',
99
+ };
100
+ }
101
+
102
+ // Compare deny rules against core-config.yaml boundary.protected paths
103
+ const boundaryIssues = checkBoundaryAlignment(context, denyRules);
104
+ if (boundaryIssues.length > 0) {
105
+ return {
106
+ check: name,
107
+ status: 'WARN',
108
+ message: `Deny rules present (${denyCount}) but missing boundary coverage: ${boundaryIssues.join(', ')}`,
109
+ fixCommand: 'aios doctor --fix',
110
+ };
111
+ }
112
+
113
+ return {
114
+ check: name,
115
+ status: 'PASS',
116
+ message: `Deny rules present (${denyCount} rules, ${allowCount} allows)`,
117
+ fixCommand: null,
118
+ };
119
+ }
120
+
121
+ module.exports = { name, run };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Doctor Check: Skills Count
3
+ *
4
+ * Counts skill directories in .claude/skills/ that contain SKILL.md.
5
+ * PASS: >=7, WARN: 1-6, FAIL: 0 or directory missing.
6
+ *
7
+ * @module aios-core/doctor/checks/skills-count
8
+ * @story INS-4.8
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+
14
+ const name = 'skills-count';
15
+
16
+ async function run(context) {
17
+ const skillsDir = path.join(context.projectRoot, '.claude', 'skills');
18
+
19
+ if (!fs.existsSync(skillsDir)) {
20
+ return {
21
+ check: name,
22
+ status: 'FAIL',
23
+ message: 'Skills directory not found (.claude/skills/)',
24
+ fixCommand: 'npx aios-core install --force',
25
+ };
26
+ }
27
+
28
+ let entries;
29
+ try {
30
+ entries = fs.readdirSync(skillsDir, { withFileTypes: true });
31
+ } catch {
32
+ return {
33
+ check: name,
34
+ status: 'FAIL',
35
+ message: 'Cannot read skills directory',
36
+ fixCommand: 'npx aios-core install --force',
37
+ };
38
+ }
39
+
40
+ const skills = entries.filter(
41
+ (d) => d.isDirectory() && fs.existsSync(path.join(skillsDir, d.name, 'SKILL.md')),
42
+ );
43
+
44
+ const count = skills.length;
45
+
46
+ if (count === 0) {
47
+ return {
48
+ check: name,
49
+ status: 'FAIL',
50
+ message: 'No skills found (expected >=7)',
51
+ fixCommand: 'npx aios-core install --force',
52
+ };
53
+ }
54
+
55
+ if (count >= 7) {
56
+ return {
57
+ check: name,
58
+ status: 'PASS',
59
+ message: `${count} skills found`,
60
+ fixCommand: null,
61
+ };
62
+ }
63
+
64
+ return {
65
+ check: name,
66
+ status: 'WARN',
67
+ message: `Only ${count}/7 skills found`,
68
+ fixCommand: 'npx aios-core install --force',
69
+ };
70
+ }
71
+
72
+ module.exports = { name, run };
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Doctor Fix Handler
3
+ *
4
+ * Maps check names to fix functions. Supports --fix and --dry-run modes.
5
+ * All fix operations are idempotent.
6
+ *
7
+ * @module aios-core/doctor/fix-handler
8
+ * @story INS-4.1
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+
14
+ const { EXPECTED_RULES } = require('./checks/rules-files');
15
+ const { EXPECTED_AGENTS } = require('./checks/agent-memory');
16
+
17
+ /**
18
+ * Apply fixes for WARN/FAIL results
19
+ *
20
+ * @param {Array} results - Check results
21
+ * @param {Object} context - Doctor context
22
+ * @returns {Array} Fix results
23
+ */
24
+ async function applyFixes(results, context) {
25
+ const { projectRoot, frameworkRoot, options } = context;
26
+ const { dryRun = false } = options;
27
+ const fixResults = [];
28
+
29
+ for (const result of results) {
30
+ if (result.status !== 'WARN' && result.status !== 'FAIL') {
31
+ continue;
32
+ }
33
+
34
+ const fixer = FIX_MAP[result.check];
35
+ if (!fixer) {
36
+ fixResults.push({
37
+ check: result.check,
38
+ applied: false,
39
+ message: 'No auto-fix available',
40
+ });
41
+ continue;
42
+ }
43
+
44
+ try {
45
+ if (dryRun) {
46
+ const description = fixer.describe(result, { projectRoot, frameworkRoot });
47
+ fixResults.push({
48
+ check: result.check,
49
+ applied: false,
50
+ message: `[DRY RUN] Would: ${description}`,
51
+ });
52
+ } else {
53
+ const fixMessage = await fixer.apply(result, { projectRoot, frameworkRoot });
54
+ fixResults.push({
55
+ check: result.check,
56
+ applied: true,
57
+ message: fixMessage,
58
+ });
59
+ }
60
+ } catch (error) {
61
+ fixResults.push({
62
+ check: result.check,
63
+ applied: false,
64
+ message: `Fix failed: ${error.message}`,
65
+ });
66
+ }
67
+ }
68
+
69
+ return fixResults;
70
+ }
71
+
72
+ const FIX_MAP = {
73
+ 'rules-files': {
74
+ describe(result, { projectRoot, frameworkRoot }) {
75
+ const rulesSource = path.join(frameworkRoot, '.claude', 'rules');
76
+ const rulesTarget = path.join(projectRoot, '.claude', 'rules');
77
+ return `Copy missing rules from ${rulesSource} to ${rulesTarget}`;
78
+ },
79
+ async apply(result, { projectRoot, frameworkRoot }) {
80
+ const rulesSource = path.join(frameworkRoot, '.claude', 'rules');
81
+ const rulesTarget = path.join(projectRoot, '.claude', 'rules');
82
+
83
+ if (!fs.existsSync(rulesTarget)) {
84
+ fs.mkdirSync(rulesTarget, { recursive: true });
85
+ }
86
+
87
+ let copied = 0;
88
+ for (const file of EXPECTED_RULES) {
89
+ const targetFile = path.join(rulesTarget, file);
90
+ const sourceFile = path.join(rulesSource, file);
91
+
92
+ if (!fs.existsSync(targetFile) && fs.existsSync(sourceFile)) {
93
+ fs.copyFileSync(sourceFile, targetFile);
94
+ copied++;
95
+ }
96
+ }
97
+
98
+ return `Copied ${copied} missing rules files`;
99
+ },
100
+ },
101
+
102
+ 'agent-memory': {
103
+ describe() {
104
+ return 'Create missing MEMORY.md stubs for agents';
105
+ },
106
+ async apply(result, { projectRoot }) {
107
+ const agentsDir = path.join(projectRoot, '.aios-core', 'development', 'agents');
108
+ let created = 0;
109
+
110
+ for (const agent of EXPECTED_AGENTS) {
111
+ const memoryPath = path.join(agentsDir, agent, 'MEMORY.md');
112
+ const agentDir = path.join(agentsDir, agent);
113
+
114
+ if (!fs.existsSync(memoryPath)) {
115
+ if (!fs.existsSync(agentDir)) {
116
+ fs.mkdirSync(agentDir, { recursive: true });
117
+ }
118
+ fs.writeFileSync(memoryPath, `# ${agent} Agent Memory\n\n_Created by aios doctor --fix_\n`);
119
+ created++;
120
+ }
121
+ }
122
+
123
+ return `Created ${created} MEMORY.md stubs`;
124
+ },
125
+ },
126
+
127
+ 'claude-md': {
128
+ describe() {
129
+ return 'Regenerate CLAUDE.md with missing sections';
130
+ },
131
+ async apply() {
132
+ return 'CLAUDE.md regeneration requires npx aios-core install --force';
133
+ },
134
+ },
135
+
136
+ 'settings-json': {
137
+ describe() {
138
+ return 'Regenerate settings.json with boundary deny rules';
139
+ },
140
+ async apply(result, { frameworkRoot }) {
141
+ const generatorPath = path.join(
142
+ frameworkRoot,
143
+ 'packages',
144
+ 'installer',
145
+ 'src',
146
+ 'generators',
147
+ 'generate-settings-json',
148
+ );
149
+
150
+ try {
151
+ const generator = require(generatorPath);
152
+ if (typeof generator.generateSettingsJson === 'function') {
153
+ await generator.generateSettingsJson();
154
+ return 'settings.json regenerated';
155
+ }
156
+ } catch {
157
+ // Generator not available
158
+ }
159
+
160
+ return 'settings.json regeneration requires npx aios-core install --force';
161
+ },
162
+ },
163
+ };
164
+
165
+ module.exports = { applyFixes };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Doctor JSON Formatter
3
+ *
4
+ * Formats doctor results as structured JSON.
5
+ *
6
+ * @module aios-core/doctor/formatters/json
7
+ * @story INS-4.1
8
+ */
9
+
10
+ function formatJson(output) {
11
+ return JSON.stringify(output, null, 2);
12
+ }
13
+
14
+ module.exports = { formatJson };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Doctor Text Formatter
3
+ *
4
+ * Formats doctor results as human-readable text output.
5
+ *
6
+ * @module aios-core/doctor/formatters/text
7
+ * @story INS-4.1
8
+ */
9
+
10
+ const STATUS_PREFIX = {
11
+ PASS: '[PASS]',
12
+ WARN: '[WARN]',
13
+ FAIL: '[FAIL]',
14
+ INFO: '[INFO]',
15
+ };
16
+
17
+ function formatText(output, options = {}) {
18
+ const { quiet = false } = options;
19
+ const lines = [];
20
+
21
+ lines.push(`AIOS Doctor v${output.version} — Environment Health Check`);
22
+ lines.push('');
23
+
24
+ for (const result of output.checks) {
25
+ const prefix = STATUS_PREFIX[result.status] || '[????]';
26
+ lines.push(` ${prefix} ${result.check}: ${result.message}`);
27
+ }
28
+
29
+ lines.push('');
30
+ const { pass, warn, fail, info } = output.summary;
31
+ lines.push(`Summary: ${pass} PASS | ${warn} WARN | ${fail} FAIL | ${info} INFO`);
32
+
33
+ if (!quiet) {
34
+ const fixable = output.checks.filter(
35
+ (r) => (r.status === 'WARN' || r.status === 'FAIL') && r.fixCommand,
36
+ );
37
+
38
+ if (fixable.length > 0) {
39
+ lines.push('');
40
+ lines.push('Fix suggestions:');
41
+ fixable.forEach((r, i) => {
42
+ lines.push(` ${i + 1}. [${r.status}] ${r.check}: Run \`${r.fixCommand}\``);
43
+ });
44
+ }
45
+ }
46
+
47
+ if (output.fixResults) {
48
+ lines.push('');
49
+ lines.push('Fix results:');
50
+ for (const fr of output.fixResults) {
51
+ const icon = fr.applied ? '✓' : '✗';
52
+ lines.push(` ${icon} ${fr.check}: ${fr.message}`);
53
+ }
54
+ }
55
+
56
+ return lines.join('\n');
57
+ }
58
+
59
+ module.exports = { formatText };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * AIOS Doctor — Environment Health Check Orchestrator
3
+ *
4
+ * Runs 12 modular checks against the AIOS environment and returns
5
+ * structured results with optional --fix, --json, and --dry-run support.
6
+ *
7
+ * @module aios-core/doctor
8
+ * @version 2.0.0
9
+ * @story INS-4.1
10
+ */
11
+
12
+ const path = require('path');
13
+ const { loadChecks } = require('./checks');
14
+ const { formatText } = require('./formatters/text');
15
+ const { formatJson } = require('./formatters/json');
16
+ const { applyFixes } = require('./fix-handler');
17
+
18
+ const DOCTOR_VERSION = '2.0.0';
19
+
20
+ /**
21
+ * Run all doctor checks
22
+ *
23
+ * @param {Object} options
24
+ * @param {boolean} [options.fix=false] - Auto-correct fixable issues
25
+ * @param {boolean} [options.json=false] - Output as JSON
26
+ * @param {boolean} [options.dryRun=false] - Show what --fix would do
27
+ * @param {boolean} [options.quiet=false] - Minimal output
28
+ * @param {string} [options.projectRoot] - Project root (defaults to cwd)
29
+ * @returns {Promise<Object>} Doctor results
30
+ */
31
+ async function runDoctorChecks(options = {}) {
32
+ const {
33
+ fix = false,
34
+ json = false,
35
+ dryRun = false,
36
+ quiet = false,
37
+ projectRoot = process.cwd(),
38
+ } = options;
39
+
40
+ const context = {
41
+ projectRoot,
42
+ frameworkRoot: path.resolve(__dirname, '..', '..', '..'),
43
+ options: { fix, json, dryRun, quiet },
44
+ };
45
+
46
+ // Load and run all checks
47
+ const checks = loadChecks();
48
+ const results = [];
49
+
50
+ for (const checkModule of checks) {
51
+ try {
52
+ const result = await checkModule.run(context);
53
+ results.push(result);
54
+ } catch (error) {
55
+ results.push({
56
+ check: checkModule.name || 'unknown',
57
+ status: 'FAIL',
58
+ message: `Check threw error: ${error.message}`,
59
+ fixCommand: null,
60
+ });
61
+ }
62
+ }
63
+
64
+ // Apply fixes if requested
65
+ let fixResults = null;
66
+ if (fix || dryRun) {
67
+ fixResults = await applyFixes(results, context);
68
+ }
69
+
70
+ // Build summary
71
+ const summary = {
72
+ pass: results.filter((r) => r.status === 'PASS').length,
73
+ warn: results.filter((r) => r.status === 'WARN').length,
74
+ fail: results.filter((r) => r.status === 'FAIL').length,
75
+ info: results.filter((r) => r.status === 'INFO').length,
76
+ };
77
+
78
+ const output = {
79
+ version: DOCTOR_VERSION,
80
+ timestamp: new Date().toISOString(),
81
+ summary,
82
+ checks: results,
83
+ fixResults,
84
+ };
85
+
86
+ // Format output
87
+ if (json) {
88
+ return { formatted: formatJson(output), data: output };
89
+ }
90
+
91
+ return { formatted: formatText(output, { quiet }), data: output };
92
+ }
93
+
94
+ module.exports = { runDoctorChecks, DOCTOR_VERSION };