aios-core 2.1.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/.aios-core/core/README.md +229 -229
  2. package/.aios-core/core/data/agent-config-requirements.yaml +368 -368
  3. package/.aios-core/core/data/aios-kb.md +923 -923
  4. package/.aios-core/core/data/workflow-patterns.yaml +267 -267
  5. package/.aios-core/core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
  6. package/.aios-core/core/docs/component-creation-guide.md +457 -457
  7. package/.aios-core/core/docs/session-update-pattern.md +307 -307
  8. package/.aios-core/core/docs/template-syntax.md +266 -266
  9. package/.aios-core/core/docs/troubleshooting-guide.md +624 -624
  10. package/.aios-core/core/elicitation/elicitation-engine.js +1 -1
  11. package/.aios-core/core/index.esm.js +42 -42
  12. package/.aios-core/core/index.js +1 -1
  13. package/.aios-core/core/migration/migration-config.yaml +83 -83
  14. package/.aios-core/core/migration/module-mapping.yaml +89 -89
  15. package/.aios-core/core/quality-gates/layer2-pr-automation.js +1 -1
  16. package/.aios-core/core/quality-gates/quality-gate-config.yaml +86 -86
  17. package/.aios-core/core/registry/README.md +179 -179
  18. package/.aios-core/core/utils/security-utils.js +1 -1
  19. package/.aios-core/core-config.yaml +391 -382
  20. package/.aios-core/data/agent-config-requirements.yaml +368 -368
  21. package/.aios-core/data/aios-kb.md +923 -923
  22. package/.aios-core/data/technical-preferences.md +3 -3
  23. package/.aios-core/data/workflow-patterns.yaml +267 -267
  24. package/.aios-core/development/README.md +142 -142
  25. package/.aios-core/development/agent-teams/team-all.yaml +15 -15
  26. package/.aios-core/development/agent-teams/team-fullstack.yaml +18 -18
  27. package/.aios-core/development/agent-teams/team-ide-minimal.yaml +10 -10
  28. package/.aios-core/development/agent-teams/team-no-ui.yaml +13 -13
  29. package/.aios-core/development/agent-teams/team-qa-focused.yaml +155 -155
  30. package/.aios-core/development/agents/aios-master.md +339 -339
  31. package/.aios-core/development/agents/analyst.md +195 -195
  32. package/.aios-core/development/agents/architect.md +359 -359
  33. package/.aios-core/development/agents/data-engineer.md +468 -468
  34. package/.aios-core/development/agents/dev.md +390 -390
  35. package/.aios-core/development/agents/devops.md +398 -398
  36. package/.aios-core/development/agents/pm.md +198 -198
  37. package/.aios-core/development/agents/po.md +256 -256
  38. package/.aios-core/development/agents/qa.md +312 -312
  39. package/.aios-core/development/agents/sm.md +220 -220
  40. package/.aios-core/development/agents/ux-design-expert.md +451 -451
  41. package/.aios-core/development/scripts/greeting-config-cli.js +85 -85
  42. package/.aios-core/development/tasks/add-mcp.md +319 -319
  43. package/.aios-core/development/tasks/advanced-elicitation.md +318 -318
  44. package/.aios-core/development/tasks/analyst-facilitate-brainstorming.md +341 -341
  45. package/.aios-core/development/tasks/analyze-brownfield.md +456 -0
  46. package/.aios-core/development/tasks/analyze-framework.md +696 -696
  47. package/.aios-core/development/tasks/analyze-performance.md +637 -637
  48. package/.aios-core/development/tasks/apply-qa-fixes.md +340 -340
  49. package/.aios-core/development/tasks/architect-analyze-impact.md +826 -826
  50. package/.aios-core/development/tasks/audit-codebase.md +429 -429
  51. package/.aios-core/development/tasks/audit-tailwind-config.md +270 -270
  52. package/.aios-core/development/tasks/audit-utilities.md +358 -358
  53. package/.aios-core/development/tasks/bootstrap-shadcn-library.md +286 -286
  54. package/.aios-core/development/tasks/brownfield-create-epic.md +485 -485
  55. package/.aios-core/development/tasks/brownfield-create-story.md +356 -356
  56. package/.aios-core/development/tasks/build-component.md +478 -478
  57. package/.aios-core/development/tasks/calculate-roi.md +455 -455
  58. package/.aios-core/development/tasks/ci-cd-configuration.md +764 -764
  59. package/.aios-core/development/tasks/cleanup-utilities.md +670 -670
  60. package/.aios-core/development/tasks/collaborative-edit.md +1108 -1108
  61. package/.aios-core/development/tasks/compose-molecule.md +284 -284
  62. package/.aios-core/development/tasks/consolidate-patterns.md +414 -414
  63. package/.aios-core/development/tasks/correct-course.md +279 -279
  64. package/.aios-core/development/tasks/create-agent.md +321 -321
  65. package/.aios-core/development/tasks/create-brownfield-story.md +726 -726
  66. package/.aios-core/development/tasks/create-deep-research-prompt.md +498 -498
  67. package/.aios-core/development/tasks/create-doc.md +316 -316
  68. package/.aios-core/development/tasks/create-next-story.md +774 -774
  69. package/.aios-core/development/tasks/create-suite.md +283 -283
  70. package/.aios-core/development/tasks/create-task.md +371 -371
  71. package/.aios-core/development/tasks/create-workflow.md +370 -370
  72. package/.aios-core/development/tasks/db-analyze-hotpaths.md +572 -572
  73. package/.aios-core/development/tasks/db-apply-migration.md +381 -381
  74. package/.aios-core/development/tasks/db-bootstrap.md +642 -642
  75. package/.aios-core/development/tasks/db-domain-modeling.md +693 -693
  76. package/.aios-core/development/tasks/db-dry-run.md +293 -293
  77. package/.aios-core/development/tasks/db-env-check.md +260 -260
  78. package/.aios-core/development/tasks/db-expansion-pack-integration.md +663 -663
  79. package/.aios-core/development/tasks/db-explain.md +631 -631
  80. package/.aios-core/development/tasks/db-impersonate.md +495 -495
  81. package/.aios-core/development/tasks/db-load-csv.md +593 -593
  82. package/.aios-core/development/tasks/db-policy-apply.md +653 -653
  83. package/.aios-core/development/tasks/db-rls-audit.md +411 -411
  84. package/.aios-core/development/tasks/db-rollback.md +739 -739
  85. package/.aios-core/development/tasks/db-run-sql.md +613 -613
  86. package/.aios-core/development/tasks/db-schema-audit.md +1011 -1011
  87. package/.aios-core/development/tasks/db-seed.md +390 -390
  88. package/.aios-core/development/tasks/db-smoke-test.md +351 -351
  89. package/.aios-core/development/tasks/db-snapshot.md +569 -569
  90. package/.aios-core/development/tasks/db-supabase-setup.md +712 -712
  91. package/.aios-core/development/tasks/db-verify-order.md +515 -515
  92. package/.aios-core/development/tasks/deprecate-component.md +956 -956
  93. package/.aios-core/development/tasks/dev-apply-qa-fixes.md +318 -318
  94. package/.aios-core/development/tasks/dev-backlog-debt.md +469 -469
  95. package/.aios-core/development/tasks/dev-develop-story.md +846 -846
  96. package/.aios-core/development/tasks/dev-improve-code-quality.md +872 -872
  97. package/.aios-core/development/tasks/dev-optimize-performance.md +1033 -1033
  98. package/.aios-core/development/tasks/dev-suggest-refactoring.md +870 -870
  99. package/.aios-core/development/tasks/dev-validate-next-story.md +348 -348
  100. package/.aios-core/development/tasks/document-project.md +552 -552
  101. package/.aios-core/development/tasks/environment-bootstrap.md +1311 -1311
  102. package/.aios-core/development/tasks/execute-checklist.md +301 -301
  103. package/.aios-core/development/tasks/export-design-tokens-dtcg.md +274 -274
  104. package/.aios-core/development/tasks/extend-pattern.md +269 -269
  105. package/.aios-core/development/tasks/extract-tokens.md +467 -467
  106. package/.aios-core/development/tasks/facilitate-brainstorming-session.md +518 -518
  107. package/.aios-core/development/tasks/generate-ai-frontend-prompt.md +260 -260
  108. package/.aios-core/development/tasks/generate-documentation.md +284 -284
  109. package/.aios-core/development/tasks/generate-migration-strategy.md +522 -522
  110. package/.aios-core/development/tasks/generate-shock-report.md +501 -501
  111. package/.aios-core/development/tasks/github-devops-github-pr-automation.md +427 -427
  112. package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +733 -733
  113. package/.aios-core/development/tasks/github-devops-repository-cleanup.md +374 -374
  114. package/.aios-core/development/tasks/github-devops-version-management.md +483 -483
  115. package/.aios-core/development/tasks/improve-self.md +822 -822
  116. package/.aios-core/development/tasks/index-docs.md +387 -387
  117. package/.aios-core/development/tasks/init-project-status.md +506 -506
  118. package/.aios-core/development/tasks/integrate-expansion-pack.md +314 -314
  119. package/.aios-core/development/tasks/kb-mode-interaction.md +283 -283
  120. package/.aios-core/development/tasks/learn-patterns.md +900 -900
  121. package/.aios-core/development/tasks/mcp-workflow.md +437 -437
  122. package/.aios-core/development/tasks/modify-agent.md +381 -381
  123. package/.aios-core/development/tasks/modify-task.md +424 -424
  124. package/.aios-core/development/tasks/modify-workflow.md +465 -465
  125. package/.aios-core/development/tasks/po-backlog-add.md +370 -370
  126. package/.aios-core/development/tasks/po-manage-story-backlog.md +523 -523
  127. package/.aios-core/development/tasks/po-pull-story-from-clickup.md +540 -540
  128. package/.aios-core/development/tasks/po-pull-story.md +316 -316
  129. package/.aios-core/development/tasks/po-stories-index.md +351 -351
  130. package/.aios-core/development/tasks/po-sync-story-to-clickup.md +457 -457
  131. package/.aios-core/development/tasks/po-sync-story.md +303 -303
  132. package/.aios-core/development/tasks/pr-automation.md +701 -701
  133. package/.aios-core/development/tasks/propose-modification.md +842 -842
  134. package/.aios-core/development/tasks/qa-backlog-add-followup.md +425 -425
  135. package/.aios-core/development/tasks/qa-gate.md +373 -373
  136. package/.aios-core/development/tasks/qa-generate-tests.md +1174 -1174
  137. package/.aios-core/development/tasks/qa-nfr-assess.md +557 -557
  138. package/.aios-core/development/tasks/qa-review-proposal.md +1157 -1157
  139. package/.aios-core/development/tasks/qa-review-story.md +682 -682
  140. package/.aios-core/development/tasks/qa-risk-profile.md +566 -566
  141. package/.aios-core/development/tasks/qa-run-tests.md +277 -277
  142. package/.aios-core/development/tasks/qa-test-design.md +387 -387
  143. package/.aios-core/development/tasks/qa-trace-requirements.md +476 -476
  144. package/.aios-core/development/tasks/release-management.md +723 -723
  145. package/.aios-core/development/tasks/security-audit.md +554 -554
  146. package/.aios-core/development/tasks/security-scan.md +790 -790
  147. package/.aios-core/development/tasks/setup-database.md +741 -741
  148. package/.aios-core/development/tasks/setup-design-system.md +462 -462
  149. package/.aios-core/development/tasks/setup-github.md +874 -874
  150. package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
  151. package/.aios-core/development/tasks/setup-mcp-docker.md +584 -584
  152. package/.aios-core/development/tasks/setup-project-docs.md +440 -0
  153. package/.aios-core/development/tasks/shard-doc.md +537 -537
  154. package/.aios-core/development/tasks/sm-create-next-story.md +480 -480
  155. package/.aios-core/development/tasks/sync-documentation.md +864 -864
  156. package/.aios-core/development/tasks/tailwind-upgrade.md +294 -294
  157. package/.aios-core/development/tasks/test-as-user.md +621 -621
  158. package/.aios-core/development/tasks/test-validation-task.md +171 -171
  159. package/.aios-core/development/tasks/undo-last.md +346 -346
  160. package/.aios-core/development/tasks/update-manifest.md +409 -409
  161. package/.aios-core/development/tasks/ux-create-wireframe.md +617 -617
  162. package/.aios-core/development/tasks/ux-ds-scan-artifact.md +672 -672
  163. package/.aios-core/development/tasks/ux-user-research.md +559 -559
  164. package/.aios-core/development/tasks/validate-next-story.md +422 -422
  165. package/.aios-core/development/workflows/README.md +83 -83
  166. package/.aios-core/development/workflows/brownfield-fullstack.yaml +297 -297
  167. package/.aios-core/development/workflows/brownfield-service.yaml +187 -187
  168. package/.aios-core/development/workflows/brownfield-ui.yaml +197 -197
  169. package/.aios-core/development/workflows/greenfield-fullstack.yaml +333 -333
  170. package/.aios-core/development/workflows/greenfield-service.yaml +206 -206
  171. package/.aios-core/development/workflows/greenfield-ui.yaml +235 -235
  172. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
  173. package/.aios-core/docs/component-creation-guide.md +457 -457
  174. package/.aios-core/docs/session-update-pattern.md +307 -307
  175. package/.aios-core/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +572 -572
  176. package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-QUICK-REFERENCE.md +185 -185
  177. package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +354 -354
  178. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +1963 -1963
  179. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +821 -821
  180. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +1190 -1190
  181. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +439 -439
  182. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1339 -1339
  183. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +5398 -5398
  184. package/.aios-core/docs/standards/EXECUTOR-DECISION-TREE.md +697 -697
  185. package/.aios-core/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +511 -511
  186. package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +556 -556
  187. package/.aios-core/docs/standards/STANDARDS-INDEX.md +210 -210
  188. package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +550 -550
  189. package/.aios-core/docs/standards/TASK-FORMAT-SPECIFICATION-V1.md +1414 -1414
  190. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +523 -523
  191. package/.aios-core/docs/template-syntax.md +266 -266
  192. package/.aios-core/docs/troubleshooting-guide.md +624 -624
  193. package/.aios-core/index.esm.js +15 -15
  194. package/.aios-core/index.js +1 -1
  195. package/.aios-core/infrastructure/README.md +126 -126
  196. package/.aios-core/infrastructure/integrations/pm-adapters/README.md +59 -59
  197. package/.aios-core/infrastructure/scripts/approval-workflow.js +1 -1
  198. package/.aios-core/infrastructure/scripts/batch-creator.js +1 -1
  199. package/.aios-core/infrastructure/scripts/component-generator.js +3 -3
  200. package/.aios-core/infrastructure/scripts/component-metadata.js +1 -1
  201. package/.aios-core/infrastructure/scripts/component-search.js +1 -1
  202. package/.aios-core/infrastructure/scripts/coverage-analyzer.js +1 -1
  203. package/.aios-core/infrastructure/scripts/dependency-analyzer.js +1 -1
  204. package/.aios-core/infrastructure/scripts/dependency-impact-analyzer.js +1 -1
  205. package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +501 -0
  206. package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +368 -0
  207. package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +308 -0
  208. package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -0
  209. package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +312 -0
  210. package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +74 -0
  211. package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +389 -0
  212. package/.aios-core/infrastructure/scripts/framework-analyzer.js +1 -1
  213. package/.aios-core/infrastructure/scripts/improvement-engine.js +1 -1
  214. package/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +26 -13
  215. package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +127 -0
  216. package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.sh +108 -0
  217. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +71 -0
  218. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.sh +65 -0
  219. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +51 -0
  220. package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.sh +16 -0
  221. package/.aios-core/infrastructure/scripts/llm-routing/usage-tracker/index.js +549 -0
  222. package/.aios-core/infrastructure/scripts/modification-risk-assessment.js +1 -1
  223. package/.aios-core/infrastructure/scripts/performance-analyzer.js +1 -1
  224. package/.aios-core/infrastructure/scripts/pm-adapter.js +134 -134
  225. package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
  226. package/.aios-core/infrastructure/scripts/template-engine.js +1 -1
  227. package/.aios-core/infrastructure/scripts/template-validator.js +1 -1
  228. package/.aios-core/infrastructure/scripts/test-generator.js +1 -1
  229. package/.aios-core/infrastructure/scripts/test-quality-assessment.js +1 -1
  230. package/.aios-core/infrastructure/scripts/transaction-manager.js +1 -1
  231. package/.aios-core/infrastructure/scripts/usage-analytics.js +1 -1
  232. package/.aios-core/infrastructure/scripts/visual-impact-generator.js +2 -2
  233. package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +176 -0
  234. package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +127 -0
  235. package/.aios-core/infrastructure/templates/github-workflows/README.md +109 -109
  236. package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -0
  237. package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -0
  238. package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -0
  239. package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -0
  240. package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +346 -0
  241. package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +177 -0
  242. package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +267 -0
  243. package/.aios-core/infrastructure/tests/regression-suite-v2.md +621 -621
  244. package/.aios-core/infrastructure/tools/README.md +222 -222
  245. package/.aios-core/infrastructure/tools/cli/github-cli.yaml +200 -200
  246. package/.aios-core/infrastructure/tools/cli/railway-cli.yaml +260 -260
  247. package/.aios-core/infrastructure/tools/cli/supabase-cli.yaml +224 -224
  248. package/.aios-core/infrastructure/tools/local/ffmpeg.yaml +261 -261
  249. package/.aios-core/infrastructure/tools/mcp/21st-dev-magic.yaml +127 -127
  250. package/.aios-core/infrastructure/tools/mcp/browser.yaml +103 -103
  251. package/.aios-core/infrastructure/tools/mcp/clickup.yaml +534 -534
  252. package/.aios-core/infrastructure/tools/mcp/context7.yaml +78 -78
  253. package/.aios-core/infrastructure/tools/mcp/desktop-commander.yaml +180 -180
  254. package/.aios-core/infrastructure/tools/mcp/exa.yaml +103 -103
  255. package/.aios-core/infrastructure/tools/mcp/google-workspace.yaml +930 -930
  256. package/.aios-core/infrastructure/tools/mcp/n8n.yaml +551 -551
  257. package/.aios-core/infrastructure/tools/mcp/supabase.yaml +808 -808
  258. package/.aios-core/install-manifest.yaml +347 -347
  259. package/.aios-core/product/README.md +56 -56
  260. package/.aios-core/product/checklists/accessibility-wcag-checklist.md +80 -0
  261. package/.aios-core/product/checklists/architect-checklist.md +443 -443
  262. package/.aios-core/product/checklists/change-checklist.md +182 -182
  263. package/.aios-core/product/checklists/component-quality-checklist.md +74 -0
  264. package/.aios-core/product/checklists/database-design-checklist.md +119 -119
  265. package/.aios-core/product/checklists/dba-predeploy-checklist.md +97 -97
  266. package/.aios-core/product/checklists/dba-rollback-checklist.md +99 -99
  267. package/.aios-core/product/checklists/migration-readiness-checklist.md +75 -0
  268. package/.aios-core/product/checklists/pattern-audit-checklist.md +88 -0
  269. package/.aios-core/product/checklists/pm-checklist.md +375 -375
  270. package/.aios-core/product/checklists/po-master-checklist.md +441 -441
  271. package/.aios-core/product/checklists/pre-push-checklist.md +108 -108
  272. package/.aios-core/product/checklists/release-checklist.md +122 -122
  273. package/.aios-core/product/checklists/story-dod-checklist.md +101 -101
  274. package/.aios-core/product/checklists/story-draft-checklist.md +215 -215
  275. package/.aios-core/product/data/atomic-design-principles.md +108 -0
  276. package/.aios-core/product/data/brainstorming-techniques.md +36 -36
  277. package/.aios-core/product/data/consolidation-algorithms.md +142 -0
  278. package/.aios-core/product/data/database-best-practices.md +182 -0
  279. package/.aios-core/product/data/design-token-best-practices.md +107 -0
  280. package/.aios-core/product/data/elicitation-methods.md +134 -134
  281. package/.aios-core/product/data/integration-patterns.md +207 -0
  282. package/.aios-core/product/data/migration-safety-guide.md +329 -0
  283. package/.aios-core/product/data/mode-selection-best-practices.md +471 -471
  284. package/.aios-core/product/data/postgres-tuning-guide.md +300 -0
  285. package/.aios-core/product/data/rls-security-patterns.md +333 -0
  286. package/.aios-core/product/data/roi-calculation-guide.md +142 -0
  287. package/.aios-core/product/data/supabase-patterns.md +330 -0
  288. package/.aios-core/product/data/test-levels-framework.md +148 -148
  289. package/.aios-core/product/data/test-priorities-matrix.md +174 -174
  290. package/.aios-core/product/data/wcag-compliance-guide.md +267 -0
  291. package/.aios-core/product/templates/1mcp-config.yaml +225 -225
  292. package/.aios-core/product/templates/activation-instructions-inline-greeting.yaml +63 -63
  293. package/.aios-core/product/templates/activation-instructions-template.md +258 -258
  294. package/.aios-core/product/templates/agent-template.yaml +120 -120
  295. package/.aios-core/product/templates/architecture-tmpl.yaml +650 -650
  296. package/.aios-core/product/templates/brainstorming-output-tmpl.yaml +155 -155
  297. package/.aios-core/product/templates/brownfield-architecture-tmpl.yaml +475 -475
  298. package/.aios-core/product/templates/brownfield-prd-tmpl.yaml +279 -279
  299. package/.aios-core/product/templates/changelog-template.md +134 -134
  300. package/.aios-core/product/templates/command-rationalization-matrix.md +152 -152
  301. package/.aios-core/product/templates/competitor-analysis-tmpl.yaml +292 -292
  302. package/.aios-core/product/templates/design-story-tmpl.yaml +587 -587
  303. package/.aios-core/product/templates/ds-artifact-analysis.md +70 -70
  304. package/.aios-core/product/templates/front-end-architecture-tmpl.yaml +205 -205
  305. package/.aios-core/product/templates/front-end-spec-tmpl.yaml +348 -348
  306. package/.aios-core/product/templates/fullstack-architecture-tmpl.yaml +804 -804
  307. package/.aios-core/product/templates/github-pr-template.md +67 -67
  308. package/.aios-core/product/templates/gordon-mcp.yaml +140 -140
  309. package/.aios-core/product/templates/ide-rules/antigravity-rules.md +115 -115
  310. package/.aios-core/product/templates/ide-rules/claude-rules.md +221 -221
  311. package/.aios-core/product/templates/ide-rules/cline-rules.md +84 -84
  312. package/.aios-core/product/templates/ide-rules/copilot-rules.md +92 -92
  313. package/.aios-core/product/templates/ide-rules/cursor-rules.md +115 -115
  314. package/.aios-core/product/templates/ide-rules/gemini-rules.md +85 -85
  315. package/.aios-core/product/templates/ide-rules/roo-rules.md +86 -86
  316. package/.aios-core/product/templates/ide-rules/trae-rules.md +104 -104
  317. package/.aios-core/product/templates/ide-rules/windsurf-rules.md +80 -80
  318. package/.aios-core/product/templates/index-strategy-tmpl.yaml +53 -53
  319. package/.aios-core/product/templates/market-research-tmpl.yaml +251 -251
  320. package/.aios-core/product/templates/mcp-workflow.js +271 -271
  321. package/.aios-core/product/templates/migration-plan-tmpl.yaml +1022 -1022
  322. package/.aios-core/product/templates/migration-strategy-tmpl.md +524 -524
  323. package/.aios-core/product/templates/personalized-agent-template.md +258 -258
  324. package/.aios-core/product/templates/personalized-checklist-template.md +340 -340
  325. package/.aios-core/product/templates/personalized-task-template-v2.md +905 -905
  326. package/.aios-core/product/templates/personalized-task-template.md +344 -344
  327. package/.aios-core/product/templates/personalized-template-file.yaml +322 -322
  328. package/.aios-core/product/templates/personalized-workflow-template.yaml +460 -460
  329. package/.aios-core/product/templates/prd-tmpl.yaml +201 -201
  330. package/.aios-core/product/templates/project-brief-tmpl.yaml +220 -220
  331. package/.aios-core/product/templates/qa-gate-tmpl.yaml +240 -240
  332. package/.aios-core/product/templates/rls-policies-tmpl.yaml +1203 -1203
  333. package/.aios-core/product/templates/schema-design-tmpl.yaml +428 -428
  334. package/.aios-core/product/templates/state-persistence-tmpl.yaml +219 -219
  335. package/.aios-core/product/templates/story-tmpl.yaml +331 -331
  336. package/.aios-core/product/templates/task-execution-report.md +495 -495
  337. package/.aios-core/product/templates/task-template.md +122 -122
  338. package/.aios-core/product/templates/token-exports-tailwind-tmpl.js +395 -395
  339. package/.aios-core/product/templates/tokens-schema-tmpl.yaml +305 -305
  340. package/.aios-core/product/templates/workflow-template.yaml +133 -133
  341. package/.aios-core/scripts/README.md +354 -354
  342. package/.aios-core/scripts/aios-doc-template.md +325 -325
  343. package/.aios-core/scripts/elicitation-engine.js +1 -1
  344. package/.aios-core/scripts/test-template-system.js +1 -1
  345. package/.aios-core/scripts/workflow-management.md +69 -69
  346. package/.aios-core/user-guide.md +1413 -1413
  347. package/.aios-core/working-in-the-brownfield.md +361 -361
  348. package/LICENSE +1 -1
  349. package/README.md +702 -703
  350. package/bin/aios-init-old.js +3 -3
  351. package/bin/aios-init-v4.js +1 -1
  352. package/bin/aios-init.backup-v1.1.4.js +1 -1
  353. package/bin/aios-init.js +3 -3
  354. package/bin/aios.js +279 -279
  355. package/bin/utils/install-errors.js +339 -339
  356. package/bin/utils/install-transaction.js +445 -445
  357. package/index.d.ts +18 -18
  358. package/index.esm.js +20 -20
  359. package/index.js +6 -6
  360. package/package.json +8 -10
  361. package/packages/installer/src/config/templates/env-template.js +27 -4
  362. package/packages/installer/src/detection/detect-project-type.js +81 -81
  363. package/packages/installer/src/wizard/wizard.js +185 -34
  364. package/packages/installer/tests/integration/environment-configuration.test.js +2 -1
  365. package/packages/installer/tests/integration/wizard-detection.test.js +8 -6
  366. package/packages/installer/tests/unit/env-template.test.js +11 -10
  367. package/src/config/ide-configs.js +1 -1
  368. package/src/wizard/feedback.js +2 -2
  369. package/src/wizard/index.js +1 -1
  370. package/src/wizard/validation/report-generator.js +1 -1
  371. package/src/wizard/validation/troubleshooting-system.js +13 -13
  372. package/.aios-core/development/tasks/validate-structure.md +0 -243
  373. package/.aios-core/infrastructure/scripts/_archived/final-todo-count.js +0 -122
  374. package/.aios-core/infrastructure/scripts/_archived/fix-yaml-formatting.js +0 -89
  375. package/.aios-core/infrastructure/scripts/_archived/migration-generator.js +0 -780
  376. package/.aios-core/infrastructure/scripts/_archived/migration-path-generator.js +0 -950
  377. package/.aios-core/infrastructure/scripts/_archived/phase2-entrada-saida-errors.js +0 -425
  378. package/.aios-core/infrastructure/scripts/_archived/phase2-spot-check.js +0 -132
  379. package/.aios-core/infrastructure/scripts/_archived/phase3-tools-scripts-validation.js +0 -381
  380. package/.aios-core/infrastructure/scripts/_archived/phase4-metadata-performance.js +0 -203
  381. package/.aios-core/infrastructure/scripts/_archived/test-yaml-parsing.js +0 -24
  382. package/.aios-core/infrastructure/scripts/_archived/verify-yaml-fix.js +0 -51
  383. package/.aios-core/infrastructure/scripts/source-tree-guardian/index.js +0 -375
  384. package/.aios-core/infrastructure/scripts/source-tree-guardian/manifest-generator.js +0 -410
  385. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/naming-rules.yaml +0 -285
  386. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/placement-rules.yaml +0 -262
  387. package/.aios-core/infrastructure/scripts/source-tree-guardian/validator.js +0 -468
  388. package/.aios-core/tasks/find-component.md.legacy +0 -391
  389. package/.aios-core/tasks/generate-commit-message.md.legacy +0 -426
  390. package/.aios-core/tasks/generate-migration.md.legacy +0 -382
  391. package/.aios-core/tasks/rollback-modification.md.legacy +0 -307
  392. package/.aios-core/tasks/update-tests.md.legacy +0 -283
@@ -1,445 +1,445 @@
1
- /**
2
- * InstallTransaction - Transaction manager for AIOS installer
3
- *
4
- * Provides atomic installation operations with automatic rollback on failure.
5
- * Backs up files before modification and restores them if installation fails.
6
- *
7
- * @module bin/utils/install-transaction
8
- * @see Story 1.9 - Error Handling & Rollback
9
- */
10
-
11
- const fs = require('fs-extra');
12
- const path = require('path');
13
- const crypto = require('crypto');
14
-
15
- // Error classification constants
16
- const ERROR_TYPES = {
17
- CRITICAL: 'CRITICAL',
18
- RECOVERABLE: 'RECOVERABLE',
19
- WARNING: 'WARNING',
20
- };
21
-
22
- // Critical errors that trigger immediate rollback
23
- const CRITICAL_ERRORS = [
24
- 'EACCES', // Permission denied
25
- 'ENOSPC', // No space left on device
26
- 'EROFS', // Read-only file system
27
- 'ENOTDIR', // Not a directory
28
- 'EISDIR', // Is a directory
29
- ];
30
-
31
- class InstallTransaction {
32
- /**
33
- * Create a new installation transaction
34
- *
35
- * @param {Object} options - Transaction options
36
- * @param {string} [options.backupDir] - Custom backup directory path
37
- * @param {string} [options.logFile] - Custom log file path
38
- */
39
- constructor(options = {}) {
40
- this.backupDir = options.backupDir || path.join(process.cwd(), '.aios-backup', this._generateTimestamp());
41
- this.logFile = options.logFile || path.join(process.cwd(), '.aios-install.log');
42
- this.backups = []; // [{original, backup, hash, isDirectory}]
43
- this.operations = []; // [{timestamp, level, message}]
44
- this.isCommitted = false;
45
- this.isRolledBack = false;
46
- }
47
-
48
- /**
49
- * Generate timestamp for backup directory naming
50
- * Format: 2025-01-23_14-30-45-123Z
51
- *
52
- * @private
53
- * @returns {string} ISO timestamp with safe filename characters
54
- */
55
- _generateTimestamp() {
56
- // Replace colons, dots, and T separator for Windows compatibility
57
- return new Date().toISOString()
58
- .replace(/:/g, '-')
59
- .replace(/\./g, '-')
60
- .replace('T', '_');
61
- }
62
-
63
- /**
64
- * Backup a single file before modification
65
- *
66
- * @param {string} filePath - Path to file to backup
67
- * @throws {Error} If backup operation fails
68
- *
69
- * @example
70
- * await transaction.backup('package.json');
71
- */
72
- async backup(filePath) {
73
- const originalPath = path.resolve(filePath);
74
-
75
- // Check if file exists
76
- if (!(await fs.pathExists(originalPath))) {
77
- this.log('WARN', `File not found for backup: ${filePath}`);
78
- return;
79
- }
80
-
81
- // Prevent symlink attacks (security)
82
- const stats = await fs.lstat(originalPath);
83
- if (stats.isSymbolicLink()) {
84
- throw new Error(`Symlink detected in backup path - potential security risk: ${filePath}`);
85
- }
86
-
87
- // Skip if already backed up
88
- if (this.backups.find((b) => b.original === originalPath)) {
89
- this.log('DEBUG', `File already backed up: ${filePath}`);
90
- return;
91
- }
92
-
93
- // Generate unique backup filename using path hash to prevent collisions
94
- // e.g., /app/config.json and /data/config.json won't overwrite each other
95
- const pathHash = crypto.createHash('sha256').update(originalPath).digest('hex').substring(0, 8);
96
- const backupFilename = `${path.basename(filePath)}.${pathHash}.backup`;
97
- const backupPath = path.join(this.backupDir, backupFilename);
98
- await fs.ensureDir(this.backupDir);
99
-
100
- // Set restrictive permissions on backup directory (owner only)
101
- try {
102
- await fs.chmod(this.backupDir, 0o700);
103
- } catch (error) {
104
- // Windows doesn't support chmod - log warning but continue
105
- this.log('DEBUG', `Could not set backup directory permissions: ${error.message}`);
106
- }
107
-
108
- await fs.copy(originalPath, backupPath);
109
-
110
- const hash = await this._calculateHash(originalPath);
111
- this.backups.push({ original: originalPath, backup: backupPath, hash });
112
- this.log('INFO', `Backed up: ${filePath}`);
113
- }
114
-
115
- /**
116
- * Backup entire directory recursively
117
- *
118
- * @param {string} dirPath - Path to directory to backup
119
- * @throws {Error} If backup operation fails
120
- *
121
- * @example
122
- * await transaction.backupDirectory('.aios-core/');
123
- */
124
- async backupDirectory(dirPath) {
125
- const originalPath = path.resolve(dirPath);
126
-
127
- if (!(await fs.pathExists(originalPath))) {
128
- this.log('WARN', `Directory not found for backup: ${dirPath}`);
129
- return;
130
- }
131
-
132
- // Prevent symlink attacks (security) - use lstat to detect symlinks
133
- const stats = await fs.lstat(originalPath);
134
- if (stats.isSymbolicLink()) {
135
- throw new Error(`Symlink detected in backup path - potential security risk: ${dirPath}`);
136
- }
137
-
138
- if (!stats.isDirectory()) {
139
- throw new Error(`Path is not a directory: ${dirPath}`);
140
- }
141
-
142
- // Skip if already backed up
143
- if (this.backups.find((b) => b.original === originalPath)) {
144
- this.log('DEBUG', `Directory already backed up: ${dirPath}`);
145
- return;
146
- }
147
-
148
- // Generate unique backup dirname using path hash to prevent collisions
149
- const pathHash = crypto.createHash('sha256').update(originalPath).digest('hex').substring(0, 8);
150
- const backupDirname = `${path.basename(dirPath)}.${pathHash}`;
151
- const backupPath = path.join(this.backupDir, backupDirname);
152
- await fs.ensureDir(this.backupDir);
153
-
154
- // Set restrictive permissions
155
- try {
156
- await fs.chmod(this.backupDir, 0o700);
157
- } catch (error) {
158
- this.log('DEBUG', `Could not set backup directory permissions: ${error.message}`);
159
- }
160
-
161
- await fs.copy(originalPath, backupPath, { recursive: true });
162
-
163
- this.backups.push({ original: originalPath, backup: backupPath, isDirectory: true });
164
- this.log('INFO', `Backed up directory: ${dirPath}`);
165
- }
166
-
167
- /**
168
- * Calculate SHA-256 hash of file for verification
169
- *
170
- * @private
171
- * @param {string} filePath - Path to file
172
- * @returns {Promise<string>} Hex-encoded hash
173
- */
174
- async _calculateHash(filePath) {
175
- const content = await fs.readFile(filePath);
176
- return crypto.createHash('sha256').update(content).digest('hex');
177
- }
178
-
179
- /**
180
- * Verify backup integrity by comparing hashes
181
- *
182
- * @private
183
- * @param {Object} backup - Backup entry {original, backup, hash}
184
- * @returns {Promise<boolean>} True if backup is valid
185
- */
186
- async _verifyBackup(backup) {
187
- if (backup.isDirectory) {
188
- // For directories, just check existence
189
- return await fs.pathExists(backup.backup);
190
- }
191
-
192
- if (!(await fs.pathExists(backup.backup))) {
193
- return false;
194
- }
195
-
196
- const backupHash = await this._calculateHash(backup.backup);
197
- return backupHash === backup.hash;
198
- }
199
-
200
- /**
201
- * Rollback all changes by restoring backups
202
- *
203
- * @returns {Promise<boolean>} True if rollback succeeded, false if partial failure
204
- *
205
- * @example
206
- * try {
207
- * await installAIOS();
208
- * } catch (error) {
209
- * await transaction.rollback();
210
- * }
211
- */
212
- async rollback() {
213
- if (this.isCommitted) {
214
- this.log('ERROR', 'Cannot rollback: transaction already committed');
215
- return false;
216
- }
217
-
218
- if (this.isRolledBack) {
219
- this.log('WARN', 'Transaction already rolled back');
220
- return true;
221
- }
222
-
223
- this.log('ERROR', 'Installation failed. Starting rollback...');
224
- let rollbackSuccess = true;
225
- const failedRestores = [];
226
-
227
- // Restore in reverse order (LIFO - last backup restored first)
228
- for (const backup of [...this.backups].reverse()) {
229
- try {
230
- // Verify backup integrity before restore
231
- const isValid = await this._verifyBackup(backup);
232
- if (!isValid) {
233
- this.log('ERROR', `Backup verification failed for ${backup.original}`);
234
- failedRestores.push(backup.original);
235
- rollbackSuccess = false;
236
- continue;
237
- }
238
-
239
- // Atomic restore: Copy to temp first, then move to original
240
- // This prevents data loss if copy fails
241
- const tempPath = `${backup.original}.restore-temp`;
242
-
243
- try {
244
- // Copy backup to temporary location
245
- await fs.copy(backup.backup, tempPath, { recursive: backup.isDirectory });
246
-
247
- // Remove failed installation artifacts (safe now that restore is ready)
248
- if (await fs.pathExists(backup.original)) {
249
- await fs.remove(backup.original);
250
- }
251
-
252
- // Atomic move from temp to original
253
- await fs.move(tempPath, backup.original, { overwrite: true });
254
- } finally {
255
- // Cleanup temp file if it still exists (error case)
256
- if (await fs.pathExists(tempPath)) {
257
- await fs.remove(tempPath);
258
- }
259
- }
260
-
261
- this.log('INFO', `Restored: ${backup.original}`);
262
- } catch (error) {
263
- this.log('ERROR', `Failed to restore ${backup.original}: ${error.message}`);
264
- failedRestores.push(backup.original);
265
- rollbackSuccess = false;
266
- }
267
- }
268
-
269
- // Cleanup backup directory
270
- try {
271
- await fs.remove(this.backupDir);
272
- this.log('INFO', 'Backup directory cleaned up');
273
- } catch (error) {
274
- this.log('WARN', `Failed to cleanup backup directory: ${error.message}`);
275
- }
276
-
277
- this.isRolledBack = true;
278
-
279
- if (failedRestores.length > 0) {
280
- this.log('ERROR', `Rollback completed with errors. Failed to restore: ${failedRestores.join(', ')}`);
281
- } else {
282
- this.log('INFO', 'Rollback completed successfully');
283
- }
284
-
285
- return rollbackSuccess;
286
- }
287
-
288
- /**
289
- * Commit transaction and cleanup backups (installation succeeded)
290
- *
291
- * @example
292
- * await transaction.commit();
293
- * console.log('Installation successful!');
294
- */
295
- async commit() {
296
- if (this.isRolledBack) {
297
- this.log('ERROR', 'Cannot commit: transaction already rolled back');
298
- return;
299
- }
300
-
301
- if (this.isCommitted) {
302
- this.log('WARN', 'Transaction already committed');
303
- return;
304
- }
305
-
306
- this.log('INFO', 'Installation successful. Cleaning up backups...');
307
-
308
- try {
309
- await fs.remove(this.backupDir);
310
- this.log('INFO', 'Backups cleaned up successfully');
311
- } catch (error) {
312
- this.log('WARN', `Failed to cleanup backups: ${error.message}`);
313
- }
314
-
315
- this.isCommitted = true;
316
- }
317
-
318
- /**
319
- * Log message with timestamp and level
320
- * Sanitizes credentials before writing to log file
321
- *
322
- * @param {string} level - Log level (INFO, WARN, ERROR, DEBUG)
323
- * @param {string} message - Log message
324
- */
325
- log(level, message) {
326
- const timestamp = new Date().toISOString();
327
- const logLine = `[${timestamp}] [${level}] ${message}\n`;
328
-
329
- // Sanitize credentials (API keys, tokens, passwords)
330
- const sanitized = this._sanitizeCredentials(logLine);
331
-
332
- // Write to log file (append mode)
333
- try {
334
- fs.appendFileSync(this.logFile, sanitized);
335
- } catch (error) {
336
- // If logging fails, don't crash - just write to console
337
- console.error(`Failed to write to log file: ${error.message}`);
338
- }
339
-
340
- // Store in memory for programmatic access
341
- this.operations.push({ timestamp, level, message });
342
-
343
- // Rotate log if it exceeds 10MB
344
- this._rotateLogIfNeeded();
345
- }
346
-
347
- /**
348
- * Sanitize sensitive data from log messages
349
- * Prevents API keys, tokens, and passwords from being logged
350
- *
351
- * @private
352
- * @param {string} text - Text to sanitize
353
- * @returns {string} Sanitized text
354
- */
355
- _sanitizeCredentials(text) {
356
- // Pattern 1: Long hex strings (API keys, tokens)
357
- let sanitized = text.replace(/[a-f0-9]{32,}/gi, '[REDACTED]');
358
-
359
- // Pattern 2: Bearer tokens
360
- sanitized = sanitized.replace(/Bearer\s+[^\s]+/gi, 'Bearer [REDACTED]');
361
-
362
- // Pattern 3: Password fields (password=xxx, pwd=xxx)
363
- sanitized = sanitized.replace(/(password|pwd|token|key|secret|auth)[:=]\s*[^\s,}]+/gi, '$1=[REDACTED]');
364
-
365
- // Pattern 4: Environment variables that look like secrets
366
- sanitized = sanitized.replace(/([A-Z_]+_(?:KEY|TOKEN|SECRET|PASSWORD|AUTH))[:=]\s*[^\s,}]+/gi, '$1=[REDACTED]');
367
-
368
- return sanitized;
369
- }
370
-
371
- /**
372
- * Rotate log file if it exceeds 10MB
373
- * Keeps last 5 logs
374
- *
375
- * @private
376
- */
377
- _rotateLogIfNeeded() {
378
- try {
379
- // Check if log file exists before trying to get stats
380
- if (!fs.existsSync(this.logFile)) {
381
- return;
382
- }
383
-
384
- const stats = fs.statSync(this.logFile);
385
- const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
386
- const MAX_LOG_FILES = 5;
387
-
388
- if (stats.size < MAX_LOG_SIZE) {
389
- return;
390
- }
391
-
392
- // Rotate existing logs (log.4 -> log.5, log.3 -> log.4, etc.)
393
- for (let i = MAX_LOG_FILES - 1; i >= 1; i--) {
394
- const oldPath = `${this.logFile}.${i}`;
395
- const newPath = `${this.logFile}.${i + 1}`;
396
-
397
- if (fs.existsSync(oldPath)) {
398
- if (i === MAX_LOG_FILES - 1) {
399
- fs.unlinkSync(oldPath); // Delete oldest log
400
- } else {
401
- fs.renameSync(oldPath, newPath);
402
- }
403
- }
404
- }
405
-
406
- // Move current log to .1
407
- fs.renameSync(this.logFile, `${this.logFile}.1`);
408
-
409
- this.log('INFO', 'Log file rotated');
410
- } catch (error) {
411
- // Rotation failure is non-critical
412
- console.error(`Log rotation failed: ${error.message}`);
413
- }
414
- }
415
-
416
- /**
417
- * Classify error type based on error code
418
- *
419
- * @param {Error} error - Error object
420
- * @returns {string} ERROR_TYPES constant (CRITICAL, RECOVERABLE, WARNING)
421
- */
422
- classifyError(error) {
423
- if (!error.code) {
424
- return ERROR_TYPES.RECOVERABLE;
425
- }
426
-
427
- if (CRITICAL_ERRORS.includes(error.code)) {
428
- return ERROR_TYPES.CRITICAL;
429
- }
430
-
431
- return ERROR_TYPES.RECOVERABLE;
432
- }
433
-
434
- /**
435
- * Check if error is critical (requires rollback)
436
- *
437
- * @param {Error} error - Error object
438
- * @returns {boolean} True if error is critical
439
- */
440
- isCriticalError(error) {
441
- return this.classifyError(error) === ERROR_TYPES.CRITICAL;
442
- }
443
- }
444
-
445
- module.exports = { InstallTransaction, ERROR_TYPES, CRITICAL_ERRORS };
1
+ /**
2
+ * InstallTransaction - Transaction manager for AIOS installer
3
+ *
4
+ * Provides atomic installation operations with automatic rollback on failure.
5
+ * Backs up files before modification and restores them if installation fails.
6
+ *
7
+ * @module bin/utils/install-transaction
8
+ * @see Story 1.9 - Error Handling & Rollback
9
+ */
10
+
11
+ const fs = require('fs-extra');
12
+ const path = require('path');
13
+ const crypto = require('crypto');
14
+
15
+ // Error classification constants
16
+ const ERROR_TYPES = {
17
+ CRITICAL: 'CRITICAL',
18
+ RECOVERABLE: 'RECOVERABLE',
19
+ WARNING: 'WARNING',
20
+ };
21
+
22
+ // Critical errors that trigger immediate rollback
23
+ const CRITICAL_ERRORS = [
24
+ 'EACCES', // Permission denied
25
+ 'ENOSPC', // No space left on device
26
+ 'EROFS', // Read-only file system
27
+ 'ENOTDIR', // Not a directory
28
+ 'EISDIR', // Is a directory
29
+ ];
30
+
31
+ class InstallTransaction {
32
+ /**
33
+ * Create a new installation transaction
34
+ *
35
+ * @param {Object} options - Transaction options
36
+ * @param {string} [options.backupDir] - Custom backup directory path
37
+ * @param {string} [options.logFile] - Custom log file path
38
+ */
39
+ constructor(options = {}) {
40
+ this.backupDir = options.backupDir || path.join(process.cwd(), '.aios-backup', this._generateTimestamp());
41
+ this.logFile = options.logFile || path.join(process.cwd(), '.aios-install.log');
42
+ this.backups = []; // [{original, backup, hash, isDirectory}]
43
+ this.operations = []; // [{timestamp, level, message}]
44
+ this.isCommitted = false;
45
+ this.isRolledBack = false;
46
+ }
47
+
48
+ /**
49
+ * Generate timestamp for backup directory naming
50
+ * Format: 2025-01-23_14-30-45-123Z
51
+ *
52
+ * @private
53
+ * @returns {string} ISO timestamp with safe filename characters
54
+ */
55
+ _generateTimestamp() {
56
+ // Replace colons, dots, and T separator for Windows compatibility
57
+ return new Date().toISOString()
58
+ .replace(/:/g, '-')
59
+ .replace(/\./g, '-')
60
+ .replace('T', '_');
61
+ }
62
+
63
+ /**
64
+ * Backup a single file before modification
65
+ *
66
+ * @param {string} filePath - Path to file to backup
67
+ * @throws {Error} If backup operation fails
68
+ *
69
+ * @example
70
+ * await transaction.backup('package.json');
71
+ */
72
+ async backup(filePath) {
73
+ const originalPath = path.resolve(filePath);
74
+
75
+ // Check if file exists
76
+ if (!(await fs.pathExists(originalPath))) {
77
+ this.log('WARN', `File not found for backup: ${filePath}`);
78
+ return;
79
+ }
80
+
81
+ // Prevent symlink attacks (security)
82
+ const stats = await fs.lstat(originalPath);
83
+ if (stats.isSymbolicLink()) {
84
+ throw new Error(`Symlink detected in backup path - potential security risk: ${filePath}`);
85
+ }
86
+
87
+ // Skip if already backed up
88
+ if (this.backups.find((b) => b.original === originalPath)) {
89
+ this.log('DEBUG', `File already backed up: ${filePath}`);
90
+ return;
91
+ }
92
+
93
+ // Generate unique backup filename using path hash to prevent collisions
94
+ // e.g., /app/config.json and /data/config.json won't overwrite each other
95
+ const pathHash = crypto.createHash('sha256').update(originalPath).digest('hex').substring(0, 8);
96
+ const backupFilename = `${path.basename(filePath)}.${pathHash}.backup`;
97
+ const backupPath = path.join(this.backupDir, backupFilename);
98
+ await fs.ensureDir(this.backupDir);
99
+
100
+ // Set restrictive permissions on backup directory (owner only)
101
+ try {
102
+ await fs.chmod(this.backupDir, 0o700);
103
+ } catch (error) {
104
+ // Windows doesn't support chmod - log warning but continue
105
+ this.log('DEBUG', `Could not set backup directory permissions: ${error.message}`);
106
+ }
107
+
108
+ await fs.copy(originalPath, backupPath);
109
+
110
+ const hash = await this._calculateHash(originalPath);
111
+ this.backups.push({ original: originalPath, backup: backupPath, hash });
112
+ this.log('INFO', `Backed up: ${filePath}`);
113
+ }
114
+
115
+ /**
116
+ * Backup entire directory recursively
117
+ *
118
+ * @param {string} dirPath - Path to directory to backup
119
+ * @throws {Error} If backup operation fails
120
+ *
121
+ * @example
122
+ * await transaction.backupDirectory('.aios-core/');
123
+ */
124
+ async backupDirectory(dirPath) {
125
+ const originalPath = path.resolve(dirPath);
126
+
127
+ if (!(await fs.pathExists(originalPath))) {
128
+ this.log('WARN', `Directory not found for backup: ${dirPath}`);
129
+ return;
130
+ }
131
+
132
+ // Prevent symlink attacks (security) - use lstat to detect symlinks
133
+ const stats = await fs.lstat(originalPath);
134
+ if (stats.isSymbolicLink()) {
135
+ throw new Error(`Symlink detected in backup path - potential security risk: ${dirPath}`);
136
+ }
137
+
138
+ if (!stats.isDirectory()) {
139
+ throw new Error(`Path is not a directory: ${dirPath}`);
140
+ }
141
+
142
+ // Skip if already backed up
143
+ if (this.backups.find((b) => b.original === originalPath)) {
144
+ this.log('DEBUG', `Directory already backed up: ${dirPath}`);
145
+ return;
146
+ }
147
+
148
+ // Generate unique backup dirname using path hash to prevent collisions
149
+ const pathHash = crypto.createHash('sha256').update(originalPath).digest('hex').substring(0, 8);
150
+ const backupDirname = `${path.basename(dirPath)}.${pathHash}`;
151
+ const backupPath = path.join(this.backupDir, backupDirname);
152
+ await fs.ensureDir(this.backupDir);
153
+
154
+ // Set restrictive permissions
155
+ try {
156
+ await fs.chmod(this.backupDir, 0o700);
157
+ } catch (error) {
158
+ this.log('DEBUG', `Could not set backup directory permissions: ${error.message}`);
159
+ }
160
+
161
+ await fs.copy(originalPath, backupPath, { recursive: true });
162
+
163
+ this.backups.push({ original: originalPath, backup: backupPath, isDirectory: true });
164
+ this.log('INFO', `Backed up directory: ${dirPath}`);
165
+ }
166
+
167
+ /**
168
+ * Calculate SHA-256 hash of file for verification
169
+ *
170
+ * @private
171
+ * @param {string} filePath - Path to file
172
+ * @returns {Promise<string>} Hex-encoded hash
173
+ */
174
+ async _calculateHash(filePath) {
175
+ const content = await fs.readFile(filePath);
176
+ return crypto.createHash('sha256').update(content).digest('hex');
177
+ }
178
+
179
+ /**
180
+ * Verify backup integrity by comparing hashes
181
+ *
182
+ * @private
183
+ * @param {Object} backup - Backup entry {original, backup, hash}
184
+ * @returns {Promise<boolean>} True if backup is valid
185
+ */
186
+ async _verifyBackup(backup) {
187
+ if (backup.isDirectory) {
188
+ // For directories, just check existence
189
+ return await fs.pathExists(backup.backup);
190
+ }
191
+
192
+ if (!(await fs.pathExists(backup.backup))) {
193
+ return false;
194
+ }
195
+
196
+ const backupHash = await this._calculateHash(backup.backup);
197
+ return backupHash === backup.hash;
198
+ }
199
+
200
+ /**
201
+ * Rollback all changes by restoring backups
202
+ *
203
+ * @returns {Promise<boolean>} True if rollback succeeded, false if partial failure
204
+ *
205
+ * @example
206
+ * try {
207
+ * await installAIOS();
208
+ * } catch (error) {
209
+ * await transaction.rollback();
210
+ * }
211
+ */
212
+ async rollback() {
213
+ if (this.isCommitted) {
214
+ this.log('ERROR', 'Cannot rollback: transaction already committed');
215
+ return false;
216
+ }
217
+
218
+ if (this.isRolledBack) {
219
+ this.log('WARN', 'Transaction already rolled back');
220
+ return true;
221
+ }
222
+
223
+ this.log('ERROR', 'Installation failed. Starting rollback...');
224
+ let rollbackSuccess = true;
225
+ const failedRestores = [];
226
+
227
+ // Restore in reverse order (LIFO - last backup restored first)
228
+ for (const backup of [...this.backups].reverse()) {
229
+ try {
230
+ // Verify backup integrity before restore
231
+ const isValid = await this._verifyBackup(backup);
232
+ if (!isValid) {
233
+ this.log('ERROR', `Backup verification failed for ${backup.original}`);
234
+ failedRestores.push(backup.original);
235
+ rollbackSuccess = false;
236
+ continue;
237
+ }
238
+
239
+ // Atomic restore: Copy to temp first, then move to original
240
+ // This prevents data loss if copy fails
241
+ const tempPath = `${backup.original}.restore-temp`;
242
+
243
+ try {
244
+ // Copy backup to temporary location
245
+ await fs.copy(backup.backup, tempPath, { recursive: backup.isDirectory });
246
+
247
+ // Remove failed installation artifacts (safe now that restore is ready)
248
+ if (await fs.pathExists(backup.original)) {
249
+ await fs.remove(backup.original);
250
+ }
251
+
252
+ // Atomic move from temp to original
253
+ await fs.move(tempPath, backup.original, { overwrite: true });
254
+ } finally {
255
+ // Cleanup temp file if it still exists (error case)
256
+ if (await fs.pathExists(tempPath)) {
257
+ await fs.remove(tempPath);
258
+ }
259
+ }
260
+
261
+ this.log('INFO', `Restored: ${backup.original}`);
262
+ } catch (error) {
263
+ this.log('ERROR', `Failed to restore ${backup.original}: ${error.message}`);
264
+ failedRestores.push(backup.original);
265
+ rollbackSuccess = false;
266
+ }
267
+ }
268
+
269
+ // Cleanup backup directory
270
+ try {
271
+ await fs.remove(this.backupDir);
272
+ this.log('INFO', 'Backup directory cleaned up');
273
+ } catch (error) {
274
+ this.log('WARN', `Failed to cleanup backup directory: ${error.message}`);
275
+ }
276
+
277
+ this.isRolledBack = true;
278
+
279
+ if (failedRestores.length > 0) {
280
+ this.log('ERROR', `Rollback completed with errors. Failed to restore: ${failedRestores.join(', ')}`);
281
+ } else {
282
+ this.log('INFO', 'Rollback completed successfully');
283
+ }
284
+
285
+ return rollbackSuccess;
286
+ }
287
+
288
+ /**
289
+ * Commit transaction and cleanup backups (installation succeeded)
290
+ *
291
+ * @example
292
+ * await transaction.commit();
293
+ * console.log('Installation successful!');
294
+ */
295
+ async commit() {
296
+ if (this.isRolledBack) {
297
+ this.log('ERROR', 'Cannot commit: transaction already rolled back');
298
+ return;
299
+ }
300
+
301
+ if (this.isCommitted) {
302
+ this.log('WARN', 'Transaction already committed');
303
+ return;
304
+ }
305
+
306
+ this.log('INFO', 'Installation successful. Cleaning up backups...');
307
+
308
+ try {
309
+ await fs.remove(this.backupDir);
310
+ this.log('INFO', 'Backups cleaned up successfully');
311
+ } catch (error) {
312
+ this.log('WARN', `Failed to cleanup backups: ${error.message}`);
313
+ }
314
+
315
+ this.isCommitted = true;
316
+ }
317
+
318
+ /**
319
+ * Log message with timestamp and level
320
+ * Sanitizes credentials before writing to log file
321
+ *
322
+ * @param {string} level - Log level (INFO, WARN, ERROR, DEBUG)
323
+ * @param {string} message - Log message
324
+ */
325
+ log(level, message) {
326
+ const timestamp = new Date().toISOString();
327
+ const logLine = `[${timestamp}] [${level}] ${message}\n`;
328
+
329
+ // Sanitize credentials (API keys, tokens, passwords)
330
+ const sanitized = this._sanitizeCredentials(logLine);
331
+
332
+ // Write to log file (append mode)
333
+ try {
334
+ fs.appendFileSync(this.logFile, sanitized);
335
+ } catch (error) {
336
+ // If logging fails, don't crash - just write to console
337
+ console.error(`Failed to write to log file: ${error.message}`);
338
+ }
339
+
340
+ // Store in memory for programmatic access
341
+ this.operations.push({ timestamp, level, message });
342
+
343
+ // Rotate log if it exceeds 10MB
344
+ this._rotateLogIfNeeded();
345
+ }
346
+
347
+ /**
348
+ * Sanitize sensitive data from log messages
349
+ * Prevents API keys, tokens, and passwords from being logged
350
+ *
351
+ * @private
352
+ * @param {string} text - Text to sanitize
353
+ * @returns {string} Sanitized text
354
+ */
355
+ _sanitizeCredentials(text) {
356
+ // Pattern 1: Long hex strings (API keys, tokens)
357
+ let sanitized = text.replace(/[a-f0-9]{32,}/gi, '[REDACTED]');
358
+
359
+ // Pattern 2: Bearer tokens
360
+ sanitized = sanitized.replace(/Bearer\s+[^\s]+/gi, 'Bearer [REDACTED]');
361
+
362
+ // Pattern 3: Password fields (password=xxx, pwd=xxx)
363
+ sanitized = sanitized.replace(/(password|pwd|token|key|secret|auth)[:=]\s*[^\s,}]+/gi, '$1=[REDACTED]');
364
+
365
+ // Pattern 4: Environment variables that look like secrets
366
+ sanitized = sanitized.replace(/([A-Z_]+_(?:KEY|TOKEN|SECRET|PASSWORD|AUTH))[:=]\s*[^\s,}]+/gi, '$1=[REDACTED]');
367
+
368
+ return sanitized;
369
+ }
370
+
371
+ /**
372
+ * Rotate log file if it exceeds 10MB
373
+ * Keeps last 5 logs
374
+ *
375
+ * @private
376
+ */
377
+ _rotateLogIfNeeded() {
378
+ try {
379
+ // Check if log file exists before trying to get stats
380
+ if (!fs.existsSync(this.logFile)) {
381
+ return;
382
+ }
383
+
384
+ const stats = fs.statSync(this.logFile);
385
+ const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
386
+ const MAX_LOG_FILES = 5;
387
+
388
+ if (stats.size < MAX_LOG_SIZE) {
389
+ return;
390
+ }
391
+
392
+ // Rotate existing logs (log.4 -> log.5, log.3 -> log.4, etc.)
393
+ for (let i = MAX_LOG_FILES - 1; i >= 1; i--) {
394
+ const oldPath = `${this.logFile}.${i}`;
395
+ const newPath = `${this.logFile}.${i + 1}`;
396
+
397
+ if (fs.existsSync(oldPath)) {
398
+ if (i === MAX_LOG_FILES - 1) {
399
+ fs.unlinkSync(oldPath); // Delete oldest log
400
+ } else {
401
+ fs.renameSync(oldPath, newPath);
402
+ }
403
+ }
404
+ }
405
+
406
+ // Move current log to .1
407
+ fs.renameSync(this.logFile, `${this.logFile}.1`);
408
+
409
+ this.log('INFO', 'Log file rotated');
410
+ } catch (error) {
411
+ // Rotation failure is non-critical
412
+ console.error(`Log rotation failed: ${error.message}`);
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Classify error type based on error code
418
+ *
419
+ * @param {Error} error - Error object
420
+ * @returns {string} ERROR_TYPES constant (CRITICAL, RECOVERABLE, WARNING)
421
+ */
422
+ classifyError(error) {
423
+ if (!error.code) {
424
+ return ERROR_TYPES.RECOVERABLE;
425
+ }
426
+
427
+ if (CRITICAL_ERRORS.includes(error.code)) {
428
+ return ERROR_TYPES.CRITICAL;
429
+ }
430
+
431
+ return ERROR_TYPES.RECOVERABLE;
432
+ }
433
+
434
+ /**
435
+ * Check if error is critical (requires rollback)
436
+ *
437
+ * @param {Error} error - Error object
438
+ * @returns {boolean} True if error is critical
439
+ */
440
+ isCriticalError(error) {
441
+ return this.classifyError(error) === ERROR_TYPES.CRITICAL;
442
+ }
443
+ }
444
+
445
+ module.exports = { InstallTransaction, ERROR_TYPES, CRITICAL_ERRORS };